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>
44 #include "ardour/audioengine.h"
45 #include "ardour/profile.h"
46 #include "ardour/dB.h"
47 #include "ardour/rc_configuration.h"
48 #include "ardour/control_protocol_manager.h"
49 #include "ardour/plugin_manager.h"
50 #include "control_protocol/control_protocol.h"
52 #include "canvas/wave_view.h"
54 #include "ardour_window.h"
55 #include "ardour_dialog.h"
56 #include "gui_thread.h"
57 #include "meter_patterns.h"
58 #include "midi_tracer.h"
59 #include "rc_option_editor.h"
61 #include "midi_port_dialog.h"
64 #include "theme_manager.h"
65 #include "ui_config.h"
70 using namespace Gtkmm2ext;
72 using namespace ARDOUR;
73 using namespace ARDOUR_UI_UTILS;
75 class ClickOptions : public OptionEditorBox
78 ClickOptions (RCConfiguration* c, Gtk::Window* p)
80 , _click_browse_button (_("Browse..."))
81 , _click_emphasis_browse_button (_("Browse..."))
83 Table* t = manage (new Table (4, 3));
86 Label* l = manage (left_aligned_label (_("Emphasis on first beat:")));
87 t->attach (*l, 0, 1, 1, 2, FILL);
88 t->attach (_use_emphasis_on_click_check_button, 1, 2, 1, 2, FILL);
89 _use_emphasis_on_click_check_button.signal_toggled().connect (
90 sigc::mem_fun (*this, &ClickOptions::use_emphasis_on_click_toggled));
92 l = manage (left_aligned_label (_("Use default Click:")));
93 t->attach (*l, 0, 1, 0, 1, FILL);
94 t->attach (_use_default_click_check_button, 1, 2, 0, 1, FILL);
95 _use_default_click_check_button.signal_toggled().connect (
96 sigc::mem_fun (*this, &ClickOptions::use_default_click_toggled));
98 l = manage (left_aligned_label (_("Click audio file:")));
99 t->attach (*l, 0, 1, 2, 3, FILL);
100 t->attach (_click_path_entry, 1, 2, 2, 3, FILL);
101 _click_browse_button.signal_clicked ().connect (
102 sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
103 t->attach (_click_browse_button, 2, 3, 2, 3, FILL);
105 l = manage (left_aligned_label (_("Click emphasis audio file:")));
106 t->attach (*l, 0, 1, 3, 4, FILL);
107 t->attach (_click_emphasis_path_entry, 1, 2, 3, 4, FILL);
108 _click_emphasis_browse_button.signal_clicked ().connect (
109 sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
110 t->attach (_click_emphasis_browse_button, 2, 3, 3, 4, FILL);
112 _box->pack_start (*t, false, false);
114 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
115 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
117 if (_rc_config->get_click_sound ().empty() &&
118 _rc_config->get_click_emphasis_sound().empty()) {
119 _use_default_click_check_button.set_active (true);
120 _use_emphasis_on_click_check_button.set_active (true);
123 _use_default_click_check_button.set_active (false);
124 _use_emphasis_on_click_check_button.set_active (false);
128 void parameter_changed (string const & p)
130 if (p == "click-sound") {
131 _click_path_entry.set_text (_rc_config->get_click_sound());
132 } else if (p == "click-emphasis-sound") {
133 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
134 } else if (p == "use-click-emphasis") {
135 bool x = _rc_config->get_use_click_emphasis ();
136 _use_emphasis_on_click_check_button.set_active (x);
140 void set_state_from_config ()
142 parameter_changed ("click-sound");
143 parameter_changed ("click-emphasis-sound");
144 parameter_changed ("use-click-emphasis");
149 void click_browse_clicked ()
151 SoundFileChooser sfdb (_("Choose Click"));
156 if (sfdb.run () == RESPONSE_OK) {
157 click_chosen (sfdb.get_filename());
161 void click_chosen (string const & path)
163 _click_path_entry.set_text (path);
164 _rc_config->set_click_sound (path);
167 void click_changed ()
169 click_chosen (_click_path_entry.get_text ());
172 void click_emphasis_browse_clicked ()
174 SoundFileChooser sfdb (_("Choose Click Emphasis"));
179 if (sfdb.run () == RESPONSE_OK) {
180 click_emphasis_chosen (sfdb.get_filename());
184 void click_emphasis_chosen (string const & path)
186 _click_emphasis_path_entry.set_text (path);
187 _rc_config->set_click_emphasis_sound (path);
190 void click_emphasis_changed ()
192 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
195 void use_default_click_toggled ()
197 if (_use_default_click_check_button.get_active ()) {
198 _rc_config->set_click_sound ("");
199 _rc_config->set_click_emphasis_sound ("");
200 _click_path_entry.set_sensitive (false);
201 _click_emphasis_path_entry.set_sensitive (false);
202 _click_browse_button.set_sensitive (false);
203 _click_emphasis_browse_button.set_sensitive (false);
205 _click_path_entry.set_sensitive (true);
206 _click_emphasis_path_entry.set_sensitive (true);
207 _click_browse_button.set_sensitive (true);
208 _click_emphasis_browse_button.set_sensitive (true);
212 void use_emphasis_on_click_toggled ()
214 if (_use_emphasis_on_click_check_button.get_active ()) {
215 _rc_config->set_use_click_emphasis(true);
217 _rc_config->set_use_click_emphasis(false);
221 RCConfiguration* _rc_config;
222 CheckButton _use_default_click_check_button;
223 CheckButton _use_emphasis_on_click_check_button;
224 Entry _click_path_entry;
225 Entry _click_emphasis_path_entry;
226 Button _click_browse_button;
227 Button _click_emphasis_browse_button;
230 class UndoOptions : public OptionEditorBox
233 UndoOptions (RCConfiguration* c) :
235 _limit_undo_button (_("Limit undo history to")),
236 _save_undo_button (_("Save undo history of"))
238 Table* t = new Table (2, 3);
241 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
242 _limit_undo_spin.set_range (0, 512);
243 _limit_undo_spin.set_increments (1, 10);
244 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
245 Label* l = manage (left_aligned_label (_("commands")));
246 t->attach (*l, 2, 3, 0, 1);
248 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
249 _save_undo_spin.set_range (0, 512);
250 _save_undo_spin.set_increments (1, 10);
251 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
252 l = manage (left_aligned_label (_("commands")));
253 t->attach (*l, 2, 3, 1, 2);
255 _box->pack_start (*t);
257 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
258 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
259 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
260 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
263 void parameter_changed (string const & p)
265 if (p == "history-depth") {
266 int32_t const d = _rc_config->get_history_depth();
267 _limit_undo_button.set_active (d != 0);
268 _limit_undo_spin.set_sensitive (d != 0);
269 _limit_undo_spin.set_value (d);
270 } else if (p == "save-history") {
271 bool const x = _rc_config->get_save_history ();
272 _save_undo_button.set_active (x);
273 _save_undo_spin.set_sensitive (x);
274 } else if (p == "save-history-depth") {
275 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
279 void set_state_from_config ()
281 parameter_changed ("save-history");
282 parameter_changed ("history-depth");
283 parameter_changed ("save-history-depth");
286 void limit_undo_toggled ()
288 bool const x = _limit_undo_button.get_active ();
289 _limit_undo_spin.set_sensitive (x);
290 int32_t const n = x ? 16 : 0;
291 _limit_undo_spin.set_value (n);
292 _rc_config->set_history_depth (n);
295 void limit_undo_changed ()
297 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
300 void save_undo_toggled ()
302 bool const x = _save_undo_button.get_active ();
303 _rc_config->set_save_history (x);
306 void save_undo_changed ()
308 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
312 RCConfiguration* _rc_config;
313 CheckButton _limit_undo_button;
314 SpinButton _limit_undo_spin;
315 CheckButton _save_undo_button;
316 SpinButton _save_undo_spin;
321 static const struct {
333 { "Key|Shift", GDK_SHIFT_MASK },
334 { "Command", GDK_MOD2_MASK },
335 { "Control", GDK_CONTROL_MASK },
336 { "Option", GDK_MOD1_MASK },
337 { "Command-Shift", GDK_MOD2_MASK|GDK_SHIFT_MASK },
338 { "Command-Option", GDK_MOD2_MASK|GDK_MOD1_MASK },
339 { "Command-Option-Control", GDK_MOD2_MASK|GDK_MOD1_MASK|GDK_CONTROL_MASK },
340 { "Option-Control", GDK_MOD1_MASK|GDK_CONTROL_MASK },
341 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
342 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
343 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_MOD2_MASK },
346 { "Key|Shift", GDK_SHIFT_MASK },
347 { "Control", GDK_CONTROL_MASK },
348 { "Alt", GDK_MOD1_MASK },
349 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
350 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
351 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
352 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
353 { "Alt-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
354 { "Alt-Shift-Windows", GDK_MOD1_MASK|GDK_SHIFT_MASK|GDK_MOD4_MASK },
355 { "Mod2", GDK_MOD2_MASK },
356 { "Mod3", GDK_MOD3_MASK },
357 { "Windows", GDK_MOD4_MASK },
358 { "Mod5", GDK_MOD5_MASK },
364 class KeyboardOptions : public OptionEditorBox
368 _delete_button_adjustment (3, 1, 12),
369 _delete_button_spin (_delete_button_adjustment),
370 _edit_button_adjustment (3, 1, 5),
371 _edit_button_spin (_edit_button_adjustment),
372 _insert_note_button_adjustment (3, 1, 5),
373 _insert_note_button_spin (_insert_note_button_adjustment)
375 const Glib::ustring restart_msg = _("\nChanges to this setting will only persist after your project has been saved.");
376 /* internationalize and prepare for use with combos */
379 for (int i = 0; modifiers[i].name; ++i) {
380 dumb.push_back (S_(modifiers[i].name));
383 set_popdown_strings (_edit_modifier_combo, dumb);
384 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
385 Gtkmm2ext::UI::instance()->set_tip (_edit_modifier_combo,
386 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
387 for (int x = 0; modifiers[x].name; ++x) {
388 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
389 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
394 Table* t = manage (new Table (5, 11));
400 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
401 l->set_name ("OptionsLabel");
405 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
406 strs.push_back (bf->first);
409 set_popdown_strings (_keyboard_layout_selector, strs);
410 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
411 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
413 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
414 t->attach (_keyboard_layout_selector, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
419 l = manage (left_aligned_label (_("When Clicking:")));
420 l->set_name ("OptionEditorHeading");
421 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
426 l = manage (left_aligned_label (_("Edit using:")));
427 l->set_name ("OptionsLabel");
429 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
430 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
432 l = manage (new Label (_("+ button")));
433 l->set_name ("OptionsLabel");
435 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
436 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
438 _edit_button_spin.set_name ("OptionsEntry");
439 _edit_button_adjustment.set_value (Keyboard::edit_button());
440 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
445 set_popdown_strings (_delete_modifier_combo, dumb);
446 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
447 Gtkmm2ext::UI::instance()->set_tip (_delete_modifier_combo,
448 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
449 for (int x = 0; modifiers[x].name; ++x) {
450 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
451 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
456 l = manage (left_aligned_label (_("Delete using:")));
457 l->set_name ("OptionsLabel");
459 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
460 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
462 l = manage (new Label (_("+ button")));
463 l->set_name ("OptionsLabel");
465 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
466 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
468 _delete_button_spin.set_name ("OptionsEntry");
469 _delete_button_adjustment.set_value (Keyboard::delete_button());
470 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
475 set_popdown_strings (_insert_note_modifier_combo, dumb);
476 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
477 Gtkmm2ext::UI::instance()->set_tip (_insert_note_modifier_combo,
478 (string_compose (_("<b>Recommended Setting: %1 + button 1 (left mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
479 for (int x = 0; modifiers[x].name; ++x) {
480 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
481 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
486 l = manage (left_aligned_label (_("Insert note using:")));
487 l->set_name ("OptionsLabel");
489 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
490 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
492 l = manage (new Label (_("+ button")));
493 l->set_name ("OptionsLabel");
495 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
496 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
498 _insert_note_button_spin.set_name ("OptionsEntry");
499 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
500 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
504 l = manage (left_aligned_label (_("When Beginning a Drag:")));
505 l->set_name ("OptionEditorHeading");
506 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
512 set_popdown_strings (_copy_modifier_combo, dumb);
513 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
514 Gtkmm2ext::UI::instance()->set_tip (_copy_modifier_combo,
515 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
517 Keyboard::secondary_modifier_name (),
519 Keyboard::primary_modifier_name (),
522 for (int x = 0; modifiers[x].name; ++x) {
523 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
524 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
529 l = manage (left_aligned_label (_("Copy items using:")));
530 l->set_name ("OptionsLabel");
532 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
533 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
538 /* constraint modifier */
539 set_popdown_strings (_constraint_modifier_combo, dumb);
540 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
541 Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo,
542 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
544 Keyboard::primary_modifier_name (),
546 Keyboard::secondary_modifier_name (),
549 for (int x = 0; modifiers[x].name; ++x) {
550 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
551 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
556 l = manage (left_aligned_label (_("Constrain drag using:")));
557 l->set_name ("OptionsLabel");
559 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
560 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
564 l = manage (left_aligned_label (_("When Beginning a Trim:")));
565 l->set_name ("OptionEditorHeading");
566 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
572 set_popdown_strings (_trim_contents_combo, dumb);
573 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
574 Gtkmm2ext::UI::instance()->set_tip (_trim_contents_combo,
575 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
576 for (int x = 0; modifiers[x].name; ++x) {
577 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
578 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
583 l = manage (left_aligned_label (_("Trim contents using:")));
584 l->set_name ("OptionsLabel");
586 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
587 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
593 set_popdown_strings (_trim_anchored_combo, dumb);
594 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
595 Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo,
596 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
597 for (int x = 0; modifiers[x].name; ++x) {
598 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
599 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
604 l = manage (left_aligned_label (_("Anchored trim using:")));
605 l->set_name ("OptionsLabel");
607 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
609 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
614 /* jump trim disabled for now
615 set_popdown_strings (_trim_jump_combo, dumb);
616 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
618 for (int x = 0; modifiers[x].name; ++x) {
619 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
620 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
625 l = manage (left_aligned_label (_("Jump after trim using:")));
626 l->set_name ("OptionsLabel");
628 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
630 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
636 /* note resize relative */
637 set_popdown_strings (_note_size_relative_combo, dumb);
638 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
639 Gtkmm2ext::UI::instance()->set_tip (_note_size_relative_combo,
640 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
641 for (int x = 0; modifiers[x].name; ++x) {
642 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
643 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
648 l = manage (left_aligned_label (_("Resize notes relatively using:")));
649 l->set_name ("OptionsLabel");
651 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
653 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
657 l = manage (left_aligned_label (_("While Dragging:")));
658 l->set_name ("OptionEditorHeading");
659 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
665 set_popdown_strings (_snap_modifier_combo, dumb);
666 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
668 Glib::ustring mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ());
670 Glib::ustring mod_str = Keyboard::secondary_modifier_name();
672 Gtkmm2ext::UI::instance()->set_tip (_snap_modifier_combo,
673 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
674 for (int x = 0; modifiers[x].name; ++x) {
675 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
676 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
681 l = manage (left_aligned_label (_("Ignore snap using:")));
682 l->set_name ("OptionsLabel");
684 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
685 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
691 set_popdown_strings (_snap_delta_combo, dumb);
692 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
694 mod_str = Keyboard::level4_modifier_name ();
696 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::level4_modifier_name ());
698 Gtkmm2ext::UI::instance()->set_tip (_snap_delta_combo,
699 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
700 for (int x = 0; modifiers[x].name; ++x) {
701 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
702 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
707 l = manage (left_aligned_label (_("Snap relatively using:")));
708 l->set_name ("OptionsLabel");
710 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
711 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
715 l = manage (left_aligned_label (_("While Trimming:")));
716 l->set_name ("OptionEditorHeading");
717 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
723 set_popdown_strings (_trim_overlap_combo, dumb);
724 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
726 Gtkmm2ext::UI::instance()->set_tip (_trim_overlap_combo,
727 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
728 for (int x = 0; modifiers[x].name; ++x) {
729 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
730 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
735 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
736 l->set_name ("OptionsLabel");
738 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
739 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
743 l = manage (left_aligned_label (_("While Dragging Control Points:")));
744 l->set_name ("OptionEditorHeading");
745 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
751 set_popdown_strings (_fine_adjust_combo, dumb);
752 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
754 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::tertiary_modifier_name ());
755 Gtkmm2ext::UI::instance()->set_tip (_fine_adjust_combo,
756 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
757 for (int x = 0; modifiers[x].name; ++x) {
758 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
759 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
764 l = manage (left_aligned_label (_("Fine adjust using:")));
765 l->set_name ("OptionsLabel");
767 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
768 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
774 set_popdown_strings (_push_points_combo, dumb);
775 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
777 Gtkmm2ext::UI::instance()->set_tip (_push_points_combo,
778 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
779 for (int x = 0; modifiers[x].name; ++x) {
780 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
781 _push_points_combo.set_active_text (S_(modifiers[x].name));
786 l = manage (left_aligned_label (_("Push points using:")));
787 l->set_name ("OptionsLabel");
789 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
790 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
792 _box->pack_start (*t, false, false);
795 void parameter_changed (string const &)
797 /* XXX: these aren't really config options... */
800 void set_state_from_config ()
802 /* XXX: these aren't really config options... */
807 void bindings_changed ()
809 string const txt = _keyboard_layout_selector.get_active_text();
811 /* XXX: config...? for all this keyboard stuff */
813 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
814 if (txt == i->first) {
815 if (Keyboard::load_keybindings (i->second)) {
816 Keyboard::save_keybindings ();
822 void edit_modifier_chosen ()
824 string const txt = _edit_modifier_combo.get_active_text();
826 for (int i = 0; modifiers[i].name; ++i) {
827 if (txt == _(modifiers[i].name)) {
828 Keyboard::set_edit_modifier (modifiers[i].modifier);
834 void delete_modifier_chosen ()
836 string const txt = _delete_modifier_combo.get_active_text();
838 for (int i = 0; modifiers[i].name; ++i) {
839 if (txt == _(modifiers[i].name)) {
840 Keyboard::set_delete_modifier (modifiers[i].modifier);
846 void copy_modifier_chosen ()
848 string const txt = _copy_modifier_combo.get_active_text();
850 for (int i = 0; modifiers[i].name; ++i) {
851 if (txt == _(modifiers[i].name)) {
852 Keyboard::set_copy_modifier (modifiers[i].modifier);
858 void insert_note_modifier_chosen ()
860 string const txt = _insert_note_modifier_combo.get_active_text();
862 for (int i = 0; modifiers[i].name; ++i) {
863 if (txt == _(modifiers[i].name)) {
864 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
870 void snap_modifier_chosen ()
872 string const txt = _snap_modifier_combo.get_active_text();
874 for (int i = 0; modifiers[i].name; ++i) {
875 if (txt == _(modifiers[i].name)) {
876 Keyboard::set_snap_modifier (modifiers[i].modifier);
882 void snap_delta_modifier_chosen ()
884 string const txt = _snap_delta_combo.get_active_text();
886 for (int i = 0; modifiers[i].name; ++i) {
887 if (txt == _(modifiers[i].name)) {
888 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
894 void constraint_modifier_chosen ()
896 string const txt = _constraint_modifier_combo.get_active_text();
898 for (int i = 0; modifiers[i].name; ++i) {
899 if (txt == _(modifiers[i].name)) {
900 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
906 void trim_contents_modifier_chosen ()
908 string const txt = _trim_contents_combo.get_active_text();
910 for (int i = 0; modifiers[i].name; ++i) {
911 if (txt == _(modifiers[i].name)) {
912 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
918 void trim_overlap_modifier_chosen ()
920 string const txt = _trim_overlap_combo.get_active_text();
922 for (int i = 0; modifiers[i].name; ++i) {
923 if (txt == _(modifiers[i].name)) {
924 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
930 void trim_anchored_modifier_chosen ()
932 string const txt = _trim_anchored_combo.get_active_text();
934 for (int i = 0; modifiers[i].name; ++i) {
935 if (txt == _(modifiers[i].name)) {
936 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
942 void fine_adjust_modifier_chosen ()
944 string const txt = _fine_adjust_combo.get_active_text();
946 for (int i = 0; modifiers[i].name; ++i) {
947 if (txt == _(modifiers[i].name)) {
948 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
954 void push_points_modifier_chosen ()
956 string const txt = _push_points_combo.get_active_text();
958 for (int i = 0; modifiers[i].name; ++i) {
959 if (txt == _(modifiers[i].name)) {
960 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
966 void note_size_relative_modifier_chosen ()
968 string const txt = _note_size_relative_combo.get_active_text();
970 for (int i = 0; modifiers[i].name; ++i) {
971 if (txt == _(modifiers[i].name)) {
972 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
978 void delete_button_changed ()
980 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
983 void edit_button_changed ()
985 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
988 void insert_note_button_changed ()
990 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
993 ComboBoxText _keyboard_layout_selector;
994 ComboBoxText _edit_modifier_combo;
995 ComboBoxText _delete_modifier_combo;
996 ComboBoxText _copy_modifier_combo;
997 ComboBoxText _insert_note_modifier_combo;
998 ComboBoxText _snap_modifier_combo;
999 ComboBoxText _snap_delta_combo;
1000 ComboBoxText _constraint_modifier_combo;
1001 ComboBoxText _trim_contents_combo;
1002 ComboBoxText _trim_overlap_combo;
1003 ComboBoxText _trim_anchored_combo;
1004 ComboBoxText _trim_jump_combo;
1005 ComboBoxText _fine_adjust_combo;
1006 ComboBoxText _push_points_combo;
1007 ComboBoxText _note_size_relative_combo;
1008 Adjustment _delete_button_adjustment;
1009 SpinButton _delete_button_spin;
1010 Adjustment _edit_button_adjustment;
1011 SpinButton _edit_button_spin;
1012 Adjustment _insert_note_button_adjustment;
1013 SpinButton _insert_note_button_spin;
1017 class FontScalingOptions : public OptionEditorBox
1020 FontScalingOptions () :
1021 _dpi_adjustment (100, 50, 250, 1, 5),
1022 _dpi_slider (_dpi_adjustment)
1024 _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.);
1026 Label* l = manage (new Label (_("GUI and Font scaling:")));
1027 l->set_name ("OptionsLabel");
1029 const Glib::ustring dflt = _("Default");
1030 const Glib::ustring empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
1032 _dpi_slider.set_name("FontScaleSlider");
1033 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1034 _dpi_slider.set_draw_value(false);
1035 _dpi_slider.add_mark(50, Gtk::POS_TOP, empty);
1036 _dpi_slider.add_mark(60, Gtk::POS_TOP, empty);
1037 _dpi_slider.add_mark(70, Gtk::POS_TOP, empty);
1038 _dpi_slider.add_mark(80, Gtk::POS_TOP, empty);
1039 _dpi_slider.add_mark(90, Gtk::POS_TOP, empty);
1040 _dpi_slider.add_mark(100, Gtk::POS_TOP, dflt);
1041 _dpi_slider.add_mark(125, Gtk::POS_TOP, empty);
1042 _dpi_slider.add_mark(150, Gtk::POS_TOP, empty);
1043 _dpi_slider.add_mark(175, Gtk::POS_TOP, empty);
1044 _dpi_slider.add_mark(200, Gtk::POS_TOP, empty);
1045 _dpi_slider.add_mark(225, Gtk::POS_TOP, empty);
1046 _dpi_slider.add_mark(250, Gtk::POS_TOP, empty);
1048 HBox* h = manage (new HBox);
1050 h->pack_start (*l, false, false);
1051 h->pack_start (_dpi_slider, true, true);
1053 _box->pack_start (*h, false, false);
1055 set_note (_("Adjusting the scale require an application restart to re-layout."));
1057 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
1060 void parameter_changed (string const & p)
1062 if (p == "font-scale") {
1063 _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.);
1067 void set_state_from_config ()
1069 parameter_changed ("font-scale");
1076 UIConfiguration::instance().set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024.));
1077 /* XXX: should be triggered from the parameter changed signal */
1078 UIConfiguration::instance().reset_dpi ();
1081 Adjustment _dpi_adjustment;
1085 class ClipLevelOptions : public OptionEditorBox
1089 : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1090 , _clip_level_slider (_clip_level_adjustment)
1092 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ());
1094 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
1095 l->set_name ("OptionsLabel");
1097 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1098 HBox* h = manage (new HBox);
1100 h->pack_start (*l, false, false);
1101 h->pack_start (_clip_level_slider, true, true);
1103 _box->pack_start (*h, false, false);
1105 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1108 void parameter_changed (string const & p)
1110 if (p == "waveform-clip-level") {
1111 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level());
1115 void set_state_from_config ()
1117 parameter_changed ("waveform-clip-level");
1122 void clip_level_changed ()
1124 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1125 /* XXX: should be triggered from the parameter changed signal */
1126 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1129 Adjustment _clip_level_adjustment;
1130 HScale _clip_level_slider;
1133 class BufferingOptions : public OptionEditorBox
1136 BufferingOptions (RCConfiguration* c)
1138 , _playback_adjustment (5, 1, 60, 1, 4)
1139 , _capture_adjustment (5, 1, 60, 1, 4)
1140 , _playback_slider (_playback_adjustment)
1141 , _capture_slider (_capture_adjustment)
1143 vector<string> presets;
1145 /* these must match the order of the enums for BufferingPreset */
1147 presets.push_back (_("Small sessions (4-16 tracks)"));
1148 presets.push_back (_("Medium sessions (16-64 tracks)"));
1149 presets.push_back (_("Large sessions (64+ tracks)"));
1150 presets.push_back (_("Custom (set by sliders below)"));
1152 set_popdown_strings (_buffering_presets_combo, presets);
1154 Label* l = manage (new Label (_("Preset:")));
1155 l->set_name ("OptionsLabel");
1156 HBox* h = manage (new HBox);
1157 h->set_spacing (12);
1158 h->pack_start (*l, false, false);
1159 h->pack_start (_buffering_presets_combo, true, true);
1160 _box->pack_start (*h, false, false);
1162 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1164 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1166 l = manage (new Label (_("Playback (seconds of buffering):")));
1167 l->set_name ("OptionsLabel");
1169 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1170 h = manage (new HBox);
1172 h->pack_start (*l, false, false);
1173 h->pack_start (_playback_slider, true, true);
1175 _box->pack_start (*h, false, false);
1177 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1179 l = manage (new Label (_("Recording (seconds of buffering):")));
1180 l->set_name ("OptionsLabel");
1182 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1183 h = manage (new HBox);
1185 h->pack_start (*l, false, false);
1186 h->pack_start (_capture_slider, true, true);
1188 _box->pack_start (*h, false, false);
1190 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
1191 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
1194 void parameter_changed (string const & p)
1196 if (p == "buffering-preset") {
1197 switch (_rc_config->get_buffering_preset()) {
1199 _playback_slider.set_sensitive (false);
1200 _capture_slider.set_sensitive (false);
1201 _buffering_presets_combo.set_active (0);
1204 _playback_slider.set_sensitive (false);
1205 _capture_slider.set_sensitive (false);
1206 _buffering_presets_combo.set_active (1);
1209 _playback_slider.set_sensitive (false);
1210 _capture_slider.set_sensitive (false);
1211 _buffering_presets_combo.set_active (2);
1214 _playback_slider.set_sensitive (true);
1215 _capture_slider.set_sensitive (true);
1216 _buffering_presets_combo.set_active (3);
1221 if (p == "playback-buffer-seconds") {
1222 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1223 } else if (p == "capture-buffer-seconds") {
1224 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1228 void set_state_from_config ()
1230 parameter_changed ("buffering-preset");
1231 parameter_changed ("playback-buffer-seconds");
1232 parameter_changed ("capture-buffer-seconds");
1237 void preset_changed ()
1239 int index = _buffering_presets_combo.get_active_row_number ();
1245 _rc_config->set_buffering_preset (Small);
1248 _rc_config->set_buffering_preset (Medium);
1251 _rc_config->set_buffering_preset (Large);
1254 _rc_config->set_buffering_preset (Custom);
1257 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1262 void playback_changed ()
1264 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
1267 void capture_changed ()
1269 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
1272 RCConfiguration* _rc_config;
1273 Adjustment _playback_adjustment;
1274 Adjustment _capture_adjustment;
1275 HScale _playback_slider;
1276 HScale _capture_slider;
1277 ComboBoxText _buffering_presets_combo;
1280 class ControlSurfacesOptions : public OptionEditorBox
1283 ControlSurfacesOptions (Gtk::Window& parent)
1285 , _ignore_view_change (0)
1287 _store = ListStore::create (_model);
1288 _view.set_model (_store);
1289 _view.append_column (_("Control Surface Protocol"), _model.name);
1290 _view.get_column(0)->set_resizable (true);
1291 _view.get_column(0)->set_expand (true);
1292 _view.append_column_editable (_("Enabled"), _model.enabled);
1293 _view.append_column_editable (_("Feedback"), _model.feedback);
1295 _box->pack_start (_view, false, false);
1297 Label* label = manage (new Label);
1298 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
1300 _box->pack_start (*label, false, false);
1303 ControlProtocolManager& m = ControlProtocolManager::instance ();
1304 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1305 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1307 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1308 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1311 void parameter_changed (std::string const &)
1316 void set_state_from_config ()
1320 ControlProtocolManager& m = ControlProtocolManager::instance ();
1321 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1323 if (!(*i)->mandatory) {
1324 TreeModel::Row r = *_store->append ();
1325 r[_model.name] = (*i)->name;
1326 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1327 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
1328 r[_model.protocol_info] = *i;
1335 void protocol_status_changed (ControlProtocolInfo* cpi) {
1337 TreeModel::Children rows = _store->children();
1339 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1340 string n = ((*x)[_model.name]);
1342 if ((*x)[_model.protocol_info] == cpi) {
1343 _ignore_view_change++;
1344 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1345 _ignore_view_change--;
1351 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1353 TreeModel::Row r = *i;
1355 if (_ignore_view_change) {
1359 ControlProtocolInfo* cpi = r[_model.protocol_info];
1364 bool const was_enabled = (cpi->protocol != 0);
1365 bool const is_enabled = r[_model.enabled];
1368 if (was_enabled != is_enabled) {
1371 ControlProtocolManager::instance().activate (*cpi);
1373 ControlProtocolManager::instance().deactivate (*cpi);
1377 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
1378 bool const is_feedback = r[_model.feedback];
1380 if (was_feedback != is_feedback && cpi->protocol) {
1381 cpi->protocol->set_feedback (is_feedback);
1385 void edit_clicked (GdkEventButton* ev)
1387 if (ev->type != GDK_2BUTTON_PRESS) {
1392 ControlProtocolInfo* cpi;
1395 row = *(_view.get_selection()->get_selected());
1396 if (!row[_model.enabled]) {
1399 cpi = row[_model.protocol_info];
1400 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1403 Box* box = (Box*) cpi->protocol->get_gui ();
1407 if (box->get_parent()) {
1408 static_cast<ArdourWindow*>(box->get_parent())->present();
1411 string title = row[_model.name];
1412 /* once created, the window is managed by the surface itself (as ->get_parent())
1413 * Surface's tear_down_gui() is called on session close, when de-activating
1414 * or re-initializing a surface.
1415 * tear_down_gui() hides an deletes the Window if it exists.
1417 ArdourWindow* win = new ArdourWindow (_parent, title);
1418 win->set_title ("Control Protocol Options");
1424 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1428 ControlSurfacesModelColumns ()
1433 add (protocol_info);
1436 TreeModelColumn<string> name;
1437 TreeModelColumn<bool> enabled;
1438 TreeModelColumn<bool> feedback;
1439 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1442 Glib::RefPtr<ListStore> _store;
1443 ControlSurfacesModelColumns _model;
1445 Gtk::Window& _parent;
1446 PBD::ScopedConnection protocol_status_connection;
1447 uint32_t _ignore_view_change;
1450 class VideoTimelineOptions : public OptionEditorBox
1453 VideoTimelineOptions (RCConfiguration* c)
1455 , _show_video_export_info_button (_("Show Video Export Info before export"))
1456 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1457 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1459 Table* t = manage (new Table (2, 6));
1460 t->set_spacings (4);
1462 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
1463 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1464 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1465 _("<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."));
1467 Label* l = manage (new Label (_("Video Server URL:")));
1468 l->set_alignment (0, 0.5);
1469 t->attach (*l, 0, 1, 1, 2, FILL);
1470 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
1471 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1472 _("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"));
1474 l = manage (new Label (_("Video Folder:")));
1475 l->set_alignment (0, 0.5);
1476 t->attach (*l, 0, 1, 2, 3, FILL);
1477 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
1478 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1479 _("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."));
1481 /* small vspace y=3..4 */
1483 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
1484 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1485 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1486 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1488 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
1489 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1490 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1491 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1493 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1494 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1495 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1496 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1498 _box->pack_start (*t,true,true);
1501 void server_url_changed ()
1503 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1506 void server_docroot_changed ()
1508 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1511 void show_video_export_info_toggled ()
1513 bool const x = _show_video_export_info_button.get_active ();
1514 _rc_config->set_show_video_export_info (x);
1517 void show_video_server_dialog_toggled ()
1519 bool const x = _show_video_server_dialog_button.get_active ();
1520 _rc_config->set_show_video_server_dialog (x);
1523 void video_advanced_setup_toggled ()
1525 bool const x = _video_advanced_setup_button.get_active ();
1526 _rc_config->set_video_advanced_setup(x);
1529 void parameter_changed (string const & p)
1531 if (p == "video-server-url") {
1532 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1533 } else if (p == "video-server-docroot") {
1534 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1535 } else if (p == "show-video-export-info") {
1536 bool const x = _rc_config->get_show_video_export_info();
1537 _show_video_export_info_button.set_active (x);
1538 } else if (p == "show-video-server-dialog") {
1539 bool const x = _rc_config->get_show_video_server_dialog();
1540 _show_video_server_dialog_button.set_active (x);
1541 } else if (p == "video-advanced-setup") {
1542 bool const x = _rc_config->get_video_advanced_setup();
1543 _video_advanced_setup_button.set_active(x);
1544 _video_server_docroot_entry.set_sensitive(x);
1545 _video_server_url_entry.set_sensitive(x);
1549 void set_state_from_config ()
1551 parameter_changed ("video-server-url");
1552 parameter_changed ("video-server-docroot");
1553 parameter_changed ("video-monitor-setup-dialog");
1554 parameter_changed ("show-video-export-info");
1555 parameter_changed ("show-video-server-dialog");
1556 parameter_changed ("video-advanced-setup");
1560 RCConfiguration* _rc_config;
1561 Entry _video_server_url_entry;
1562 Entry _video_server_docroot_entry;
1563 CheckButton _show_video_export_info_button;
1564 CheckButton _show_video_server_dialog_button;
1565 CheckButton _video_advanced_setup_button;
1568 class PluginOptions : public OptionEditorBox
1571 PluginOptions (RCConfiguration* c)
1573 , _display_plugin_scan_progress (_("Always Display Plugin Scan Progress"))
1574 , _discover_vst_on_start (_("Scan for [new] VST Plugins on Application Start"))
1575 , _discover_au_on_start (_("Scan for AudioUnit Plugins on Application Start"))
1576 , _verbose_plugin_scan (_("Verbose Plugin Scan"))
1577 , _timeout_adjustment (0, 0, 3000, 50, 50)
1578 , _timeout_slider (_timeout_adjustment)
1581 std::stringstream ss;
1582 Table* t = manage (new Table (2, 6));
1583 t->set_spacings (4);
1587 ss << "<b>" << _("General") << "</b>";
1588 l = manage (left_aligned_label (ss.str()));
1589 l->set_use_markup (true);
1590 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1591 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1593 b = manage (new Button (_("Scan for Plugins")));
1594 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1595 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1597 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1598 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1599 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1600 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
1602 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
1603 _timeout_slider.set_digits (0);
1604 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &PluginOptions::timeout_changed));
1606 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1607 _("Specify the default timeout for plugin instantiation in 1/10 seconds. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1609 l = manage (left_aligned_label (_("Scan Time Out [deciseconds]")));;
1610 HBox* h = manage (new HBox);
1612 h->pack_start (*l, false, false);
1613 h->pack_start (_timeout_slider, true, true);
1614 t->attach (*h, 0, 2, n, n+1); ++n;
1617 ss << "<b>" << _("VST") << "</b>";
1618 l = manage (left_aligned_label (ss.str()));
1619 l->set_use_markup (true);
1620 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1621 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1623 b = manage (new Button (_("Clear VST Cache")));
1624 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1625 t->attach (*b, 0, 1, n, n+1, FILL);
1627 b = manage (new Button (_("Clear VST Blacklist")));
1628 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1629 t->attach (*b, 1, 2, n, n+1, FILL);
1632 t->attach (_discover_vst_on_start, 0, 2, n, n+1); ++n;
1633 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1634 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1635 _("<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"));
1637 #ifdef LXVST_SUPPORT
1638 t->attach (*manage (right_aligned_label (_("Linux VST Path:"))), 0, 1, n, n+1);
1639 b = manage (new Button (_("Edit")));
1640 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_lxvst_path_clicked));
1641 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1644 #ifdef WINDOWS_VST_SUPPORT
1645 t->attach (*manage (right_aligned_label (_("Windows VST Path:"))), 0, 1, n, n+1);
1646 b = manage (new Button (_("Edit")));
1647 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_vst_path_clicked));
1648 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1650 // currently verbose logging is only implemented for Windows VST.
1651 t->attach (_verbose_plugin_scan, 0, 2, n, n+1); ++n;
1652 _verbose_plugin_scan.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::verbose_plugin_scan_toggled));
1653 Gtkmm2ext::UI::instance()->set_tip (_verbose_plugin_scan,
1654 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
1658 #ifdef AUDIOUNIT_SUPPORT
1660 ss << "<b>" << _("Audio Unit") << "</b>";
1661 l = manage (left_aligned_label (ss.str()));
1662 l->set_use_markup (true);
1663 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1664 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1666 t->attach (_discover_au_on_start, 0, 2, n, n+1); ++n;
1667 _discover_au_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_au_on_start_toggled));
1668 Gtkmm2ext::UI::instance()->set_tip (_discover_au_on_start,
1669 _("<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."));
1672 b = manage (new Button (_("Clear AU Cache")));
1673 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_cache_clicked));
1674 t->attach (*b, 0, 1, n, n+1, FILL);
1676 b = manage (new Button (_("Clear AU Blacklist")));
1677 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_blacklist_clicked));
1678 t->attach (*b, 1, 2, n, n+1, FILL);
1682 _box->pack_start (*t,true,true);
1685 void parameter_changed (string const & p) {
1686 if (p == "show-plugin-scan-window") {
1687 bool const x = UIConfiguration::instance().get_show_plugin_scan_window();
1688 _display_plugin_scan_progress.set_active (x);
1690 else if (p == "discover-vst-on-start") {
1691 bool const x = _rc_config->get_discover_vst_on_start();
1692 _discover_vst_on_start.set_active (x);
1694 else if (p == "vst-scan-timeout") {
1695 int const x = _rc_config->get_vst_scan_timeout();
1696 _timeout_adjustment.set_value (x);
1698 else if (p == "discover-audio-units") {
1699 bool const x = _rc_config->get_discover_audio_units();
1700 _discover_au_on_start.set_active (x);
1702 else if (p == "verbose-plugin-scan") {
1703 bool const x = _rc_config->get_verbose_plugin_scan();
1704 _verbose_plugin_scan.set_active (x);
1708 void set_state_from_config () {
1709 parameter_changed ("show-plugin-scan-window");
1710 parameter_changed ("discover-vst-on-start");
1711 parameter_changed ("vst-scan-timeout");
1712 parameter_changed ("discover-audio-units");
1713 parameter_changed ("verbose-plugin-scan");
1717 RCConfiguration* _rc_config;
1718 CheckButton _display_plugin_scan_progress;
1719 CheckButton _discover_vst_on_start;
1720 CheckButton _discover_au_on_start;
1721 CheckButton _verbose_plugin_scan;
1722 Adjustment _timeout_adjustment;
1723 HScale _timeout_slider;
1725 void display_plugin_scan_progress_toggled () {
1726 bool const x = _display_plugin_scan_progress.get_active();
1727 UIConfiguration::instance().set_show_plugin_scan_window(x);
1730 void discover_vst_on_start_toggled () {
1731 bool const x = _discover_vst_on_start.get_active();
1732 _rc_config->set_discover_vst_on_start(x);
1735 void discover_au_on_start_toggled () {
1736 bool const x = _discover_au_on_start.get_active();
1737 _rc_config->set_discover_audio_units(x);
1740 void verbose_plugin_scan_toggled () {
1741 bool const x = _verbose_plugin_scan.get_active();
1742 _rc_config->set_verbose_plugin_scan(x);
1745 void timeout_changed () {
1746 int x = floor(_timeout_adjustment.get_value());
1747 _rc_config->set_vst_scan_timeout(x);
1750 void clear_vst_cache_clicked () {
1751 PluginManager::instance().clear_vst_cache();
1754 void clear_vst_blacklist_clicked () {
1755 PluginManager::instance().clear_vst_blacklist();
1758 void clear_au_cache_clicked () {
1759 PluginManager::instance().clear_au_cache();
1762 void clear_au_blacklist_clicked () {
1763 PluginManager::instance().clear_au_blacklist();
1767 void edit_vst_path_clicked () {
1768 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1769 _("Set Windows VST Search Path"),
1770 _rc_config->get_plugin_path_vst(),
1771 PluginManager::instance().get_default_windows_vst_path()
1773 ResponseType r = (ResponseType) pd->run ();
1775 if (r == RESPONSE_ACCEPT) {
1776 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
1781 // todo consolidate with edit_vst_path_clicked..
1782 void edit_lxvst_path_clicked () {
1783 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1784 _("Set Linux VST Search Path"),
1785 _rc_config->get_plugin_path_lxvst(),
1786 PluginManager::instance().get_default_lxvst_path()
1788 ResponseType r = (ResponseType) pd->run ();
1790 if (r == RESPONSE_ACCEPT) {
1791 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
1796 void refresh_clicked () {
1797 PluginManager::instance().refresh();
1802 /** A class which allows control of visibility of some editor components usign
1803 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1804 * which has the correct members, but with null widget pointers. This
1805 * class allows the user to set visibility of the members, the details
1806 * of which are stored in a configuration variable which can be watched
1807 * by parts of the editor that actually contain the widgets whose visibility
1808 * is being controlled.
1811 class VisibilityOption : public Option
1814 /** @param name User-visible name for this group.
1815 * @param g `Dummy' VisibilityGroup (as described above).
1816 * @param get Method to get the value of the appropriate configuration variable.
1817 * @param set Method to set the value of the appropriate configuration variable.
1819 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1820 : Option (g->get_state_name(), name)
1822 , _visibility_group (g)
1826 /* Watch for changes made by the user to our members */
1827 _visibility_group->VisibilityChanged.connect_same_thread (
1828 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1832 void set_state_from_config ()
1834 /* Set our state from the current configuration */
1835 _visibility_group->set_state (_get ());
1838 void add_to_page (OptionEditorPage* p)
1840 _heading.add_to_page (p);
1841 add_widget_to_page (p, _visibility_group->list_view ());
1844 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1849 /* The user has changed something, so reflect this change
1850 in the RCConfiguration.
1852 _set (_visibility_group->get_state_value ());
1855 OptionEditorHeading _heading;
1856 VisibilityGroup* _visibility_group;
1857 sigc::slot<std::string> _get;
1858 sigc::slot<bool, std::string> _set;
1859 PBD::ScopedConnection _visibility_group_connection;
1864 RCOptionEditor::RCOptionEditor ()
1865 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1866 , _rc_config (Config)
1867 , _mixer_strip_visibility ("mixer-element-visibility")
1871 uint32_t hwcpus = hardware_concurrency ();
1873 BoolComboOption* bco;
1876 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1878 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1880 _("Signal processing uses"),
1881 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1882 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1885 procs->add (-1, _("all but one processor"));
1886 procs->add (0, _("all available processors"));
1888 for (uint32_t i = 1; i <= hwcpus; ++i) {
1889 procs->add (i, string_compose (_("%1 processors"), i));
1892 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1894 add_option (_("Misc"), procs);
1897 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1899 add_option (_("Misc"), new UndoOptions (_rc_config));
1901 add_option (_("Misc"),
1903 "verify-remove-last-capture",
1904 _("Verify removal of last capture"),
1905 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1906 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1909 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1911 add_option (_("Misc"),
1913 "periodic-safety-backups",
1914 _("Make periodic backups of the session file"),
1915 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1916 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1919 add_option (_("Misc"),
1921 "only-copy-imported-files",
1922 _("Always copy imported files"),
1923 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
1924 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
1927 add_option (_("Misc"), new DirectoryOption (
1928 X_("default-session-parent-dir"),
1929 _("Default folder for new sessions:"),
1930 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1931 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1934 add_option (_("Misc"),
1935 new SpinOption<uint32_t> (
1936 "max-recent-sessions",
1937 _("Maximum number of recent sessions"),
1938 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1939 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1943 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1945 add_option (_("Misc"), new ClickOptions (_rc_config, this));
1947 add_option (_("Misc"),
1950 _("Click gain level"),
1951 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1952 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1955 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1957 add_option (_("Misc"),
1958 new SpinOption<double> (
1959 "automation-thinning-factor",
1960 _("Thinning factor (larger value => less data)"),
1961 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1962 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1966 add_option (_("Misc"),
1967 new SpinOption<double> (
1968 "automation-interval-msecs",
1969 _("Automation sampling interval (milliseconds)"),
1970 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1971 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1977 add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options")));
1981 tsf = new BoolOption (
1982 "latched-record-enable",
1983 _("Keep record-enable engaged on stop"),
1984 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1985 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1987 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1988 add_option (_("Transport"), tsf);
1990 tsf = new BoolOption (
1992 _("Play loop is a transport mode"),
1993 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1994 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1996 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1997 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1998 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1999 add_option (_("Transport"), tsf);
2001 tsf = new BoolOption (
2002 "stop-recording-on-xrun",
2003 _("Stop recording when an xrun occurs"),
2004 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
2005 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
2007 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2008 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
2010 add_option (_("Transport"), tsf);
2012 tsf = new BoolOption (
2013 "create-xrun-marker",
2014 _("Create markers where xruns occur"),
2015 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
2016 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
2018 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
2019 add_option (_("Transport"), tsf);
2021 tsf = new BoolOption (
2022 "stop-at-session-end",
2023 _("Stop at the end of the session"),
2024 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
2025 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
2027 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2028 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
2029 "when it reaches the current session end marker\n\n"
2030 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
2032 add_option (_("Transport"), tsf);
2034 tsf = new BoolOption (
2036 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
2037 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
2038 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
2040 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2041 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
2042 "preventing any need to do a transport locate at the end of the loop\n\n"
2043 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
2044 "which will often cause a small click or delay"), PROGRAM_NAME));
2045 add_option (_("Transport"), tsf);
2047 tsf = new BoolOption (
2048 "disable-disarm-during-roll",
2049 _("Disable per-track record disarm while rolling"),
2050 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
2051 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
2053 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("<b>When enabled</b> this will prevent you from accidentally stopping specific tracks recording during a take"));
2054 add_option (_("Transport"), tsf);
2056 tsf = new BoolOption (
2058 _("12dB gain reduction during fast-forward and fast-rewind"),
2059 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
2060 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2062 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
2063 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2064 add_option (_("Transport"), tsf);
2066 ComboOption<float>* psc = new ComboOption<float> (
2069 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
2070 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
2072 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
2073 (_("The amount of preroll (in seconds) to apply when <b>Play with Preroll</b> is initiated.\n\n"
2074 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
2075 psc->add (0.0, _("0 (no pre-roll)"));
2076 psc->add (0.1, _("0.1 second"));
2077 psc->add (0.25, _("0.25 second"));
2078 psc->add (0.5, _("0.5 second"));
2079 psc->add (1.0, _("1.0 second"));
2080 psc->add (2.0, _("2.0 seconds"));
2081 add_option (_("Transport"), psc);
2083 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
2085 _sync_source = new ComboOption<SyncSource> (
2087 _("External timecode source"),
2088 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
2089 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
2092 add_option (_("Transport"), _sync_source);
2094 _sync_framerate = new BoolOption (
2095 "timecode-sync-frame-rate",
2096 _("Match session video frame rate to external timecode"),
2097 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
2098 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
2100 Gtkmm2ext::UI::instance()->set_tip
2101 (_sync_framerate->tip_widget(),
2102 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
2103 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
2104 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
2105 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
2106 "timecode standard and the session standard."), PROGRAM_NAME));
2108 add_option (_("Transport"), _sync_framerate);
2110 _sync_genlock = new BoolOption (
2111 "timecode-source-is-synced",
2112 _("Sync-lock timecode to clock (disable drift compensation)"),
2113 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
2114 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
2116 Gtkmm2ext::UI::instance()->set_tip
2117 (_sync_genlock->tip_widget(),
2118 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
2119 "Sync Lock indicates that the selected external timecode source shares clock-sync "
2120 "(Black & Burst, Wordclock, etc) with the audio interface. "
2121 "This option disables drift compensation. The transport speed is fixed at 1.0. "
2122 "Vari-speed LTC will be ignored and cause drift."
2124 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
2125 "timecode sources shares clock sync."
2129 add_option (_("Transport"), _sync_genlock);
2131 _sync_source_2997 = new BoolOption (
2132 "timecode-source-2997",
2133 _("Lock to 29.9700 fps instead of 30000/1001"),
2134 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
2135 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
2137 Gtkmm2ext::UI::instance()->set_tip
2138 (_sync_source_2997->tip_widget(),
2139 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
2140 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
2141 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
2142 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
2143 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
2144 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
2147 add_option (_("Transport"), _sync_source_2997);
2149 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
2151 _ltc_port = new ComboStringOption (
2153 _("LTC incoming port"),
2154 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
2155 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
2158 vector<string> physical_inputs;
2159 physical_inputs.push_back (_("None"));
2160 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
2161 _ltc_port->set_popdown_strings (physical_inputs);
2163 populate_sync_options ();
2165 add_option (_("Transport"), _ltc_port);
2167 // TODO; rather disable this button than not compile it..
2168 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
2170 add_option (_("Transport"),
2173 _("Enable LTC generator"),
2174 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
2175 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
2178 _ltc_send_continuously = new BoolOption (
2179 "ltc-send-continuously",
2180 _("Send LTC while stopped"),
2181 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
2182 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
2184 Gtkmm2ext::UI::instance()->set_tip
2185 (_ltc_send_continuously->tip_widget(),
2186 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
2187 add_option (_("Transport"), _ltc_send_continuously);
2189 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
2190 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
2191 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
2192 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
2194 Gtkmm2ext::UI::instance()->set_tip
2195 (_ltc_volume_slider->tip_widget(),
2196 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
2198 add_option (_("Transport"), _ltc_volume_slider);
2202 add_option (_("Editor"),
2204 "rubberbanding-snaps-to-grid",
2205 _("Make rubberband selection rectangle snap to the grid"),
2206 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2207 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2210 bo = new BoolOption (
2212 _("Name new markers"),
2213 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2214 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2216 add_option (_("Editor"), bo);
2217 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."
2218 "\n\nYou can always rename markers by right-clicking on them"));
2220 add_option (S_("Editor"),
2222 "draggable-playhead",
2223 _("Allow dragging of playhead"),
2224 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2225 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2228 add_option (_("Editor"),
2230 "show-track-meters",
2231 _("Show meters on tracks in the editor"),
2232 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
2233 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
2236 add_option (_("Editor"),
2238 "show-editor-meter",
2239 _("Display master-meter in the toolbar"),
2240 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
2241 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
2244 if (!Profile->get_mixbus()) {
2245 add_option (_("Editor"),
2248 _("Show zoom toolbar (if torn off)"),
2249 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_zoom_tools),
2250 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_zoom_tools)
2254 add_option (_("Editor"),
2256 "update-editor-during-summary-drag",
2257 _("Update editor window during drags of the summary"),
2258 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2259 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2262 add_option (_("Editor"),
2264 "autoscroll-editor",
2265 _("Auto-scroll editor window when dragging near its edges"),
2266 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2267 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2270 add_option (_("Editor"),
2271 new BoolComboOption (
2272 "show-region-gain-envelopes",
2273 _("Show gain envelopes in audio regions"),
2275 _("only in Draw and Internal Edit modes"),
2276 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2277 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2280 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2282 add_option (_("Editor"),
2284 "automation-follows-regions",
2285 _("Move relevant automation when audio regions are moved"),
2286 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2287 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2290 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2291 "default-fade-shape",
2292 _("Default fade shape"),
2293 sigc::mem_fun (*_rc_config,
2294 &RCConfiguration::get_default_fade_shape),
2295 sigc::mem_fun (*_rc_config,
2296 &RCConfiguration::set_default_fade_shape)
2299 fadeshape->add (FadeLinear,
2300 _("Linear (for highly correlated material)"));
2301 fadeshape->add (FadeConstantPower, _("Constant power"));
2302 fadeshape->add (FadeSymmetric, _("Symmetric"));
2303 fadeshape->add (FadeSlow, _("Slow"));
2304 fadeshape->add (FadeFast, _("Fast"));
2306 add_option (_("Editor"), fadeshape);
2309 bco = new BoolComboOption (
2310 "use-overlap-equivalency",
2311 _("Regions in active edit groups are edited together"),
2312 _("whenever they overlap in time"),
2313 _("only if they have identical length, position and origin"),
2314 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2315 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2318 add_option (_("Editor"), bco);
2320 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2322 _("Layering model"),
2323 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2324 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2327 lm->add (LaterHigher, _("later is higher"));
2328 lm->add (Manual, _("manual layering"));
2329 add_option (_("Editor"), lm);
2331 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2332 "region-selection-after-split",
2333 _("After splitting selected regions, select"),
2334 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2335 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2337 // TODO: decide which of these modes are really useful
2338 rsas->add(None, _("no regions"));
2339 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2340 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2341 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2342 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2343 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2344 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2345 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2347 add_option (_("Editor"), rsas);
2349 add_option (_("Editor"), new OptionEditorHeading (_("Waveforms")));
2351 if (!Profile->get_mixbus()) {
2352 add_option (_("Editor"),
2355 _("Show waveforms in regions"),
2356 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
2357 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
2361 add_option (_("Editor"),
2363 "show-waveforms-while-recording",
2364 _("Show waveforms for audio while it is being recorded"),
2365 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
2366 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
2369 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
2371 _("Waveform scale"),
2372 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
2373 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
2376 wfs->add (Linear, _("linear"));
2377 wfs->add (Logarithmic, _("logarithmic"));
2379 add_option (_("Editor"), wfs);
2381 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
2383 _("Waveform shape"),
2384 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
2385 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
2388 wfsh->add (Traditional, _("traditional"));
2389 wfsh->add (Rectified, _("rectified"));
2391 add_option (_("Editor"), wfsh);
2393 add_option (_("Editor"), new ClipLevelOptions ());
2398 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2400 add_option (_("Audio"), new BufferingOptions (_rc_config));
2402 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2404 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2406 _("Record monitoring handled by"),
2407 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2408 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2411 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2412 mm->add (HardwareMonitoring, _("via Audio Driver"));
2415 string prog (PROGRAM_NAME);
2416 boost::algorithm::to_lower (prog);
2417 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2418 mm->add (ExternalMonitoring, _("audio hardware"));
2420 add_option (_("Audio"), mm);
2422 add_option (_("Audio"),
2424 "tape-machine-mode",
2425 _("Tape machine mode"),
2426 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2427 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2430 if (!Profile->get_mixbus()) {
2431 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2433 add_option (_("Audio"),
2435 "auto-connect-standard-busses",
2436 _("Auto-connect master/monitor busses"),
2437 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2438 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2441 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2442 "input-auto-connect",
2443 _("Connect track inputs"),
2444 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2445 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2448 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2449 iac->add (ManualConnect, _("manually"));
2451 add_option (_("Audio"), iac);
2453 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2454 "output-auto-connect",
2455 _("Connect track and bus outputs"),
2456 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2457 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2460 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2461 oac->add (AutoConnectMaster, _("automatically to master bus"));
2462 oac->add (ManualConnect, _("manually"));
2464 add_option (_("Audio"), oac);
2467 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2469 add_option (_("Audio"),
2471 "denormal-protection",
2472 _("Use DC bias to protect against denormals"),
2473 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2474 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2477 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2479 _("Processor handling"),
2480 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2481 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2485 dm->add (DenormalNone, _("no processor handling"));
2487 FPU* fpu = FPU::instance();
2489 if (fpu->has_flush_to_zero()) {
2491 dm->add (DenormalFTZ, _("use FlushToZero"));
2492 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2493 _rc_config->set_denormal_model(DenormalNone);
2496 if (fpu->has_denormals_are_zero()) {
2498 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2499 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2500 _rc_config->set_denormal_model(DenormalNone);
2503 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2505 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2506 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2507 _rc_config->set_denormal_model(DenormalNone);
2511 dm->set_sensitive(false);
2514 add_option (_("Audio"), dm);
2516 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
2518 add_option (_("Audio"),
2520 "plugins-stop-with-transport",
2521 _("Silence plugins when the transport is stopped"),
2522 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
2523 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
2526 add_option (_("Audio"),
2528 "new-plugins-active",
2529 _("Make new plugins active"),
2530 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
2531 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
2534 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2536 add_option (_("Audio"),
2538 "auto-analyse-audio",
2539 _("Enable automatic analysis of audio"),
2540 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2541 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2544 add_option (_("Audio"),
2546 "replicate-missing-region-channels",
2547 _("Replicate missing region channels"),
2548 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2549 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2554 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
2556 _solo_control_is_listen_control = new BoolOption (
2557 "solo-control-is-listen-control",
2558 _("Solo controls are Listen controls"),
2559 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2560 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2563 add_option (_("Solo / mute"), _solo_control_is_listen_control);
2565 add_option (_("Solo / mute"),
2568 _("Exclusive solo"),
2569 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2570 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2573 add_option (_("Solo / mute"),
2576 _("Show solo muting"),
2577 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2578 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2581 add_option (_("Solo / mute"),
2583 "solo-mute-override",
2584 _("Soloing overrides muting"),
2585 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2586 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2589 add_option (_("Solo / mute"),
2592 _("Solo-in-place mute cut (dB)"),
2593 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2594 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2597 _listen_position = new ComboOption<ListenPosition> (
2599 _("Listen Position"),
2600 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2601 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2604 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2605 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2607 add_option (_("Solo / mute"), _listen_position);
2609 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2611 _("PFL signals come from"),
2612 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2613 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2616 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2617 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2619 add_option (_("Solo / mute"), pp);
2621 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2623 _("AFL signals come from"),
2624 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2625 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2628 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2629 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2631 add_option (_("Solo / mute"), pa);
2633 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2635 add_option (_("Solo / mute"),
2637 "mute-affects-pre-fader",
2638 _("Mute affects pre-fader sends"),
2639 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2640 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2643 add_option (_("Solo / mute"),
2645 "mute-affects-post-fader",
2646 _("Mute affects post-fader sends"),
2647 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2648 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2651 add_option (_("Solo / mute"),
2653 "mute-affects-control-outs",
2654 _("Mute affects control outputs"),
2655 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2656 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2659 add_option (_("Solo / mute"),
2661 "mute-affects-main-outs",
2662 _("Mute affects main outputs"),
2663 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2664 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2667 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
2669 add_option (_("Solo / mute"),
2671 "link-send-and-route-panner",
2672 _("Link panners of Aux and External Sends with main panner by default"),
2673 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2674 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2677 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Preferences")));
2679 add_option (_("MIDI"),
2680 new SpinOption<float> (
2682 _("MIDI read-ahead time (seconds)"),
2683 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2684 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2689 add_option (_("MIDI"),
2690 new SpinOption<int32_t> (
2691 "initial-program-change",
2692 _("Initial program change"),
2693 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2694 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2698 add_option (_("MIDI"),
2700 "display-first-midi-bank-as-zero",
2701 _("Display first MIDI bank/program as 0"),
2702 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2703 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2706 add_option (_("MIDI"),
2708 "never-display-periodic-midi",
2709 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2710 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
2711 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
2714 add_option (_("MIDI"),
2717 _("Sound MIDI notes as they are selected in the editor"),
2718 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2719 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2722 add_option (_("MIDI"),
2725 _("Send MIDI control feedback"),
2726 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2727 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2730 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Clock")));
2732 add_option (_("MIDI"),
2735 _("Send MIDI Clock"),
2736 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2737 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2740 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC)")));
2742 add_option (_("MIDI"),
2745 _("Send MIDI Time Code"),
2746 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2747 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2750 add_option (_("MIDI"),
2751 new SpinOption<int> (
2752 "mtc-qf-speed-tolerance",
2753 _("Percentage either side of normal transport speed to transmit MTC"),
2754 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2755 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2759 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Machine Control (MMC)")));
2761 add_option (_("MIDI"),
2764 _("Obey MIDI Machine Control commands"),
2765 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2766 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2769 add_option (_("MIDI"),
2772 _("Send MIDI Machine Control commands"),
2773 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2774 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2777 add_option (_("MIDI"),
2778 new SpinOption<uint8_t> (
2779 "mmc-receive-device-id",
2780 _("Inbound MMC device ID"),
2781 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2782 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2786 add_option (_("MIDI"),
2787 new SpinOption<uint8_t> (
2788 "mmc-send-device-id",
2789 _("Outbound MMC device ID"),
2790 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2791 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2795 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2797 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2798 "midi-audition-synth-uri",
2799 _("Midi Audition Synth (LV2)"),
2800 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2801 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2804 audition_synth->add(X_(""), _("None"));
2805 PluginInfoList all_plugs;
2806 PluginManager& manager (PluginManager::instance());
2808 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2810 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2811 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2812 if (!(*i)->is_instrument()) continue;
2813 if ((*i)->type != ARDOUR::LV2) continue;
2814 audition_synth->add((*i)->unique_id, (*i)->name);
2818 add_option (_("MIDI"), audition_synth);
2820 /* USER INTERACTION */
2823 #ifdef PLATFORM_WINDOWS
2826 getenv ("ARDOUR_BUNDLED")
2830 add_option (_("User interaction"),
2832 "enable-translation",
2833 string_compose (_("Use translations of %1 messages\n"
2834 " <i>(requires a restart of %1 to take effect)</i>\n"
2835 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2836 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2837 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2840 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2842 add_option (_("User interaction"), new KeyboardOptions);
2844 /* Control Surfaces */
2846 add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2848 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2850 _("Control surface remote ID"),
2851 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2852 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2855 rm->add (UserOrdered, _("assigned by user"));
2856 rm->add (MixerOrdered, _("follows order of mixer"));
2858 add_option (_("Control Surfaces"), rm);
2860 /* VIDEO Timeline */
2861 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2863 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2864 /* Plugin options (currrently VST only) */
2865 add_option (_("Plugins"), new PluginOptions (_rc_config));
2870 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
2871 BoolOption* bgc = new BoolOption (
2872 "cairo-image-surface",
2873 _("Disable Graphics Hardware Acceleration (requires restart)"),
2874 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
2875 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
2878 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
2879 _("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));
2880 add_option (S_("Preferences|GUI"), bgc);
2883 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
2884 BoolOption* bgo = new BoolOption (
2886 _("Possibly improve slow graphical performance (requires restart)"),
2887 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
2888 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
2891 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));
2892 add_option (S_("Preferences|GUI"), bgo);
2895 add_option (S_("Preferences|GUI"),
2898 _("Graphically indicate mouse pointer hovering over various widgets"),
2899 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
2900 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
2903 #ifdef TOOLTIPS_GOT_FIXED
2904 add_option (S_("Preferences|GUI"),
2907 _("Show tooltips if mouse hovers over a control"),
2908 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
2909 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
2913 add_option (S_("Preferences|GUI"),
2915 "show-name-highlight",
2916 _("Use name highlight bars in region displays (requires a restart)"),
2917 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
2918 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
2921 add_option (S_("GUI"),
2923 "super-rapid-clock-update",
2924 _("Update transport clock display at FPS instead of every 100ms"),
2925 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
2926 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
2931 /* font scaling does nothing with GDK/Quartz */
2932 add_option (S_("Preferences|GUI"), new FontScalingOptions ());
2935 /* Image cache size */
2937 Gtk::Adjustment *ics = manage (new Gtk::Adjustment(0, 1, 1024, 10)); /* 1 MB to 1GB in steps of 10MB */
2938 HSliderOption *sics = new HSliderOption("waveform-cache-size",
2939 _("Waveform image cache size (megabytes)"),
2941 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
2942 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size)
2944 sics->scale().set_digits (0);
2945 Gtkmm2ext::UI::instance()->set_tip
2946 (sics->tip_widget(),
2947 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
2948 add_option (S_("Preferences|GUI"), sics);
2950 if (!ARDOUR::Profile->get_mixbus()) {
2951 /* Lock GUI timeout */
2953 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
2954 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2955 _("Lock timeout (seconds)"),
2957 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
2958 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds)
2960 slts->scale().set_digits (0);
2961 Gtkmm2ext::UI::instance()->set_tip
2962 (slts->tip_widget(),
2963 _("Lock GUI after this many idle seconds (zero to never lock)"));
2964 add_option (S_("Preferences|GUI"), slts);
2967 /* The names of these controls must be the same as those given in MixerStrip
2968 for the actual widgets being controlled.
2970 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
2971 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2972 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
2973 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
2974 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
2975 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2978 S_("Preferences|GUI"),
2979 new VisibilityOption (
2981 &_mixer_strip_visibility,
2982 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
2983 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
2987 add_option (S_("Preferences|GUI"),
2989 "default-narrow_ms",
2990 _("Use narrow strips in the mixer by default"),
2991 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
2992 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
2995 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2997 ComboOption<float>* mht = new ComboOption<float> (
2999 _("Peak hold time"),
3000 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
3001 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
3004 mht->add (MeterHoldOff, _("off"));
3005 mht->add (MeterHoldShort, _("short"));
3006 mht->add (MeterHoldMedium, _("medium"));
3007 mht->add (MeterHoldLong, _("long"));
3009 add_option (S_("Preferences|Metering"), mht);
3011 ComboOption<float>* mfo = new ComboOption<float> (
3014 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
3015 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
3018 mfo->add (METER_FALLOFF_OFF, _("off"));
3019 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
3020 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
3021 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
3022 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
3023 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
3024 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
3026 add_option (S_("Preferences|Metering"), mfo);
3028 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
3029 "meter-line-up-level",
3030 _("Meter line-up level; 0dBu"),
3031 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
3032 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
3035 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3036 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3037 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3038 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3040 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."));
3042 add_option (S_("Preferences|Metering"), mlu);
3044 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
3045 "meter-line-up-din",
3046 _("IEC1/DIN Meter line-up level; 0dBu"),
3047 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
3048 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
3051 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3052 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3053 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3054 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3056 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
3058 add_option (S_("Preferences|Metering"), mld);
3060 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
3061 "meter-vu-standard",
3062 _("VU Meter standard"),
3063 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
3064 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
3067 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
3068 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
3069 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
3070 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
3072 add_option (S_("Preferences|Metering"), mvu);
3074 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
3075 HSliderOption *mpks = new HSliderOption("meter-peak",
3076 _("Peak threshold [dBFS]"),
3078 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
3079 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak)
3083 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3084 "meter-type-master",
3085 _("Default Meter Type for Master Bus"),
3086 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3087 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3089 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3090 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3091 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3092 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3093 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3094 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3095 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3096 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3098 add_option (S_("Preferences|Metering"), mtm);
3101 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3103 _("Default Meter Type for Busses"),
3104 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3105 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3107 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3108 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3109 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3110 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3111 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3112 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3113 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3114 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3116 add_option (S_("Preferences|Metering"), mtb);
3118 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3120 _("Default Meter Type for Tracks"),
3121 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3122 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3124 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3125 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3127 add_option (S_("Preferences|Metering"), mtt);
3130 Gtkmm2ext::UI::instance()->set_tip
3131 (mpks->tip_widget(),
3132 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
3134 add_option (S_("Preferences|Metering"), mpks);
3136 add_option (S_("Preferences|Metering"),
3139 _("LED meter style"),
3140 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3141 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3144 /* and now the theme manager */
3146 ThemeManager* tm = manage (new ThemeManager);
3147 add_page (_("Theme"), *tm);
3149 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3150 parameter_changed ("send-ltc");
3151 parameter_changed ("sync-source");
3152 parameter_changed ("use-monitor-bus");
3156 RCOptionEditor::parameter_changed (string const & p)
3158 OptionEditor::parameter_changed (p);
3160 if (p == "use-monitor-bus") {
3161 bool const s = Config->get_use_monitor_bus ();
3163 /* we can't use this if we don't have a monitor bus */
3164 Config->set_solo_control_is_listen_control (false);
3166 _solo_control_is_listen_control->set_sensitive (s);
3167 _listen_position->set_sensitive (s);
3168 } else if (p == "sync-source") {
3169 _sync_source->set_sensitive (true);
3171 _sync_source->set_sensitive (!_session->config.get_external_sync());
3173 switch(Config->get_sync_source()) {
3176 _sync_genlock->set_sensitive (true);
3177 _sync_framerate->set_sensitive (true);
3178 _sync_source_2997->set_sensitive (true);
3181 _sync_genlock->set_sensitive (false);
3182 _sync_framerate->set_sensitive (false);
3183 _sync_source_2997->set_sensitive (false);
3186 } else if (p == "send-ltc") {
3187 bool const s = Config->get_send_ltc ();
3188 _ltc_send_continuously->set_sensitive (s);
3189 _ltc_volume_slider->set_sensitive (s);
3193 void RCOptionEditor::ltc_generator_volume_changed () {
3194 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
3198 RCOptionEditor::populate_sync_options ()
3200 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3202 _sync_source->clear ();
3204 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3205 _sync_source->add (*i, sync_source_to_string (*i));
3208 if (sync_opts.empty()) {
3209 _sync_source->set_sensitive(false);
3211 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3212 _rc_config->set_sync_source(sync_opts.front());