2 Copyright (C) 2001-2011 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "gtk2ardour-config.h"
24 #if !defined USE_CAIRO_IMAGE_SURFACE && !defined NDEBUG
25 #define OPTIONAL_CAIRO_IMAGE_SURFACE
28 #include <cairo/cairo.h>
30 #include <boost/algorithm/string.hpp>
32 #include <gtkmm/liststore.h>
33 #include <gtkmm/stock.h>
34 #include <gtkmm/scale.h>
36 #include <gtkmm2ext/utils.h>
37 #include <gtkmm2ext/slider_controller.h>
38 #include <gtkmm2ext/gtk_ui.h>
39 #include <gtkmm2ext/paths_dialog.h>
40 #include <gtkmm2ext/window_title.h>
45 #include "ardour/audioengine.h"
46 #include "ardour/profile.h"
47 #include "ardour/dB.h"
48 #include "ardour/rc_configuration.h"
49 #include "ardour/control_protocol_manager.h"
50 #include "ardour/plugin_manager.h"
51 #include "control_protocol/control_protocol.h"
53 #include "canvas/wave_view.h"
55 #include "ardour_window.h"
56 #include "ardour_dialog.h"
57 #include "gui_thread.h"
58 #include "meter_patterns.h"
59 #include "midi_tracer.h"
60 #include "rc_option_editor.h"
62 #include "midi_port_dialog.h"
65 #include "theme_manager.h"
66 #include "ui_config.h"
71 using namespace Gtkmm2ext;
73 using namespace ARDOUR;
74 using namespace ARDOUR_UI_UTILS;
76 class ClickOptions : public OptionEditorBox
79 ClickOptions (RCConfiguration* c, Gtk::Window* p)
81 , _click_browse_button (_("Browse..."))
82 , _click_emphasis_browse_button (_("Browse..."))
84 Table* t = manage (new Table (4, 3));
87 Label* l = manage (left_aligned_label (_("Emphasis on first beat:")));
88 t->attach (*l, 0, 1, 1, 2, FILL);
89 t->attach (_use_emphasis_on_click_check_button, 1, 2, 1, 2, FILL);
90 _use_emphasis_on_click_check_button.signal_toggled().connect (
91 sigc::mem_fun (*this, &ClickOptions::use_emphasis_on_click_toggled));
93 l = manage (left_aligned_label (_("Use default Click:")));
94 t->attach (*l, 0, 1, 0, 1, FILL);
95 t->attach (_use_default_click_check_button, 1, 2, 0, 1, FILL);
96 _use_default_click_check_button.signal_toggled().connect (
97 sigc::mem_fun (*this, &ClickOptions::use_default_click_toggled));
99 l = manage (left_aligned_label (_("Click audio file:")));
100 t->attach (*l, 0, 1, 2, 3, FILL);
101 t->attach (_click_path_entry, 1, 2, 2, 3, FILL);
102 _click_browse_button.signal_clicked ().connect (
103 sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
104 t->attach (_click_browse_button, 2, 3, 2, 3, FILL);
106 l = manage (left_aligned_label (_("Click emphasis audio file:")));
107 t->attach (*l, 0, 1, 3, 4, FILL);
108 t->attach (_click_emphasis_path_entry, 1, 2, 3, 4, FILL);
109 _click_emphasis_browse_button.signal_clicked ().connect (
110 sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
111 t->attach (_click_emphasis_browse_button, 2, 3, 3, 4, FILL);
113 _box->pack_start (*t, false, false);
115 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
116 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
118 if (_rc_config->get_click_sound ().empty() &&
119 _rc_config->get_click_emphasis_sound().empty()) {
120 _use_default_click_check_button.set_active (true);
121 _use_emphasis_on_click_check_button.set_active (true);
124 _use_default_click_check_button.set_active (false);
125 _use_emphasis_on_click_check_button.set_active (false);
129 void parameter_changed (string const & p)
131 if (p == "click-sound") {
132 _click_path_entry.set_text (_rc_config->get_click_sound());
133 } else if (p == "click-emphasis-sound") {
134 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
135 } else if (p == "use-click-emphasis") {
136 bool x = _rc_config->get_use_click_emphasis ();
137 _use_emphasis_on_click_check_button.set_active (x);
141 void set_state_from_config ()
143 parameter_changed ("click-sound");
144 parameter_changed ("click-emphasis-sound");
145 parameter_changed ("use-click-emphasis");
150 void click_browse_clicked ()
152 SoundFileChooser sfdb (_("Choose Click"));
157 if (sfdb.run () == RESPONSE_OK) {
158 click_chosen (sfdb.get_filename());
162 void click_chosen (string const & path)
164 _click_path_entry.set_text (path);
165 _rc_config->set_click_sound (path);
168 void click_changed ()
170 click_chosen (_click_path_entry.get_text ());
173 void click_emphasis_browse_clicked ()
175 SoundFileChooser sfdb (_("Choose Click Emphasis"));
180 if (sfdb.run () == RESPONSE_OK) {
181 click_emphasis_chosen (sfdb.get_filename());
185 void click_emphasis_chosen (string const & path)
187 _click_emphasis_path_entry.set_text (path);
188 _rc_config->set_click_emphasis_sound (path);
191 void click_emphasis_changed ()
193 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
196 void use_default_click_toggled ()
198 if (_use_default_click_check_button.get_active ()) {
199 _rc_config->set_click_sound ("");
200 _rc_config->set_click_emphasis_sound ("");
201 _click_path_entry.set_sensitive (false);
202 _click_emphasis_path_entry.set_sensitive (false);
203 _click_browse_button.set_sensitive (false);
204 _click_emphasis_browse_button.set_sensitive (false);
206 _click_path_entry.set_sensitive (true);
207 _click_emphasis_path_entry.set_sensitive (true);
208 _click_browse_button.set_sensitive (true);
209 _click_emphasis_browse_button.set_sensitive (true);
213 void use_emphasis_on_click_toggled ()
215 if (_use_emphasis_on_click_check_button.get_active ()) {
216 _rc_config->set_use_click_emphasis(true);
218 _rc_config->set_use_click_emphasis(false);
222 RCConfiguration* _rc_config;
223 CheckButton _use_default_click_check_button;
224 CheckButton _use_emphasis_on_click_check_button;
225 Entry _click_path_entry;
226 Entry _click_emphasis_path_entry;
227 Button _click_browse_button;
228 Button _click_emphasis_browse_button;
231 class UndoOptions : public OptionEditorBox
234 UndoOptions (RCConfiguration* c) :
236 _limit_undo_button (_("Limit undo history to")),
237 _save_undo_button (_("Save undo history of"))
239 Table* t = new Table (2, 3);
242 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
243 _limit_undo_spin.set_range (0, 512);
244 _limit_undo_spin.set_increments (1, 10);
245 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
246 Label* l = manage (left_aligned_label (_("commands")));
247 t->attach (*l, 2, 3, 0, 1);
249 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
250 _save_undo_spin.set_range (0, 512);
251 _save_undo_spin.set_increments (1, 10);
252 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
253 l = manage (left_aligned_label (_("commands")));
254 t->attach (*l, 2, 3, 1, 2);
256 _box->pack_start (*t);
258 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
259 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
260 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
261 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
264 void parameter_changed (string const & p)
266 if (p == "history-depth") {
267 int32_t const d = _rc_config->get_history_depth();
268 _limit_undo_button.set_active (d != 0);
269 _limit_undo_spin.set_sensitive (d != 0);
270 _limit_undo_spin.set_value (d);
271 } else if (p == "save-history") {
272 bool const x = _rc_config->get_save_history ();
273 _save_undo_button.set_active (x);
274 _save_undo_spin.set_sensitive (x);
275 } else if (p == "save-history-depth") {
276 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
280 void set_state_from_config ()
282 parameter_changed ("save-history");
283 parameter_changed ("history-depth");
284 parameter_changed ("save-history-depth");
287 void limit_undo_toggled ()
289 bool const x = _limit_undo_button.get_active ();
290 _limit_undo_spin.set_sensitive (x);
291 int32_t const n = x ? 16 : 0;
292 _limit_undo_spin.set_value (n);
293 _rc_config->set_history_depth (n);
296 void limit_undo_changed ()
298 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
301 void save_undo_toggled ()
303 bool const x = _save_undo_button.get_active ();
304 _rc_config->set_save_history (x);
307 void save_undo_changed ()
309 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
313 RCConfiguration* _rc_config;
314 CheckButton _limit_undo_button;
315 SpinButton _limit_undo_spin;
316 CheckButton _save_undo_button;
317 SpinButton _save_undo_spin;
322 static const struct {
334 { "Key|Shift", GDK_SHIFT_MASK },
335 { "Command", GDK_MOD2_MASK },
336 { "Control", GDK_CONTROL_MASK },
337 { "Option", GDK_MOD1_MASK },
338 { "Command-Shift", GDK_MOD2_MASK|GDK_SHIFT_MASK },
339 { "Command-Option", GDK_MOD2_MASK|GDK_MOD1_MASK },
340 { "Command-Option-Control", GDK_MOD2_MASK|GDK_MOD1_MASK|GDK_CONTROL_MASK },
341 { "Option-Control", GDK_MOD1_MASK|GDK_CONTROL_MASK },
342 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
343 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
344 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_MOD2_MASK },
347 { "Key|Shift", GDK_SHIFT_MASK },
348 { "Control", GDK_CONTROL_MASK },
349 { "Alt", GDK_MOD1_MASK },
350 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
351 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
352 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
353 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
354 { "Alt-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
355 { "Alt-Shift-Windows", GDK_MOD1_MASK|GDK_SHIFT_MASK|GDK_MOD4_MASK },
356 { "Mod2", GDK_MOD2_MASK },
357 { "Mod3", GDK_MOD3_MASK },
358 { "Windows", GDK_MOD4_MASK },
359 { "Mod5", GDK_MOD5_MASK },
365 class KeyboardOptions : public OptionEditorBox
369 _delete_button_adjustment (3, 1, 12),
370 _delete_button_spin (_delete_button_adjustment),
371 _edit_button_adjustment (3, 1, 5),
372 _edit_button_spin (_edit_button_adjustment),
373 _insert_note_button_adjustment (3, 1, 5),
374 _insert_note_button_spin (_insert_note_button_adjustment)
376 const Glib::ustring restart_msg = _("\nChanges to this setting will only persist after your project has been saved.");
377 /* internationalize and prepare for use with combos */
380 for (int i = 0; modifiers[i].name; ++i) {
381 dumb.push_back (S_(modifiers[i].name));
384 set_popdown_strings (_edit_modifier_combo, dumb);
385 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
386 Gtkmm2ext::UI::instance()->set_tip (_edit_modifier_combo,
387 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
388 for (int x = 0; modifiers[x].name; ++x) {
389 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
390 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
395 Table* t = manage (new Table (5, 11));
401 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
402 l->set_name ("OptionsLabel");
406 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
407 strs.push_back (bf->first);
410 set_popdown_strings (_keyboard_layout_selector, strs);
411 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
412 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
414 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
415 t->attach (_keyboard_layout_selector, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
420 l = manage (left_aligned_label (_("When Clicking:")));
421 l->set_name ("OptionEditorHeading");
422 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
427 l = manage (left_aligned_label (_("Edit using:")));
428 l->set_name ("OptionsLabel");
430 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
431 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
433 l = manage (new Label (_("+ button")));
434 l->set_name ("OptionsLabel");
436 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
437 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
439 _edit_button_spin.set_name ("OptionsEntry");
440 _edit_button_adjustment.set_value (Keyboard::edit_button());
441 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
446 set_popdown_strings (_delete_modifier_combo, dumb);
447 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
448 Gtkmm2ext::UI::instance()->set_tip (_delete_modifier_combo,
449 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
450 for (int x = 0; modifiers[x].name; ++x) {
451 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
452 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
457 l = manage (left_aligned_label (_("Delete using:")));
458 l->set_name ("OptionsLabel");
460 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
461 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
463 l = manage (new Label (_("+ button")));
464 l->set_name ("OptionsLabel");
466 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
467 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
469 _delete_button_spin.set_name ("OptionsEntry");
470 _delete_button_adjustment.set_value (Keyboard::delete_button());
471 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
476 set_popdown_strings (_insert_note_modifier_combo, dumb);
477 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
478 Gtkmm2ext::UI::instance()->set_tip (_insert_note_modifier_combo,
479 (string_compose (_("<b>Recommended Setting: %1 + button 1 (left mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
480 for (int x = 0; modifiers[x].name; ++x) {
481 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
482 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
487 l = manage (left_aligned_label (_("Insert note using:")));
488 l->set_name ("OptionsLabel");
490 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
491 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
493 l = manage (new Label (_("+ button")));
494 l->set_name ("OptionsLabel");
496 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
497 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
499 _insert_note_button_spin.set_name ("OptionsEntry");
500 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
501 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
505 l = manage (left_aligned_label (_("When Beginning a Drag:")));
506 l->set_name ("OptionEditorHeading");
507 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
513 set_popdown_strings (_copy_modifier_combo, dumb);
514 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
515 Gtkmm2ext::UI::instance()->set_tip (_copy_modifier_combo,
516 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
518 Keyboard::secondary_modifier_name (),
520 Keyboard::primary_modifier_name (),
523 for (int x = 0; modifiers[x].name; ++x) {
524 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
525 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
530 l = manage (left_aligned_label (_("Copy items using:")));
531 l->set_name ("OptionsLabel");
533 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
534 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
539 /* constraint modifier */
540 set_popdown_strings (_constraint_modifier_combo, dumb);
541 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
542 Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo,
543 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
545 Keyboard::primary_modifier_name (),
547 Keyboard::secondary_modifier_name (),
550 for (int x = 0; modifiers[x].name; ++x) {
551 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
552 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
557 l = manage (left_aligned_label (_("Constrain drag using:")));
558 l->set_name ("OptionsLabel");
560 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
561 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
565 l = manage (left_aligned_label (_("When Beginning a Trim:")));
566 l->set_name ("OptionEditorHeading");
567 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
573 set_popdown_strings (_trim_contents_combo, dumb);
574 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
575 Gtkmm2ext::UI::instance()->set_tip (_trim_contents_combo,
576 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
577 for (int x = 0; modifiers[x].name; ++x) {
578 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
579 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
584 l = manage (left_aligned_label (_("Trim contents using:")));
585 l->set_name ("OptionsLabel");
587 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
588 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
594 set_popdown_strings (_trim_anchored_combo, dumb);
595 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
596 Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo,
597 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
598 for (int x = 0; modifiers[x].name; ++x) {
599 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
600 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
605 l = manage (left_aligned_label (_("Anchored trim using:")));
606 l->set_name ("OptionsLabel");
608 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
610 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
615 /* jump trim disabled for now
616 set_popdown_strings (_trim_jump_combo, dumb);
617 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
619 for (int x = 0; modifiers[x].name; ++x) {
620 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
621 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
626 l = manage (left_aligned_label (_("Jump after trim using:")));
627 l->set_name ("OptionsLabel");
629 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
631 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
637 /* note resize relative */
638 set_popdown_strings (_note_size_relative_combo, dumb);
639 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
640 Gtkmm2ext::UI::instance()->set_tip (_note_size_relative_combo,
641 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
642 for (int x = 0; modifiers[x].name; ++x) {
643 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
644 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
649 l = manage (left_aligned_label (_("Resize notes relatively using:")));
650 l->set_name ("OptionsLabel");
652 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
654 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
658 l = manage (left_aligned_label (_("While Dragging:")));
659 l->set_name ("OptionEditorHeading");
660 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
666 set_popdown_strings (_snap_modifier_combo, dumb);
667 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
669 Glib::ustring mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ());
671 Glib::ustring mod_str = Keyboard::secondary_modifier_name();
673 Gtkmm2ext::UI::instance()->set_tip (_snap_modifier_combo,
674 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
675 for (int x = 0; modifiers[x].name; ++x) {
676 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
677 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
682 l = manage (left_aligned_label (_("Ignore snap using:")));
683 l->set_name ("OptionsLabel");
685 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
686 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
692 set_popdown_strings (_snap_delta_combo, dumb);
693 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
695 mod_str = Keyboard::level4_modifier_name ();
697 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::level4_modifier_name ());
699 Gtkmm2ext::UI::instance()->set_tip (_snap_delta_combo,
700 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
701 for (int x = 0; modifiers[x].name; ++x) {
702 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
703 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
708 l = manage (left_aligned_label (_("Snap relatively using:")));
709 l->set_name ("OptionsLabel");
711 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
712 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
716 l = manage (left_aligned_label (_("While Trimming:")));
717 l->set_name ("OptionEditorHeading");
718 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
724 set_popdown_strings (_trim_overlap_combo, dumb);
725 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
727 Gtkmm2ext::UI::instance()->set_tip (_trim_overlap_combo,
728 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
729 for (int x = 0; modifiers[x].name; ++x) {
730 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
731 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
736 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
737 l->set_name ("OptionsLabel");
739 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
740 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
744 l = manage (left_aligned_label (_("While Dragging Control Points:")));
745 l->set_name ("OptionEditorHeading");
746 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
752 set_popdown_strings (_fine_adjust_combo, dumb);
753 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
755 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::tertiary_modifier_name ());
756 Gtkmm2ext::UI::instance()->set_tip (_fine_adjust_combo,
757 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
758 for (int x = 0; modifiers[x].name; ++x) {
759 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
760 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
765 l = manage (left_aligned_label (_("Fine adjust using:")));
766 l->set_name ("OptionsLabel");
768 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
769 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
775 set_popdown_strings (_push_points_combo, dumb);
776 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
778 Gtkmm2ext::UI::instance()->set_tip (_push_points_combo,
779 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
780 for (int x = 0; modifiers[x].name; ++x) {
781 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
782 _push_points_combo.set_active_text (S_(modifiers[x].name));
787 l = manage (left_aligned_label (_("Push points using:")));
788 l->set_name ("OptionsLabel");
790 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
791 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
793 _box->pack_start (*t, false, false);
796 void parameter_changed (string const &)
798 /* XXX: these aren't really config options... */
801 void set_state_from_config ()
803 /* XXX: these aren't really config options... */
808 void bindings_changed ()
810 string const txt = _keyboard_layout_selector.get_active_text();
812 /* XXX: config...? for all this keyboard stuff */
814 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
815 if (txt == i->first) {
816 if (Keyboard::load_keybindings (i->second)) {
817 Keyboard::save_keybindings ();
823 void edit_modifier_chosen ()
825 string const txt = _edit_modifier_combo.get_active_text();
827 for (int i = 0; modifiers[i].name; ++i) {
828 if (txt == _(modifiers[i].name)) {
829 Keyboard::set_edit_modifier (modifiers[i].modifier);
835 void delete_modifier_chosen ()
837 string const txt = _delete_modifier_combo.get_active_text();
839 for (int i = 0; modifiers[i].name; ++i) {
840 if (txt == _(modifiers[i].name)) {
841 Keyboard::set_delete_modifier (modifiers[i].modifier);
847 void copy_modifier_chosen ()
849 string const txt = _copy_modifier_combo.get_active_text();
851 for (int i = 0; modifiers[i].name; ++i) {
852 if (txt == _(modifiers[i].name)) {
853 Keyboard::set_copy_modifier (modifiers[i].modifier);
859 void insert_note_modifier_chosen ()
861 string const txt = _insert_note_modifier_combo.get_active_text();
863 for (int i = 0; modifiers[i].name; ++i) {
864 if (txt == _(modifiers[i].name)) {
865 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
871 void snap_modifier_chosen ()
873 string const txt = _snap_modifier_combo.get_active_text();
875 for (int i = 0; modifiers[i].name; ++i) {
876 if (txt == _(modifiers[i].name)) {
877 Keyboard::set_snap_modifier (modifiers[i].modifier);
883 void snap_delta_modifier_chosen ()
885 string const txt = _snap_delta_combo.get_active_text();
887 for (int i = 0; modifiers[i].name; ++i) {
888 if (txt == _(modifiers[i].name)) {
889 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
895 void constraint_modifier_chosen ()
897 string const txt = _constraint_modifier_combo.get_active_text();
899 for (int i = 0; modifiers[i].name; ++i) {
900 if (txt == _(modifiers[i].name)) {
901 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
907 void trim_contents_modifier_chosen ()
909 string const txt = _trim_contents_combo.get_active_text();
911 for (int i = 0; modifiers[i].name; ++i) {
912 if (txt == _(modifiers[i].name)) {
913 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
919 void trim_overlap_modifier_chosen ()
921 string const txt = _trim_overlap_combo.get_active_text();
923 for (int i = 0; modifiers[i].name; ++i) {
924 if (txt == _(modifiers[i].name)) {
925 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
931 void trim_anchored_modifier_chosen ()
933 string const txt = _trim_anchored_combo.get_active_text();
935 for (int i = 0; modifiers[i].name; ++i) {
936 if (txt == _(modifiers[i].name)) {
937 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
943 void fine_adjust_modifier_chosen ()
945 string const txt = _fine_adjust_combo.get_active_text();
947 for (int i = 0; modifiers[i].name; ++i) {
948 if (txt == _(modifiers[i].name)) {
949 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
955 void push_points_modifier_chosen ()
957 string const txt = _push_points_combo.get_active_text();
959 for (int i = 0; modifiers[i].name; ++i) {
960 if (txt == _(modifiers[i].name)) {
961 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
967 void note_size_relative_modifier_chosen ()
969 string const txt = _note_size_relative_combo.get_active_text();
971 for (int i = 0; modifiers[i].name; ++i) {
972 if (txt == _(modifiers[i].name)) {
973 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
979 void delete_button_changed ()
981 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
984 void edit_button_changed ()
986 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
989 void insert_note_button_changed ()
991 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
994 ComboBoxText _keyboard_layout_selector;
995 ComboBoxText _edit_modifier_combo;
996 ComboBoxText _delete_modifier_combo;
997 ComboBoxText _copy_modifier_combo;
998 ComboBoxText _insert_note_modifier_combo;
999 ComboBoxText _snap_modifier_combo;
1000 ComboBoxText _snap_delta_combo;
1001 ComboBoxText _constraint_modifier_combo;
1002 ComboBoxText _trim_contents_combo;
1003 ComboBoxText _trim_overlap_combo;
1004 ComboBoxText _trim_anchored_combo;
1005 ComboBoxText _trim_jump_combo;
1006 ComboBoxText _fine_adjust_combo;
1007 ComboBoxText _push_points_combo;
1008 ComboBoxText _note_size_relative_combo;
1009 Adjustment _delete_button_adjustment;
1010 SpinButton _delete_button_spin;
1011 Adjustment _edit_button_adjustment;
1012 SpinButton _edit_button_spin;
1013 Adjustment _insert_note_button_adjustment;
1014 SpinButton _insert_note_button_spin;
1018 class FontScalingOptions : public OptionEditorBox
1021 FontScalingOptions () :
1022 _dpi_adjustment (100, 50, 250, 1, 5),
1023 _dpi_slider (_dpi_adjustment)
1025 _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.);
1027 Label* l = manage (new Label (_("GUI and Font scaling:")));
1028 l->set_name ("OptionsLabel");
1030 const Glib::ustring dflt = _("Default");
1031 const Glib::ustring empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
1033 _dpi_slider.set_name("FontScaleSlider");
1034 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1035 _dpi_slider.set_draw_value(false);
1036 _dpi_slider.add_mark(50, Gtk::POS_TOP, empty);
1037 _dpi_slider.add_mark(60, Gtk::POS_TOP, empty);
1038 _dpi_slider.add_mark(70, Gtk::POS_TOP, empty);
1039 _dpi_slider.add_mark(80, Gtk::POS_TOP, empty);
1040 _dpi_slider.add_mark(90, Gtk::POS_TOP, empty);
1041 _dpi_slider.add_mark(100, Gtk::POS_TOP, dflt);
1042 _dpi_slider.add_mark(125, Gtk::POS_TOP, empty);
1043 _dpi_slider.add_mark(150, Gtk::POS_TOP, empty);
1044 _dpi_slider.add_mark(175, Gtk::POS_TOP, empty);
1045 _dpi_slider.add_mark(200, Gtk::POS_TOP, empty);
1046 _dpi_slider.add_mark(225, Gtk::POS_TOP, empty);
1047 _dpi_slider.add_mark(250, Gtk::POS_TOP, empty);
1049 HBox* h = manage (new HBox);
1051 h->pack_start (*l, false, false);
1052 h->pack_start (_dpi_slider, true, true);
1054 _box->pack_start (*h, false, false);
1056 set_note (_("Adjusting the scale require an application restart to re-layout."));
1058 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
1061 void parameter_changed (string const & p)
1063 if (p == "font-scale") {
1064 _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.);
1068 void set_state_from_config ()
1070 parameter_changed ("font-scale");
1077 UIConfiguration::instance().set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024.));
1078 /* XXX: should be triggered from the parameter changed signal */
1079 UIConfiguration::instance().reset_dpi ();
1082 Adjustment _dpi_adjustment;
1086 class ClipLevelOptions : public OptionEditorBox
1090 : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1091 , _clip_level_slider (_clip_level_adjustment)
1093 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ());
1095 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
1096 l->set_name ("OptionsLabel");
1098 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1099 HBox* h = manage (new HBox);
1101 h->pack_start (*l, false, false);
1102 h->pack_start (_clip_level_slider, true, true);
1104 _box->pack_start (*h, false, false);
1106 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1109 void parameter_changed (string const & p)
1111 if (p == "waveform-clip-level") {
1112 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level());
1116 void set_state_from_config ()
1118 parameter_changed ("waveform-clip-level");
1123 void clip_level_changed ()
1125 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1126 /* XXX: should be triggered from the parameter changed signal */
1127 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1130 Adjustment _clip_level_adjustment;
1131 HScale _clip_level_slider;
1134 class BufferingOptions : public OptionEditorBox
1137 BufferingOptions (RCConfiguration* c)
1139 , _playback_adjustment (5, 1, 60, 1, 4)
1140 , _capture_adjustment (5, 1, 60, 1, 4)
1141 , _playback_slider (_playback_adjustment)
1142 , _capture_slider (_capture_adjustment)
1144 vector<string> presets;
1146 /* these must match the order of the enums for BufferingPreset */
1148 presets.push_back (_("Small sessions (4-16 tracks)"));
1149 presets.push_back (_("Medium sessions (16-64 tracks)"));
1150 presets.push_back (_("Large sessions (64+ tracks)"));
1151 presets.push_back (_("Custom (set by sliders below)"));
1153 set_popdown_strings (_buffering_presets_combo, presets);
1155 Label* l = manage (new Label (_("Preset:")));
1156 l->set_name ("OptionsLabel");
1157 HBox* h = manage (new HBox);
1158 h->set_spacing (12);
1159 h->pack_start (*l, false, false);
1160 h->pack_start (_buffering_presets_combo, true, true);
1161 _box->pack_start (*h, false, false);
1163 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1165 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1167 l = manage (new Label (_("Playback (seconds of buffering):")));
1168 l->set_name ("OptionsLabel");
1170 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1171 h = manage (new HBox);
1173 h->pack_start (*l, false, false);
1174 h->pack_start (_playback_slider, true, true);
1176 _box->pack_start (*h, false, false);
1178 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1180 l = manage (new Label (_("Recording (seconds of buffering):")));
1181 l->set_name ("OptionsLabel");
1183 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1184 h = manage (new HBox);
1186 h->pack_start (*l, false, false);
1187 h->pack_start (_capture_slider, true, true);
1189 _box->pack_start (*h, false, false);
1191 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
1192 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
1195 void parameter_changed (string const & p)
1197 if (p == "buffering-preset") {
1198 switch (_rc_config->get_buffering_preset()) {
1200 _playback_slider.set_sensitive (false);
1201 _capture_slider.set_sensitive (false);
1202 _buffering_presets_combo.set_active (0);
1205 _playback_slider.set_sensitive (false);
1206 _capture_slider.set_sensitive (false);
1207 _buffering_presets_combo.set_active (1);
1210 _playback_slider.set_sensitive (false);
1211 _capture_slider.set_sensitive (false);
1212 _buffering_presets_combo.set_active (2);
1215 _playback_slider.set_sensitive (true);
1216 _capture_slider.set_sensitive (true);
1217 _buffering_presets_combo.set_active (3);
1222 if (p == "playback-buffer-seconds") {
1223 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1224 } else if (p == "capture-buffer-seconds") {
1225 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1229 void set_state_from_config ()
1231 parameter_changed ("buffering-preset");
1232 parameter_changed ("playback-buffer-seconds");
1233 parameter_changed ("capture-buffer-seconds");
1238 void preset_changed ()
1240 int index = _buffering_presets_combo.get_active_row_number ();
1246 _rc_config->set_buffering_preset (Small);
1249 _rc_config->set_buffering_preset (Medium);
1252 _rc_config->set_buffering_preset (Large);
1255 _rc_config->set_buffering_preset (Custom);
1258 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1263 void playback_changed ()
1265 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
1268 void capture_changed ()
1270 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
1273 RCConfiguration* _rc_config;
1274 Adjustment _playback_adjustment;
1275 Adjustment _capture_adjustment;
1276 HScale _playback_slider;
1277 HScale _capture_slider;
1278 ComboBoxText _buffering_presets_combo;
1281 class ControlSurfacesOptions : public OptionEditorBox
1284 ControlSurfacesOptions (Gtk::Window& parent)
1286 , _ignore_view_change (0)
1288 _store = ListStore::create (_model);
1289 _view.set_model (_store);
1290 _view.append_column (_("Control Surface Protocol"), _model.name);
1291 _view.get_column(0)->set_resizable (true);
1292 _view.get_column(0)->set_expand (true);
1293 _view.append_column_editable (_("Enabled"), _model.enabled);
1294 _view.append_column_editable (_("Feedback"), _model.feedback);
1296 _box->pack_start (_view, false, false);
1298 Gtk::HBox* edit_box = manage (new Gtk::HBox);
1299 edit_box->set_spacing(3);
1300 _box->pack_start (*edit_box, false, false);
1303 Label* label = manage (new Label);
1304 label->set_text (_("Click to edit the settings for selected protocol ( it must be ENABLED first ):"));
1305 edit_box->pack_start (*label, false, false);
1308 edit_button = manage (new Button(_("Show Protocol Settings")));
1309 edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
1310 edit_box->pack_start (*edit_button, true, true);
1311 edit_button->set_sensitive (false);
1312 edit_button->show ();
1314 ControlProtocolManager& m = ControlProtocolManager::instance ();
1315 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1316 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1318 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1319 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1320 _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
1323 void parameter_changed (std::string const &)
1328 void set_state_from_config ()
1332 ControlProtocolManager& m = ControlProtocolManager::instance ();
1333 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1335 if (!(*i)->mandatory) {
1336 TreeModel::Row r = *_store->append ();
1337 r[_model.name] = (*i)->name;
1338 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1339 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
1340 r[_model.protocol_info] = *i;
1347 void protocol_status_changed (ControlProtocolInfo* cpi) {
1349 TreeModel::Children rows = _store->children();
1351 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1352 string n = ((*x)[_model.name]);
1354 if ((*x)[_model.protocol_info] == cpi) {
1355 _ignore_view_change++;
1356 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1357 _ignore_view_change--;
1363 void selection_changed ()
1365 //enable the Edit button when a row is selected for editing
1366 TreeModel::Row row = *(_view.get_selection()->get_selected());
1367 if (row && row[_model.enabled])
1368 edit_button->set_sensitive (true);
1370 edit_button->set_sensitive (false);
1373 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1375 TreeModel::Row r = *i;
1377 if (_ignore_view_change) {
1381 ControlProtocolInfo* cpi = r[_model.protocol_info];
1386 bool const was_enabled = (cpi->protocol != 0);
1387 bool const is_enabled = r[_model.enabled];
1390 if (was_enabled != is_enabled) {
1393 ControlProtocolManager::instance().activate (*cpi);
1395 ControlProtocolManager::instance().deactivate (*cpi);
1399 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
1400 bool const is_feedback = r[_model.feedback];
1402 if (was_feedback != is_feedback && cpi->protocol) {
1403 cpi->protocol->set_feedback (is_feedback);
1407 void edit_btn_clicked ()
1410 ControlProtocolInfo* cpi;
1413 row = *(_view.get_selection()->get_selected());
1414 if (!row[_model.enabled]) {
1417 cpi = row[_model.protocol_info];
1418 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1421 Box* box = (Box*) cpi->protocol->get_gui ();
1425 if (box->get_parent()) {
1426 static_cast<ArdourWindow*>(box->get_parent())->present();
1429 WindowTitle title (Glib::get_application_name());
1430 title += row[_model.name];
1431 title += _("Configuration");
1432 /* once created, the window is managed by the surface itself (as ->get_parent())
1433 * Surface's tear_down_gui() is called on session close, when de-activating
1434 * or re-initializing a surface.
1435 * tear_down_gui() hides an deletes the Window if it exists.
1437 ArdourWindow* win = new ArdourWindow (_parent, title.get_string());
1443 void edit_clicked (GdkEventButton* ev)
1445 if (ev->type != GDK_2BUTTON_PRESS) {
1452 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1456 ControlSurfacesModelColumns ()
1461 add (protocol_info);
1464 TreeModelColumn<string> name;
1465 TreeModelColumn<bool> enabled;
1466 TreeModelColumn<bool> feedback;
1467 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1470 Glib::RefPtr<ListStore> _store;
1471 ControlSurfacesModelColumns _model;
1473 Gtk::Window& _parent;
1474 PBD::ScopedConnection protocol_status_connection;
1475 uint32_t _ignore_view_change;
1476 Gtk::Button* edit_button;
1479 class VideoTimelineOptions : public OptionEditorBox
1482 VideoTimelineOptions (RCConfiguration* c)
1484 , _show_video_export_info_button (_("Show Video Export Info before export"))
1485 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1486 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1488 Table* t = manage (new Table (2, 6));
1489 t->set_spacings (4);
1491 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
1492 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1493 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1494 _("<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."));
1496 Label* l = manage (new Label (_("Video Server URL:")));
1497 l->set_alignment (0, 0.5);
1498 t->attach (*l, 0, 1, 1, 2, FILL);
1499 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
1500 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1501 _("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"));
1503 l = manage (new Label (_("Video Folder:")));
1504 l->set_alignment (0, 0.5);
1505 t->attach (*l, 0, 1, 2, 3, FILL);
1506 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
1507 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1508 _("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."));
1510 /* small vspace y=3..4 */
1512 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
1513 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1514 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1515 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1517 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
1518 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1519 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1520 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1522 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1523 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1524 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1525 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1527 _box->pack_start (*t,true,true);
1530 void server_url_changed ()
1532 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1535 void server_docroot_changed ()
1537 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1540 void show_video_export_info_toggled ()
1542 bool const x = _show_video_export_info_button.get_active ();
1543 _rc_config->set_show_video_export_info (x);
1546 void show_video_server_dialog_toggled ()
1548 bool const x = _show_video_server_dialog_button.get_active ();
1549 _rc_config->set_show_video_server_dialog (x);
1552 void video_advanced_setup_toggled ()
1554 bool const x = _video_advanced_setup_button.get_active ();
1555 _rc_config->set_video_advanced_setup(x);
1558 void parameter_changed (string const & p)
1560 if (p == "video-server-url") {
1561 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1562 } else if (p == "video-server-docroot") {
1563 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1564 } else if (p == "show-video-export-info") {
1565 bool const x = _rc_config->get_show_video_export_info();
1566 _show_video_export_info_button.set_active (x);
1567 } else if (p == "show-video-server-dialog") {
1568 bool const x = _rc_config->get_show_video_server_dialog();
1569 _show_video_server_dialog_button.set_active (x);
1570 } else if (p == "video-advanced-setup") {
1571 bool const x = _rc_config->get_video_advanced_setup();
1572 _video_advanced_setup_button.set_active(x);
1573 _video_server_docroot_entry.set_sensitive(x);
1574 _video_server_url_entry.set_sensitive(x);
1578 void set_state_from_config ()
1580 parameter_changed ("video-server-url");
1581 parameter_changed ("video-server-docroot");
1582 parameter_changed ("video-monitor-setup-dialog");
1583 parameter_changed ("show-video-export-info");
1584 parameter_changed ("show-video-server-dialog");
1585 parameter_changed ("video-advanced-setup");
1589 RCConfiguration* _rc_config;
1590 Entry _video_server_url_entry;
1591 Entry _video_server_docroot_entry;
1592 CheckButton _show_video_export_info_button;
1593 CheckButton _show_video_server_dialog_button;
1594 CheckButton _video_advanced_setup_button;
1597 class PluginOptions : public OptionEditorBox
1600 PluginOptions (RCConfiguration* c)
1602 , _display_plugin_scan_progress (_("Always Display Plugin Scan Progress"))
1603 , _discover_vst_on_start (_("Scan for [new] VST Plugins on Application Start"))
1604 , _discover_au_on_start (_("Scan for AudioUnit Plugins on Application Start"))
1605 , _verbose_plugin_scan (_("Verbose Plugin Scan"))
1606 , _timeout_adjustment (0, 0, 3000, 50, 50)
1607 , _timeout_slider (_timeout_adjustment)
1609 // TODO define an OptionActionButton (with callback),
1610 // then use the OptionEditorPage's table
1611 // and standardOptionEditorHeading
1614 std::stringstream ss;
1615 Table* t = manage (new Table (2, 6));
1616 t->set_spacings (4);
1620 ss << "<b>" << _("General") << "</b>";
1621 l = manage (left_aligned_label (ss.str()));
1622 l->set_use_markup (true);
1623 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1624 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1626 b = manage (new Button (_("Scan for Plugins")));
1627 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1628 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1630 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1631 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1632 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1633 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
1635 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
1636 _timeout_slider.set_digits (0);
1637 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &PluginOptions::timeout_changed));
1639 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1640 _("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."));
1642 l = manage (left_aligned_label (_("Scan Time Out [deciseconds]")));;
1643 HBox* h = manage (new HBox);
1645 h->pack_start (*l, false, false);
1646 h->pack_start (_timeout_slider, true, true);
1647 t->attach (*h, 0, 2, n, n+1); ++n;
1650 ss << "<b>" << _("VST") << "</b>";
1651 l = manage (left_aligned_label (ss.str()));
1652 l->set_use_markup (true);
1653 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1654 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1656 b = manage (new Button (_("Clear VST Cache")));
1657 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1658 t->attach (*b, 0, 1, n, n+1, FILL);
1660 b = manage (new Button (_("Clear VST Blacklist")));
1661 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1662 t->attach (*b, 1, 2, n, n+1, FILL);
1665 t->attach (_discover_vst_on_start, 0, 2, n, n+1); ++n;
1666 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1667 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1668 _("<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"));
1670 #ifdef LXVST_SUPPORT
1671 t->attach (*manage (right_aligned_label (_("Linux VST Path:"))), 0, 1, n, n+1);
1672 b = manage (new Button (_("Edit")));
1673 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_lxvst_path_clicked));
1674 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1677 #ifdef WINDOWS_VST_SUPPORT
1678 t->attach (*manage (right_aligned_label (_("Windows VST Path:"))), 0, 1, n, n+1);
1679 b = manage (new Button (_("Edit")));
1680 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_vst_path_clicked));
1681 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1683 // currently verbose logging is only implemented for Windows VST.
1684 t->attach (_verbose_plugin_scan, 0, 2, n, n+1); ++n;
1685 _verbose_plugin_scan.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::verbose_plugin_scan_toggled));
1686 Gtkmm2ext::UI::instance()->set_tip (_verbose_plugin_scan,
1687 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
1691 #ifdef AUDIOUNIT_SUPPORT
1693 ss << "<b>" << _("Audio Unit") << "</b>";
1694 l = manage (left_aligned_label (ss.str()));
1695 l->set_use_markup (true);
1696 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1697 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1699 t->attach (_discover_au_on_start, 0, 2, n, n+1); ++n;
1700 _discover_au_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_au_on_start_toggled));
1701 Gtkmm2ext::UI::instance()->set_tip (_discover_au_on_start,
1702 _("<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."));
1705 b = manage (new Button (_("Clear AU Cache")));
1706 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_cache_clicked));
1707 t->attach (*b, 0, 1, n, n+1, FILL);
1709 b = manage (new Button (_("Clear AU Blacklist")));
1710 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_blacklist_clicked));
1711 t->attach (*b, 1, 2, n, n+1, FILL);
1715 _box->pack_start (*t,true,true);
1718 void parameter_changed (string const & p) {
1719 if (p == "show-plugin-scan-window") {
1720 bool const x = UIConfiguration::instance().get_show_plugin_scan_window();
1721 _display_plugin_scan_progress.set_active (x);
1723 else if (p == "discover-vst-on-start") {
1724 bool const x = _rc_config->get_discover_vst_on_start();
1725 _discover_vst_on_start.set_active (x);
1727 else if (p == "vst-scan-timeout") {
1728 int const x = _rc_config->get_vst_scan_timeout();
1729 _timeout_adjustment.set_value (x);
1731 else if (p == "discover-audio-units") {
1732 bool const x = _rc_config->get_discover_audio_units();
1733 _discover_au_on_start.set_active (x);
1735 else if (p == "verbose-plugin-scan") {
1736 bool const x = _rc_config->get_verbose_plugin_scan();
1737 _verbose_plugin_scan.set_active (x);
1741 void set_state_from_config () {
1742 parameter_changed ("show-plugin-scan-window");
1743 parameter_changed ("discover-vst-on-start");
1744 parameter_changed ("vst-scan-timeout");
1745 parameter_changed ("discover-audio-units");
1746 parameter_changed ("verbose-plugin-scan");
1749 void add_to_page (OptionEditorPage* p) {
1750 int const n = p->table.property_n_rows();
1751 p->table.resize (n + 1, 3);
1752 p->table.attach (*_box, 0, 3, n, n + 1, FILL | EXPAND);
1756 RCConfiguration* _rc_config;
1757 CheckButton _display_plugin_scan_progress;
1758 CheckButton _discover_vst_on_start;
1759 CheckButton _discover_au_on_start;
1760 CheckButton _verbose_plugin_scan;
1761 Adjustment _timeout_adjustment;
1762 HScale _timeout_slider;
1764 void display_plugin_scan_progress_toggled () {
1765 bool const x = _display_plugin_scan_progress.get_active();
1766 UIConfiguration::instance().set_show_plugin_scan_window(x);
1769 void discover_vst_on_start_toggled () {
1770 bool const x = _discover_vst_on_start.get_active();
1771 _rc_config->set_discover_vst_on_start(x);
1774 void discover_au_on_start_toggled () {
1775 bool const x = _discover_au_on_start.get_active();
1776 _rc_config->set_discover_audio_units(x);
1779 void verbose_plugin_scan_toggled () {
1780 bool const x = _verbose_plugin_scan.get_active();
1781 _rc_config->set_verbose_plugin_scan(x);
1784 void timeout_changed () {
1785 int x = floor(_timeout_adjustment.get_value());
1786 _rc_config->set_vst_scan_timeout(x);
1789 void clear_vst_cache_clicked () {
1790 PluginManager::instance().clear_vst_cache();
1793 void clear_vst_blacklist_clicked () {
1794 PluginManager::instance().clear_vst_blacklist();
1797 void clear_au_cache_clicked () {
1798 PluginManager::instance().clear_au_cache();
1801 void clear_au_blacklist_clicked () {
1802 PluginManager::instance().clear_au_blacklist();
1806 void edit_vst_path_clicked () {
1807 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1808 _("Set Windows VST Search Path"),
1809 _rc_config->get_plugin_path_vst(),
1810 PluginManager::instance().get_default_windows_vst_path()
1812 ResponseType r = (ResponseType) pd->run ();
1814 if (r == RESPONSE_ACCEPT) {
1815 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
1820 // todo consolidate with edit_vst_path_clicked..
1821 void edit_lxvst_path_clicked () {
1822 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1823 _("Set Linux VST Search Path"),
1824 _rc_config->get_plugin_path_lxvst(),
1825 PluginManager::instance().get_default_lxvst_path()
1827 ResponseType r = (ResponseType) pd->run ();
1829 if (r == RESPONSE_ACCEPT) {
1830 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
1835 void refresh_clicked () {
1836 PluginManager::instance().refresh();
1841 /** A class which allows control of visibility of some editor components usign
1842 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1843 * which has the correct members, but with null widget pointers. This
1844 * class allows the user to set visibility of the members, the details
1845 * of which are stored in a configuration variable which can be watched
1846 * by parts of the editor that actually contain the widgets whose visibility
1847 * is being controlled.
1850 class VisibilityOption : public Option
1853 /** @param name User-visible name for this group.
1854 * @param g `Dummy' VisibilityGroup (as described above).
1855 * @param get Method to get the value of the appropriate configuration variable.
1856 * @param set Method to set the value of the appropriate configuration variable.
1858 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1859 : Option (g->get_state_name(), name)
1861 , _visibility_group (g)
1865 /* Watch for changes made by the user to our members */
1866 _visibility_group->VisibilityChanged.connect_same_thread (
1867 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1871 void set_state_from_config ()
1873 /* Set our state from the current configuration */
1874 _visibility_group->set_state (_get ());
1877 void add_to_page (OptionEditorPage* p)
1879 _heading.add_to_page (p);
1880 add_widget_to_page (p, _visibility_group->list_view ());
1883 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1888 /* The user has changed something, so reflect this change
1889 in the RCConfiguration.
1891 _set (_visibility_group->get_state_value ());
1894 OptionEditorHeading _heading;
1895 VisibilityGroup* _visibility_group;
1896 sigc::slot<std::string> _get;
1897 sigc::slot<bool, std::string> _set;
1898 PBD::ScopedConnection _visibility_group_connection;
1903 RCOptionEditor::RCOptionEditor ()
1904 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1905 , _rc_config (Config)
1906 , _mixer_strip_visibility ("mixer-element-visibility")
1910 uint32_t hwcpus = hardware_concurrency ();
1912 BoolComboOption* bco;
1915 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1917 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1919 _("Signal processing uses"),
1920 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1921 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1924 procs->add (-1, _("all but one processor"));
1925 procs->add (0, _("all available processors"));
1927 for (uint32_t i = 1; i <= hwcpus; ++i) {
1928 procs->add (i, string_compose (_("%1 processors"), i));
1931 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1933 add_option (_("Misc"), procs);
1936 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1938 add_option (_("Misc"), new UndoOptions (_rc_config));
1940 add_option (_("Misc"),
1942 "verify-remove-last-capture",
1943 _("Verify removal of last capture"),
1944 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1945 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1948 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1950 add_option (_("Misc"),
1952 "periodic-safety-backups",
1953 _("Make periodic backups of the session file"),
1954 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1955 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1958 add_option (_("Misc"),
1960 "only-copy-imported-files",
1961 _("Always copy imported files"),
1962 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
1963 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
1966 add_option (_("Misc"), new DirectoryOption (
1967 X_("default-session-parent-dir"),
1968 _("Default folder for new sessions:"),
1969 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1970 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1973 add_option (_("Misc"),
1974 new SpinOption<uint32_t> (
1975 "max-recent-sessions",
1976 _("Maximum number of recent sessions"),
1977 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1978 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1982 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1984 add_option (_("Misc"), new ClickOptions (_rc_config, this));
1986 add_option (_("Misc"),
1989 _("Click gain level"),
1990 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1991 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1994 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1996 add_option (_("Misc"),
1997 new SpinOption<double> (
1998 "automation-thinning-factor",
1999 _("Thinning factor (larger value => less data)"),
2000 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
2001 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
2005 add_option (_("Misc"),
2006 new SpinOption<double> (
2007 "automation-interval-msecs",
2008 _("Automation sampling interval (milliseconds)"),
2009 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
2010 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
2016 add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options")));
2020 tsf = new BoolOption (
2021 "latched-record-enable",
2022 _("Keep record-enable engaged on stop"),
2023 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
2024 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
2026 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
2027 add_option (_("Transport"), tsf);
2029 tsf = new BoolOption (
2031 _("Play loop is a transport mode"),
2032 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
2033 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
2035 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2036 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
2037 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
2038 add_option (_("Transport"), tsf);
2040 tsf = new BoolOption (
2041 "stop-recording-on-xrun",
2042 _("Stop recording when an xrun occurs"),
2043 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
2044 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
2046 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2047 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
2049 add_option (_("Transport"), tsf);
2051 tsf = new BoolOption (
2052 "create-xrun-marker",
2053 _("Create markers where xruns occur"),
2054 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
2055 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
2057 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
2058 add_option (_("Transport"), tsf);
2060 tsf = new BoolOption (
2061 "stop-at-session-end",
2062 _("Stop at the end of the session"),
2063 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
2064 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
2066 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2067 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
2068 "when it reaches the current session end marker\n\n"
2069 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
2071 add_option (_("Transport"), tsf);
2073 tsf = new BoolOption (
2075 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
2076 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
2077 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
2079 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2080 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
2081 "preventing any need to do a transport locate at the end of the loop\n\n"
2082 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
2083 "which will often cause a small click or delay"), PROGRAM_NAME));
2084 add_option (_("Transport"), tsf);
2086 tsf = new BoolOption (
2087 "disable-disarm-during-roll",
2088 _("Disable per-track record disarm while rolling"),
2089 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
2090 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
2092 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"));
2093 add_option (_("Transport"), tsf);
2095 tsf = new BoolOption (
2097 _("12dB gain reduction during fast-forward and fast-rewind"),
2098 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
2099 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2101 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
2102 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2103 add_option (_("Transport"), tsf);
2105 ComboOption<float>* psc = new ComboOption<float> (
2108 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
2109 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
2111 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
2112 (_("The amount of preroll (in seconds) to apply when <b>Play with Preroll</b> is initiated.\n\n"
2113 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
2114 psc->add (0.0, _("0 (no pre-roll)"));
2115 psc->add (0.1, _("0.1 second"));
2116 psc->add (0.25, _("0.25 second"));
2117 psc->add (0.5, _("0.5 second"));
2118 psc->add (1.0, _("1.0 second"));
2119 psc->add (2.0, _("2.0 seconds"));
2120 add_option (_("Transport"), psc);
2122 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
2124 _sync_source = new ComboOption<SyncSource> (
2126 _("External timecode source"),
2127 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
2128 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
2131 add_option (_("Transport"), _sync_source);
2133 _sync_framerate = new BoolOption (
2134 "timecode-sync-frame-rate",
2135 _("Match session video frame rate to external timecode"),
2136 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
2137 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
2139 Gtkmm2ext::UI::instance()->set_tip
2140 (_sync_framerate->tip_widget(),
2141 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
2142 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
2143 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
2144 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
2145 "timecode standard and the session standard."), PROGRAM_NAME));
2147 add_option (_("Transport"), _sync_framerate);
2149 _sync_genlock = new BoolOption (
2150 "timecode-source-is-synced",
2151 _("Sync-lock timecode to clock (disable drift compensation)"),
2152 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
2153 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
2155 Gtkmm2ext::UI::instance()->set_tip
2156 (_sync_genlock->tip_widget(),
2157 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
2158 "Sync Lock indicates that the selected external timecode source shares clock-sync "
2159 "(Black & Burst, Wordclock, etc) with the audio interface. "
2160 "This option disables drift compensation. The transport speed is fixed at 1.0. "
2161 "Vari-speed LTC will be ignored and cause drift."
2163 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
2164 "timecode sources shares clock sync."
2168 add_option (_("Transport"), _sync_genlock);
2170 _sync_source_2997 = new BoolOption (
2171 "timecode-source-2997",
2172 _("Lock to 29.9700 fps instead of 30000/1001"),
2173 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
2174 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
2176 Gtkmm2ext::UI::instance()->set_tip
2177 (_sync_source_2997->tip_widget(),
2178 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
2179 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
2180 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
2181 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
2182 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
2183 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
2186 add_option (_("Transport"), _sync_source_2997);
2188 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
2190 _ltc_port = new ComboStringOption (
2192 _("LTC incoming port"),
2193 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
2194 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
2197 vector<string> physical_inputs;
2198 physical_inputs.push_back (_("None"));
2199 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
2200 _ltc_port->set_popdown_strings (physical_inputs);
2202 populate_sync_options ();
2204 add_option (_("Transport"), _ltc_port);
2206 // TODO; rather disable this button than not compile it..
2207 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
2209 add_option (_("Transport"),
2212 _("Enable LTC generator"),
2213 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
2214 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
2217 _ltc_send_continuously = new BoolOption (
2218 "ltc-send-continuously",
2219 _("Send LTC while stopped"),
2220 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
2221 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
2223 Gtkmm2ext::UI::instance()->set_tip
2224 (_ltc_send_continuously->tip_widget(),
2225 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
2226 add_option (_("Transport"), _ltc_send_continuously);
2228 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
2229 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
2230 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
2231 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
2233 Gtkmm2ext::UI::instance()->set_tip
2234 (_ltc_volume_slider->tip_widget(),
2235 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
2237 add_option (_("Transport"), _ltc_volume_slider);
2241 add_option (_("Editor"),
2243 "rubberbanding-snaps-to-grid",
2244 _("Make rubberband selection rectangle snap to the grid"),
2245 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2246 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2249 bo = new BoolOption (
2251 _("Name new markers"),
2252 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2253 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2255 add_option (_("Editor"), bo);
2256 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."
2257 "\n\nYou can always rename markers by right-clicking on them"));
2259 add_option (S_("Editor"),
2261 "draggable-playhead",
2262 _("Allow dragging of playhead"),
2263 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2264 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2267 add_option (_("Editor"),
2269 "show-track-meters",
2270 _("Show meters on tracks in the editor"),
2271 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
2272 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
2275 add_option (_("Editor"),
2277 "show-editor-meter",
2278 _("Display master-meter in the toolbar"),
2279 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
2280 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
2283 if (!Profile->get_mixbus()) {
2284 add_option (_("Editor"),
2287 _("Show zoom toolbar (if torn off)"),
2288 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_zoom_tools),
2289 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_zoom_tools)
2293 add_option (_("Editor"),
2295 "update-editor-during-summary-drag",
2296 _("Update editor window during drags of the summary"),
2297 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2298 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2301 add_option (_("Editor"),
2303 "autoscroll-editor",
2304 _("Auto-scroll editor window when dragging near its edges"),
2305 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2306 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2309 add_option (_("Editor"),
2310 new BoolComboOption (
2311 "show-region-gain-envelopes",
2312 _("Show gain envelopes in audio regions"),
2314 _("only in Draw and Internal Edit modes"),
2315 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2316 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2319 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2321 add_option (_("Editor"),
2323 "automation-follows-regions",
2324 _("Move relevant automation when audio regions are moved"),
2325 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2326 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2329 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2330 "default-fade-shape",
2331 _("Default fade shape"),
2332 sigc::mem_fun (*_rc_config,
2333 &RCConfiguration::get_default_fade_shape),
2334 sigc::mem_fun (*_rc_config,
2335 &RCConfiguration::set_default_fade_shape)
2338 fadeshape->add (FadeLinear,
2339 _("Linear (for highly correlated material)"));
2340 fadeshape->add (FadeConstantPower, _("Constant power"));
2341 fadeshape->add (FadeSymmetric, _("Symmetric"));
2342 fadeshape->add (FadeSlow, _("Slow"));
2343 fadeshape->add (FadeFast, _("Fast"));
2345 add_option (_("Editor"), fadeshape);
2348 bco = new BoolComboOption (
2349 "use-overlap-equivalency",
2350 _("Regions in active edit groups are edited together"),
2351 _("whenever they overlap in time"),
2352 _("only if they have identical length, position and origin"),
2353 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2354 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2357 add_option (_("Editor"), bco);
2359 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2361 _("Layering model"),
2362 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2363 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2366 lm->add (LaterHigher, _("later is higher"));
2367 lm->add (Manual, _("manual layering"));
2368 add_option (_("Editor"), lm);
2370 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2371 "region-selection-after-split",
2372 _("After splitting selected regions, select"),
2373 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2374 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2376 // TODO: decide which of these modes are really useful
2377 rsas->add(None, _("no regions"));
2378 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2379 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2380 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2381 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2382 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2383 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2384 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2386 add_option (_("Editor"), rsas);
2388 add_option (_("Editor"), new OptionEditorHeading (_("Waveforms")));
2390 if (!Profile->get_mixbus()) {
2391 add_option (_("Editor"),
2394 _("Show waveforms in regions"),
2395 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
2396 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
2400 add_option (_("Editor"),
2402 "show-waveforms-while-recording",
2403 _("Show waveforms for audio while it is being recorded"),
2404 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
2405 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
2408 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
2410 _("Waveform scale"),
2411 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
2412 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
2415 wfs->add (Linear, _("linear"));
2416 wfs->add (Logarithmic, _("logarithmic"));
2418 add_option (_("Editor"), wfs);
2420 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
2422 _("Waveform shape"),
2423 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
2424 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
2427 wfsh->add (Traditional, _("traditional"));
2428 wfsh->add (Rectified, _("rectified"));
2430 add_option (_("Editor"), wfsh);
2432 add_option (_("Editor"), new ClipLevelOptions ());
2437 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2439 add_option (_("Audio"), new BufferingOptions (_rc_config));
2441 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2443 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2445 _("Record monitoring handled by"),
2446 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2447 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2450 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2451 mm->add (HardwareMonitoring, _("via Audio Driver"));
2454 string prog (PROGRAM_NAME);
2455 boost::algorithm::to_lower (prog);
2456 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2457 mm->add (ExternalMonitoring, _("audio hardware"));
2459 add_option (_("Audio"), mm);
2461 add_option (_("Audio"),
2463 "tape-machine-mode",
2464 _("Tape machine mode"),
2465 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2466 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2469 if (!Profile->get_mixbus()) {
2470 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2472 add_option (_("Audio"),
2474 "auto-connect-standard-busses",
2475 _("Auto-connect master/monitor busses"),
2476 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2477 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2480 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2481 "input-auto-connect",
2482 _("Connect track inputs"),
2483 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2484 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2487 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2488 iac->add (ManualConnect, _("manually"));
2490 add_option (_("Audio"), iac);
2492 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2493 "output-auto-connect",
2494 _("Connect track and bus outputs"),
2495 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2496 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2499 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2500 oac->add (AutoConnectMaster, _("automatically to master bus"));
2501 oac->add (ManualConnect, _("manually"));
2503 add_option (_("Audio"), oac);
2506 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2508 add_option (_("Audio"),
2510 "denormal-protection",
2511 _("Use DC bias to protect against denormals"),
2512 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2513 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2516 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2518 _("Processor handling"),
2519 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2520 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2524 dm->add (DenormalNone, _("no processor handling"));
2526 FPU* fpu = FPU::instance();
2528 if (fpu->has_flush_to_zero()) {
2530 dm->add (DenormalFTZ, _("use FlushToZero"));
2531 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2532 _rc_config->set_denormal_model(DenormalNone);
2535 if (fpu->has_denormals_are_zero()) {
2537 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2538 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2539 _rc_config->set_denormal_model(DenormalNone);
2542 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2544 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2545 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2546 _rc_config->set_denormal_model(DenormalNone);
2550 dm->set_sensitive(false);
2553 add_option (_("Audio"), dm);
2555 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
2557 add_option (_("Audio"),
2559 "plugins-stop-with-transport",
2560 _("Silence plugins when the transport is stopped"),
2561 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
2562 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
2565 add_option (_("Audio"),
2567 "new-plugins-active",
2568 _("Make new plugins active"),
2569 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
2570 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
2573 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2575 add_option (_("Audio"),
2577 "auto-analyse-audio",
2578 _("Enable automatic analysis of audio"),
2579 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2580 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2583 add_option (_("Audio"),
2585 "replicate-missing-region-channels",
2586 _("Replicate missing region channels"),
2587 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2588 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2593 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
2595 _solo_control_is_listen_control = new BoolOption (
2596 "solo-control-is-listen-control",
2597 _("Solo controls are Listen controls"),
2598 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2599 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2602 add_option (_("Solo / mute"), _solo_control_is_listen_control);
2604 add_option (_("Solo / mute"),
2607 _("Exclusive solo"),
2608 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2609 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2612 add_option (_("Solo / mute"),
2615 _("Show solo muting"),
2616 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2617 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2620 add_option (_("Solo / mute"),
2622 "solo-mute-override",
2623 _("Soloing overrides muting"),
2624 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2625 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2628 add_option (_("Solo / mute"),
2631 _("Solo-in-place mute cut (dB)"),
2632 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2633 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2636 _listen_position = new ComboOption<ListenPosition> (
2638 _("Listen Position"),
2639 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2640 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2643 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2644 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2646 add_option (_("Solo / mute"), _listen_position);
2648 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2650 _("PFL signals come from"),
2651 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2652 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2655 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2656 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2658 add_option (_("Solo / mute"), pp);
2660 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2662 _("AFL signals come from"),
2663 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2664 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2667 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2668 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2670 add_option (_("Solo / mute"), pa);
2672 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2674 add_option (_("Solo / mute"),
2676 "mute-affects-pre-fader",
2677 _("Mute affects pre-fader sends"),
2678 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2679 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2682 add_option (_("Solo / mute"),
2684 "mute-affects-post-fader",
2685 _("Mute affects post-fader sends"),
2686 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2687 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2690 add_option (_("Solo / mute"),
2692 "mute-affects-control-outs",
2693 _("Mute affects control outputs"),
2694 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2695 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2698 add_option (_("Solo / mute"),
2700 "mute-affects-main-outs",
2701 _("Mute affects main outputs"),
2702 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2703 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2706 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
2708 add_option (_("Solo / mute"),
2710 "link-send-and-route-panner",
2711 _("Link panners of Aux and External Sends with main panner by default"),
2712 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2713 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2716 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Preferences")));
2718 add_option (_("MIDI"),
2719 new SpinOption<float> (
2721 _("MIDI read-ahead time (seconds)"),
2722 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2723 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2728 add_option (_("MIDI"),
2729 new SpinOption<int32_t> (
2730 "initial-program-change",
2731 _("Initial program change"),
2732 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2733 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2737 add_option (_("MIDI"),
2739 "display-first-midi-bank-as-zero",
2740 _("Display first MIDI bank/program as 0"),
2741 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2742 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2745 add_option (_("MIDI"),
2747 "never-display-periodic-midi",
2748 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2749 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
2750 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
2753 add_option (_("MIDI"),
2756 _("Sound MIDI notes as they are selected in the editor"),
2757 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2758 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2761 add_option (_("MIDI"),
2764 _("Send MIDI control feedback"),
2765 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2766 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2769 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Clock")));
2771 add_option (_("MIDI"),
2774 _("Send MIDI Clock"),
2775 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2776 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2779 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC)")));
2781 add_option (_("MIDI"),
2784 _("Send MIDI Time Code"),
2785 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2786 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2789 add_option (_("MIDI"),
2790 new SpinOption<int> (
2791 "mtc-qf-speed-tolerance",
2792 _("Percentage either side of normal transport speed to transmit MTC"),
2793 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2794 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2798 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Machine Control (MMC)")));
2800 add_option (_("MIDI"),
2803 _("Obey MIDI Machine Control commands"),
2804 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2805 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2808 add_option (_("MIDI"),
2811 _("Send MIDI Machine Control commands"),
2812 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2813 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2816 add_option (_("MIDI"),
2817 new SpinOption<uint8_t> (
2818 "mmc-receive-device-id",
2819 _("Inbound MMC device ID"),
2820 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2821 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2825 add_option (_("MIDI"),
2826 new SpinOption<uint8_t> (
2827 "mmc-send-device-id",
2828 _("Outbound MMC device ID"),
2829 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2830 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2834 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2836 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2837 "midi-audition-synth-uri",
2838 _("Midi Audition Synth (LV2)"),
2839 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2840 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2843 audition_synth->add(X_(""), _("None"));
2844 PluginInfoList all_plugs;
2845 PluginManager& manager (PluginManager::instance());
2847 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2849 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2850 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2851 if (!(*i)->is_instrument()) continue;
2852 if ((*i)->type != ARDOUR::LV2) continue;
2853 audition_synth->add((*i)->unique_id, (*i)->name);
2857 add_option (_("MIDI"), audition_synth);
2859 /* USER INTERACTION */
2862 #ifdef PLATFORM_WINDOWS
2865 getenv ("ARDOUR_BUNDLED")
2869 add_option (_("User interaction"),
2871 "enable-translation",
2872 string_compose (_("Use translations of %1 messages\n"
2873 " <i>(requires a restart of %1 to take effect)</i>\n"
2874 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2875 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2876 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2879 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2881 add_option (_("User interaction"), new KeyboardOptions);
2883 /* Control Surfaces */
2885 add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2887 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2889 _("Control surface remote ID"),
2890 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2891 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2894 rm->add (UserOrdered, _("assigned by user"));
2895 rm->add (MixerOrdered, _("follows order of mixer"));
2897 add_option (_("Control Surfaces"), rm);
2899 /* VIDEO Timeline */
2900 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2902 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2903 /* Plugin options (currrently VST only) */
2904 add_option (_("Plugins"), new PluginOptions (_rc_config));
2907 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
2908 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
2909 add_option (_("Plugins"),
2911 "open-gui-after-adding-plugin",
2912 _("Automatically open the plugin GUI when adding a new plugin."),
2913 sigc::mem_fun (*_rc_config, &RCConfiguration::get_open_gui_after_adding_plugin),
2914 sigc::mem_fun (*_rc_config, &RCConfiguration::set_open_gui_after_adding_plugin)
2920 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
2921 BoolOption* bgc = new BoolOption (
2922 "cairo-image-surface",
2923 _("Disable Graphics Hardware Acceleration (requires restart)"),
2924 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
2925 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
2928 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
2929 _("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));
2930 add_option (S_("Preferences|GUI"), bgc);
2933 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
2934 BoolOption* bgo = new BoolOption (
2936 _("Possibly improve slow graphical performance (requires restart)"),
2937 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
2938 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
2941 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));
2942 add_option (S_("Preferences|GUI"), bgo);
2945 add_option (S_("Preferences|GUI"),
2948 _("Graphically indicate mouse pointer hovering over various widgets"),
2949 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
2950 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
2953 #ifdef TOOLTIPS_GOT_FIXED
2954 add_option (S_("Preferences|GUI"),
2957 _("Show tooltips if mouse hovers over a control"),
2958 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
2959 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
2963 add_option (S_("Preferences|GUI"),
2965 "show-name-highlight",
2966 _("Use name highlight bars in region displays (requires a restart)"),
2967 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
2968 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
2971 add_option (S_("GUI"),
2973 "super-rapid-clock-update",
2974 _("Update transport clock display at FPS instead of every 100ms"),
2975 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
2976 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
2981 /* font scaling does nothing with GDK/Quartz */
2982 add_option (S_("Preferences|GUI"), new FontScalingOptions ());
2985 /* Image cache size */
2987 Gtk::Adjustment *ics = manage (new Gtk::Adjustment(0, 1, 1024, 10)); /* 1 MB to 1GB in steps of 10MB */
2988 HSliderOption *sics = new HSliderOption("waveform-cache-size",
2989 _("Waveform image cache size (megabytes)"),
2991 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
2992 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size)
2994 sics->scale().set_digits (0);
2995 Gtkmm2ext::UI::instance()->set_tip
2996 (sics->tip_widget(),
2997 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
2998 add_option (S_("Preferences|GUI"), sics);
3000 if (!ARDOUR::Profile->get_mixbus()) {
3001 /* Lock GUI timeout */
3003 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
3004 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
3005 _("Lock timeout (seconds)"),
3007 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
3008 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds)
3010 slts->scale().set_digits (0);
3011 Gtkmm2ext::UI::instance()->set_tip
3012 (slts->tip_widget(),
3013 _("Lock GUI after this many idle seconds (zero to never lock)"));
3014 add_option (S_("Preferences|GUI"), slts);
3017 /* The names of these controls must be the same as those given in MixerStrip
3018 for the actual widgets being controlled.
3020 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3021 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3022 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3023 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3024 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3025 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3028 S_("Preferences|GUI"),
3029 new VisibilityOption (
3031 &_mixer_strip_visibility,
3032 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3033 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3037 add_option (S_("Preferences|GUI"),
3039 "default-narrow_ms",
3040 _("Use narrow strips in the mixer by default"),
3041 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3042 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3045 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
3047 ComboOption<float>* mht = new ComboOption<float> (
3049 _("Peak hold time"),
3050 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
3051 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
3054 mht->add (MeterHoldOff, _("off"));
3055 mht->add (MeterHoldShort, _("short"));
3056 mht->add (MeterHoldMedium, _("medium"));
3057 mht->add (MeterHoldLong, _("long"));
3059 add_option (S_("Preferences|Metering"), mht);
3061 ComboOption<float>* mfo = new ComboOption<float> (
3064 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
3065 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
3068 mfo->add (METER_FALLOFF_OFF, _("off"));
3069 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
3070 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
3071 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
3072 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
3073 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
3074 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
3076 add_option (S_("Preferences|Metering"), mfo);
3078 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
3079 "meter-line-up-level",
3080 _("Meter line-up level; 0dBu"),
3081 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
3082 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
3085 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3086 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3087 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3088 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3090 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."));
3092 add_option (S_("Preferences|Metering"), mlu);
3094 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
3095 "meter-line-up-din",
3096 _("IEC1/DIN Meter line-up level; 0dBu"),
3097 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
3098 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
3101 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3102 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3103 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3104 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3106 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
3108 add_option (S_("Preferences|Metering"), mld);
3110 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
3111 "meter-vu-standard",
3112 _("VU Meter standard"),
3113 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
3114 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
3117 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
3118 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
3119 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
3120 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
3122 add_option (S_("Preferences|Metering"), mvu);
3124 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
3125 HSliderOption *mpks = new HSliderOption("meter-peak",
3126 _("Peak threshold [dBFS]"),
3128 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
3129 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak)
3133 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3134 "meter-type-master",
3135 _("Default Meter Type for Master Bus"),
3136 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3137 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3139 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3140 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3141 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3142 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3143 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3144 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3145 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3146 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3148 add_option (S_("Preferences|Metering"), mtm);
3151 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3153 _("Default Meter Type for Busses"),
3154 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3155 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3157 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3158 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3159 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3160 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3161 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3162 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3163 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3164 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3166 add_option (S_("Preferences|Metering"), mtb);
3168 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3170 _("Default Meter Type for Tracks"),
3171 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3172 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3174 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3175 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3177 add_option (S_("Preferences|Metering"), mtt);
3180 Gtkmm2ext::UI::instance()->set_tip
3181 (mpks->tip_widget(),
3182 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
3184 add_option (S_("Preferences|Metering"), mpks);
3186 add_option (S_("Preferences|Metering"),
3189 _("LED meter style"),
3190 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3191 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3194 /* and now the theme manager */
3196 ThemeManager* tm = manage (new ThemeManager);
3197 add_page (_("Theme"), *tm);
3199 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3200 parameter_changed ("send-ltc");
3201 parameter_changed ("sync-source");
3202 parameter_changed ("use-monitor-bus");
3206 RCOptionEditor::parameter_changed (string const & p)
3208 OptionEditor::parameter_changed (p);
3210 if (p == "use-monitor-bus") {
3211 bool const s = Config->get_use_monitor_bus ();
3213 /* we can't use this if we don't have a monitor bus */
3214 Config->set_solo_control_is_listen_control (false);
3216 _solo_control_is_listen_control->set_sensitive (s);
3217 _listen_position->set_sensitive (s);
3218 } else if (p == "sync-source") {
3219 _sync_source->set_sensitive (true);
3221 _sync_source->set_sensitive (!_session->config.get_external_sync());
3223 switch(Config->get_sync_source()) {
3226 _sync_genlock->set_sensitive (true);
3227 _sync_framerate->set_sensitive (true);
3228 _sync_source_2997->set_sensitive (true);
3231 _sync_genlock->set_sensitive (false);
3232 _sync_framerate->set_sensitive (false);
3233 _sync_source_2997->set_sensitive (false);
3236 } else if (p == "send-ltc") {
3237 bool const s = Config->get_send_ltc ();
3238 _ltc_send_continuously->set_sensitive (s);
3239 _ltc_volume_slider->set_sensitive (s);
3243 void RCOptionEditor::ltc_generator_volume_changed () {
3244 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
3248 RCOptionEditor::populate_sync_options ()
3250 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3252 _sync_source->clear ();
3254 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3255 _sync_source->add (*i, sync_source_to_string (*i));
3258 if (sync_opts.empty()) {
3259 _sync_source->set_sensitive(false);
3261 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3262 _rc_config->set_sync_source(sync_opts.front());