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 "gui_thread.h"
59 #include "meter_patterns.h"
60 #include "midi_tracer.h"
61 #include "rc_option_editor.h"
63 #include "midi_port_dialog.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, false, 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-Option-Control", GDK_MOD2_MASK|GDK_MOD1_MASK|GDK_CONTROL_MASK },
342 { "Option-Control", GDK_MOD1_MASK|GDK_CONTROL_MASK },
343 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
344 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
345 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_MOD2_MASK },
348 { "Key|Shift", GDK_SHIFT_MASK },
349 { "Control", GDK_CONTROL_MASK },
350 { "Alt", GDK_MOD1_MASK },
351 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
352 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
353 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
354 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
355 { "Alt-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
356 { "Alt-Shift-Windows", GDK_MOD1_MASK|GDK_SHIFT_MASK|GDK_MOD4_MASK },
357 { "Mod2", GDK_MOD2_MASK },
358 { "Mod3", GDK_MOD3_MASK },
359 { "Windows", GDK_MOD4_MASK },
360 { "Mod5", GDK_MOD5_MASK },
366 class KeyboardOptions : public OptionEditorBox
370 _delete_button_adjustment (3, 1, 12),
371 _delete_button_spin (_delete_button_adjustment),
372 _edit_button_adjustment (3, 1, 5),
373 _edit_button_spin (_edit_button_adjustment),
374 _insert_note_button_adjustment (3, 1, 5),
375 _insert_note_button_spin (_insert_note_button_adjustment)
377 const std::string restart_msg = _("\nChanges to this setting will only persist after your project has been saved.");
378 /* internationalize and prepare for use with combos */
381 for (int i = 0; modifiers[i].name; ++i) {
382 dumb.push_back (S_(modifiers[i].name));
385 set_popdown_strings (_edit_modifier_combo, dumb);
386 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
387 Gtkmm2ext::UI::instance()->set_tip (_edit_modifier_combo,
388 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
389 for (int x = 0; modifiers[x].name; ++x) {
390 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
391 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
396 Table* t = manage (new Table (5, 11));
402 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
403 l->set_name ("OptionsLabel");
407 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
408 strs.push_back (bf->first);
411 set_popdown_strings (_keyboard_layout_selector, strs);
412 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
413 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
415 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
416 t->attach (_keyboard_layout_selector, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
421 l = manage (left_aligned_label (_("When Clicking:")));
422 l->set_name ("OptionEditorHeading");
423 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
428 l = manage (left_aligned_label (_("Edit using:")));
429 l->set_name ("OptionsLabel");
431 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
432 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
434 l = manage (new Label (_("+ button")));
435 l->set_name ("OptionsLabel");
437 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
438 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
440 _edit_button_spin.set_name ("OptionsEntry");
441 _edit_button_adjustment.set_value (Keyboard::edit_button());
442 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
447 set_popdown_strings (_delete_modifier_combo, dumb);
448 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
449 Gtkmm2ext::UI::instance()->set_tip (_delete_modifier_combo,
450 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
451 for (int x = 0; modifiers[x].name; ++x) {
452 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
453 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
458 l = manage (left_aligned_label (_("Delete using:")));
459 l->set_name ("OptionsLabel");
461 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
462 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
464 l = manage (new Label (_("+ button")));
465 l->set_name ("OptionsLabel");
467 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
468 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
470 _delete_button_spin.set_name ("OptionsEntry");
471 _delete_button_adjustment.set_value (Keyboard::delete_button());
472 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
477 set_popdown_strings (_insert_note_modifier_combo, dumb);
478 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
479 Gtkmm2ext::UI::instance()->set_tip (_insert_note_modifier_combo,
480 (string_compose (_("<b>Recommended Setting: %1 + button 1 (left mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
481 for (int x = 0; modifiers[x].name; ++x) {
482 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
483 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
488 l = manage (left_aligned_label (_("Insert note using:")));
489 l->set_name ("OptionsLabel");
491 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
492 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
494 l = manage (new Label (_("+ button")));
495 l->set_name ("OptionsLabel");
497 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
498 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
500 _insert_note_button_spin.set_name ("OptionsEntry");
501 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
502 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
506 l = manage (left_aligned_label (_("When Beginning a Drag:")));
507 l->set_name ("OptionEditorHeading");
508 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
514 set_popdown_strings (_copy_modifier_combo, dumb);
515 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
516 Gtkmm2ext::UI::instance()->set_tip (_copy_modifier_combo,
517 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
519 Keyboard::secondary_modifier_name (),
521 Keyboard::primary_modifier_name (),
524 for (int x = 0; modifiers[x].name; ++x) {
525 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
526 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
531 l = manage (left_aligned_label (_("Copy items using:")));
532 l->set_name ("OptionsLabel");
534 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
535 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
540 /* constraint modifier */
541 set_popdown_strings (_constraint_modifier_combo, dumb);
542 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
543 Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo,
544 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
546 Keyboard::primary_modifier_name (),
548 Keyboard::secondary_modifier_name (),
551 for (int x = 0; modifiers[x].name; ++x) {
552 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
553 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
558 l = manage (left_aligned_label (_("Constrain drag using:")));
559 l->set_name ("OptionsLabel");
561 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
562 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
566 l = manage (left_aligned_label (_("When Beginning a Trim:")));
567 l->set_name ("OptionEditorHeading");
568 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
574 set_popdown_strings (_trim_contents_combo, dumb);
575 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
576 Gtkmm2ext::UI::instance()->set_tip (_trim_contents_combo,
577 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
578 for (int x = 0; modifiers[x].name; ++x) {
579 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
580 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
585 l = manage (left_aligned_label (_("Trim contents using:")));
586 l->set_name ("OptionsLabel");
588 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
589 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
595 set_popdown_strings (_trim_anchored_combo, dumb);
596 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
597 Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo,
598 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
599 for (int x = 0; modifiers[x].name; ++x) {
600 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
601 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
606 l = manage (left_aligned_label (_("Anchored trim using:")));
607 l->set_name ("OptionsLabel");
609 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
611 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
616 /* jump trim disabled for now
617 set_popdown_strings (_trim_jump_combo, dumb);
618 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
620 for (int x = 0; modifiers[x].name; ++x) {
621 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
622 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
627 l = manage (left_aligned_label (_("Jump after trim using:")));
628 l->set_name ("OptionsLabel");
630 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
632 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
638 /* note resize relative */
639 set_popdown_strings (_note_size_relative_combo, dumb);
640 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
641 Gtkmm2ext::UI::instance()->set_tip (_note_size_relative_combo,
642 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
643 for (int x = 0; modifiers[x].name; ++x) {
644 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
645 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
650 l = manage (left_aligned_label (_("Resize notes relatively using:")));
651 l->set_name ("OptionsLabel");
653 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
655 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
659 l = manage (left_aligned_label (_("While Dragging:")));
660 l->set_name ("OptionEditorHeading");
661 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
667 set_popdown_strings (_snap_modifier_combo, dumb);
668 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
670 std::string mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ());
672 std::string mod_str = Keyboard::secondary_modifier_name();
674 Gtkmm2ext::UI::instance()->set_tip (_snap_modifier_combo,
675 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
676 for (int x = 0; modifiers[x].name; ++x) {
677 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
678 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
683 l = manage (left_aligned_label (_("Ignore snap using:")));
684 l->set_name ("OptionsLabel");
686 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
687 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
693 set_popdown_strings (_snap_delta_combo, dumb);
694 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
696 mod_str = Keyboard::level4_modifier_name ();
698 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::level4_modifier_name ());
700 Gtkmm2ext::UI::instance()->set_tip (_snap_delta_combo,
701 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
702 for (int x = 0; modifiers[x].name; ++x) {
703 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
704 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
709 l = manage (left_aligned_label (_("Snap relatively using:")));
710 l->set_name ("OptionsLabel");
712 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
713 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
717 l = manage (left_aligned_label (_("While Trimming:")));
718 l->set_name ("OptionEditorHeading");
719 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
725 set_popdown_strings (_trim_overlap_combo, dumb);
726 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
728 Gtkmm2ext::UI::instance()->set_tip (_trim_overlap_combo,
729 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
730 for (int x = 0; modifiers[x].name; ++x) {
731 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
732 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
737 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
738 l->set_name ("OptionsLabel");
740 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
741 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
745 l = manage (left_aligned_label (_("While Dragging Control Points:")));
746 l->set_name ("OptionEditorHeading");
747 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
753 set_popdown_strings (_fine_adjust_combo, dumb);
754 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
756 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::tertiary_modifier_name ());
757 Gtkmm2ext::UI::instance()->set_tip (_fine_adjust_combo,
758 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
759 for (int x = 0; modifiers[x].name; ++x) {
760 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
761 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
766 l = manage (left_aligned_label (_("Fine adjust using:")));
767 l->set_name ("OptionsLabel");
769 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
770 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
776 set_popdown_strings (_push_points_combo, dumb);
777 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
779 Gtkmm2ext::UI::instance()->set_tip (_push_points_combo,
780 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
781 for (int x = 0; modifiers[x].name; ++x) {
782 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
783 _push_points_combo.set_active_text (S_(modifiers[x].name));
788 l = manage (left_aligned_label (_("Push points using:")));
789 l->set_name ("OptionsLabel");
791 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
792 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
794 _box->pack_start (*t, false, false);
797 void parameter_changed (string const &)
799 /* XXX: these aren't really config options... */
802 void set_state_from_config ()
804 /* XXX: these aren't really config options... */
809 void bindings_changed ()
811 string const txt = _keyboard_layout_selector.get_active_text();
813 /* XXX: config...? for all this keyboard stuff */
815 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
816 if (txt == i->first) {
817 if (Keyboard::load_keybindings (i->second)) {
818 Keyboard::save_keybindings ();
824 void edit_modifier_chosen ()
826 string const txt = _edit_modifier_combo.get_active_text();
828 for (int i = 0; modifiers[i].name; ++i) {
829 if (txt == _(modifiers[i].name)) {
830 Keyboard::set_edit_modifier (modifiers[i].modifier);
836 void delete_modifier_chosen ()
838 string const txt = _delete_modifier_combo.get_active_text();
840 for (int i = 0; modifiers[i].name; ++i) {
841 if (txt == _(modifiers[i].name)) {
842 Keyboard::set_delete_modifier (modifiers[i].modifier);
848 void copy_modifier_chosen ()
850 string const txt = _copy_modifier_combo.get_active_text();
852 for (int i = 0; modifiers[i].name; ++i) {
853 if (txt == _(modifiers[i].name)) {
854 Keyboard::set_copy_modifier (modifiers[i].modifier);
860 void insert_note_modifier_chosen ()
862 string const txt = _insert_note_modifier_combo.get_active_text();
864 for (int i = 0; modifiers[i].name; ++i) {
865 if (txt == _(modifiers[i].name)) {
866 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
872 void snap_modifier_chosen ()
874 string const txt = _snap_modifier_combo.get_active_text();
876 for (int i = 0; modifiers[i].name; ++i) {
877 if (txt == _(modifiers[i].name)) {
878 Keyboard::set_snap_modifier (modifiers[i].modifier);
884 void snap_delta_modifier_chosen ()
886 string const txt = _snap_delta_combo.get_active_text();
888 for (int i = 0; modifiers[i].name; ++i) {
889 if (txt == _(modifiers[i].name)) {
890 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
896 void constraint_modifier_chosen ()
898 string const txt = _constraint_modifier_combo.get_active_text();
900 for (int i = 0; modifiers[i].name; ++i) {
901 if (txt == _(modifiers[i].name)) {
902 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
908 void trim_contents_modifier_chosen ()
910 string const txt = _trim_contents_combo.get_active_text();
912 for (int i = 0; modifiers[i].name; ++i) {
913 if (txt == _(modifiers[i].name)) {
914 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
920 void trim_overlap_modifier_chosen ()
922 string const txt = _trim_overlap_combo.get_active_text();
924 for (int i = 0; modifiers[i].name; ++i) {
925 if (txt == _(modifiers[i].name)) {
926 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
932 void trim_anchored_modifier_chosen ()
934 string const txt = _trim_anchored_combo.get_active_text();
936 for (int i = 0; modifiers[i].name; ++i) {
937 if (txt == _(modifiers[i].name)) {
938 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
944 void fine_adjust_modifier_chosen ()
946 string const txt = _fine_adjust_combo.get_active_text();
948 for (int i = 0; modifiers[i].name; ++i) {
949 if (txt == _(modifiers[i].name)) {
950 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
956 void push_points_modifier_chosen ()
958 string const txt = _push_points_combo.get_active_text();
960 for (int i = 0; modifiers[i].name; ++i) {
961 if (txt == _(modifiers[i].name)) {
962 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
968 void note_size_relative_modifier_chosen ()
970 string const txt = _note_size_relative_combo.get_active_text();
972 for (int i = 0; modifiers[i].name; ++i) {
973 if (txt == _(modifiers[i].name)) {
974 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
980 void delete_button_changed ()
982 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
985 void edit_button_changed ()
987 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
990 void insert_note_button_changed ()
992 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
995 ComboBoxText _keyboard_layout_selector;
996 ComboBoxText _edit_modifier_combo;
997 ComboBoxText _delete_modifier_combo;
998 ComboBoxText _copy_modifier_combo;
999 ComboBoxText _insert_note_modifier_combo;
1000 ComboBoxText _snap_modifier_combo;
1001 ComboBoxText _snap_delta_combo;
1002 ComboBoxText _constraint_modifier_combo;
1003 ComboBoxText _trim_contents_combo;
1004 ComboBoxText _trim_overlap_combo;
1005 ComboBoxText _trim_anchored_combo;
1006 ComboBoxText _trim_jump_combo;
1007 ComboBoxText _fine_adjust_combo;
1008 ComboBoxText _push_points_combo;
1009 ComboBoxText _note_size_relative_combo;
1010 Adjustment _delete_button_adjustment;
1011 SpinButton _delete_button_spin;
1012 Adjustment _edit_button_adjustment;
1013 SpinButton _edit_button_spin;
1014 Adjustment _insert_note_button_adjustment;
1015 SpinButton _insert_note_button_spin;
1019 class FontScalingOptions : public OptionEditorBox
1022 FontScalingOptions () :
1023 _dpi_adjustment (100, 50, 250, 1, 5),
1024 _dpi_slider (_dpi_adjustment)
1026 _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.);
1028 Label* l = manage (new Label (_("GUI and Font scaling:")));
1029 l->set_name ("OptionsLabel");
1031 const std::string dflt = _("Default");
1032 const std::string empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
1034 _dpi_slider.set_name("FontScaleSlider");
1035 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1036 _dpi_slider.set_draw_value(false);
1037 _dpi_slider.add_mark(50, Gtk::POS_TOP, empty);
1038 _dpi_slider.add_mark(60, Gtk::POS_TOP, empty);
1039 _dpi_slider.add_mark(70, Gtk::POS_TOP, empty);
1040 _dpi_slider.add_mark(80, Gtk::POS_TOP, empty);
1041 _dpi_slider.add_mark(90, Gtk::POS_TOP, empty);
1042 _dpi_slider.add_mark(100, Gtk::POS_TOP, dflt);
1043 _dpi_slider.add_mark(125, Gtk::POS_TOP, empty);
1044 _dpi_slider.add_mark(150, Gtk::POS_TOP, empty);
1045 _dpi_slider.add_mark(175, Gtk::POS_TOP, empty);
1046 _dpi_slider.add_mark(200, Gtk::POS_TOP, empty);
1047 _dpi_slider.add_mark(225, Gtk::POS_TOP, empty);
1048 _dpi_slider.add_mark(250, Gtk::POS_TOP, empty);
1050 HBox* h = manage (new HBox);
1052 h->pack_start (*l, false, false);
1053 h->pack_start (_dpi_slider, true, true);
1055 _box->pack_start (*h, false, false);
1057 set_note (_("Adjusting the scale requires an application restart to re-layout."));
1059 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
1062 void parameter_changed (string const & p)
1064 if (p == "font-scale") {
1065 _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.);
1069 void set_state_from_config ()
1071 parameter_changed ("font-scale");
1078 UIConfiguration::instance().set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024.));
1079 /* XXX: should be triggered from the parameter changed signal */
1080 UIConfiguration::instance().reset_dpi ();
1083 Adjustment _dpi_adjustment;
1087 class VstTimeOutSliderOption : public OptionEditorBox
1090 VstTimeOutSliderOption (RCConfiguration* c)
1092 , _timeout_adjustment (0, 0, 3000, 50, 50)
1093 , _timeout_slider (_timeout_adjustment)
1095 _timeout_slider.set_digits (0);
1096 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &VstTimeOutSliderOption::timeout_changed));
1098 _timeout_slider.set_draw_value(false);
1099 _timeout_slider.add_mark( 0, Gtk::POS_TOP, _("\u221e")); // infinity
1100 _timeout_slider.add_mark( 300, Gtk::POS_TOP, _("30 sec"));
1101 _timeout_slider.add_mark( 600, Gtk::POS_TOP, _("1 min"));
1102 _timeout_slider.add_mark(1200, Gtk::POS_TOP, _("2 mins"));
1103 _timeout_slider.add_mark(1800, Gtk::POS_TOP, _("3 mins"));
1104 _timeout_slider.add_mark(2400, Gtk::POS_TOP, _("4 mins"));
1105 _timeout_slider.add_mark(3000, Gtk::POS_TOP, _("5 mins"));
1107 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1108 _("Specify the default timeout for plugin instantiation. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1110 Label* l = manage (left_aligned_label (_("Scan Time Out:")));
1111 HBox* h = manage (new HBox);
1113 h->pack_start (*l, false, false);
1114 h->pack_start (_timeout_slider, true, true);
1116 _box->pack_start (*h, false, false);
1119 void parameter_changed (string const & p)
1121 if (p == "vst-scan-timeout") {
1122 int const x = _rc_config->get_vst_scan_timeout();
1123 _timeout_adjustment.set_value (x);
1127 void set_state_from_config ()
1129 parameter_changed ("vst-scan-timeout");
1134 void timeout_changed ()
1136 int x = floor(_timeout_adjustment.get_value());
1137 _rc_config->set_vst_scan_timeout(x);
1140 RCConfiguration* _rc_config;
1141 Adjustment _timeout_adjustment;
1142 HScale _timeout_slider;
1149 class ClipLevelOptions : public OptionEditorBox
1153 : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1154 , _clip_level_slider (_clip_level_adjustment)
1156 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ());
1158 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
1159 l->set_name ("OptionsLabel");
1161 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1162 HBox* h = manage (new HBox);
1164 h->pack_start (*l, false, false);
1165 h->pack_start (_clip_level_slider, true, true);
1167 _box->pack_start (*h, false, false);
1169 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1172 void parameter_changed (string const & p)
1174 if (p == "waveform-clip-level") {
1175 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level());
1179 void set_state_from_config ()
1181 parameter_changed ("waveform-clip-level");
1186 void clip_level_changed ()
1188 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1189 /* XXX: should be triggered from the parameter changed signal */
1190 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1193 Adjustment _clip_level_adjustment;
1194 HScale _clip_level_slider;
1197 class BufferingOptions : public OptionEditorBox
1200 BufferingOptions (RCConfiguration* c)
1202 , _playback_adjustment (5, 1, 60, 1, 4)
1203 , _capture_adjustment (5, 1, 60, 1, 4)
1204 , _playback_slider (_playback_adjustment)
1205 , _capture_slider (_capture_adjustment)
1207 vector<string> presets;
1209 /* these must match the order of the enums for BufferingPreset */
1211 presets.push_back (_("Small sessions (4-16 tracks)"));
1212 presets.push_back (_("Medium sessions (16-64 tracks)"));
1213 presets.push_back (_("Large sessions (64+ tracks)"));
1214 presets.push_back (_("Custom (set by sliders below)"));
1216 set_popdown_strings (_buffering_presets_combo, presets);
1218 Label* l = manage (new Label (_("Preset:")));
1219 l->set_name ("OptionsLabel");
1220 HBox* h = manage (new HBox);
1221 h->set_spacing (12);
1222 h->pack_start (*l, false, false);
1223 h->pack_start (_buffering_presets_combo, true, true);
1224 _box->pack_start (*h, false, false);
1226 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1228 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1230 l = manage (new Label (_("Playback (seconds of buffering):")));
1231 l->set_name ("OptionsLabel");
1233 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1234 h = manage (new HBox);
1236 h->pack_start (*l, false, false);
1237 h->pack_start (_playback_slider, true, true);
1239 _box->pack_start (*h, false, false);
1241 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1243 l = manage (new Label (_("Recording (seconds of buffering):")));
1244 l->set_name ("OptionsLabel");
1246 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1247 h = manage (new HBox);
1249 h->pack_start (*l, false, false);
1250 h->pack_start (_capture_slider, true, true);
1252 _box->pack_start (*h, false, false);
1254 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
1255 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
1258 void parameter_changed (string const & p)
1260 if (p == "buffering-preset") {
1261 switch (_rc_config->get_buffering_preset()) {
1263 _playback_slider.set_sensitive (false);
1264 _capture_slider.set_sensitive (false);
1265 _buffering_presets_combo.set_active (0);
1268 _playback_slider.set_sensitive (false);
1269 _capture_slider.set_sensitive (false);
1270 _buffering_presets_combo.set_active (1);
1273 _playback_slider.set_sensitive (false);
1274 _capture_slider.set_sensitive (false);
1275 _buffering_presets_combo.set_active (2);
1278 _playback_slider.set_sensitive (true);
1279 _capture_slider.set_sensitive (true);
1280 _buffering_presets_combo.set_active (3);
1285 if (p == "playback-buffer-seconds") {
1286 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1287 } else if (p == "capture-buffer-seconds") {
1288 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1292 void set_state_from_config ()
1294 parameter_changed ("buffering-preset");
1295 parameter_changed ("playback-buffer-seconds");
1296 parameter_changed ("capture-buffer-seconds");
1301 void preset_changed ()
1303 int index = _buffering_presets_combo.get_active_row_number ();
1309 _rc_config->set_buffering_preset (Small);
1312 _rc_config->set_buffering_preset (Medium);
1315 _rc_config->set_buffering_preset (Large);
1318 _rc_config->set_buffering_preset (Custom);
1321 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1326 void playback_changed ()
1328 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
1331 void capture_changed ()
1333 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
1336 RCConfiguration* _rc_config;
1337 Adjustment _playback_adjustment;
1338 Adjustment _capture_adjustment;
1339 HScale _playback_slider;
1340 HScale _capture_slider;
1341 ComboBoxText _buffering_presets_combo;
1344 class ControlSurfacesOptions : public OptionEditorBox
1347 ControlSurfacesOptions ()
1348 : _ignore_view_change (0)
1350 _store = ListStore::create (_model);
1351 _view.set_model (_store);
1352 _view.append_column (_("Control Surface Protocol"), _model.name);
1353 _view.get_column(0)->set_resizable (true);
1354 _view.get_column(0)->set_expand (true);
1355 _view.append_column_editable (_("Enabled"), _model.enabled);
1356 _view.append_column_editable (_("Feedback"), _model.feedback);
1358 _box->pack_start (_view, false, false);
1360 Gtk::HBox* edit_box = manage (new Gtk::HBox);
1361 edit_box->set_spacing(3);
1362 _box->pack_start (*edit_box, false, false);
1365 Label* label = manage (new Label);
1366 label->set_text (_("Click to edit the settings for selected protocol ( it must be ENABLED first ):"));
1367 edit_box->pack_start (*label, false, false);
1370 edit_button = manage (new Button(_("Show Protocol Settings")));
1371 edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
1372 edit_box->pack_start (*edit_button, true, true);
1373 edit_button->set_sensitive (false);
1374 edit_button->show ();
1376 ControlProtocolManager& m = ControlProtocolManager::instance ();
1377 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1378 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1380 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1381 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1382 _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
1385 void parameter_changed (std::string const &)
1390 void set_state_from_config ()
1394 ControlProtocolManager& m = ControlProtocolManager::instance ();
1395 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1397 if (!(*i)->mandatory) {
1398 TreeModel::Row r = *_store->append ();
1399 r[_model.name] = (*i)->name;
1400 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1401 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
1402 r[_model.protocol_info] = *i;
1409 void protocol_status_changed (ControlProtocolInfo* cpi) {
1411 TreeModel::Children rows = _store->children();
1413 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1414 string n = ((*x)[_model.name]);
1416 if ((*x)[_model.protocol_info] == cpi) {
1417 _ignore_view_change++;
1418 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1419 _ignore_view_change--;
1425 void selection_changed ()
1427 //enable the Edit button when a row is selected for editing
1428 TreeModel::Row row = *(_view.get_selection()->get_selected());
1429 if (row && row[_model.enabled])
1430 edit_button->set_sensitive (true);
1432 edit_button->set_sensitive (false);
1435 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1437 TreeModel::Row r = *i;
1439 if (_ignore_view_change) {
1443 ControlProtocolInfo* cpi = r[_model.protocol_info];
1448 bool const was_enabled = (cpi->protocol != 0);
1449 bool const is_enabled = r[_model.enabled];
1452 if (was_enabled != is_enabled) {
1455 ControlProtocolManager::instance().activate (*cpi);
1457 ControlProtocolManager::instance().deactivate (*cpi);
1461 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
1462 bool const is_feedback = r[_model.feedback];
1464 if (was_feedback != is_feedback && cpi->protocol) {
1465 cpi->protocol->set_feedback (is_feedback);
1469 void edit_btn_clicked ()
1472 ControlProtocolInfo* cpi;
1475 row = *(_view.get_selection()->get_selected());
1476 if (!row[_model.enabled]) {
1479 cpi = row[_model.protocol_info];
1480 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1483 Box* box = (Box*) cpi->protocol->get_gui ();
1487 if (box->get_parent()) {
1488 static_cast<ArdourWindow*>(box->get_parent())->present();
1491 WindowTitle title (Glib::get_application_name());
1492 title += row[_model.name];
1493 title += _("Configuration");
1494 /* once created, the window is managed by the surface itself (as ->get_parent())
1495 * Surface's tear_down_gui() is called on session close, when de-activating
1496 * or re-initializing a surface.
1497 * tear_down_gui() hides an deletes the Window if it exists.
1499 ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
1500 win->set_title ("Control Protocol Options");
1506 void edit_clicked (GdkEventButton* ev)
1508 if (ev->type != GDK_2BUTTON_PRESS) {
1515 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1519 ControlSurfacesModelColumns ()
1524 add (protocol_info);
1527 TreeModelColumn<string> name;
1528 TreeModelColumn<bool> enabled;
1529 TreeModelColumn<bool> feedback;
1530 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1533 Glib::RefPtr<ListStore> _store;
1534 ControlSurfacesModelColumns _model;
1536 PBD::ScopedConnection protocol_status_connection;
1537 uint32_t _ignore_view_change;
1538 Gtk::Button* edit_button;
1541 class VideoTimelineOptions : public OptionEditorBox
1544 VideoTimelineOptions (RCConfiguration* c)
1546 , _show_video_export_info_button (_("Show Video Export Info before export"))
1547 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1548 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1549 , _xjadeo_browse_button (_("Browse..."))
1551 Table* t = manage (new Table (8, 4));
1552 t->set_spacings (4);
1554 std::stringstream s;
1555 s << "<b>" << _("Video Server") << "</b>";
1556 Label* l = manage (new Label (s.str()));
1557 l->set_use_markup (true);
1558 l->set_alignment (0, 0.5);
1559 t->attach (*l, 0, 4, 0, 1, EXPAND | FILL, FILL | EXPAND, 0, 8);
1561 t->attach (_video_advanced_setup_button, 1, 4, 1, 2);
1562 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1563 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1564 _("<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."));
1566 l = manage (new Label (_("Video Server URL:")));
1567 l->set_alignment (0, 0.5);
1568 t->attach (*l, 1, 2, 2, 3, FILL);
1569 t->attach (_video_server_url_entry, 2, 4, 2, 3, FILL);
1570 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1571 _("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"));
1573 l = manage (new Label (_("Video Folder:")));
1574 l->set_alignment (0, 0.5);
1575 t->attach (*l, 1, 2, 3, 4, FILL);
1576 t->attach (_video_server_docroot_entry, 2, 4, 3, 4);
1577 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1578 _("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."));
1580 t->attach (_show_video_export_info_button, 1, 4, 4, 5);
1581 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1582 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1583 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1585 t->attach (_show_video_server_dialog_button, 1, 4, 5, 6);
1586 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1587 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1588 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1590 s.str (std::string ());
1591 s << "<b>" << _("Video Monitor") << "</b>";
1592 l = manage (new Label (s.str()));
1593 l->set_use_markup (true);
1594 l->set_alignment (0, 0.5);
1595 t->attach (*l, 0, 4, 6, 7, EXPAND | FILL, FILL | EXPAND, 0, 8);
1597 l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"),
1600 #elif defined PLATFORM_WINDOWS
1606 l->set_alignment (0, 0.5);
1607 t->attach (*l, 1, 4, 7, 8, FILL);
1608 t->attach (_custom_xjadeo_path, 2, 3, 8, 9);
1609 Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart."));
1610 t->attach (_xjadeo_browse_button, 3, 4, 8, 9, FILL);
1612 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1613 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1614 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1615 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1616 _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed));
1617 _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked));
1619 // xjadeo-path is a UIConfig parameter
1620 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &VideoTimelineOptions::parameter_changed));
1622 _box->pack_start (*t,true,true);
1625 void server_url_changed ()
1627 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1630 void server_docroot_changed ()
1632 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1635 void show_video_export_info_toggled ()
1637 bool const x = _show_video_export_info_button.get_active ();
1638 _rc_config->set_show_video_export_info (x);
1641 void show_video_server_dialog_toggled ()
1643 bool const x = _show_video_server_dialog_button.get_active ();
1644 _rc_config->set_show_video_server_dialog (x);
1647 void video_advanced_setup_toggled ()
1649 bool const x = _video_advanced_setup_button.get_active ();
1650 _rc_config->set_video_advanced_setup(x);
1653 void custom_xjadeo_path_changed ()
1655 UIConfiguration::instance().set_xjadeo_binary (_custom_xjadeo_path.get_text());
1658 void xjadeo_browse_clicked ()
1660 Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN);
1661 dialog.set_filename (UIConfiguration::instance().get_xjadeo_binary());
1662 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1663 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1664 if (dialog.run () == Gtk::RESPONSE_OK) {
1665 const std::string& filename = dialog.get_filename();
1666 if (!filename.empty() && (
1668 Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) ||
1670 Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)
1672 UIConfiguration::instance().set_xjadeo_binary (filename);
1677 void parameter_changed (string const & p)
1679 if (p == "video-server-url") {
1680 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1681 } else if (p == "video-server-docroot") {
1682 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1683 } else if (p == "show-video-export-info") {
1684 bool const x = _rc_config->get_show_video_export_info();
1685 _show_video_export_info_button.set_active (x);
1686 } else if (p == "show-video-server-dialog") {
1687 bool const x = _rc_config->get_show_video_server_dialog();
1688 _show_video_server_dialog_button.set_active (x);
1689 } else if (p == "video-advanced-setup") {
1690 bool const x = _rc_config->get_video_advanced_setup();
1691 _video_advanced_setup_button.set_active(x);
1692 _video_server_docroot_entry.set_sensitive(x);
1693 _video_server_url_entry.set_sensitive(x);
1694 } else if (p == "xjadeo-binary") {
1695 _custom_xjadeo_path.set_text (UIConfiguration::instance().get_xjadeo_binary());
1699 void set_state_from_config ()
1701 parameter_changed ("video-server-url");
1702 parameter_changed ("video-server-docroot");
1703 parameter_changed ("video-monitor-setup-dialog");
1704 parameter_changed ("show-video-export-info");
1705 parameter_changed ("show-video-server-dialog");
1706 parameter_changed ("video-advanced-setup");
1707 parameter_changed ("xjadeo-binary");
1711 RCConfiguration* _rc_config;
1712 Entry _video_server_url_entry;
1713 Entry _video_server_docroot_entry;
1714 Entry _custom_xjadeo_path;
1715 CheckButton _show_video_export_info_button;
1716 CheckButton _show_video_server_dialog_button;
1717 CheckButton _video_advanced_setup_button;
1718 Button _xjadeo_browse_button;
1721 class ColumVisibilityOption : public Option
1724 ColumVisibilityOption (string id, string name, uint32_t n_col, sigc::slot<uint32_t> get, sigc::slot<bool, uint32_t> set)
1731 cb = (CheckButton**) malloc (sizeof (CheckButton*) * n_col);
1732 for (uint32_t i = 0; i < n_col; ++i) {
1733 CheckButton* col = manage (new CheckButton (string_compose (_("Column %1"), i + 1)));
1734 col->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ColumVisibilityOption::column_toggled), i));
1735 _hbox.pack_start (*col);
1738 parameter_changed (id);
1741 ~ColumVisibilityOption () {
1745 Gtk::Widget& tip_widget() { return _hbox; }
1747 void set_state_from_config ()
1749 uint32_t c = _get();
1750 for (uint32_t i = 0; i < _n_col; ++i) {
1751 bool en = (c & (1<<i)) ? true : false;
1752 if (cb[i]->get_active () != en) {
1753 cb[i]->set_active (en);
1758 void add_to_page (OptionEditorPage* p)
1760 _heading.add_to_page (p);
1761 add_widget_to_page (p, &_hbox);
1765 void column_toggled (int b) {
1766 uint32_t c = _get();
1768 if (cb[b]->get_active ()) {
1779 OptionEditorHeading _heading;
1783 sigc::slot<uint32_t> _get;
1784 sigc::slot<bool, uint32_t> _set;
1788 /** A class which allows control of visibility of some editor components usign
1789 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1790 * which has the correct members, but with null widget pointers. This
1791 * class allows the user to set visibility of the members, the details
1792 * of which are stored in a configuration variable which can be watched
1793 * by parts of the editor that actually contain the widgets whose visibility
1794 * is being controlled.
1797 class VisibilityOption : public Option
1800 /** @param name User-visible name for this group.
1801 * @param g `Dummy' VisibilityGroup (as described above).
1802 * @param get Method to get the value of the appropriate configuration variable.
1803 * @param set Method to set the value of the appropriate configuration variable.
1805 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1806 : Option (g->get_state_name(), name)
1808 , _visibility_group (g)
1812 /* Watch for changes made by the user to our members */
1813 _visibility_group->VisibilityChanged.connect_same_thread (
1814 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1818 void set_state_from_config ()
1820 /* Set our state from the current configuration */
1821 _visibility_group->set_state (_get ());
1824 void add_to_page (OptionEditorPage* p)
1826 _heading.add_to_page (p);
1827 add_widget_to_page (p, _visibility_group->list_view ());
1830 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1835 /* The user has changed something, so reflect this change
1836 in the RCConfiguration.
1838 _set (_visibility_group->get_state_value ());
1841 OptionEditorHeading _heading;
1842 VisibilityGroup* _visibility_group;
1843 sigc::slot<std::string> _get;
1844 sigc::slot<bool, std::string> _set;
1845 PBD::ScopedConnection _visibility_group_connection;
1850 RCOptionEditor::RCOptionEditor ()
1851 : OptionEditorContainer (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1852 , Tabbable (*this, _("Preferences")) /* pack self-as-vbox into tabbable */
1853 , _rc_config (Config)
1854 , _mixer_strip_visibility ("mixer-element-visibility")
1857 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
1861 uint32_t hwcpus = hardware_concurrency ();
1863 BoolComboOption* bco;
1866 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1868 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1870 _("Signal processing uses"),
1871 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1872 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1875 procs->add (-1, _("all but one processor"));
1876 procs->add (0, _("all available processors"));
1878 for (uint32_t i = 1; i <= hwcpus; ++i) {
1879 procs->add (i, string_compose (_("%1 processors"), i));
1882 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1884 add_option (_("Misc"), procs);
1887 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1889 add_option (_("Misc"), new UndoOptions (_rc_config));
1891 add_option (_("Misc"),
1893 "verify-remove-last-capture",
1894 _("Verify removal of last capture"),
1895 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1896 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1899 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1901 add_option (_("Misc"),
1903 "periodic-safety-backups",
1904 _("Make periodic backups of the session file"),
1905 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1906 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1909 add_option (_("Misc"),
1911 "only-copy-imported-files",
1912 _("Always copy imported files"),
1913 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
1914 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
1917 add_option (_("Misc"), new DirectoryOption (
1918 X_("default-session-parent-dir"),
1919 _("Default folder for new sessions:"),
1920 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1921 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1924 add_option (_("Misc"),
1925 new SpinOption<uint32_t> (
1926 "max-recent-sessions",
1927 _("Maximum number of recent sessions"),
1928 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1929 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1933 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1935 add_option (_("Misc"), new ClickOptions (_rc_config));
1937 add_option (_("Misc"),
1940 _("Click gain level"),
1941 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1942 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1945 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1947 add_option (_("Misc"),
1948 new SpinOption<double> (
1949 "automation-thinning-factor",
1950 _("Thinning factor (larger value => less data)"),
1951 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1952 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1956 add_option (_("Misc"),
1957 new SpinOption<double> (
1958 "automation-interval-msecs",
1959 _("Automation sampling interval (milliseconds)"),
1960 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1961 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1967 add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options")));
1971 tsf = new BoolOption (
1972 "latched-record-enable",
1973 _("Keep record-enable engaged on stop"),
1974 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1975 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1977 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1978 add_option (_("Transport"), tsf);
1980 tsf = new BoolOption (
1982 _("Play loop is a transport mode"),
1983 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1984 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1986 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1987 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1988 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1989 add_option (_("Transport"), tsf);
1991 tsf = new BoolOption (
1992 "stop-recording-on-xrun",
1993 _("Stop recording when an xrun occurs"),
1994 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1995 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1997 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1998 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
2000 add_option (_("Transport"), tsf);
2002 tsf = new BoolOption (
2003 "create-xrun-marker",
2004 _("Create markers where xruns occur"),
2005 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
2006 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
2008 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
2009 add_option (_("Transport"), tsf);
2011 tsf = new BoolOption (
2012 "stop-at-session-end",
2013 _("Stop at the end of the session"),
2014 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
2015 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
2017 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2018 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
2019 "when it reaches the current session end marker\n\n"
2020 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
2022 add_option (_("Transport"), tsf);
2024 tsf = new BoolOption (
2026 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
2027 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
2028 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
2030 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2031 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
2032 "preventing any need to do a transport locate at the end of the loop\n\n"
2033 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
2034 "which will often cause a small click or delay"), PROGRAM_NAME));
2035 add_option (_("Transport"), tsf);
2037 tsf = new BoolOption (
2038 "disable-disarm-during-roll",
2039 _("Disable per-track record disarm while rolling"),
2040 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
2041 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
2043 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"));
2044 add_option (_("Transport"), tsf);
2046 tsf = new BoolOption (
2048 _("12dB gain reduction during fast-forward and fast-rewind"),
2049 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
2050 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2052 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
2053 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2054 add_option (_("Transport"), tsf);
2056 ComboOption<float>* psc = new ComboOption<float> (
2059 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
2060 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
2062 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
2063 (_("The amount of preroll (in seconds) to apply when <b>Play with Preroll</b> is initiated.\n\n"
2064 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
2065 psc->add (0.0, _("0 (no pre-roll)"));
2066 psc->add (0.1, _("0.1 second"));
2067 psc->add (0.25, _("0.25 second"));
2068 psc->add (0.5, _("0.5 second"));
2069 psc->add (1.0, _("1.0 second"));
2070 psc->add (2.0, _("2.0 seconds"));
2071 add_option (_("Transport"), psc);
2073 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("Synchronization and Slave Options")));
2075 _sync_source = new ComboOption<SyncSource> (
2077 _("External timecode source"),
2078 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
2079 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
2082 add_option (_("Transport/Sync"), _sync_source);
2084 _sync_framerate = new BoolOption (
2085 "timecode-sync-frame-rate",
2086 _("Match session video frame rate to external timecode"),
2087 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
2088 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
2090 Gtkmm2ext::UI::instance()->set_tip
2091 (_sync_framerate->tip_widget(),
2092 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
2093 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
2094 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
2095 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
2096 "timecode standard and the session standard."), PROGRAM_NAME));
2098 add_option (_("Transport/Sync"), _sync_framerate);
2100 _sync_genlock = new BoolOption (
2101 "timecode-source-is-synced",
2102 _("Sync-lock timecode to clock (disable drift compensation)"),
2103 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
2104 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
2106 Gtkmm2ext::UI::instance()->set_tip
2107 (_sync_genlock->tip_widget(),
2108 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
2109 "Sync Lock indicates that the selected external timecode source shares clock-sync "
2110 "(Black & Burst, Wordclock, etc) with the audio interface. "
2111 "This option disables drift compensation. The transport speed is fixed at 1.0. "
2112 "Vari-speed LTC will be ignored and cause drift."
2114 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
2115 "timecode sources shares clock sync."
2119 add_option (_("Transport/Sync"), _sync_genlock);
2121 _sync_source_2997 = new BoolOption (
2122 "timecode-source-2997",
2123 _("Lock to 29.9700 fps instead of 30000/1001"),
2124 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
2125 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
2127 Gtkmm2ext::UI::instance()->set_tip
2128 (_sync_source_2997->tip_widget(),
2129 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
2130 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
2131 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
2132 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
2133 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
2134 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
2137 add_option (_("Transport/Sync"), _sync_source_2997);
2139 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("LTC Reader")));
2141 _ltc_port = new ComboStringOption (
2143 _("LTC incoming port"),
2144 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
2145 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
2148 vector<string> physical_inputs;
2149 physical_inputs.push_back (_("None"));
2150 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
2151 _ltc_port->set_popdown_strings (physical_inputs);
2153 populate_sync_options ();
2154 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
2156 add_option (_("Transport/Sync"), _ltc_port);
2158 // TODO; rather disable this button than not compile it..
2159 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("LTC Generator")));
2161 add_option (_("Transport/Sync"),
2164 _("Enable LTC generator"),
2165 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
2166 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
2169 _ltc_send_continuously = new BoolOption (
2170 "ltc-send-continuously",
2171 _("Send LTC while stopped"),
2172 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
2173 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
2175 Gtkmm2ext::UI::instance()->set_tip
2176 (_ltc_send_continuously->tip_widget(),
2177 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
2178 add_option (_("Transport"), _ltc_send_continuously);
2180 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
2181 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
2182 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
2183 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
2185 Gtkmm2ext::UI::instance()->set_tip
2186 (_ltc_volume_slider->tip_widget(),
2187 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
2189 add_option (_("Transport/Sync"), _ltc_volume_slider);
2193 add_option (_("Editor"),
2195 "rubberbanding-snaps-to-grid",
2196 _("Make rubberband selection rectangle snap to the grid"),
2197 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2198 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2201 bo = new BoolOption (
2203 _("Name new markers"),
2204 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2205 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2207 add_option (_("Editor"), bo);
2208 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."
2209 "\n\nYou can always rename markers by right-clicking on them"));
2211 add_option (S_("Editor"),
2213 "draggable-playhead",
2214 _("Allow dragging of playhead"),
2215 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2216 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2219 add_option (_("Editor"),
2221 "show-editor-meter",
2222 _("Display master-meter in the toolbar"),
2223 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
2224 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
2227 if (!Profile->get_mixbus()) {
2228 add_option (_("Editor"),
2231 _("Show zoom toolbar (if torn off)"),
2232 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_zoom_tools),
2233 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_zoom_tools)
2236 add_option (_("Editor"),
2238 "use-mouse-position-as-zoom-focus-on-scroll",
2239 _("Always use mouse cursor position as zoom focus when zooming using mouse scroll wheel"),
2240 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2241 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2245 add_option (_("Editor"),
2247 "update-editor-during-summary-drag",
2248 _("Update editor window during drags of the summary"),
2249 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2250 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2253 add_option (_("Editor"),
2255 "autoscroll-editor",
2256 _("Auto-scroll editor window when dragging near its edges"),
2257 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2258 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2261 add_option (_("Editor"),
2262 new BoolComboOption (
2263 "show-region-gain-envelopes",
2264 _("Show gain envelopes in audio regions"),
2266 _("only in Draw and Internal Edit modes"),
2267 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2268 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2271 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2273 add_option (_("Editor"),
2275 "automation-follows-regions",
2276 _("Move relevant automation when audio regions are moved"),
2277 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2278 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2281 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2282 "default-fade-shape",
2283 _("Default fade shape"),
2284 sigc::mem_fun (*_rc_config,
2285 &RCConfiguration::get_default_fade_shape),
2286 sigc::mem_fun (*_rc_config,
2287 &RCConfiguration::set_default_fade_shape)
2290 fadeshape->add (FadeLinear,
2291 _("Linear (for highly correlated material)"));
2292 fadeshape->add (FadeConstantPower, _("Constant power"));
2293 fadeshape->add (FadeSymmetric, _("Symmetric"));
2294 fadeshape->add (FadeSlow, _("Slow"));
2295 fadeshape->add (FadeFast, _("Fast"));
2297 add_option (_("Editor"), fadeshape);
2300 bco = new BoolComboOption (
2301 "use-overlap-equivalency",
2302 _("Regions in active edit groups are edited together"),
2303 _("whenever they overlap in time"),
2304 _("only if they have identical length, position and origin"),
2305 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2306 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2309 add_option (_("Editor"), bco);
2311 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2313 _("Layering model"),
2314 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2315 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2318 lm->add (LaterHigher, _("later is higher"));
2319 lm->add (Manual, _("manual layering"));
2320 add_option (_("Editor"), lm);
2322 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2323 "region-selection-after-split",
2324 _("After splitting selected regions, select"),
2325 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2326 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2328 // TODO: decide which of these modes are really useful
2329 rsas->add(None, _("no regions"));
2330 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2331 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2332 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2333 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2334 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2335 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2336 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2338 add_option (_("Editor"), rsas);
2340 add_option (_("Editor"), new OptionEditorHeading (_("Waveforms")));
2342 if (!Profile->get_mixbus()) {
2343 add_option (_("Editor"),
2346 _("Show waveforms in regions"),
2347 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
2348 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
2352 add_option (_("Editor"),
2354 "show-waveforms-while-recording",
2355 _("Show waveforms for audio while it is being recorded"),
2356 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
2357 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
2360 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
2362 _("Waveform scale"),
2363 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
2364 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
2367 wfs->add (Linear, _("linear"));
2368 wfs->add (Logarithmic, _("logarithmic"));
2370 add_option (_("Editor"), wfs);
2372 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
2374 _("Waveform shape"),
2375 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
2376 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
2379 wfsh->add (Traditional, _("traditional"));
2380 wfsh->add (Rectified, _("rectified"));
2382 add_option (_("Editor"), wfsh);
2384 add_option (_("Editor"), new ClipLevelOptions ());
2389 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2391 add_option (_("Audio"), new BufferingOptions (_rc_config));
2393 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2395 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2397 _("Record monitoring handled by"),
2398 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2399 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2402 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2403 mm->add (HardwareMonitoring, _("via Audio Driver"));
2406 string prog (PROGRAM_NAME);
2407 boost::algorithm::to_lower (prog);
2408 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2409 mm->add (ExternalMonitoring, _("audio hardware"));
2411 add_option (_("Audio"), mm);
2413 add_option (_("Audio"),
2415 "tape-machine-mode",
2416 _("Tape machine mode"),
2417 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2418 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2421 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2422 if (!Profile->get_mixbus()) {
2424 add_option (_("Audio"),
2426 "auto-connect-standard-busses",
2427 _("Auto-connect master/monitor busses"),
2428 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2429 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2432 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2433 "input-auto-connect",
2434 _("Connect track inputs"),
2435 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2436 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2439 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2440 iac->add (ManualConnect, _("manually"));
2442 add_option (_("Audio"), iac);
2444 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2445 "output-auto-connect",
2446 _("Connect track and bus outputs"),
2447 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2448 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2451 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2452 oac->add (AutoConnectMaster, _("automatically to master bus"));
2453 oac->add (ManualConnect, _("manually"));
2455 add_option (_("Audio"), oac);
2457 bo = new BoolOption (
2459 _("Use 'Strict-I/O' for new tracks or Busses"),
2460 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2461 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2464 add_option (_("Audio"), bo);
2465 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2466 _("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."));
2470 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2472 add_option (_("Audio"),
2474 "denormal-protection",
2475 _("Use DC bias to protect against denormals"),
2476 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2477 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2480 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2482 _("Processor handling"),
2483 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2484 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2488 dm->add (DenormalNone, _("no processor handling"));
2490 FPU* fpu = FPU::instance();
2492 if (fpu->has_flush_to_zero()) {
2494 dm->add (DenormalFTZ, _("use FlushToZero"));
2495 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2496 _rc_config->set_denormal_model(DenormalNone);
2499 if (fpu->has_denormals_are_zero()) {
2501 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2502 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2503 _rc_config->set_denormal_model(DenormalNone);
2506 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2508 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2509 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2510 _rc_config->set_denormal_model(DenormalNone);
2514 dm->set_sensitive(false);
2517 add_option (_("Audio"), dm);
2519 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
2521 add_option (_("Audio"),
2523 "plugins-stop-with-transport",
2524 _("Silence plugins when the transport is stopped"),
2525 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
2526 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
2529 add_option (_("Audio"),
2531 "new-plugins-active",
2532 _("Make new plugins active"),
2533 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
2534 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
2537 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2539 add_option (_("Audio"),
2541 "auto-analyse-audio",
2542 _("Enable automatic analysis of audio"),
2543 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2544 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2547 add_option (_("Audio"),
2549 "replicate-missing-region-channels",
2550 _("Replicate missing region channels"),
2551 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2552 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2557 add_option (_("Solo & mute"), new OptionEditorHeading (_("Solo")));
2559 _solo_control_is_listen_control = new BoolOption (
2560 "solo-control-is-listen-control",
2561 _("Solo controls are Listen controls"),
2562 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2563 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2566 add_option (_("Solo & mute"), _solo_control_is_listen_control);
2568 add_option (_("Solo & mute"),
2571 _("Exclusive solo"),
2572 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2573 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2576 add_option (_("Solo & mute"),
2579 _("Show solo muting"),
2580 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2581 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2584 add_option (_("Solo & mute"),
2586 "solo-mute-override",
2587 _("Soloing overrides muting"),
2588 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2589 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2592 add_option (_("Solo & mute"),
2595 _("Solo-in-place mute cut (dB)"),
2596 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2597 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2600 _listen_position = new ComboOption<ListenPosition> (
2602 _("Listen Position"),
2603 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2604 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2607 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2608 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2610 add_option (_("Solo & mute"), _listen_position);
2612 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2614 _("PFL signals come from"),
2615 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2616 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2619 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2620 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2622 add_option (_("Solo & mute"), pp);
2624 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2626 _("AFL signals come from"),
2627 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2628 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2631 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2632 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2634 add_option (_("Solo & mute"), pa);
2636 add_option (_("Solo & mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2638 add_option (_("Solo & mute"),
2640 "mute-affects-pre-fader",
2641 _("Mute affects pre-fader sends"),
2642 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2643 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2646 add_option (_("Solo & mute"),
2648 "mute-affects-post-fader",
2649 _("Mute affects post-fader sends"),
2650 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2651 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2654 add_option (_("Solo & mute"),
2656 "mute-affects-control-outs",
2657 _("Mute affects control outputs"),
2658 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2659 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2662 add_option (_("Solo & mute"),
2664 "mute-affects-main-outs",
2665 _("Mute affects main outputs"),
2666 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2667 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2671 if (!ARDOUR::Profile->get_mixbus()) {
2672 add_option (_("Solo & mute"), new OptionEditorHeading (_("Send Routing")));
2673 add_option (_("Solo & mute"),
2675 "link-send-and-route-panner",
2676 _("Link panners of Aux and External Sends with main panner by default"),
2677 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2678 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2682 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Preferences")));
2684 add_option (_("MIDI"),
2685 new SpinOption<float> (
2687 _("MIDI read-ahead time (seconds)"),
2688 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2689 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2694 add_option (_("MIDI"),
2695 new SpinOption<int32_t> (
2696 "initial-program-change",
2697 _("Initial program change"),
2698 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2699 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2703 add_option (_("MIDI"),
2705 "display-first-midi-bank-as-zero",
2706 _("Display first MIDI bank/program as 0"),
2707 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2708 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2711 add_option (_("MIDI"),
2713 "never-display-periodic-midi",
2714 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2715 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
2716 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
2719 add_option (_("MIDI"),
2722 _("Sound MIDI notes as they are selected in the editor"),
2723 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2724 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2727 add_option (_("MIDI"),
2730 _("Send MIDI control feedback"),
2731 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2732 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2735 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Clock")));
2737 add_option (_("MIDI"),
2740 _("Send MIDI Clock"),
2741 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2742 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2745 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC)")));
2747 add_option (_("MIDI"),
2750 _("Send MIDI Time Code"),
2751 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2752 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2755 add_option (_("MIDI"),
2756 new SpinOption<int> (
2757 "mtc-qf-speed-tolerance",
2758 _("Percentage either side of normal transport speed to transmit MTC"),
2759 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2760 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2764 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Machine Control (MMC)")));
2766 add_option (_("MIDI"),
2769 _("Obey MIDI Machine Control commands"),
2770 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2771 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2774 add_option (_("MIDI"),
2777 _("Send MIDI Machine Control commands"),
2778 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2779 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2782 add_option (_("MIDI"),
2783 new SpinOption<uint8_t> (
2784 "mmc-receive-device-id",
2785 _("Inbound MMC device ID"),
2786 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2787 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2791 add_option (_("MIDI"),
2792 new SpinOption<uint8_t> (
2793 "mmc-send-device-id",
2794 _("Outbound MMC device ID"),
2795 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2796 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2800 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2802 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2803 "midi-audition-synth-uri",
2804 _("Midi Audition Synth (LV2)"),
2805 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2806 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2809 audition_synth->add(X_(""), _("None"));
2810 PluginInfoList all_plugs;
2811 PluginManager& manager (PluginManager::instance());
2813 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2815 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2816 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2817 if (!(*i)->is_instrument()) continue;
2818 if ((*i)->type != ARDOUR::LV2) continue;
2819 audition_synth->add((*i)->unique_id, (*i)->name);
2823 add_option (_("MIDI"), audition_synth);
2825 /* USER INTERACTION */
2828 #ifdef PLATFORM_WINDOWS
2831 getenv ("ARDOUR_BUNDLED")
2835 add_option (_("User interaction"),
2837 "enable-translation",
2838 string_compose (_("Use translations of %1 messages\n"
2839 " <i>(requires a restart of %1 to take effect)</i>\n"
2840 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2841 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2842 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2845 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2847 add_option (_("User interaction"), new KeyboardOptions);
2849 /* Control Surfaces */
2851 add_option (_("Control Surfaces"), new ControlSurfacesOptions);
2853 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2855 _("Control surface remote ID"),
2856 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2857 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2860 rm->add (UserOrdered, _("assigned by user"));
2861 rm->add (MixerOrdered, _("follows order of mixer"));
2863 add_option (_("Control Surfaces"), rm);
2865 /* VIDEO Timeline */
2866 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2868 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2869 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
2871 add_option (_("Plugins"),
2872 new RcActionButton (_("Scan for Plugins"),
2873 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
2875 bo = new BoolOption (
2876 "show-plugin-scan-window",
2877 _("Always Display Plugin Scan Progress"),
2878 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
2879 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
2881 add_option (_("Plugins"), bo);
2882 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2883 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
2887 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
2888 add_option (_("Plugins"), new OptionEditorHeading (_("VST")));
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"), 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"), 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"), new VstTimeOutSliderOption (_rc_config));
2915 add_option (_("Plugins"),
2916 new RcActionButton (_("Clear"),
2917 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
2920 add_option (_("Plugins"),
2921 new RcActionButton (_("Clear"),
2922 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
2923 _("VST Blacklist:")));
2926 #ifdef LXVST_SUPPORT
2927 add_option (_("Plugins"),
2928 new RcActionButton (_("Edit"),
2929 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
2930 _("Linux VST Path:")));
2932 add_option (_("Plugins"),
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"),
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
2954 add_option (_("Plugins"), new OptionEditorHeading (_("Audio Unit")));
2956 bo = new BoolOption (
2957 "discover-audio-units",
2958 _("Scan for AudioUnit Plugins on Application Start"),
2959 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
2960 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
2962 add_option (_("Plugins"), bo);
2963 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2964 _("<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."));
2966 add_option (_("Plugins"),
2967 new RcActionButton (_("Clear"),
2968 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
2971 add_option (_("Plugins"),
2972 new RcActionButton (_("Clear"),
2973 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
2974 _("AU Blacklist:")));
2977 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
2978 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
2979 add_option (_("Plugins"),
2981 "open-gui-after-adding-plugin",
2982 _("Automatically open the plugin GUI when adding a new plugin"),
2983 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
2984 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
2988 add_option (_("Plugins"),
2990 "show-inline-display-by-default",
2991 _("Show Plugin Inline Display on Mixerstrip by default"),
2992 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
2993 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
2996 _plugin_prefer_inline = new BoolOption (
2997 "prefer-inline-over-gui",
2998 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
2999 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3000 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3002 add_option (_("Plugins"), _plugin_prefer_inline);
3008 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3009 BoolOption* bgc = new BoolOption (
3010 "cairo-image-surface",
3011 _("Disable Graphics Hardware Acceleration (requires restart)"),
3012 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3013 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3016 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3017 _("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));
3018 add_option (S_("Preferences|GUI"), bgc);
3021 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3022 BoolOption* bgo = new BoolOption (
3024 _("Possibly improve slow graphical performance (requires restart)"),
3025 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3026 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3029 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));
3030 add_option (S_("Preferences|GUI"), bgo);
3033 add_option (S_("Preferences|GUI"),
3036 _("Graphically indicate mouse pointer hovering over various widgets"),
3037 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3038 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3041 add_option (S_("Preferences|GUI"),
3044 _("Show tooltips if mouse hovers over a control"),
3045 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3046 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3049 add_option (S_("Preferences|GUI"),
3051 "show-name-highlight",
3052 _("Use name highlight bars in region displays (requires a restart)"),
3053 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3054 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3057 add_option (S_("Preferences|GUI"),
3059 "super-rapid-clock-update",
3060 _("Update transport clock display at FPS instead of every 100ms"),
3061 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3062 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3067 /* font scaling does nothing with GDK/Quartz */
3068 add_option (S_("Preferences|GUI"), new FontScalingOptions ());
3071 /* Image cache size */
3073 Gtk::Adjustment *ics = manage (new Gtk::Adjustment(0, 1, 1024, 10)); /* 1 MB to 1GB in steps of 10MB */
3074 HSliderOption *sics = new HSliderOption("waveform-cache-size",
3075 _("Waveform image cache size (megabytes)"),
3077 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
3078 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size)
3080 sics->scale().set_digits (0);
3081 Gtkmm2ext::UI::instance()->set_tip
3082 (sics->tip_widget(),
3083 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
3084 add_option (S_("Preferences|GUI"), sics);
3086 if (!ARDOUR::Profile->get_mixbus()) {
3087 /* Lock GUI timeout */
3089 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
3090 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
3091 _("Lock timeout (seconds)"),
3093 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
3094 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds)
3096 slts->scale().set_digits (0);
3097 Gtkmm2ext::UI::instance()->set_tip
3098 (slts->tip_widget(),
3099 _("Lock GUI after this many idle seconds (zero to never lock)"));
3100 add_option (S_("Preferences|GUI"), slts);
3103 /* The names of these controls must be the same as those given in MixerStrip
3104 for the actual widgets being controlled.
3106 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3107 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3108 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3109 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3110 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3111 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3114 S_("Preferences|GUI"),
3115 new VisibilityOption (
3117 &_mixer_strip_visibility,
3118 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3119 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3123 add_option (S_("Preferences|GUI"),
3125 "default-narrow_ms",
3126 _("Use narrow strips in the mixer by default"),
3127 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3128 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3131 add_option (S_("Preferences|GUI"),
3132 new ColumVisibilityOption (
3133 "action-table-columns", _("Action Script Button Visibility"), 3,
3134 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3135 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3139 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
3141 ComboOption<float>* mht = new ComboOption<float> (
3143 _("Peak hold time"),
3144 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
3145 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
3148 mht->add (MeterHoldOff, _("off"));
3149 mht->add (MeterHoldShort, _("short"));
3150 mht->add (MeterHoldMedium, _("medium"));
3151 mht->add (MeterHoldLong, _("long"));
3153 add_option (S_("Preferences|Metering"), mht);
3155 ComboOption<float>* mfo = new ComboOption<float> (
3158 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
3159 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
3162 mfo->add (METER_FALLOFF_OFF, _("off"));
3163 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
3164 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
3165 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
3166 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
3167 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
3168 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
3170 add_option (S_("Preferences|Metering"), mfo);
3172 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
3173 "meter-line-up-level",
3174 _("Meter line-up level; 0dBu"),
3175 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
3176 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
3179 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3180 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3181 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3182 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3184 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."));
3186 add_option (S_("Preferences|Metering"), mlu);
3188 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
3189 "meter-line-up-din",
3190 _("IEC1/DIN Meter line-up level; 0dBu"),
3191 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
3192 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
3195 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3196 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3197 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3198 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3200 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
3202 add_option (S_("Preferences|Metering"), mld);
3204 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
3205 "meter-vu-standard",
3206 _("VU Meter standard"),
3207 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
3208 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
3211 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
3212 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
3213 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
3214 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
3216 add_option (S_("Preferences|Metering"), mvu);
3218 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
3219 HSliderOption *mpks = new HSliderOption("meter-peak",
3220 _("Peak threshold [dBFS]"),
3222 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
3223 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak)
3227 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3228 "meter-type-master",
3229 _("Default Meter Type for Master Bus"),
3230 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3231 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3233 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3234 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3235 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3236 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3237 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3238 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3239 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3240 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3242 add_option (S_("Preferences|Metering"), mtm);
3245 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3247 _("Default Meter Type for Busses"),
3248 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3249 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3251 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3252 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3253 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3254 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3255 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3256 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3257 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3258 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3260 add_option (S_("Preferences|Metering"), mtb);
3262 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3264 _("Default Meter Type for Tracks"),
3265 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3266 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3268 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3269 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3271 add_option (S_("Preferences|Metering"), mtt);
3274 Gtkmm2ext::UI::instance()->set_tip
3275 (mpks->tip_widget(),
3276 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
3278 add_option (S_("Preferences|Metering"), mpks);
3280 add_option (S_("Preferences|Metering"),
3283 _("LED meter style"),
3284 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3285 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3288 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Editor Meters")));
3290 add_option (S_("Preferences|Metering"),
3292 "show-track-meters",
3293 _("Show meters on tracks in the editor"),
3294 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3295 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3298 add_option (S_("Preferences|Metering"),
3300 "editor-stereo-only-meters",
3301 _("Show at most stereo meters in the track-header"),
3302 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3303 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3306 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
3308 add_option (S_("Preferences|Metering"),
3310 "save-export-analysis-image",
3311 _("Save loudness analysis as image file"),
3312 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
3313 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
3316 /* and now the theme manager */
3318 ThemeManager* tm = manage (new ThemeManager);
3319 add_page (_("Theme"), *tm);
3321 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3322 parameter_changed ("send-ltc");
3323 parameter_changed ("sync-source");
3324 parameter_changed ("use-monitor-bus");
3328 RCOptionEditor::parameter_changed (string const & p)
3330 OptionEditor::parameter_changed (p);
3332 if (p == "use-monitor-bus") {
3333 bool const s = Config->get_use_monitor_bus ();
3335 /* we can't use this if we don't have a monitor bus */
3336 Config->set_solo_control_is_listen_control (false);
3338 _solo_control_is_listen_control->set_sensitive (s);
3339 _listen_position->set_sensitive (s);
3340 } else if (p == "sync-source") {
3341 _sync_source->set_sensitive (true);
3343 _sync_source->set_sensitive (!_session->config.get_external_sync());
3345 switch(Config->get_sync_source()) {
3348 _sync_genlock->set_sensitive (true);
3349 _sync_framerate->set_sensitive (true);
3350 _sync_source_2997->set_sensitive (true);
3353 _sync_genlock->set_sensitive (false);
3354 _sync_framerate->set_sensitive (false);
3355 _sync_source_2997->set_sensitive (false);
3358 } else if (p == "send-ltc") {
3359 bool const s = Config->get_send_ltc ();
3360 _ltc_send_continuously->set_sensitive (s);
3361 _ltc_volume_slider->set_sensitive (s);
3362 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
3364 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
3369 void RCOptionEditor::ltc_generator_volume_changed () {
3370 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
3373 void RCOptionEditor::plugin_scan_refresh () {
3374 PluginManager::instance().refresh();
3377 void RCOptionEditor::clear_vst_cache () {
3378 PluginManager::instance().clear_vst_cache();
3381 void RCOptionEditor::clear_vst_blacklist () {
3382 PluginManager::instance().clear_vst_blacklist();
3385 void RCOptionEditor::clear_au_cache () {
3386 PluginManager::instance().clear_au_cache();
3389 void RCOptionEditor::clear_au_blacklist () {
3390 PluginManager::instance().clear_au_blacklist();
3393 void RCOptionEditor::edit_lxvst_path () {
3394 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
3395 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3396 *current_toplevel(), _("Set Linux VST Search Path"),
3397 _rc_config->get_plugin_path_lxvst(),
3398 PluginManager::instance().get_default_lxvst_path()
3400 ResponseType r = (ResponseType) pd->run ();
3402 if (r == RESPONSE_ACCEPT) {
3403 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
3408 void RCOptionEditor::edit_vst_path () {
3409 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3410 *current_toplevel(), _("Set Windows VST Search Path"),
3411 _rc_config->get_plugin_path_vst(),
3412 PluginManager::instance().get_default_windows_vst_path()
3414 ResponseType r = (ResponseType) pd->run ();
3416 if (r == RESPONSE_ACCEPT) {
3417 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
3424 RCOptionEditor::populate_sync_options ()
3426 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3428 _sync_source->clear ();
3430 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3431 _sync_source->add (*i, sync_source_to_string (*i));
3434 if (sync_opts.empty()) {
3435 _sync_source->set_sensitive(false);
3437 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3438 _rc_config->set_sync_source(sync_opts.front());
3442 parameter_changed ("sync-source");
3446 RCOptionEditor::use_own_window (bool and_fill_it)
3448 bool new_window = !own_window();
3450 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
3452 if (win && new_window) {
3453 win->set_name ("PreferencesWindow");
3454 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);