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"
66 #include "theme_manager.h"
67 #include "ui_config.h"
72 using namespace Gtkmm2ext;
74 using namespace ARDOUR;
75 using namespace ARDOUR_UI_UTILS;
77 class ClickOptions : public OptionEditorBox
80 ClickOptions (RCConfiguration* c)
82 , _click_browse_button (_("Browse..."))
83 , _click_emphasis_browse_button (_("Browse..."))
85 Table* t = manage (new Table (4, 3));
88 Label* l = manage (left_aligned_label (_("Emphasis on first beat:")));
89 t->attach (*l, 0, 1, 1, 2, FILL);
90 t->attach (_use_emphasis_on_click_check_button, 1, 2, 1, 2, FILL);
91 _use_emphasis_on_click_check_button.signal_toggled().connect (
92 sigc::mem_fun (*this, &ClickOptions::use_emphasis_on_click_toggled));
94 l = manage (left_aligned_label (_("Use default Click:")));
95 t->attach (*l, 0, 1, 0, 1, FILL);
96 t->attach (_use_default_click_check_button, 1, 2, 0, 1, FILL);
97 _use_default_click_check_button.signal_toggled().connect (
98 sigc::mem_fun (*this, &ClickOptions::use_default_click_toggled));
100 l = manage (left_aligned_label (_("Click audio file:")));
101 t->attach (*l, 0, 1, 2, 3, FILL);
102 t->attach (_click_path_entry, 1, 2, 2, 3, FILL);
103 _click_browse_button.signal_clicked ().connect (
104 sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
105 t->attach (_click_browse_button, 2, 3, 2, 3, FILL);
107 l = manage (left_aligned_label (_("Click emphasis audio file:")));
108 t->attach (*l, 0, 1, 3, 4, FILL);
109 t->attach (_click_emphasis_path_entry, 1, 2, 3, 4, FILL);
110 _click_emphasis_browse_button.signal_clicked ().connect (
111 sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
112 t->attach (_click_emphasis_browse_button, 2, 3, 3, 4, FILL);
114 _box->pack_start (*t, true, false);
116 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
117 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
119 if (_rc_config->get_click_sound ().empty() &&
120 _rc_config->get_click_emphasis_sound().empty()) {
121 _use_default_click_check_button.set_active (true);
122 _use_emphasis_on_click_check_button.set_active (true);
125 _use_default_click_check_button.set_active (false);
126 _use_emphasis_on_click_check_button.set_active (false);
130 void parameter_changed (string const & p)
132 if (p == "click-sound") {
133 _click_path_entry.set_text (_rc_config->get_click_sound());
134 } else if (p == "click-emphasis-sound") {
135 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
136 } else if (p == "use-click-emphasis") {
137 bool x = _rc_config->get_use_click_emphasis ();
138 _use_emphasis_on_click_check_button.set_active (x);
142 void set_state_from_config ()
144 parameter_changed ("click-sound");
145 parameter_changed ("click-emphasis-sound");
146 parameter_changed ("use-click-emphasis");
151 void click_browse_clicked ()
153 SoundFileChooser sfdb (_("Choose Click"));
158 if (sfdb.run () == RESPONSE_OK) {
159 click_chosen (sfdb.get_filename());
163 void click_chosen (string const & path)
165 _click_path_entry.set_text (path);
166 _rc_config->set_click_sound (path);
169 void click_changed ()
171 click_chosen (_click_path_entry.get_text ());
174 void click_emphasis_browse_clicked ()
176 SoundFileChooser sfdb (_("Choose Click Emphasis"));
181 if (sfdb.run () == RESPONSE_OK) {
182 click_emphasis_chosen (sfdb.get_filename());
186 void click_emphasis_chosen (string const & path)
188 _click_emphasis_path_entry.set_text (path);
189 _rc_config->set_click_emphasis_sound (path);
192 void click_emphasis_changed ()
194 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
197 void use_default_click_toggled ()
199 if (_use_default_click_check_button.get_active ()) {
200 _rc_config->set_click_sound ("");
201 _rc_config->set_click_emphasis_sound ("");
202 _click_path_entry.set_sensitive (false);
203 _click_emphasis_path_entry.set_sensitive (false);
204 _click_browse_button.set_sensitive (false);
205 _click_emphasis_browse_button.set_sensitive (false);
207 _click_path_entry.set_sensitive (true);
208 _click_emphasis_path_entry.set_sensitive (true);
209 _click_browse_button.set_sensitive (true);
210 _click_emphasis_browse_button.set_sensitive (true);
214 void use_emphasis_on_click_toggled ()
216 if (_use_emphasis_on_click_check_button.get_active ()) {
217 _rc_config->set_use_click_emphasis(true);
219 _rc_config->set_use_click_emphasis(false);
223 RCConfiguration* _rc_config;
224 CheckButton _use_default_click_check_button;
225 CheckButton _use_emphasis_on_click_check_button;
226 Entry _click_path_entry;
227 Entry _click_emphasis_path_entry;
228 Button _click_browse_button;
229 Button _click_emphasis_browse_button;
232 class UndoOptions : public OptionEditorBox
235 UndoOptions (RCConfiguration* c) :
237 _limit_undo_button (_("Limit undo history to")),
238 _save_undo_button (_("Save undo history of"))
240 Table* t = new Table (2, 3);
243 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
244 _limit_undo_spin.set_range (0, 512);
245 _limit_undo_spin.set_increments (1, 10);
246 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
247 Label* l = manage (left_aligned_label (_("commands")));
248 t->attach (*l, 2, 3, 0, 1);
250 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
251 _save_undo_spin.set_range (0, 512);
252 _save_undo_spin.set_increments (1, 10);
253 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
254 l = manage (left_aligned_label (_("commands")));
255 t->attach (*l, 2, 3, 1, 2);
257 _box->pack_start (*t);
259 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
260 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
261 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
262 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
265 void parameter_changed (string const & p)
267 if (p == "history-depth") {
268 int32_t const d = _rc_config->get_history_depth();
269 _limit_undo_button.set_active (d != 0);
270 _limit_undo_spin.set_sensitive (d != 0);
271 _limit_undo_spin.set_value (d);
272 } else if (p == "save-history") {
273 bool const x = _rc_config->get_save_history ();
274 _save_undo_button.set_active (x);
275 _save_undo_spin.set_sensitive (x);
276 } else if (p == "save-history-depth") {
277 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
281 void set_state_from_config ()
283 parameter_changed ("save-history");
284 parameter_changed ("history-depth");
285 parameter_changed ("save-history-depth");
288 void limit_undo_toggled ()
290 bool const x = _limit_undo_button.get_active ();
291 _limit_undo_spin.set_sensitive (x);
292 int32_t const n = x ? 16 : 0;
293 _limit_undo_spin.set_value (n);
294 _rc_config->set_history_depth (n);
297 void limit_undo_changed ()
299 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
302 void save_undo_toggled ()
304 bool const x = _save_undo_button.get_active ();
305 _rc_config->set_save_history (x);
308 void save_undo_changed ()
310 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
314 RCConfiguration* _rc_config;
315 CheckButton _limit_undo_button;
316 SpinButton _limit_undo_spin;
317 CheckButton _save_undo_button;
318 SpinButton _save_undo_spin;
323 static const struct {
335 { "Key|Shift", GDK_SHIFT_MASK },
336 { "Command", GDK_MOD2_MASK },
337 { "Control", GDK_CONTROL_MASK },
338 { "Option", GDK_MOD1_MASK },
339 { "Command-Shift", GDK_MOD2_MASK|GDK_SHIFT_MASK },
340 { "Command-Option", GDK_MOD2_MASK|GDK_MOD1_MASK },
341 { "Command-Control", GDK_MOD2_MASK|GDK_CONTROL_MASK },
342 { "Command-Option-Control", GDK_MOD2_MASK|GDK_MOD1_MASK|GDK_CONTROL_MASK },
343 { "Option-Control", GDK_MOD1_MASK|GDK_CONTROL_MASK },
344 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
345 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
346 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_MOD2_MASK },
349 { "Key|Shift", GDK_SHIFT_MASK },
350 { "Control", GDK_CONTROL_MASK },
351 { "Alt", GDK_MOD1_MASK },
352 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
353 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
354 { "Control-Windows", GDK_CONTROL_MASK|GDK_MOD4_MASK },
355 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
356 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
357 { "Alt-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
358 { "Alt-Shift-Windows", GDK_MOD1_MASK|GDK_SHIFT_MASK|GDK_MOD4_MASK },
359 { "Mod2", GDK_MOD2_MASK },
360 { "Mod3", GDK_MOD3_MASK },
361 { "Windows", GDK_MOD4_MASK },
362 { "Mod5", GDK_MOD5_MASK },
368 class KeyboardOptions : public OptionEditorBox
372 _delete_button_adjustment (3, 1, 12),
373 _delete_button_spin (_delete_button_adjustment),
374 _edit_button_adjustment (3, 1, 5),
375 _edit_button_spin (_edit_button_adjustment),
376 _insert_note_button_adjustment (3, 1, 5),
377 _insert_note_button_spin (_insert_note_button_adjustment)
379 const std::string restart_msg = _("\nChanges to this setting will only persist after your project has been saved.");
380 /* internationalize and prepare for use with combos */
383 for (int i = 0; modifiers[i].name; ++i) {
384 dumb.push_back (S_(modifiers[i].name));
387 set_popdown_strings (_edit_modifier_combo, dumb);
388 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
389 Gtkmm2ext::UI::instance()->set_tip (_edit_modifier_combo,
390 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
391 for (int x = 0; modifiers[x].name; ++x) {
392 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
393 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
398 Table* t = manage (new Table (5, 11));
404 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
405 l->set_name ("OptionsLabel");
409 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
410 strs.push_back (bf->first);
413 set_popdown_strings (_keyboard_layout_selector, strs);
414 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
415 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
417 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
418 t->attach (_keyboard_layout_selector, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
423 l = manage (left_aligned_label (_("When Clicking:")));
424 l->set_name ("OptionEditorHeading");
425 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
430 l = manage (left_aligned_label (_("Edit using:")));
431 l->set_name ("OptionsLabel");
433 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
434 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
436 l = manage (new Label (_("+ button")));
437 l->set_name ("OptionsLabel");
439 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
440 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
442 _edit_button_spin.set_name ("OptionsEntry");
443 _edit_button_adjustment.set_value (Keyboard::edit_button());
444 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
449 set_popdown_strings (_delete_modifier_combo, dumb);
450 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
451 Gtkmm2ext::UI::instance()->set_tip (_delete_modifier_combo,
452 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
453 for (int x = 0; modifiers[x].name; ++x) {
454 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
455 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
460 l = manage (left_aligned_label (_("Delete using:")));
461 l->set_name ("OptionsLabel");
463 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
464 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
466 l = manage (new Label (_("+ button")));
467 l->set_name ("OptionsLabel");
469 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
470 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
472 _delete_button_spin.set_name ("OptionsEntry");
473 _delete_button_adjustment.set_value (Keyboard::delete_button());
474 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
479 set_popdown_strings (_insert_note_modifier_combo, dumb);
480 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
481 Gtkmm2ext::UI::instance()->set_tip (_insert_note_modifier_combo,
482 (string_compose (_("<b>Recommended Setting: %1 + button 1 (left mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
483 for (int x = 0; modifiers[x].name; ++x) {
484 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
485 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
490 l = manage (left_aligned_label (_("Insert note using:")));
491 l->set_name ("OptionsLabel");
493 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
494 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
496 l = manage (new Label (_("+ button")));
497 l->set_name ("OptionsLabel");
499 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
500 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
502 _insert_note_button_spin.set_name ("OptionsEntry");
503 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
504 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
508 l = manage (left_aligned_label (_("When Beginning a Drag:")));
509 l->set_name ("OptionEditorHeading");
510 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
516 set_popdown_strings (_copy_modifier_combo, dumb);
517 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
518 Gtkmm2ext::UI::instance()->set_tip (_copy_modifier_combo,
519 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
521 Keyboard::secondary_modifier_name (),
523 Keyboard::primary_modifier_name (),
526 for (int x = 0; modifiers[x].name; ++x) {
527 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
528 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
533 l = manage (left_aligned_label (_("Copy items using:")));
534 l->set_name ("OptionsLabel");
536 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
537 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
542 /* constraint modifier */
543 set_popdown_strings (_constraint_modifier_combo, dumb);
544 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
545 std::string mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
546 Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo,
547 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
549 Keyboard::primary_modifier_name (),
551 Keyboard::tertiary_modifier_name (),
554 for (int x = 0; modifiers[x].name; ++x) {
555 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
556 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
561 l = manage (left_aligned_label (_("Constrain drag using:")));
562 l->set_name ("OptionsLabel");
564 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
565 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
571 set_popdown_strings (_push_points_combo, dumb);
572 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
574 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
575 Gtkmm2ext::UI::instance()->set_tip (_push_points_combo,
576 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
577 for (int x = 0; modifiers[x].name; ++x) {
578 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
579 _push_points_combo.set_active_text (S_(modifiers[x].name));
584 l = manage (left_aligned_label (_("Push points using:")));
585 l->set_name ("OptionsLabel");
587 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
588 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
592 l = manage (left_aligned_label (_("When Beginning a Trim:")));
593 l->set_name ("OptionEditorHeading");
594 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
600 set_popdown_strings (_trim_contents_combo, dumb);
601 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
602 Gtkmm2ext::UI::instance()->set_tip (_trim_contents_combo,
603 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
604 for (int x = 0; modifiers[x].name; ++x) {
605 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
606 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
611 l = manage (left_aligned_label (_("Trim contents using:")));
612 l->set_name ("OptionsLabel");
614 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
615 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
621 set_popdown_strings (_trim_anchored_combo, dumb);
622 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
624 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::tertiary_modifier_name ());
625 Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo,
626 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
627 for (int x = 0; modifiers[x].name; ++x) {
628 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
629 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
634 l = manage (left_aligned_label (_("Anchored trim using:")));
635 l->set_name ("OptionsLabel");
637 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
639 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
644 /* jump trim disabled for now
645 set_popdown_strings (_trim_jump_combo, dumb);
646 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
648 for (int x = 0; modifiers[x].name; ++x) {
649 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
650 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
655 l = manage (left_aligned_label (_("Jump after trim using:")));
656 l->set_name ("OptionsLabel");
658 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
660 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
666 /* note resize relative */
667 set_popdown_strings (_note_size_relative_combo, dumb);
668 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
669 Gtkmm2ext::UI::instance()->set_tip (_note_size_relative_combo,
670 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
671 for (int x = 0; modifiers[x].name; ++x) {
672 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
673 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
678 l = manage (left_aligned_label (_("Resize notes relatively using:")));
679 l->set_name ("OptionsLabel");
681 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
683 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
687 l = manage (left_aligned_label (_("While Dragging:")));
688 l->set_name ("OptionEditorHeading");
689 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
695 set_popdown_strings (_snap_modifier_combo, dumb);
696 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
698 mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ());
700 mod_str = Keyboard::secondary_modifier_name();
702 Gtkmm2ext::UI::instance()->set_tip (_snap_modifier_combo,
703 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
704 for (int x = 0; modifiers[x].name; ++x) {
705 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
706 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
711 l = manage (left_aligned_label (_("Ignore snap using:")));
712 l->set_name ("OptionsLabel");
714 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
715 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
721 set_popdown_strings (_snap_delta_combo, dumb);
722 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
724 mod_str = Keyboard::level4_modifier_name ();
726 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::level4_modifier_name ());
728 Gtkmm2ext::UI::instance()->set_tip (_snap_delta_combo,
729 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
730 for (int x = 0; modifiers[x].name; ++x) {
731 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
732 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
737 l = manage (left_aligned_label (_("Snap relatively using:")));
738 l->set_name ("OptionsLabel");
740 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
741 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
745 l = manage (left_aligned_label (_("While Trimming:")));
746 l->set_name ("OptionEditorHeading");
747 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
753 set_popdown_strings (_trim_overlap_combo, dumb);
754 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
756 Gtkmm2ext::UI::instance()->set_tip (_trim_overlap_combo,
757 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
758 for (int x = 0; modifiers[x].name; ++x) {
759 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
760 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
765 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
766 l->set_name ("OptionsLabel");
768 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
769 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
773 l = manage (left_aligned_label (_("While Dragging Control Points:")));
774 l->set_name ("OptionEditorHeading");
775 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
781 set_popdown_strings (_fine_adjust_combo, dumb);
782 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
784 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::secondary_modifier_name ());
785 Gtkmm2ext::UI::instance()->set_tip (_fine_adjust_combo,
786 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
787 for (int x = 0; modifiers[x].name; ++x) {
788 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
789 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
794 l = manage (left_aligned_label (_("Fine adjust using:")));
795 l->set_name ("OptionsLabel");
797 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
798 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
800 _box->pack_start (*t, false, false);
803 void parameter_changed (string const &)
805 /* XXX: these aren't really config options... */
808 void set_state_from_config ()
810 /* XXX: these aren't really config options... */
815 void bindings_changed ()
817 string const txt = _keyboard_layout_selector.get_active_text();
819 /* XXX: config...? for all this keyboard stuff */
821 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
822 if (txt == i->first) {
823 if (Keyboard::load_keybindings (i->second)) {
824 Keyboard::save_keybindings ();
830 void edit_modifier_chosen ()
832 string const txt = _edit_modifier_combo.get_active_text();
834 for (int i = 0; modifiers[i].name; ++i) {
835 if (txt == S_(modifiers[i].name)) {
836 Keyboard::set_edit_modifier (modifiers[i].modifier);
842 void delete_modifier_chosen ()
844 string const txt = _delete_modifier_combo.get_active_text();
846 for (int i = 0; modifiers[i].name; ++i) {
847 if (txt == S_(modifiers[i].name)) {
848 Keyboard::set_delete_modifier (modifiers[i].modifier);
854 void copy_modifier_chosen ()
856 string const txt = _copy_modifier_combo.get_active_text();
858 for (int i = 0; modifiers[i].name; ++i) {
859 if (txt == S_(modifiers[i].name)) {
860 Keyboard::set_copy_modifier (modifiers[i].modifier);
866 void insert_note_modifier_chosen ()
868 string const txt = _insert_note_modifier_combo.get_active_text();
870 for (int i = 0; modifiers[i].name; ++i) {
871 if (txt == S_(modifiers[i].name)) {
872 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
878 void snap_modifier_chosen ()
880 string const txt = _snap_modifier_combo.get_active_text();
882 for (int i = 0; modifiers[i].name; ++i) {
883 if (txt == S_(modifiers[i].name)) {
884 Keyboard::set_snap_modifier (modifiers[i].modifier);
890 void snap_delta_modifier_chosen ()
892 string const txt = _snap_delta_combo.get_active_text();
894 for (int i = 0; modifiers[i].name; ++i) {
895 if (txt == S_(modifiers[i].name)) {
896 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
902 void constraint_modifier_chosen ()
904 string const txt = _constraint_modifier_combo.get_active_text();
906 for (int i = 0; modifiers[i].name; ++i) {
907 if (txt == S_(modifiers[i].name)) {
908 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
914 void trim_contents_modifier_chosen ()
916 string const txt = _trim_contents_combo.get_active_text();
918 for (int i = 0; modifiers[i].name; ++i) {
919 if (txt == S_(modifiers[i].name)) {
920 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
926 void trim_overlap_modifier_chosen ()
928 string const txt = _trim_overlap_combo.get_active_text();
930 for (int i = 0; modifiers[i].name; ++i) {
931 if (txt == S_(modifiers[i].name)) {
932 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
938 void trim_anchored_modifier_chosen ()
940 string const txt = _trim_anchored_combo.get_active_text();
942 for (int i = 0; modifiers[i].name; ++i) {
943 if (txt == S_(modifiers[i].name)) {
944 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
950 void fine_adjust_modifier_chosen ()
952 string const txt = _fine_adjust_combo.get_active_text();
954 for (int i = 0; modifiers[i].name; ++i) {
955 if (txt == S_(modifiers[i].name)) {
956 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
962 void push_points_modifier_chosen ()
964 string const txt = _push_points_combo.get_active_text();
966 for (int i = 0; modifiers[i].name; ++i) {
967 if (txt == S_(modifiers[i].name)) {
968 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
974 void note_size_relative_modifier_chosen ()
976 string const txt = _note_size_relative_combo.get_active_text();
978 for (int i = 0; modifiers[i].name; ++i) {
979 if (txt == S_(modifiers[i].name)) {
980 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
986 void delete_button_changed ()
988 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
991 void edit_button_changed ()
993 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
996 void insert_note_button_changed ()
998 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
1001 ComboBoxText _keyboard_layout_selector;
1002 ComboBoxText _edit_modifier_combo;
1003 ComboBoxText _delete_modifier_combo;
1004 ComboBoxText _copy_modifier_combo;
1005 ComboBoxText _insert_note_modifier_combo;
1006 ComboBoxText _snap_modifier_combo;
1007 ComboBoxText _snap_delta_combo;
1008 ComboBoxText _constraint_modifier_combo;
1009 ComboBoxText _trim_contents_combo;
1010 ComboBoxText _trim_overlap_combo;
1011 ComboBoxText _trim_anchored_combo;
1012 ComboBoxText _trim_jump_combo;
1013 ComboBoxText _fine_adjust_combo;
1014 ComboBoxText _push_points_combo;
1015 ComboBoxText _note_size_relative_combo;
1016 Adjustment _delete_button_adjustment;
1017 SpinButton _delete_button_spin;
1018 Adjustment _edit_button_adjustment;
1019 SpinButton _edit_button_spin;
1020 Adjustment _insert_note_button_adjustment;
1021 SpinButton _insert_note_button_spin;
1025 class FontScalingOptions : public OptionEditorBox
1028 FontScalingOptions () :
1029 _dpi_adjustment (100, 50, 250, 1, 5),
1030 _dpi_slider (_dpi_adjustment)
1032 _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.);
1034 Label* l = manage (new Label (_("GUI and Font scaling:")));
1035 l->set_name ("OptionsLabel");
1037 const std::string dflt = _("Default");
1038 const std::string empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
1040 _dpi_slider.set_name("FontScaleSlider");
1041 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1042 _dpi_slider.set_draw_value(false);
1043 _dpi_slider.add_mark(50, Gtk::POS_TOP, empty);
1044 _dpi_slider.add_mark(60, Gtk::POS_TOP, empty);
1045 _dpi_slider.add_mark(70, Gtk::POS_TOP, empty);
1046 _dpi_slider.add_mark(80, Gtk::POS_TOP, empty);
1047 _dpi_slider.add_mark(90, Gtk::POS_TOP, empty);
1048 _dpi_slider.add_mark(100, Gtk::POS_TOP, dflt);
1049 _dpi_slider.add_mark(125, Gtk::POS_TOP, empty);
1050 _dpi_slider.add_mark(150, Gtk::POS_TOP, empty);
1051 _dpi_slider.add_mark(175, Gtk::POS_TOP, empty);
1052 _dpi_slider.add_mark(200, Gtk::POS_TOP, empty);
1053 _dpi_slider.add_mark(225, Gtk::POS_TOP, empty);
1054 _dpi_slider.add_mark(250, Gtk::POS_TOP, empty);
1056 HBox* h = manage (new HBox);
1058 h->pack_start (*l, false, false);
1059 h->pack_start (_dpi_slider, true, true);
1061 _box->pack_start (*h, false, false);
1063 set_note (_("Adjusting the scale requires an application restart to re-layout."));
1065 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
1068 void parameter_changed (string const & p)
1070 if (p == "font-scale") {
1071 _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.);
1075 void set_state_from_config ()
1077 parameter_changed ("font-scale");
1084 UIConfiguration::instance().set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024.));
1085 /* XXX: should be triggered from the parameter changed signal */
1086 UIConfiguration::instance().reset_dpi ();
1089 Adjustment _dpi_adjustment;
1093 class VstTimeOutSliderOption : public OptionEditorBox
1096 VstTimeOutSliderOption (RCConfiguration* c)
1098 , _timeout_adjustment (0, 0, 3000, 50, 50)
1099 , _timeout_slider (_timeout_adjustment)
1101 _timeout_slider.set_digits (0);
1102 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &VstTimeOutSliderOption::timeout_changed));
1104 _timeout_slider.set_draw_value(false);
1105 _timeout_slider.add_mark( 0, Gtk::POS_TOP, _("\u221e")); // infinity
1106 _timeout_slider.add_mark( 300, Gtk::POS_TOP, _("30 sec"));
1107 _timeout_slider.add_mark( 600, Gtk::POS_TOP, _("1 min"));
1108 _timeout_slider.add_mark(1200, Gtk::POS_TOP, _("2 mins"));
1109 _timeout_slider.add_mark(1800, Gtk::POS_TOP, _("3 mins"));
1110 _timeout_slider.add_mark(2400, Gtk::POS_TOP, _("4 mins"));
1111 _timeout_slider.add_mark(3000, Gtk::POS_TOP, _("5 mins"));
1113 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1114 _("Specify the default timeout for plugin instantiation. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1116 Label* l = manage (left_aligned_label (_("Scan Time Out:")));
1117 HBox* h = manage (new HBox);
1119 h->pack_start (*l, false, false);
1120 h->pack_start (_timeout_slider, true, true);
1122 _box->pack_start (*h, false, false);
1125 void parameter_changed (string const & p)
1127 if (p == "vst-scan-timeout") {
1128 int const x = _rc_config->get_vst_scan_timeout();
1129 _timeout_adjustment.set_value (x);
1133 void set_state_from_config ()
1135 parameter_changed ("vst-scan-timeout");
1140 void timeout_changed ()
1142 int x = floor(_timeout_adjustment.get_value());
1143 _rc_config->set_vst_scan_timeout(x);
1146 RCConfiguration* _rc_config;
1147 Adjustment _timeout_adjustment;
1148 HScale _timeout_slider;
1155 class ClipLevelOptions : public OptionEditorBox
1159 : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1160 , _clip_level_slider (_clip_level_adjustment)
1162 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ());
1164 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
1165 l->set_name ("OptionsLabel");
1167 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1168 HBox* h = manage (new HBox);
1170 h->pack_start (*l, false, false);
1171 h->pack_start (_clip_level_slider, true, true);
1173 _box->pack_start (*h, false, false);
1175 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1178 void parameter_changed (string const & p)
1180 if (p == "waveform-clip-level") {
1181 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level());
1185 void set_state_from_config ()
1187 parameter_changed ("waveform-clip-level");
1192 void clip_level_changed ()
1194 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1195 /* XXX: should be triggered from the parameter changed signal */
1196 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1199 Adjustment _clip_level_adjustment;
1200 HScale _clip_level_slider;
1203 class BufferingOptions : public OptionEditorBox
1206 BufferingOptions (RCConfiguration* c)
1208 , _playback_adjustment (5, 1, 60, 1, 4)
1209 , _capture_adjustment (5, 1, 60, 1, 4)
1210 , _playback_slider (_playback_adjustment)
1211 , _capture_slider (_capture_adjustment)
1213 vector<string> presets;
1215 /* these must match the order of the enums for BufferingPreset */
1217 presets.push_back (_("Small sessions (4-16 tracks)"));
1218 presets.push_back (_("Medium sessions (16-64 tracks)"));
1219 presets.push_back (_("Large sessions (64+ tracks)"));
1220 presets.push_back (_("Custom (set by sliders below)"));
1222 set_popdown_strings (_buffering_presets_combo, presets);
1224 Label* l = manage (new Label (_("Preset:")));
1225 l->set_name ("OptionsLabel");
1226 HBox* h = manage (new HBox);
1227 h->set_spacing (12);
1228 h->pack_start (*l, false, false);
1229 h->pack_start (_buffering_presets_combo, true, true);
1230 _box->pack_start (*h, false, false);
1232 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1234 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1236 l = manage (new Label (_("Playback (seconds of buffering):")));
1237 l->set_name ("OptionsLabel");
1239 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1240 h = manage (new HBox);
1242 h->pack_start (*l, false, false);
1243 h->pack_start (_playback_slider, true, true);
1245 _box->pack_start (*h, false, false);
1247 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1249 l = manage (new Label (_("Recording (seconds of buffering):")));
1250 l->set_name ("OptionsLabel");
1252 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1253 h = manage (new HBox);
1255 h->pack_start (*l, false, false);
1256 h->pack_start (_capture_slider, true, true);
1258 _box->pack_start (*h, false, false);
1260 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
1261 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
1264 void parameter_changed (string const & p)
1266 if (p == "buffering-preset") {
1267 switch (_rc_config->get_buffering_preset()) {
1269 _playback_slider.set_sensitive (false);
1270 _capture_slider.set_sensitive (false);
1271 _buffering_presets_combo.set_active (0);
1274 _playback_slider.set_sensitive (false);
1275 _capture_slider.set_sensitive (false);
1276 _buffering_presets_combo.set_active (1);
1279 _playback_slider.set_sensitive (false);
1280 _capture_slider.set_sensitive (false);
1281 _buffering_presets_combo.set_active (2);
1284 _playback_slider.set_sensitive (true);
1285 _capture_slider.set_sensitive (true);
1286 _buffering_presets_combo.set_active (3);
1291 if (p == "playback-buffer-seconds") {
1292 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1293 } else if (p == "capture-buffer-seconds") {
1294 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1298 void set_state_from_config ()
1300 parameter_changed ("buffering-preset");
1301 parameter_changed ("playback-buffer-seconds");
1302 parameter_changed ("capture-buffer-seconds");
1307 void preset_changed ()
1309 int index = _buffering_presets_combo.get_active_row_number ();
1315 _rc_config->set_buffering_preset (Small);
1318 _rc_config->set_buffering_preset (Medium);
1321 _rc_config->set_buffering_preset (Large);
1324 _rc_config->set_buffering_preset (Custom);
1327 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1332 void playback_changed ()
1334 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
1337 void capture_changed ()
1339 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
1342 RCConfiguration* _rc_config;
1343 Adjustment _playback_adjustment;
1344 Adjustment _capture_adjustment;
1345 HScale _playback_slider;
1346 HScale _capture_slider;
1347 ComboBoxText _buffering_presets_combo;
1350 class ControlSurfacesOptions : public OptionEditorBox
1353 ControlSurfacesOptions ()
1354 : _ignore_view_change (0)
1356 _store = ListStore::create (_model);
1357 _view.set_model (_store);
1358 _view.append_column (_("Control Surface Protocol"), _model.name);
1359 _view.get_column(0)->set_resizable (true);
1360 _view.get_column(0)->set_expand (true);
1361 _view.append_column_editable (_("Enabled"), _model.enabled);
1362 _view.append_column_editable (_("Feedback"), _model.feedback);
1364 _box->pack_start (_view, false, false);
1366 Gtk::HBox* edit_box = manage (new Gtk::HBox);
1367 edit_box->set_spacing(3);
1368 _box->pack_start (*edit_box, false, false);
1371 Label* label = manage (new Label);
1372 label->set_text (_("Click to edit the settings for selected protocol ( it must be ENABLED first ):"));
1373 edit_box->pack_start (*label, false, false);
1376 edit_button = manage (new Button(_("Show Protocol Settings")));
1377 edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
1378 edit_box->pack_start (*edit_button, true, true);
1379 edit_button->set_sensitive (false);
1380 edit_button->show ();
1382 ControlProtocolManager& m = ControlProtocolManager::instance ();
1383 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1384 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1386 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1387 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1388 _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
1391 void parameter_changed (std::string const &)
1396 void set_state_from_config ()
1400 ControlProtocolManager& m = ControlProtocolManager::instance ();
1401 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1403 if (!(*i)->mandatory) {
1404 TreeModel::Row r = *_store->append ();
1405 r[_model.name] = (*i)->name;
1406 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1407 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
1408 r[_model.protocol_info] = *i;
1415 void protocol_status_changed (ControlProtocolInfo* cpi) {
1417 TreeModel::Children rows = _store->children();
1419 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1420 string n = ((*x)[_model.name]);
1422 if ((*x)[_model.protocol_info] == cpi) {
1423 _ignore_view_change++;
1424 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1425 _ignore_view_change--;
1431 void selection_changed ()
1433 //enable the Edit button when a row is selected for editing
1434 TreeModel::Row row = *(_view.get_selection()->get_selected());
1435 if (row && row[_model.enabled])
1436 edit_button->set_sensitive (true);
1438 edit_button->set_sensitive (false);
1441 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1443 TreeModel::Row r = *i;
1445 if (_ignore_view_change) {
1449 ControlProtocolInfo* cpi = r[_model.protocol_info];
1454 bool const was_enabled = (cpi->protocol != 0);
1455 bool const is_enabled = r[_model.enabled];
1458 if (was_enabled != is_enabled) {
1461 ControlProtocolManager::instance().activate (*cpi);
1463 ControlProtocolManager::instance().deactivate (*cpi);
1467 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
1468 bool const is_feedback = r[_model.feedback];
1470 if (was_feedback != is_feedback && cpi->protocol) {
1471 cpi->protocol->set_feedback (is_feedback);
1475 void edit_btn_clicked ()
1478 ControlProtocolInfo* cpi;
1481 row = *(_view.get_selection()->get_selected());
1482 if (!row[_model.enabled]) {
1485 cpi = row[_model.protocol_info];
1486 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1489 Box* box = (Box*) cpi->protocol->get_gui ();
1493 if (box->get_parent()) {
1494 static_cast<ArdourWindow*>(box->get_parent())->present();
1497 WindowTitle title (Glib::get_application_name());
1498 title += row[_model.name];
1499 title += _("Configuration");
1500 /* once created, the window is managed by the surface itself (as ->get_parent())
1501 * Surface's tear_down_gui() is called on session close, when de-activating
1502 * or re-initializing a surface.
1503 * tear_down_gui() hides an deletes the Window if it exists.
1505 ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
1506 win->set_title ("Control Protocol Options");
1512 void edit_clicked (GdkEventButton* ev)
1514 if (ev->type != GDK_2BUTTON_PRESS) {
1521 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1525 ControlSurfacesModelColumns ()
1530 add (protocol_info);
1533 TreeModelColumn<string> name;
1534 TreeModelColumn<bool> enabled;
1535 TreeModelColumn<bool> feedback;
1536 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1539 Glib::RefPtr<ListStore> _store;
1540 ControlSurfacesModelColumns _model;
1542 PBD::ScopedConnection protocol_status_connection;
1543 uint32_t _ignore_view_change;
1544 Gtk::Button* edit_button;
1547 class VideoTimelineOptions : public OptionEditorBox
1550 VideoTimelineOptions (RCConfiguration* c)
1552 , _show_video_export_info_button (_("Show Video Export Info before export"))
1553 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1554 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1555 , _xjadeo_browse_button (_("Browse..."))
1557 Table* t = manage (new Table (8, 4));
1558 t->set_spacings (4);
1560 std::stringstream s;
1561 s << "<b>" << _("Video Server") << "</b>";
1562 Label* l = manage (new Label (s.str()));
1563 l->set_use_markup (true);
1564 l->set_alignment (0, 0.5);
1565 t->attach (*l, 0, 4, 0, 1, EXPAND | FILL, FILL | EXPAND, 0, 8);
1567 t->attach (_video_advanced_setup_button, 1, 4, 1, 2);
1568 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1569 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1570 _("<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."));
1572 l = manage (new Label (_("Video Server URL:")));
1573 l->set_alignment (0, 0.5);
1574 t->attach (*l, 1, 2, 2, 3, FILL);
1575 t->attach (_video_server_url_entry, 2, 4, 2, 3, FILL);
1576 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1577 _("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"));
1579 l = manage (new Label (_("Video Folder:")));
1580 l->set_alignment (0, 0.5);
1581 t->attach (*l, 1, 2, 3, 4, FILL);
1582 t->attach (_video_server_docroot_entry, 2, 4, 3, 4);
1583 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1584 _("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."));
1586 t->attach (_show_video_export_info_button, 1, 4, 4, 5);
1587 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1588 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1589 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1591 t->attach (_show_video_server_dialog_button, 1, 4, 5, 6);
1592 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1593 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1594 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1596 s.str (std::string ());
1597 s << "<b>" << _("Video Monitor") << "</b>";
1598 l = manage (new Label (s.str()));
1599 l->set_use_markup (true);
1600 l->set_alignment (0, 0.5);
1601 t->attach (*l, 0, 4, 6, 7, EXPAND | FILL, FILL | EXPAND, 0, 8);
1603 l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"),
1606 #elif defined PLATFORM_WINDOWS
1612 l->set_alignment (0, 0.5);
1613 t->attach (*l, 1, 4, 7, 8, FILL);
1614 t->attach (_custom_xjadeo_path, 2, 3, 8, 9);
1615 Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart."));
1616 t->attach (_xjadeo_browse_button, 3, 4, 8, 9, FILL);
1618 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1619 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1620 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1621 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1622 _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed));
1623 _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked));
1625 // xjadeo-path is a UIConfig parameter
1626 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &VideoTimelineOptions::parameter_changed));
1628 _box->pack_start (*t,true,true);
1631 void server_url_changed ()
1633 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1636 void server_docroot_changed ()
1638 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1641 void show_video_export_info_toggled ()
1643 bool const x = _show_video_export_info_button.get_active ();
1644 _rc_config->set_show_video_export_info (x);
1647 void show_video_server_dialog_toggled ()
1649 bool const x = _show_video_server_dialog_button.get_active ();
1650 _rc_config->set_show_video_server_dialog (x);
1653 void video_advanced_setup_toggled ()
1655 bool const x = _video_advanced_setup_button.get_active ();
1656 _rc_config->set_video_advanced_setup(x);
1659 void custom_xjadeo_path_changed ()
1661 UIConfiguration::instance().set_xjadeo_binary (_custom_xjadeo_path.get_text());
1664 void xjadeo_browse_clicked ()
1666 Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN);
1667 dialog.set_filename (UIConfiguration::instance().get_xjadeo_binary());
1668 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1669 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1670 if (dialog.run () == Gtk::RESPONSE_OK) {
1671 const std::string& filename = dialog.get_filename();
1672 if (!filename.empty() && (
1674 Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) ||
1676 Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)
1678 UIConfiguration::instance().set_xjadeo_binary (filename);
1683 void parameter_changed (string const & p)
1685 if (p == "video-server-url") {
1686 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1687 } else if (p == "video-server-docroot") {
1688 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1689 } else if (p == "show-video-export-info") {
1690 bool const x = _rc_config->get_show_video_export_info();
1691 _show_video_export_info_button.set_active (x);
1692 } else if (p == "show-video-server-dialog") {
1693 bool const x = _rc_config->get_show_video_server_dialog();
1694 _show_video_server_dialog_button.set_active (x);
1695 } else if (p == "video-advanced-setup") {
1696 bool const x = _rc_config->get_video_advanced_setup();
1697 _video_advanced_setup_button.set_active(x);
1698 _video_server_docroot_entry.set_sensitive(x);
1699 _video_server_url_entry.set_sensitive(x);
1700 } else if (p == "xjadeo-binary") {
1701 _custom_xjadeo_path.set_text (UIConfiguration::instance().get_xjadeo_binary());
1705 void set_state_from_config ()
1707 parameter_changed ("video-server-url");
1708 parameter_changed ("video-server-docroot");
1709 parameter_changed ("video-monitor-setup-dialog");
1710 parameter_changed ("show-video-export-info");
1711 parameter_changed ("show-video-server-dialog");
1712 parameter_changed ("video-advanced-setup");
1713 parameter_changed ("xjadeo-binary");
1717 RCConfiguration* _rc_config;
1718 Entry _video_server_url_entry;
1719 Entry _video_server_docroot_entry;
1720 Entry _custom_xjadeo_path;
1721 CheckButton _show_video_export_info_button;
1722 CheckButton _show_video_server_dialog_button;
1723 CheckButton _video_advanced_setup_button;
1724 Button _xjadeo_browse_button;
1727 class ColumVisibilityOption : public Option
1730 ColumVisibilityOption (string id, string name, uint32_t n_col, sigc::slot<uint32_t> get, sigc::slot<bool, uint32_t> set)
1737 cb = (CheckButton**) malloc (sizeof (CheckButton*) * n_col);
1738 for (uint32_t i = 0; i < n_col; ++i) {
1739 CheckButton* col = manage (new CheckButton (string_compose (_("Column %1"), i + 1)));
1740 col->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ColumVisibilityOption::column_toggled), i));
1741 _hbox.pack_start (*col);
1744 parameter_changed (id);
1747 ~ColumVisibilityOption () {
1751 Gtk::Widget& tip_widget() { return _hbox; }
1753 void set_state_from_config ()
1755 uint32_t c = _get();
1756 for (uint32_t i = 0; i < _n_col; ++i) {
1757 bool en = (c & (1<<i)) ? true : false;
1758 if (cb[i]->get_active () != en) {
1759 cb[i]->set_active (en);
1764 void add_to_page (OptionEditorPage* p)
1766 _heading.add_to_page (p);
1767 add_widget_to_page (p, &_hbox);
1771 void column_toggled (int b) {
1772 uint32_t c = _get();
1774 if (cb[b]->get_active ()) {
1785 OptionEditorHeading _heading;
1789 sigc::slot<uint32_t> _get;
1790 sigc::slot<bool, uint32_t> _set;
1794 /** A class which allows control of visibility of some editor components usign
1795 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1796 * which has the correct members, but with null widget pointers. This
1797 * class allows the user to set visibility of the members, the details
1798 * of which are stored in a configuration variable which can be watched
1799 * by parts of the editor that actually contain the widgets whose visibility
1800 * is being controlled.
1803 class VisibilityOption : public Option
1806 /** @param name User-visible name for this group.
1807 * @param g `Dummy' VisibilityGroup (as described above).
1808 * @param get Method to get the value of the appropriate configuration variable.
1809 * @param set Method to set the value of the appropriate configuration variable.
1811 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1812 : Option (g->get_state_name(), name)
1814 , _visibility_group (g)
1818 /* Watch for changes made by the user to our members */
1819 _visibility_group->VisibilityChanged.connect_same_thread (
1820 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1824 void set_state_from_config ()
1826 /* Set our state from the current configuration */
1827 _visibility_group->set_state (_get ());
1830 void add_to_page (OptionEditorPage* p)
1832 _heading.add_to_page (p);
1833 add_widget_to_page (p, _visibility_group->list_view ());
1836 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1841 /* The user has changed something, so reflect this change
1842 in the RCConfiguration.
1844 _set (_visibility_group->get_state_value ());
1847 OptionEditorHeading _heading;
1848 VisibilityGroup* _visibility_group;
1849 sigc::slot<std::string> _get;
1850 sigc::slot<bool, std::string> _set;
1851 PBD::ScopedConnection _visibility_group_connection;
1856 RCOptionEditor::RCOptionEditor ()
1857 : OptionEditorContainer (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1858 , Tabbable (*this, _("Preferences")) /* pack self-as-vbox into tabbable */
1859 , _rc_config (Config)
1860 , _mixer_strip_visibility ("mixer-element-visibility")
1862 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
1866 uint32_t hwcpus = hardware_concurrency ();
1868 BoolComboOption* bco;
1871 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1873 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1875 _("Signal processing uses"),
1876 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1877 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1880 procs->add (-1, _("all but one processor"));
1881 procs->add (0, _("all available processors"));
1883 for (uint32_t i = 1; i <= hwcpus; ++i) {
1884 procs->add (i, string_compose (P_("%1 processor", "%1 processors", i), i));
1887 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1889 add_option (_("Misc"), procs);
1892 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1894 add_option (_("Misc"), new UndoOptions (_rc_config));
1896 add_option (_("Misc"),
1898 "verify-remove-last-capture",
1899 _("Verify removal of last capture"),
1900 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1901 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1904 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1906 add_option (_("Misc"),
1908 "periodic-safety-backups",
1909 _("Make periodic backups of the session file"),
1910 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1911 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1914 add_option (_("Misc"),
1916 "only-copy-imported-files",
1917 _("Always copy imported files"),
1918 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
1919 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
1922 add_option (_("Misc"), new DirectoryOption (
1923 X_("default-session-parent-dir"),
1924 _("Default folder for new sessions:"),
1925 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1926 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1929 add_option (_("Misc"),
1930 new SpinOption<uint32_t> (
1931 "max-recent-sessions",
1932 _("Maximum number of recent sessions"),
1933 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1934 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1938 add_option (_("Misc/Click"), new OptionEditorHeading (_("Click")));
1940 add_option (_("Misc/Click"), new ClickOptions (_rc_config));
1942 add_option (_("Misc/Click"),
1945 _("Click gain level"),
1946 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1947 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1950 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1952 add_option (_("Misc"),
1953 new SpinOption<double> (
1954 "automation-thinning-factor",
1955 _("Thinning factor (larger value => less data)"),
1956 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1957 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1961 add_option (_("Misc"),
1962 new SpinOption<double> (
1963 "automation-interval-msecs",
1964 _("Automation sampling interval (milliseconds)"),
1965 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1966 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1972 add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options")));
1976 tsf = new BoolOption (
1977 "latched-record-enable",
1978 _("Keep record-enable engaged on stop"),
1979 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1980 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1982 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1983 add_option (_("Transport"), tsf);
1985 tsf = new BoolOption (
1987 _("Play loop is a transport mode"),
1988 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1989 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1991 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1992 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1993 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1994 add_option (_("Transport"), tsf);
1996 tsf = new BoolOption (
1997 "stop-recording-on-xrun",
1998 _("Stop recording when an xrun occurs"),
1999 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
2000 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
2002 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2003 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
2005 add_option (_("Transport"), tsf);
2007 tsf = new BoolOption (
2008 "create-xrun-marker",
2009 _("Create markers where xruns occur"),
2010 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
2011 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
2013 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
2014 add_option (_("Transport"), tsf);
2016 tsf = new BoolOption (
2017 "stop-at-session-end",
2018 _("Stop at the end of the session"),
2019 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
2020 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
2022 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2023 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
2024 "when it reaches the current session end marker\n\n"
2025 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
2027 add_option (_("Transport"), tsf);
2029 tsf = new BoolOption (
2031 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
2032 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
2033 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
2035 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2036 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
2037 "preventing any need to do a transport locate at the end of the loop\n\n"
2038 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
2039 "which will often cause a small click or delay"), PROGRAM_NAME));
2040 add_option (_("Transport"), tsf);
2042 tsf = new BoolOption (
2043 "disable-disarm-during-roll",
2044 _("Disable per-track record disarm while rolling"),
2045 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
2046 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
2048 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"));
2049 add_option (_("Transport"), tsf);
2051 tsf = new BoolOption (
2053 _("12dB gain reduction during fast-forward and fast-rewind"),
2054 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
2055 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2057 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
2058 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2059 add_option (_("Transport"), tsf);
2061 ComboOption<float>* psc = new ComboOption<float> (
2064 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
2065 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
2067 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
2068 (_("The amount of preroll (in seconds) to apply when <b>Play with Preroll</b> is initiated.\n\n"
2069 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
2070 psc->add (0.0, _("0 (no pre-roll)"));
2071 psc->add (0.1, _("0.1 second"));
2072 psc->add (0.25, _("0.25 second"));
2073 psc->add (0.5, _("0.5 second"));
2074 psc->add (1.0, _("1.0 second"));
2075 psc->add (2.0, _("2.0 seconds"));
2076 add_option (_("Transport"), psc);
2078 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("Synchronization and Slave Options")));
2080 _sync_source = new ComboOption<SyncSource> (
2082 _("External timecode source"),
2083 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
2084 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
2087 add_option (_("Transport/Sync"), _sync_source);
2089 _sync_framerate = new BoolOption (
2090 "timecode-sync-frame-rate",
2091 _("Match session video frame rate to external timecode"),
2092 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
2093 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
2095 Gtkmm2ext::UI::instance()->set_tip
2096 (_sync_framerate->tip_widget(),
2097 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
2098 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
2099 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
2100 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
2101 "timecode standard and the session standard."), PROGRAM_NAME));
2103 add_option (_("Transport/Sync"), _sync_framerate);
2105 _sync_genlock = new BoolOption (
2106 "timecode-source-is-synced",
2107 _("Sync-lock timecode to clock (disable drift compensation)"),
2108 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
2109 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
2111 Gtkmm2ext::UI::instance()->set_tip
2112 (_sync_genlock->tip_widget(),
2113 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
2114 "Sync Lock indicates that the selected external timecode source shares clock-sync "
2115 "(Black & Burst, Wordclock, etc) with the audio interface. "
2116 "This option disables drift compensation. The transport speed is fixed at 1.0. "
2117 "Vari-speed LTC will be ignored and cause drift."
2119 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
2120 "timecode sources shares clock sync."
2124 add_option (_("Transport/Sync"), _sync_genlock);
2126 _sync_source_2997 = new BoolOption (
2127 "timecode-source-2997",
2128 _("Lock to 29.9700 fps instead of 30000/1001"),
2129 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
2130 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
2132 Gtkmm2ext::UI::instance()->set_tip
2133 (_sync_source_2997->tip_widget(),
2134 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
2135 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
2136 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
2137 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
2138 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
2139 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
2142 add_option (_("Transport/Sync"), _sync_source_2997);
2144 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("LTC Reader")));
2146 _ltc_port = new ComboStringOption (
2148 _("LTC incoming port"),
2149 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
2150 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
2153 vector<string> physical_inputs;
2154 physical_inputs.push_back (_("None"));
2155 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
2156 _ltc_port->set_popdown_strings (physical_inputs);
2158 populate_sync_options ();
2159 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
2161 add_option (_("Transport/Sync"), _ltc_port);
2163 // TODO; rather disable this button than not compile it..
2164 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("LTC Generator")));
2166 add_option (_("Transport/Sync"),
2169 _("Enable LTC generator"),
2170 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
2171 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
2174 _ltc_send_continuously = new BoolOption (
2175 "ltc-send-continuously",
2176 _("Send LTC while stopped"),
2177 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
2178 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
2180 Gtkmm2ext::UI::instance()->set_tip
2181 (_ltc_send_continuously->tip_widget(),
2182 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
2183 add_option (_("Transport"), _ltc_send_continuously);
2185 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
2186 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
2187 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
2188 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
2190 Gtkmm2ext::UI::instance()->set_tip
2191 (_ltc_volume_slider->tip_widget(),
2192 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
2194 add_option (_("Transport/Sync"), _ltc_volume_slider);
2198 add_option (_("Editor"),
2200 "rubberbanding-snaps-to-grid",
2201 _("Make rubberband selection rectangle snap to the grid"),
2202 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2203 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2206 bo = new BoolOption (
2208 _("Name new markers"),
2209 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2210 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2212 add_option (_("Editor"), bo);
2213 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."
2214 "\n\nYou can always rename markers by right-clicking on them"));
2216 add_option (S_("Editor"),
2218 "draggable-playhead",
2219 _("Allow dragging of playhead"),
2220 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2221 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2224 add_option (_("Editor"),
2226 "show-editor-meter",
2227 _("Display master-meter in the toolbar"),
2228 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
2229 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
2232 if (!Profile->get_mixbus()) {
2233 add_option (_("Editor"),
2236 _("Show zoom toolbar (if torn off)"),
2237 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_zoom_tools),
2238 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_zoom_tools)
2241 add_option (_("Editor"),
2243 "use-mouse-position-as-zoom-focus-on-scroll",
2244 _("Always use mouse cursor position as zoom focus when zooming using mouse scroll wheel"),
2245 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2246 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2250 add_option (_("Editor"),
2252 "update-editor-during-summary-drag",
2253 _("Update editor window during drags of the summary"),
2254 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2255 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2258 add_option (_("Editor"),
2260 "autoscroll-editor",
2261 _("Auto-scroll editor window when dragging near its edges"),
2262 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2263 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2266 add_option (_("Editor"),
2267 new BoolComboOption (
2268 "show-region-gain-envelopes",
2269 _("Show gain envelopes in audio regions"),
2271 _("only in Draw and Internal Edit modes"),
2272 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2273 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2276 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2278 add_option (_("Editor"),
2280 "automation-follows-regions",
2281 _("Move relevant automation when audio regions are moved"),
2282 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2283 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2286 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2287 "default-fade-shape",
2288 _("Default fade shape"),
2289 sigc::mem_fun (*_rc_config,
2290 &RCConfiguration::get_default_fade_shape),
2291 sigc::mem_fun (*_rc_config,
2292 &RCConfiguration::set_default_fade_shape)
2295 fadeshape->add (FadeLinear,
2296 _("Linear (for highly correlated material)"));
2297 fadeshape->add (FadeConstantPower, _("Constant power"));
2298 fadeshape->add (FadeSymmetric, _("Symmetric"));
2299 fadeshape->add (FadeSlow, _("Slow"));
2300 fadeshape->add (FadeFast, _("Fast"));
2302 add_option (_("Editor"), fadeshape);
2305 bco = new BoolComboOption (
2306 "use-overlap-equivalency",
2307 _("Regions in active edit groups are edited together"),
2308 _("whenever they overlap in time"),
2309 _("only if they have identical length, position and origin"),
2310 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2311 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2314 add_option (_("Editor"), bco);
2316 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2318 _("Layering model"),
2319 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2320 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2323 lm->add (LaterHigher, _("later is higher"));
2324 lm->add (Manual, _("manual layering"));
2325 add_option (_("Editor"), lm);
2327 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2328 "region-selection-after-split",
2329 _("After splitting selected regions, select"),
2330 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2331 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2333 // TODO: decide which of these modes are really useful
2334 rsas->add(None, _("no regions"));
2335 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2336 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2337 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2338 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2339 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2340 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2341 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2343 add_option (_("Editor"), rsas);
2345 add_option (_("Editor/Waveforms"), new OptionEditorHeading (_("Waveforms")));
2347 if (!Profile->get_mixbus()) {
2348 add_option (_("Editor/Waveforms"),
2351 _("Show waveforms in regions"),
2352 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
2353 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
2357 add_option (_("Editor/Waveforms"),
2359 "show-waveforms-while-recording",
2360 _("Show waveforms for audio while it is being recorded"),
2361 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
2362 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
2365 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
2367 _("Waveform scale"),
2368 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
2369 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
2372 wfs->add (Linear, _("linear"));
2373 wfs->add (Logarithmic, _("logarithmic"));
2375 add_option (_("Editor/Waveforms"), wfs);
2377 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
2379 _("Waveform shape"),
2380 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
2381 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
2384 wfsh->add (Traditional, _("traditional"));
2385 wfsh->add (Rectified, _("rectified"));
2387 add_option (_("Editor/Waveforms"), wfsh);
2389 add_option (_("Editor/Waveforms"), new ClipLevelOptions ());
2394 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2396 add_option (_("Audio"), new BufferingOptions (_rc_config));
2398 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2400 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2402 _("Record monitoring handled by"),
2403 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2404 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2407 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2408 mm->add (HardwareMonitoring, _("via Audio Driver"));
2411 string prog (PROGRAM_NAME);
2412 boost::algorithm::to_lower (prog);
2413 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2414 mm->add (ExternalMonitoring, _("audio hardware"));
2416 add_option (_("Audio"), mm);
2418 add_option (_("Audio"),
2420 "tape-machine-mode",
2421 _("Tape machine mode"),
2422 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2423 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2426 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2427 if (!Profile->get_mixbus()) {
2429 add_option (_("Audio"),
2431 "auto-connect-standard-busses",
2432 _("Auto-connect master/monitor busses"),
2433 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2434 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2437 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2438 "input-auto-connect",
2439 _("Connect track inputs"),
2440 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2441 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2444 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2445 iac->add (ManualConnect, _("manually"));
2447 add_option (_("Audio"), iac);
2449 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2450 "output-auto-connect",
2451 _("Connect track and bus outputs"),
2452 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2453 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2456 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2457 oac->add (AutoConnectMaster, _("automatically to master bus"));
2458 oac->add (ManualConnect, _("manually"));
2460 add_option (_("Audio"), oac);
2462 bo = new BoolOption (
2464 _("Use 'Strict-I/O' for new tracks or Busses"),
2465 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2466 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2469 add_option (_("Audio"), bo);
2470 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2471 _("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."));
2475 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2477 add_option (_("Audio"),
2479 "denormal-protection",
2480 _("Use DC bias to protect against denormals"),
2481 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2482 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2485 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2487 _("Processor handling"),
2488 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2489 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2493 dm->add (DenormalNone, _("no processor handling"));
2495 FPU* fpu = FPU::instance();
2497 if (fpu->has_flush_to_zero()) {
2499 dm->add (DenormalFTZ, _("use FlushToZero"));
2500 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2501 _rc_config->set_denormal_model(DenormalNone);
2504 if (fpu->has_denormals_are_zero()) {
2506 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2507 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2508 _rc_config->set_denormal_model(DenormalNone);
2511 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2513 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2514 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2515 _rc_config->set_denormal_model(DenormalNone);
2519 dm->set_sensitive(false);
2522 add_option (_("Audio"), dm);
2524 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2526 add_option (_("Audio"),
2528 "auto-analyse-audio",
2529 _("Enable automatic analysis of audio"),
2530 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2531 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2534 add_option (_("Audio"),
2536 "replicate-missing-region-channels",
2537 _("Replicate missing region channels"),
2538 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2539 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2544 add_option (_("Solo & mute"), new OptionEditorHeading (_("Solo")));
2546 _solo_control_is_listen_control = new BoolOption (
2547 "solo-control-is-listen-control",
2548 _("Solo controls are Listen controls"),
2549 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2550 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2553 add_option (_("Solo & mute"), _solo_control_is_listen_control);
2555 add_option (_("Solo & mute"),
2558 _("Exclusive solo"),
2559 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2560 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2563 add_option (_("Solo & mute"),
2566 _("Show solo muting"),
2567 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2568 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2571 add_option (_("Solo & mute"),
2573 "solo-mute-override",
2574 _("Soloing overrides muting"),
2575 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2576 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2579 add_option (_("Solo & mute"),
2582 _("Solo-in-place mute cut (dB)"),
2583 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2584 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2587 _listen_position = new ComboOption<ListenPosition> (
2589 _("Listen Position"),
2590 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2591 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2594 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2595 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2597 add_option (_("Solo & mute"), _listen_position);
2599 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2601 _("PFL signals come from"),
2602 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2603 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2606 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2607 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2609 add_option (_("Solo & mute"), pp);
2611 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2613 _("AFL signals come from"),
2614 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2615 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2618 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2619 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2621 add_option (_("Solo & mute"), pa);
2623 add_option (_("Solo & mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2625 add_option (_("Solo & mute"),
2627 "mute-affects-pre-fader",
2628 _("Mute affects pre-fader sends"),
2629 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2630 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2633 add_option (_("Solo & mute"),
2635 "mute-affects-post-fader",
2636 _("Mute affects post-fader sends"),
2637 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2638 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2641 add_option (_("Solo & mute"),
2643 "mute-affects-control-outs",
2644 _("Mute affects control outputs"),
2645 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2646 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2649 add_option (_("Solo & mute"),
2651 "mute-affects-main-outs",
2652 _("Mute affects main outputs"),
2653 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2654 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2658 if (!ARDOUR::Profile->get_mixbus()) {
2659 add_option (_("Solo & mute"), new OptionEditorHeading (_("Send Routing")));
2660 add_option (_("Solo & mute"),
2662 "link-send-and-route-panner",
2663 _("Link panners of Aux and External Sends with main panner by default"),
2664 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2665 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2669 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Preferences")));
2671 add_option (_("MIDI"),
2672 new SpinOption<float> (
2674 _("MIDI read-ahead time (seconds)"),
2675 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2676 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2681 add_option (_("MIDI"),
2682 new SpinOption<int32_t> (
2683 "initial-program-change",
2684 _("Initial program change"),
2685 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2686 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2690 add_option (_("MIDI"),
2692 "display-first-midi-bank-as-zero",
2693 _("Display first MIDI bank/program as 0"),
2694 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2695 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2698 add_option (_("MIDI"),
2700 "never-display-periodic-midi",
2701 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2702 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
2703 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
2706 add_option (_("MIDI"),
2709 _("Sound MIDI notes as they are selected in the editor"),
2710 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2711 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2714 add_option (_("MIDI"),
2717 _("Send MIDI control feedback"),
2718 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2719 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2722 add_option (_("MIDI/Sync"), new OptionEditorHeading (_("MIDI Clock")));
2724 add_option (_("MIDI/Sync"),
2727 _("Send MIDI Clock"),
2728 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2729 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2732 add_option (_("MIDI/Sync"), new OptionEditorHeading (_("MIDI Time Code (MTC)")));
2734 add_option (_("MIDI/Sync"),
2737 _("Send MIDI Time Code"),
2738 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2739 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2742 add_option (_("MIDI/Sync"),
2743 new SpinOption<int> (
2744 "mtc-qf-speed-tolerance",
2745 _("Percentage either side of normal transport speed to transmit MTC"),
2746 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2747 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2751 add_option (_("MIDI/Sync"), new OptionEditorHeading (_("Midi Machine Control (MMC)")));
2753 add_option (_("MIDI/Sync"),
2756 _("Obey MIDI Machine Control commands"),
2757 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2758 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2761 add_option (_("MIDI/Sync"),
2764 _("Send MIDI Machine Control commands"),
2765 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2766 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2769 add_option (_("MIDI/Sync"),
2770 new SpinOption<uint8_t> (
2771 "mmc-receive-device-id",
2772 _("Inbound MMC device ID"),
2773 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2774 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2778 add_option (_("MIDI/Sync"),
2779 new SpinOption<uint8_t> (
2780 "mmc-send-device-id",
2781 _("Outbound MMC device ID"),
2782 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2783 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2787 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2789 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2790 "midi-audition-synth-uri",
2791 _("Midi Audition Synth (LV2)"),
2792 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2793 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2796 audition_synth->add(X_(""), _("None"));
2797 PluginInfoList all_plugs;
2798 PluginManager& manager (PluginManager::instance());
2800 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2802 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2803 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2804 if (!(*i)->is_instrument()) continue;
2805 if ((*i)->type != ARDOUR::LV2) continue;
2806 audition_synth->add((*i)->unique_id, (*i)->name);
2810 add_option (_("MIDI"), audition_synth);
2812 /* USER INTERACTION */
2815 #ifdef PLATFORM_WINDOWS
2818 getenv ("ARDOUR_BUNDLED")
2822 add_option (_("User interaction"),
2824 "enable-translation",
2825 string_compose (_("Use translations of %1 messages\n"
2826 " <i>(requires a restart of %1 to take effect)</i>\n"
2827 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2828 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2829 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2832 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2834 add_option (_("User interaction"), new KeyboardOptions);
2836 /* Control Surfaces */
2838 add_option (_("Control Surfaces"), new ControlSurfacesOptions);
2840 /* VIDEO Timeline */
2841 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2843 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2844 add_option (_("Plugins"),
2845 new RcActionButton (_("Scan for Plugins"),
2846 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
2850 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
2852 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2853 bo = new BoolOption (
2854 "show-plugin-scan-window",
2855 _("Always Display Plugin Scan Progress"),
2856 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
2857 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
2859 add_option (_("Plugins"), bo);
2860 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2861 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
2864 bo = new BoolOption (
2865 "plugins-stop-with-transport",
2866 _("Silence plugins when the transport is stopped"),
2867 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
2868 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
2870 add_option (_("Plugins"), bo);
2871 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2872 _("<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."));
2874 bo = new BoolOption (
2875 "new-plugins-active",
2876 _("Make new plugins active"),
2877 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
2878 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
2880 add_option (_("Plugins"), bo);
2881 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2882 _("<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"));
2884 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
2885 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
2886 add_option (_("Plugins/VST"),
2887 new RcActionButton (_("Scan for Plugins"),
2888 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
2890 bo = new BoolOption (
2891 "discover-vst-on-start",
2892 _("Scan for [new] VST Plugins on Application Start"),
2893 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
2894 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
2896 add_option (_("Plugins/VST"), bo);
2897 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2898 _("<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"));
2900 #ifdef WINDOWS_VST_SUPPORT
2901 // currently verbose logging is only implemented for Windows VST.
2902 bo = new BoolOption (
2903 "verbose-plugin-scan",
2904 _("Verbose Plugin Scan"),
2905 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
2906 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
2908 add_option (_("Plugins/VST"), bo);
2909 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2910 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
2913 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
2915 add_option (_("Plugins/VST"),
2916 new RcActionButton (_("Clear"),
2917 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
2920 add_option (_("Plugins/VST"),
2921 new RcActionButton (_("Clear"),
2922 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
2923 _("VST Blacklist:")));
2926 #ifdef LXVST_SUPPORT
2927 add_option (_("Plugins/VST"),
2928 new RcActionButton (_("Edit"),
2929 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
2930 _("Linux VST Path:")));
2932 add_option (_("Plugins/VST"),
2933 new RcConfigDisplay (
2934 "plugin-path-lxvst",
2936 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
2940 #ifdef WINDOWS_VST_SUPPORT
2941 add_option (_("Plugins/VST"),
2942 new RcActionButton (_("Edit"),
2943 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
2944 _("Windows VST Path:")));
2945 add_option (_("Plugins"),
2946 new RcConfigDisplay (
2949 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
2953 #ifdef AUDIOUNIT_SUPPORT
2955 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
2956 add_option (_("Plugins/Audio Unit"),
2957 new RcActionButton (_("Scan for Plugins"),
2958 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
2960 bo = new BoolOption (
2961 "discover-audio-units",
2962 _("Scan for AudioUnit Plugins on Application Start"),
2963 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
2964 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
2966 add_option (_("Plugins"), bo);
2967 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2968 _("<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."));
2970 add_option (_("Plugins/Audio Unit"),
2971 new RcActionButton (_("Clear"),
2972 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
2975 add_option (_("Plugins/Audio Unit"),
2976 new RcActionButton (_("Clear"),
2977 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
2978 _("AU Blacklist:")));
2981 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
2982 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
2983 add_option (_("Plugins"),
2985 "open-gui-after-adding-plugin",
2986 _("Automatically open the plugin GUI when adding a new plugin"),
2987 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
2988 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
2991 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
2992 add_option (_("Plugins"),
2994 "show-inline-display-by-default",
2995 _("Show Plugin Inline Display on Mixerstrip by default"),
2996 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
2997 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3000 _plugin_prefer_inline = new BoolOption (
3001 "prefer-inline-over-gui",
3002 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3003 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3004 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3006 add_option (_("Plugins"), _plugin_prefer_inline);
3009 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3011 bo = new BoolOption (
3012 "ask-replace-instrument",
3013 _("Ask to replace existing instrument plugin"),
3014 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3015 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3017 add_option (_("Plugins"), bo);
3019 bo = new BoolOption (
3020 "ask-setup_instrument",
3021 _("Interactively configure instrument plugins on insert"),
3022 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3023 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3025 add_option (_("Plugins"), bo);
3026 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3027 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3033 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3034 BoolOption* bgc = new BoolOption (
3035 "cairo-image-surface",
3036 _("Disable Graphics Hardware Acceleration (requires restart)"),
3037 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3038 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3041 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3042 _("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));
3043 add_option (S_("Preferences|GUI"), bgc);
3046 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3047 BoolOption* bgo = new BoolOption (
3049 _("Possibly improve slow graphical performance (requires restart)"),
3050 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3051 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3054 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));
3055 add_option (S_("Preferences|GUI"), bgo);
3058 add_option (S_("Preferences|GUI"),
3060 "use-wm-visibility",
3061 _("Use Window Manager/Desktop visibility information"),
3062 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3063 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3066 add_option (S_("Preferences|GUI"),
3069 _("Graphically indicate mouse pointer hovering over various widgets"),
3070 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3071 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3074 add_option (S_("Preferences|GUI"),
3077 _("Show tooltips if mouse hovers over a control"),
3078 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3079 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3082 add_option (S_("Preferences|GUI"),
3084 "show-name-highlight",
3085 _("Use name highlight bars in region displays (requires a restart)"),
3086 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3087 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3090 add_option (S_("Preferences|GUI"),
3092 "super-rapid-clock-update",
3093 _("Update transport clock display at FPS instead of every 100ms"),
3094 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3095 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3100 /* font scaling does nothing with GDK/Quartz */
3101 add_option (S_("Preferences|GUI"), new FontScalingOptions ());
3104 /* Image cache size */
3106 Gtk::Adjustment *ics = manage (new Gtk::Adjustment(0, 1, 1024, 10)); /* 1 MB to 1GB in steps of 10MB */
3107 HSliderOption *sics = new HSliderOption("waveform-cache-size",
3108 _("Waveform image cache size (megabytes)"),
3110 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
3111 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size)
3113 sics->scale().set_digits (0);
3114 Gtkmm2ext::UI::instance()->set_tip
3115 (sics->tip_widget(),
3116 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
3117 add_option (S_("Preferences|GUI"), sics);
3119 if (!ARDOUR::Profile->get_mixbus()) {
3120 /* Lock GUI timeout */
3122 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
3123 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
3124 _("Lock timeout (seconds)"),
3126 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
3127 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds)
3129 slts->scale().set_digits (0);
3130 Gtkmm2ext::UI::instance()->set_tip
3131 (slts->tip_widget(),
3132 _("Lock GUI after this many idle seconds (zero to never lock)"));
3133 add_option (S_("Preferences|GUI"), slts);
3136 /* The names of these controls must be the same as those given in MixerStrip
3137 for the actual widgets being controlled.
3139 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3140 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3141 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3142 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3143 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3144 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3145 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3148 S_("Preferences|GUI"),
3149 new VisibilityOption (
3151 &_mixer_strip_visibility,
3152 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3153 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3157 add_option (S_("Preferences|GUI"),
3159 "default-narrow_ms",
3160 _("Use narrow strips in the mixer by default"),
3161 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3162 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3165 add_option (S_("Preferences|GUI"),
3166 new ColumVisibilityOption (
3167 "action-table-columns", _("Action Script Button Visibility"), 3,
3168 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3169 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3173 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
3175 ComboOption<float>* mht = new ComboOption<float> (
3177 _("Peak hold time"),
3178 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
3179 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
3182 mht->add (MeterHoldOff, _("off"));
3183 mht->add (MeterHoldShort, _("short"));
3184 mht->add (MeterHoldMedium, _("medium"));
3185 mht->add (MeterHoldLong, _("long"));
3187 add_option (S_("Preferences|Metering"), mht);
3189 ComboOption<float>* mfo = new ComboOption<float> (
3192 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
3193 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
3196 mfo->add (METER_FALLOFF_OFF, _("off"));
3197 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
3198 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
3199 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
3200 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
3201 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
3202 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
3204 add_option (S_("Preferences|Metering"), mfo);
3206 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
3207 "meter-line-up-level",
3208 _("Meter line-up level; 0dBu"),
3209 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
3210 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
3213 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3214 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3215 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3216 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3218 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."));
3220 add_option (S_("Preferences|Metering"), mlu);
3222 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
3223 "meter-line-up-din",
3224 _("IEC1/DIN Meter line-up level; 0dBu"),
3225 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
3226 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
3229 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3230 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3231 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3232 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3234 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
3236 add_option (S_("Preferences|Metering"), mld);
3238 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
3239 "meter-vu-standard",
3240 _("VU Meter standard"),
3241 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
3242 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
3245 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
3246 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
3247 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
3248 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
3250 add_option (S_("Preferences|Metering"), mvu);
3252 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
3253 HSliderOption *mpks = new HSliderOption("meter-peak",
3254 _("Peak threshold [dBFS]"),
3256 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
3257 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak)
3261 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3262 "meter-type-master",
3263 _("Default Meter Type for Master Bus"),
3264 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3265 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3267 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3268 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3269 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3270 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3271 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3272 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3273 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3274 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3276 add_option (S_("Preferences|Metering"), mtm);
3279 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3281 _("Default Meter Type for Busses"),
3282 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3283 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3285 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3286 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3287 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3288 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3289 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3290 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3291 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3292 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3294 add_option (S_("Preferences|Metering"), mtb);
3296 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3298 _("Default Meter Type for Tracks"),
3299 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3300 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3302 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3303 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3305 add_option (S_("Preferences|Metering"), mtt);
3308 Gtkmm2ext::UI::instance()->set_tip
3309 (mpks->tip_widget(),
3310 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
3312 add_option (S_("Preferences|Metering"), mpks);
3314 add_option (S_("Preferences|Metering"),
3317 _("LED meter style"),
3318 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3319 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3322 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Editor Meters")));
3324 add_option (S_("Preferences|Metering"),
3326 "show-track-meters",
3327 _("Show meters on tracks in the editor"),
3328 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3329 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3332 add_option (S_("Preferences|Metering"),
3334 "editor-stereo-only-meters",
3335 _("Show at most stereo meters in the track-header"),
3336 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3337 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3340 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
3342 add_option (S_("Preferences|Metering"),
3344 "save-export-analysis-image",
3345 _("Save loudness analysis as image file"),
3346 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
3347 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
3350 /* and now the theme manager */
3352 ThemeManager* tm = manage (new ThemeManager);
3353 add_page (_("Theme"), *tm);
3355 add_option (_("Theme/Colors"), new ColorThemeManager);
3357 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3358 parameter_changed ("send-ltc");
3359 parameter_changed ("sync-source");
3360 parameter_changed ("use-monitor-bus");
3361 parameter_changed ("open-gui-after-adding-plugin");
3363 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
3365 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
3366 (Gtk::StateType) here !!!
3368 Tabbable::set_state (*node, Stateful::loading_state_version);
3373 RCOptionEditor::parameter_changed (string const & p)
3375 OptionEditor::parameter_changed (p);
3377 if (p == "use-monitor-bus") {
3378 bool const s = Config->get_use_monitor_bus ();
3380 /* we can't use this if we don't have a monitor bus */
3381 Config->set_solo_control_is_listen_control (false);
3383 _solo_control_is_listen_control->set_sensitive (s);
3384 _listen_position->set_sensitive (s);
3385 } else if (p == "sync-source") {
3386 _sync_source->set_sensitive (true);
3388 _sync_source->set_sensitive (!_session->config.get_external_sync());
3390 switch(Config->get_sync_source()) {
3393 _sync_genlock->set_sensitive (true);
3394 _sync_framerate->set_sensitive (true);
3395 _sync_source_2997->set_sensitive (true);
3398 _sync_genlock->set_sensitive (false);
3399 _sync_framerate->set_sensitive (false);
3400 _sync_source_2997->set_sensitive (false);
3403 } else if (p == "send-ltc") {
3404 bool const s = Config->get_send_ltc ();
3405 _ltc_send_continuously->set_sensitive (s);
3406 _ltc_volume_slider->set_sensitive (s);
3407 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
3408 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3409 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
3414 void RCOptionEditor::ltc_generator_volume_changed () {
3415 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
3418 void RCOptionEditor::plugin_scan_refresh () {
3419 PluginManager::instance().refresh();
3422 void RCOptionEditor::clear_vst_cache () {
3423 PluginManager::instance().clear_vst_cache();
3426 void RCOptionEditor::clear_vst_blacklist () {
3427 PluginManager::instance().clear_vst_blacklist();
3430 void RCOptionEditor::clear_au_cache () {
3431 PluginManager::instance().clear_au_cache();
3434 void RCOptionEditor::clear_au_blacklist () {
3435 PluginManager::instance().clear_au_blacklist();
3438 void RCOptionEditor::edit_lxvst_path () {
3439 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
3440 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3441 *current_toplevel(), _("Set Linux VST Search Path"),
3442 _rc_config->get_plugin_path_lxvst(),
3443 PluginManager::instance().get_default_lxvst_path()
3445 ResponseType r = (ResponseType) pd->run ();
3447 if (r == RESPONSE_ACCEPT) {
3448 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
3453 void RCOptionEditor::edit_vst_path () {
3454 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3455 *current_toplevel(), _("Set Windows VST Search Path"),
3456 _rc_config->get_plugin_path_vst(),
3457 PluginManager::instance().get_default_windows_vst_path()
3459 ResponseType r = (ResponseType) pd->run ();
3461 if (r == RESPONSE_ACCEPT) {
3462 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
3469 RCOptionEditor::populate_sync_options ()
3471 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3473 _sync_source->clear ();
3475 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3476 _sync_source->add (*i, sync_source_to_string (*i));
3479 if (sync_opts.empty()) {
3480 _sync_source->set_sensitive(false);
3482 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3483 _rc_config->set_sync_source(sync_opts.front());
3487 parameter_changed ("sync-source");
3491 RCOptionEditor::use_own_window (bool and_fill_it)
3493 bool new_window = !own_window ();
3495 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
3497 if (win && new_window) {
3498 win->set_name ("PreferencesWindow");
3499 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
3506 RCOptionEditor::get_state ()
3508 XMLNode* node = new XMLNode (X_("Preferences"));
3509 node->add_child_nocopy (Tabbable::get_state());