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)
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 requires 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 VstTimeOutSliderOption : public OptionEditorBox
1089 VstTimeOutSliderOption (RCConfiguration* c)
1091 , _timeout_adjustment (0, 0, 3000, 50, 50)
1092 , _timeout_slider (_timeout_adjustment)
1094 _timeout_slider.set_digits (0);
1095 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &VstTimeOutSliderOption::timeout_changed));
1097 _timeout_slider.set_draw_value(false);
1098 _timeout_slider.add_mark( 0, Gtk::POS_TOP, _("\u221e")); // infinity
1099 _timeout_slider.add_mark( 300, Gtk::POS_TOP, _("30 sec"));
1100 _timeout_slider.add_mark( 600, Gtk::POS_TOP, _("1 min"));
1101 _timeout_slider.add_mark(1200, Gtk::POS_TOP, _("2 mins"));
1102 _timeout_slider.add_mark(1800, Gtk::POS_TOP, _("3 mins"));
1103 _timeout_slider.add_mark(2400, Gtk::POS_TOP, _("4 mins"));
1104 _timeout_slider.add_mark(3000, Gtk::POS_TOP, _("5 mins"));
1106 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1107 _("Specify the default timeout for plugin instantiation. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1109 Label* l = manage (left_aligned_label (_("Scan Time Out:")));
1110 HBox* h = manage (new HBox);
1112 h->pack_start (*l, false, false);
1113 h->pack_start (_timeout_slider, true, true);
1115 _box->pack_start (*h, false, false);
1118 void parameter_changed (string const & p)
1120 if (p == "vst-scan-timeout") {
1121 int const x = _rc_config->get_vst_scan_timeout();
1122 _timeout_adjustment.set_value (x);
1126 void set_state_from_config ()
1128 parameter_changed ("vst-scan-timeout");
1133 void timeout_changed ()
1135 int x = floor(_timeout_adjustment.get_value());
1136 _rc_config->set_vst_scan_timeout(x);
1139 RCConfiguration* _rc_config;
1140 Adjustment _timeout_adjustment;
1141 HScale _timeout_slider;
1148 class ClipLevelOptions : public OptionEditorBox
1152 : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1153 , _clip_level_slider (_clip_level_adjustment)
1155 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ());
1157 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
1158 l->set_name ("OptionsLabel");
1160 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1161 HBox* h = manage (new HBox);
1163 h->pack_start (*l, false, false);
1164 h->pack_start (_clip_level_slider, true, true);
1166 _box->pack_start (*h, false, false);
1168 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1171 void parameter_changed (string const & p)
1173 if (p == "waveform-clip-level") {
1174 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level());
1178 void set_state_from_config ()
1180 parameter_changed ("waveform-clip-level");
1185 void clip_level_changed ()
1187 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1188 /* XXX: should be triggered from the parameter changed signal */
1189 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1192 Adjustment _clip_level_adjustment;
1193 HScale _clip_level_slider;
1196 class BufferingOptions : public OptionEditorBox
1199 BufferingOptions (RCConfiguration* c)
1201 , _playback_adjustment (5, 1, 60, 1, 4)
1202 , _capture_adjustment (5, 1, 60, 1, 4)
1203 , _playback_slider (_playback_adjustment)
1204 , _capture_slider (_capture_adjustment)
1206 vector<string> presets;
1208 /* these must match the order of the enums for BufferingPreset */
1210 presets.push_back (_("Small sessions (4-16 tracks)"));
1211 presets.push_back (_("Medium sessions (16-64 tracks)"));
1212 presets.push_back (_("Large sessions (64+ tracks)"));
1213 presets.push_back (_("Custom (set by sliders below)"));
1215 set_popdown_strings (_buffering_presets_combo, presets);
1217 Label* l = manage (new Label (_("Preset:")));
1218 l->set_name ("OptionsLabel");
1219 HBox* h = manage (new HBox);
1220 h->set_spacing (12);
1221 h->pack_start (*l, false, false);
1222 h->pack_start (_buffering_presets_combo, true, true);
1223 _box->pack_start (*h, false, false);
1225 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1227 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1229 l = manage (new Label (_("Playback (seconds of buffering):")));
1230 l->set_name ("OptionsLabel");
1232 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1233 h = manage (new HBox);
1235 h->pack_start (*l, false, false);
1236 h->pack_start (_playback_slider, true, true);
1238 _box->pack_start (*h, false, false);
1240 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1242 l = manage (new Label (_("Recording (seconds of buffering):")));
1243 l->set_name ("OptionsLabel");
1245 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1246 h = manage (new HBox);
1248 h->pack_start (*l, false, false);
1249 h->pack_start (_capture_slider, true, true);
1251 _box->pack_start (*h, false, false);
1253 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
1254 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
1257 void parameter_changed (string const & p)
1259 if (p == "buffering-preset") {
1260 switch (_rc_config->get_buffering_preset()) {
1262 _playback_slider.set_sensitive (false);
1263 _capture_slider.set_sensitive (false);
1264 _buffering_presets_combo.set_active (0);
1267 _playback_slider.set_sensitive (false);
1268 _capture_slider.set_sensitive (false);
1269 _buffering_presets_combo.set_active (1);
1272 _playback_slider.set_sensitive (false);
1273 _capture_slider.set_sensitive (false);
1274 _buffering_presets_combo.set_active (2);
1277 _playback_slider.set_sensitive (true);
1278 _capture_slider.set_sensitive (true);
1279 _buffering_presets_combo.set_active (3);
1284 if (p == "playback-buffer-seconds") {
1285 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1286 } else if (p == "capture-buffer-seconds") {
1287 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1291 void set_state_from_config ()
1293 parameter_changed ("buffering-preset");
1294 parameter_changed ("playback-buffer-seconds");
1295 parameter_changed ("capture-buffer-seconds");
1300 void preset_changed ()
1302 int index = _buffering_presets_combo.get_active_row_number ();
1308 _rc_config->set_buffering_preset (Small);
1311 _rc_config->set_buffering_preset (Medium);
1314 _rc_config->set_buffering_preset (Large);
1317 _rc_config->set_buffering_preset (Custom);
1320 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1325 void playback_changed ()
1327 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
1330 void capture_changed ()
1332 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
1335 RCConfiguration* _rc_config;
1336 Adjustment _playback_adjustment;
1337 Adjustment _capture_adjustment;
1338 HScale _playback_slider;
1339 HScale _capture_slider;
1340 ComboBoxText _buffering_presets_combo;
1343 class ControlSurfacesOptions : public OptionEditorBox
1346 ControlSurfacesOptions ()
1347 : _ignore_view_change (0)
1349 _store = ListStore::create (_model);
1350 _view.set_model (_store);
1351 _view.append_column (_("Control Surface Protocol"), _model.name);
1352 _view.get_column(0)->set_resizable (true);
1353 _view.get_column(0)->set_expand (true);
1354 _view.append_column_editable (_("Enabled"), _model.enabled);
1355 _view.append_column_editable (_("Feedback"), _model.feedback);
1357 _box->pack_start (_view, false, false);
1359 Gtk::HBox* edit_box = manage (new Gtk::HBox);
1360 edit_box->set_spacing(3);
1361 _box->pack_start (*edit_box, false, false);
1364 Label* label = manage (new Label);
1365 label->set_text (_("Click to edit the settings for selected protocol ( it must be ENABLED first ):"));
1366 edit_box->pack_start (*label, false, false);
1369 edit_button = manage (new Button(_("Show Protocol Settings")));
1370 edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
1371 edit_box->pack_start (*edit_button, true, true);
1372 edit_button->set_sensitive (false);
1373 edit_button->show ();
1375 ControlProtocolManager& m = ControlProtocolManager::instance ();
1376 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1377 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1379 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1380 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1381 _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
1384 void parameter_changed (std::string const &)
1389 void set_state_from_config ()
1393 ControlProtocolManager& m = ControlProtocolManager::instance ();
1394 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1396 if (!(*i)->mandatory) {
1397 TreeModel::Row r = *_store->append ();
1398 r[_model.name] = (*i)->name;
1399 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1400 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
1401 r[_model.protocol_info] = *i;
1408 void protocol_status_changed (ControlProtocolInfo* cpi) {
1410 TreeModel::Children rows = _store->children();
1412 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1413 string n = ((*x)[_model.name]);
1415 if ((*x)[_model.protocol_info] == cpi) {
1416 _ignore_view_change++;
1417 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1418 _ignore_view_change--;
1424 void selection_changed ()
1426 //enable the Edit button when a row is selected for editing
1427 TreeModel::Row row = *(_view.get_selection()->get_selected());
1428 if (row && row[_model.enabled])
1429 edit_button->set_sensitive (true);
1431 edit_button->set_sensitive (false);
1434 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1436 TreeModel::Row r = *i;
1438 if (_ignore_view_change) {
1442 ControlProtocolInfo* cpi = r[_model.protocol_info];
1447 bool const was_enabled = (cpi->protocol != 0);
1448 bool const is_enabled = r[_model.enabled];
1451 if (was_enabled != is_enabled) {
1454 ControlProtocolManager::instance().activate (*cpi);
1456 ControlProtocolManager::instance().deactivate (*cpi);
1460 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
1461 bool const is_feedback = r[_model.feedback];
1463 if (was_feedback != is_feedback && cpi->protocol) {
1464 cpi->protocol->set_feedback (is_feedback);
1468 void edit_btn_clicked ()
1471 ControlProtocolInfo* cpi;
1474 row = *(_view.get_selection()->get_selected());
1475 if (!row[_model.enabled]) {
1478 cpi = row[_model.protocol_info];
1479 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1482 Box* box = (Box*) cpi->protocol->get_gui ();
1486 if (box->get_parent()) {
1487 static_cast<ArdourWindow*>(box->get_parent())->present();
1490 WindowTitle title (Glib::get_application_name());
1491 title += row[_model.name];
1492 title += _("Configuration");
1493 /* once created, the window is managed by the surface itself (as ->get_parent())
1494 * Surface's tear_down_gui() is called on session close, when de-activating
1495 * or re-initializing a surface.
1496 * tear_down_gui() hides an deletes the Window if it exists.
1498 ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
1499 win->set_title ("Control Protocol Options");
1505 void edit_clicked (GdkEventButton* ev)
1507 if (ev->type != GDK_2BUTTON_PRESS) {
1514 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1518 ControlSurfacesModelColumns ()
1523 add (protocol_info);
1526 TreeModelColumn<string> name;
1527 TreeModelColumn<bool> enabled;
1528 TreeModelColumn<bool> feedback;
1529 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1532 Glib::RefPtr<ListStore> _store;
1533 ControlSurfacesModelColumns _model;
1535 PBD::ScopedConnection protocol_status_connection;
1536 uint32_t _ignore_view_change;
1537 Gtk::Button* edit_button;
1540 class VideoTimelineOptions : public OptionEditorBox
1543 VideoTimelineOptions (RCConfiguration* c)
1545 , _show_video_export_info_button (_("Show Video Export Info before export"))
1546 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1547 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1549 Table* t = manage (new Table (2, 6));
1550 t->set_spacings (4);
1552 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
1553 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1554 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1555 _("<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."));
1557 Label* l = manage (new Label (_("Video Server URL:")));
1558 l->set_alignment (0, 0.5);
1559 t->attach (*l, 0, 1, 1, 2, FILL);
1560 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
1561 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1562 _("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"));
1564 l = manage (new Label (_("Video Folder:")));
1565 l->set_alignment (0, 0.5);
1566 t->attach (*l, 0, 1, 2, 3, FILL);
1567 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
1568 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1569 _("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."));
1571 /* small vspace y=3..4 */
1573 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
1574 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1575 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1576 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1578 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
1579 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1580 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1581 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1583 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1584 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1585 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1586 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1588 _box->pack_start (*t,true,true);
1591 void server_url_changed ()
1593 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1596 void server_docroot_changed ()
1598 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1601 void show_video_export_info_toggled ()
1603 bool const x = _show_video_export_info_button.get_active ();
1604 _rc_config->set_show_video_export_info (x);
1607 void show_video_server_dialog_toggled ()
1609 bool const x = _show_video_server_dialog_button.get_active ();
1610 _rc_config->set_show_video_server_dialog (x);
1613 void video_advanced_setup_toggled ()
1615 bool const x = _video_advanced_setup_button.get_active ();
1616 _rc_config->set_video_advanced_setup(x);
1619 void parameter_changed (string const & p)
1621 if (p == "video-server-url") {
1622 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1623 } else if (p == "video-server-docroot") {
1624 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1625 } else if (p == "show-video-export-info") {
1626 bool const x = _rc_config->get_show_video_export_info();
1627 _show_video_export_info_button.set_active (x);
1628 } else if (p == "show-video-server-dialog") {
1629 bool const x = _rc_config->get_show_video_server_dialog();
1630 _show_video_server_dialog_button.set_active (x);
1631 } else if (p == "video-advanced-setup") {
1632 bool const x = _rc_config->get_video_advanced_setup();
1633 _video_advanced_setup_button.set_active(x);
1634 _video_server_docroot_entry.set_sensitive(x);
1635 _video_server_url_entry.set_sensitive(x);
1639 void set_state_from_config ()
1641 parameter_changed ("video-server-url");
1642 parameter_changed ("video-server-docroot");
1643 parameter_changed ("video-monitor-setup-dialog");
1644 parameter_changed ("show-video-export-info");
1645 parameter_changed ("show-video-server-dialog");
1646 parameter_changed ("video-advanced-setup");
1650 RCConfiguration* _rc_config;
1651 Entry _video_server_url_entry;
1652 Entry _video_server_docroot_entry;
1653 CheckButton _show_video_export_info_button;
1654 CheckButton _show_video_server_dialog_button;
1655 CheckButton _video_advanced_setup_button;
1659 /** A class which allows control of visibility of some editor components usign
1660 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1661 * which has the correct members, but with null widget pointers. This
1662 * class allows the user to set visibility of the members, the details
1663 * of which are stored in a configuration variable which can be watched
1664 * by parts of the editor that actually contain the widgets whose visibility
1665 * is being controlled.
1668 class VisibilityOption : public Option
1671 /** @param name User-visible name for this group.
1672 * @param g `Dummy' VisibilityGroup (as described above).
1673 * @param get Method to get the value of the appropriate configuration variable.
1674 * @param set Method to set the value of the appropriate configuration variable.
1676 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1677 : Option (g->get_state_name(), name)
1679 , _visibility_group (g)
1683 /* Watch for changes made by the user to our members */
1684 _visibility_group->VisibilityChanged.connect_same_thread (
1685 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1689 void set_state_from_config ()
1691 /* Set our state from the current configuration */
1692 _visibility_group->set_state (_get ());
1695 void add_to_page (OptionEditorPage* p)
1697 _heading.add_to_page (p);
1698 add_widget_to_page (p, _visibility_group->list_view ());
1701 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1706 /* The user has changed something, so reflect this change
1707 in the RCConfiguration.
1709 _set (_visibility_group->get_state_value ());
1712 OptionEditorHeading _heading;
1713 VisibilityGroup* _visibility_group;
1714 sigc::slot<std::string> _get;
1715 sigc::slot<bool, std::string> _set;
1716 PBD::ScopedConnection _visibility_group_connection;
1721 RCOptionEditor::RCOptionEditor ()
1722 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1723 , Tabbable (*this, _("Preferences")) /* pack self-as-vbox into tabbable */
1724 , _rc_config (Config)
1725 , _mixer_strip_visibility ("mixer-element-visibility")
1729 uint32_t hwcpus = hardware_concurrency ();
1731 BoolComboOption* bco;
1734 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1736 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1738 _("Signal processing uses"),
1739 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1740 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1743 procs->add (-1, _("all but one processor"));
1744 procs->add (0, _("all available processors"));
1746 for (uint32_t i = 1; i <= hwcpus; ++i) {
1747 procs->add (i, string_compose (_("%1 processors"), i));
1750 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1752 add_option (_("Misc"), procs);
1755 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1757 add_option (_("Misc"), new UndoOptions (_rc_config));
1759 add_option (_("Misc"),
1761 "verify-remove-last-capture",
1762 _("Verify removal of last capture"),
1763 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1764 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1767 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1769 add_option (_("Misc"),
1771 "periodic-safety-backups",
1772 _("Make periodic backups of the session file"),
1773 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1774 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1777 add_option (_("Misc"),
1779 "only-copy-imported-files",
1780 _("Always copy imported files"),
1781 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
1782 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
1785 add_option (_("Misc"), new DirectoryOption (
1786 X_("default-session-parent-dir"),
1787 _("Default folder for new sessions:"),
1788 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1789 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1792 add_option (_("Misc"),
1793 new SpinOption<uint32_t> (
1794 "max-recent-sessions",
1795 _("Maximum number of recent sessions"),
1796 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1797 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1801 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1803 add_option (_("Misc"), new ClickOptions (_rc_config));
1805 add_option (_("Misc"),
1808 _("Click gain level"),
1809 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1810 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1813 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1815 add_option (_("Misc"),
1816 new SpinOption<double> (
1817 "automation-thinning-factor",
1818 _("Thinning factor (larger value => less data)"),
1819 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1820 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1824 add_option (_("Misc"),
1825 new SpinOption<double> (
1826 "automation-interval-msecs",
1827 _("Automation sampling interval (milliseconds)"),
1828 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1829 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1835 add_option (_("Transport"), new OptionEditorHeading (S_("Playhead Behaviour")));
1836 add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options")));
1840 tsf = new BoolOption (
1841 "latched-record-enable",
1842 _("Keep record-enable engaged on stop"),
1843 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1844 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1846 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1847 add_option (_("Transport"), tsf);
1849 tsf = new BoolOption (
1851 _("Play loop is a transport mode"),
1852 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1853 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1855 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1856 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1857 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1858 add_option (_("Transport"), tsf);
1860 tsf = new BoolOption (
1861 "stop-recording-on-xrun",
1862 _("Stop recording when an xrun occurs"),
1863 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1864 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1866 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1867 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
1869 add_option (_("Transport"), tsf);
1871 tsf = new BoolOption (
1872 "create-xrun-marker",
1873 _("Create markers where xruns occur"),
1874 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1875 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1877 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1878 add_option (_("Transport"), tsf);
1880 tsf = new BoolOption (
1881 "stop-at-session-end",
1882 _("Stop at the end of the session"),
1883 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1884 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1886 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1887 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
1888 "when it reaches the current session end marker\n\n"
1889 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
1891 add_option (_("Transport"), tsf);
1893 tsf = new BoolOption (
1895 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
1896 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1897 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1899 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1900 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1901 "preventing any need to do a transport locate at the end of the loop\n\n"
1902 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
1903 "which will often cause a small click or delay"), PROGRAM_NAME));
1904 add_option (_("Transport"), tsf);
1906 tsf = new BoolOption (
1907 "disable-disarm-during-roll",
1908 _("Disable per-track record disarm while rolling"),
1909 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
1910 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
1912 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"));
1913 add_option (_("Transport"), tsf);
1915 tsf = new BoolOption (
1917 _("12dB gain reduction during fast-forward and fast-rewind"),
1918 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
1919 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
1921 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
1922 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
1923 add_option (_("Transport"), tsf);
1925 ComboOption<float>* psc = new ComboOption<float> (
1928 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
1929 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
1931 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
1932 (_("The amount of preroll (in seconds) to apply when <b>Play with Preroll</b> is initiated.\n\n"
1933 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
1934 psc->add (0.0, _("0 (no pre-roll)"));
1935 psc->add (0.1, _("0.1 second"));
1936 psc->add (0.25, _("0.25 second"));
1937 psc->add (0.5, _("0.5 second"));
1938 psc->add (1.0, _("1.0 second"));
1939 psc->add (2.0, _("2.0 seconds"));
1940 add_option (_("Transport"), psc);
1942 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
1944 _sync_source = new ComboOption<SyncSource> (
1946 _("External timecode source"),
1947 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
1948 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
1951 add_option (_("Transport"), _sync_source);
1953 _sync_framerate = new BoolOption (
1954 "timecode-sync-frame-rate",
1955 _("Match session video frame rate to external timecode"),
1956 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
1957 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
1959 Gtkmm2ext::UI::instance()->set_tip
1960 (_sync_framerate->tip_widget(),
1961 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
1962 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
1963 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
1964 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
1965 "timecode standard and the session standard."), PROGRAM_NAME));
1967 add_option (_("Transport"), _sync_framerate);
1969 _sync_genlock = new BoolOption (
1970 "timecode-source-is-synced",
1971 _("Sync-lock timecode to clock (disable drift compensation)"),
1972 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
1973 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
1975 Gtkmm2ext::UI::instance()->set_tip
1976 (_sync_genlock->tip_widget(),
1977 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
1978 "Sync Lock indicates that the selected external timecode source shares clock-sync "
1979 "(Black & Burst, Wordclock, etc) with the audio interface. "
1980 "This option disables drift compensation. The transport speed is fixed at 1.0. "
1981 "Vari-speed LTC will be ignored and cause drift."
1983 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
1984 "timecode sources shares clock sync."
1988 add_option (_("Transport"), _sync_genlock);
1990 _sync_source_2997 = new BoolOption (
1991 "timecode-source-2997",
1992 _("Lock to 29.9700 fps instead of 30000/1001"),
1993 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
1994 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
1996 Gtkmm2ext::UI::instance()->set_tip
1997 (_sync_source_2997->tip_widget(),
1998 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
1999 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
2000 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
2001 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
2002 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
2003 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
2006 add_option (_("Transport"), _sync_source_2997);
2008 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
2010 _ltc_port = new ComboStringOption (
2012 _("LTC incoming port"),
2013 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
2014 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
2017 vector<string> physical_inputs;
2018 physical_inputs.push_back (_("None"));
2019 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
2020 _ltc_port->set_popdown_strings (physical_inputs);
2022 populate_sync_options ();
2023 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
2025 add_option (_("Transport"), _ltc_port);
2027 // TODO; rather disable this button than not compile it..
2028 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
2030 add_option (_("Transport"),
2033 _("Enable LTC generator"),
2034 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
2035 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
2038 _ltc_send_continuously = new BoolOption (
2039 "ltc-send-continuously",
2040 _("Send LTC while stopped"),
2041 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
2042 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
2044 Gtkmm2ext::UI::instance()->set_tip
2045 (_ltc_send_continuously->tip_widget(),
2046 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
2047 add_option (_("Transport"), _ltc_send_continuously);
2049 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
2050 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
2051 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
2052 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
2054 Gtkmm2ext::UI::instance()->set_tip
2055 (_ltc_volume_slider->tip_widget(),
2056 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
2058 add_option (_("Transport"), _ltc_volume_slider);
2062 add_option (_("Editor"),
2064 "rubberbanding-snaps-to-grid",
2065 _("Make rubberband selection rectangle snap to the grid"),
2066 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2067 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2070 bo = new BoolOption (
2072 _("Name new markers"),
2073 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2074 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2076 add_option (_("Editor"), bo);
2077 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."
2078 "\n\nYou can always rename markers by right-clicking on them"));
2080 add_option (S_("Editor"),
2082 "draggable-playhead",
2083 _("Allow dragging of playhead"),
2084 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2085 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2088 add_option (_("Editor"),
2090 "show-track-meters",
2091 _("Show meters on tracks in the editor"),
2092 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
2093 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
2096 add_option (_("Editor"),
2098 "show-editor-meter",
2099 _("Display master-meter in the toolbar"),
2100 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
2101 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
2104 if (!Profile->get_mixbus()) {
2105 add_option (_("Editor"),
2108 _("Show zoom toolbar (if torn off)"),
2109 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_zoom_tools),
2110 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_zoom_tools)
2113 add_option (_("Editor"),
2115 "use-mouse-position-as-zoom-focus-on-scroll",
2116 _("Always use mouse cursor position as zoom focus when zooming using mouse scroll wheel"),
2117 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2118 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2122 add_option (_("Editor"),
2124 "update-editor-during-summary-drag",
2125 _("Update editor window during drags of the summary"),
2126 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2127 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2130 add_option (_("Editor"),
2132 "autoscroll-editor",
2133 _("Auto-scroll editor window when dragging near its edges"),
2134 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2135 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2138 add_option (_("Editor"),
2139 new BoolComboOption (
2140 "show-region-gain-envelopes",
2141 _("Show gain envelopes in audio regions"),
2143 _("only in Draw and Internal Edit modes"),
2144 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2145 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2148 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2150 add_option (_("Editor"),
2152 "automation-follows-regions",
2153 _("Move relevant automation when audio regions are moved"),
2154 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2155 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2158 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2159 "default-fade-shape",
2160 _("Default fade shape"),
2161 sigc::mem_fun (*_rc_config,
2162 &RCConfiguration::get_default_fade_shape),
2163 sigc::mem_fun (*_rc_config,
2164 &RCConfiguration::set_default_fade_shape)
2167 fadeshape->add (FadeLinear,
2168 _("Linear (for highly correlated material)"));
2169 fadeshape->add (FadeConstantPower, _("Constant power"));
2170 fadeshape->add (FadeSymmetric, _("Symmetric"));
2171 fadeshape->add (FadeSlow, _("Slow"));
2172 fadeshape->add (FadeFast, _("Fast"));
2174 add_option (_("Editor"), fadeshape);
2177 bco = new BoolComboOption (
2178 "use-overlap-equivalency",
2179 _("Regions in active edit groups are edited together"),
2180 _("whenever they overlap in time"),
2181 _("only if they have identical length, position and origin"),
2182 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2183 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2186 add_option (_("Editor"), bco);
2188 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2190 _("Layering model"),
2191 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2192 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2195 lm->add (LaterHigher, _("later is higher"));
2196 lm->add (Manual, _("manual layering"));
2197 add_option (_("Editor"), lm);
2199 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2200 "region-selection-after-split",
2201 _("After splitting selected regions, select"),
2202 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2203 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2205 // TODO: decide which of these modes are really useful
2206 rsas->add(None, _("no regions"));
2207 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2208 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2209 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2210 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2211 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2212 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2213 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2215 add_option (_("Editor"), rsas);
2217 add_option (_("Editor"), new OptionEditorHeading (_("Waveforms")));
2219 if (!Profile->get_mixbus()) {
2220 add_option (_("Editor"),
2223 _("Show waveforms in regions"),
2224 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
2225 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
2229 add_option (_("Editor"),
2231 "show-waveforms-while-recording",
2232 _("Show waveforms for audio while it is being recorded"),
2233 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
2234 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
2237 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
2239 _("Waveform scale"),
2240 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
2241 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
2244 wfs->add (Linear, _("linear"));
2245 wfs->add (Logarithmic, _("logarithmic"));
2247 add_option (_("Editor"), wfs);
2249 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
2251 _("Waveform shape"),
2252 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
2253 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
2256 wfsh->add (Traditional, _("traditional"));
2257 wfsh->add (Rectified, _("rectified"));
2259 add_option (_("Editor"), wfsh);
2261 add_option (_("Editor"), new ClipLevelOptions ());
2266 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2268 add_option (_("Audio"), new BufferingOptions (_rc_config));
2270 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2272 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2274 _("Record monitoring handled by"),
2275 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2276 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2279 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2280 mm->add (HardwareMonitoring, _("via Audio Driver"));
2283 string prog (PROGRAM_NAME);
2284 boost::algorithm::to_lower (prog);
2285 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2286 mm->add (ExternalMonitoring, _("audio hardware"));
2288 add_option (_("Audio"), mm);
2290 add_option (_("Audio"),
2292 "tape-machine-mode",
2293 _("Tape machine mode"),
2294 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2295 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2298 if (!Profile->get_mixbus()) {
2299 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2301 add_option (_("Audio"),
2303 "auto-connect-standard-busses",
2304 _("Auto-connect master/monitor busses"),
2305 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2306 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2309 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2310 "input-auto-connect",
2311 _("Connect track inputs"),
2312 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2313 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2316 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2317 iac->add (ManualConnect, _("manually"));
2319 add_option (_("Audio"), iac);
2321 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2322 "output-auto-connect",
2323 _("Connect track and bus outputs"),
2324 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2325 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2328 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2329 oac->add (AutoConnectMaster, _("automatically to master bus"));
2330 oac->add (ManualConnect, _("manually"));
2332 add_option (_("Audio"), oac);
2335 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2337 add_option (_("Audio"),
2339 "denormal-protection",
2340 _("Use DC bias to protect against denormals"),
2341 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2342 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2345 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2347 _("Processor handling"),
2348 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2349 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2353 dm->add (DenormalNone, _("no processor handling"));
2355 FPU* fpu = FPU::instance();
2357 if (fpu->has_flush_to_zero()) {
2359 dm->add (DenormalFTZ, _("use FlushToZero"));
2360 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2361 _rc_config->set_denormal_model(DenormalNone);
2364 if (fpu->has_denormals_are_zero()) {
2366 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2367 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2368 _rc_config->set_denormal_model(DenormalNone);
2371 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2373 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2374 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2375 _rc_config->set_denormal_model(DenormalNone);
2379 dm->set_sensitive(false);
2382 add_option (_("Audio"), dm);
2384 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
2386 add_option (_("Audio"),
2388 "plugins-stop-with-transport",
2389 _("Silence plugins when the transport is stopped"),
2390 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
2391 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
2394 add_option (_("Audio"),
2396 "new-plugins-active",
2397 _("Make new plugins active"),
2398 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
2399 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
2402 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2404 add_option (_("Audio"),
2406 "auto-analyse-audio",
2407 _("Enable automatic analysis of audio"),
2408 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2409 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2412 add_option (_("Audio"),
2414 "replicate-missing-region-channels",
2415 _("Replicate missing region channels"),
2416 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2417 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2422 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
2424 _solo_control_is_listen_control = new BoolOption (
2425 "solo-control-is-listen-control",
2426 _("Solo controls are Listen controls"),
2427 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2428 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2431 add_option (_("Solo / mute"), _solo_control_is_listen_control);
2433 add_option (_("Solo / mute"),
2436 _("Exclusive solo"),
2437 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2438 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2441 add_option (_("Solo / mute"),
2444 _("Show solo muting"),
2445 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2446 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2449 add_option (_("Solo / mute"),
2451 "solo-mute-override",
2452 _("Soloing overrides muting"),
2453 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2454 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2457 add_option (_("Solo / mute"),
2460 _("Solo-in-place mute cut (dB)"),
2461 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2462 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2465 _listen_position = new ComboOption<ListenPosition> (
2467 _("Listen Position"),
2468 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2469 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2472 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2473 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2475 add_option (_("Solo / mute"), _listen_position);
2477 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2479 _("PFL signals come from"),
2480 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2481 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2484 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2485 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2487 add_option (_("Solo / mute"), pp);
2489 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2491 _("AFL signals come from"),
2492 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2493 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2496 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2497 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2499 add_option (_("Solo / mute"), pa);
2501 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2503 add_option (_("Solo / mute"),
2505 "mute-affects-pre-fader",
2506 _("Mute affects pre-fader sends"),
2507 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2508 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2511 add_option (_("Solo / mute"),
2513 "mute-affects-post-fader",
2514 _("Mute affects post-fader sends"),
2515 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2516 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2519 add_option (_("Solo / mute"),
2521 "mute-affects-control-outs",
2522 _("Mute affects control outputs"),
2523 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2524 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2527 add_option (_("Solo / mute"),
2529 "mute-affects-main-outs",
2530 _("Mute affects main outputs"),
2531 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2532 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2535 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
2537 add_option (_("Solo / mute"),
2539 "link-send-and-route-panner",
2540 _("Link panners of Aux and External Sends with main panner by default"),
2541 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2542 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2545 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Preferences")));
2547 add_option (_("MIDI"),
2548 new SpinOption<float> (
2550 _("MIDI read-ahead time (seconds)"),
2551 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2552 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2557 add_option (_("MIDI"),
2558 new SpinOption<int32_t> (
2559 "initial-program-change",
2560 _("Initial program change"),
2561 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2562 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2566 add_option (_("MIDI"),
2568 "display-first-midi-bank-as-zero",
2569 _("Display first MIDI bank/program as 0"),
2570 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2571 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2574 add_option (_("MIDI"),
2576 "never-display-periodic-midi",
2577 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2578 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
2579 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
2582 add_option (_("MIDI"),
2585 _("Sound MIDI notes as they are selected in the editor"),
2586 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2587 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2590 add_option (_("MIDI"),
2593 _("Send MIDI control feedback"),
2594 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2595 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2598 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Clock")));
2600 add_option (_("MIDI"),
2603 _("Send MIDI Clock"),
2604 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2605 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2608 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC)")));
2610 add_option (_("MIDI"),
2613 _("Send MIDI Time Code"),
2614 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2615 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2618 add_option (_("MIDI"),
2619 new SpinOption<int> (
2620 "mtc-qf-speed-tolerance",
2621 _("Percentage either side of normal transport speed to transmit MTC"),
2622 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2623 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2627 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Machine Control (MMC)")));
2629 add_option (_("MIDI"),
2632 _("Obey MIDI Machine Control commands"),
2633 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2634 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2637 add_option (_("MIDI"),
2640 _("Send MIDI Machine Control commands"),
2641 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2642 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2645 add_option (_("MIDI"),
2646 new SpinOption<uint8_t> (
2647 "mmc-receive-device-id",
2648 _("Inbound MMC device ID"),
2649 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2650 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2654 add_option (_("MIDI"),
2655 new SpinOption<uint8_t> (
2656 "mmc-send-device-id",
2657 _("Outbound MMC device ID"),
2658 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2659 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2663 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2665 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2666 "midi-audition-synth-uri",
2667 _("Midi Audition Synth (LV2)"),
2668 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2669 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2672 audition_synth->add(X_(""), _("None"));
2673 PluginInfoList all_plugs;
2674 PluginManager& manager (PluginManager::instance());
2676 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2678 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2679 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2680 if (!(*i)->is_instrument()) continue;
2681 if ((*i)->type != ARDOUR::LV2) continue;
2682 audition_synth->add((*i)->unique_id, (*i)->name);
2686 add_option (_("MIDI"), audition_synth);
2688 /* USER INTERACTION */
2691 #ifdef PLATFORM_WINDOWS
2694 getenv ("ARDOUR_BUNDLED")
2698 add_option (_("User interaction"),
2700 "enable-translation",
2701 string_compose (_("Use translations of %1 messages\n"
2702 " <i>(requires a restart of %1 to take effect)</i>\n"
2703 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2704 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2705 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2708 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2710 add_option (_("User interaction"), new KeyboardOptions);
2712 /* Control Surfaces */
2714 add_option (_("Control Surfaces"), new ControlSurfacesOptions);
2716 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2718 _("Control surface remote ID"),
2719 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2720 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2723 rm->add (UserOrdered, _("assigned by user"));
2724 rm->add (MixerOrdered, _("follows order of mixer"));
2726 add_option (_("Control Surfaces"), rm);
2728 /* VIDEO Timeline */
2729 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2731 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2732 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
2734 add_option (_("Plugins"),
2735 new RcActionButton (_("Scan for Plugins"),
2736 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
2738 bo = new BoolOption (
2739 "show-plugin-scan-window",
2740 _("Always Display Plugin Scan Progress"),
2741 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
2742 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
2744 add_option (_("Plugins"), bo);
2745 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2746 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
2750 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
2751 add_option (_("Plugins"), new OptionEditorHeading (_("VST")));
2753 bo = new BoolOption (
2754 "discover-vst-on-start",
2755 _("Scan for [new] VST Plugins on Application Start"),
2756 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
2757 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
2759 add_option (_("Plugins"), bo);
2760 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2761 _("<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"));
2763 #ifdef WINDOWS_VST_SUPPORT
2764 // currently verbose logging is only implemented for Windows VST.
2765 bo = new BoolOption (
2766 "verbose-plugin-scan",
2767 _("Verbose Plugin Scan"),
2768 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
2769 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
2771 add_option (_("Plugins"), bo);
2772 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2773 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
2776 add_option (_("Plugins"), new VstTimeOutSliderOption (_rc_config));
2778 add_option (_("Plugins"),
2779 new RcActionButton (_("Clear"),
2780 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
2783 add_option (_("Plugins"),
2784 new RcActionButton (_("Clear"),
2785 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
2786 _("VST Blacklist:")));
2789 #ifdef LXVST_SUPPORT
2790 add_option (_("Plugins"),
2791 new RcActionButton (_("Edit"),
2792 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
2793 _("Linux VST Path:")));
2795 add_option (_("Plugins"),
2796 new RcConfigDisplay (
2797 "plugin-path-lxvst",
2799 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
2803 #ifdef WINDOWS_VST_SUPPORT
2804 add_option (_("Plugins"),
2805 new RcActionButton (_("Edit"),
2806 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
2807 _("Windows VST Path:")));
2808 add_option (_("Plugins"),
2809 new RcConfigDisplay (
2812 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
2816 #ifdef AUDIOUNIT_SUPPORT
2817 add_option (_("Plugins"), new OptionEditorHeading (_("Audio Unit")));
2819 bo = new BoolOption (
2820 "discover-audio-units",
2821 _("Scan for AudioUnit Plugins on Application Start"),
2822 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
2823 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
2825 add_option (_("Plugins"), bo);
2826 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2827 _("<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."));
2829 add_option (_("Plugins"),
2830 new RcActionButton (_("Clear"),
2831 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
2834 add_option (_("Plugins"),
2835 new RcActionButton (_("Clear"),
2836 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
2837 _("AU Blacklist:")));
2840 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
2841 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
2842 add_option (_("Plugins"),
2844 "open-gui-after-adding-plugin",
2845 _("Automatically open the plugin GUI when adding a new plugin"),
2846 sigc::mem_fun (*_rc_config, &RCConfiguration::get_open_gui_after_adding_plugin),
2847 sigc::mem_fun (*_rc_config, &RCConfiguration::set_open_gui_after_adding_plugin)
2853 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
2854 BoolOption* bgc = new BoolOption (
2855 "cairo-image-surface",
2856 _("Disable Graphics Hardware Acceleration (requires restart)"),
2857 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
2858 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
2861 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
2862 _("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));
2863 add_option (S_("Preferences|GUI"), bgc);
2866 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
2867 BoolOption* bgo = new BoolOption (
2869 _("Possibly improve slow graphical performance (requires restart)"),
2870 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
2871 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
2874 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));
2875 add_option (S_("Preferences|GUI"), bgo);
2878 add_option (S_("Preferences|GUI"),
2881 _("Graphically indicate mouse pointer hovering over various widgets"),
2882 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
2883 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
2886 #ifdef TOOLTIPS_GOT_FIXED
2887 add_option (S_("Preferences|GUI"),
2890 _("Show tooltips if mouse hovers over a control"),
2891 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
2892 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
2896 add_option (S_("Preferences|GUI"),
2898 "show-name-highlight",
2899 _("Use name highlight bars in region displays (requires a restart)"),
2900 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
2901 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
2904 add_option (S_("GUI"),
2906 "super-rapid-clock-update",
2907 _("Update transport clock display at FPS instead of every 100ms"),
2908 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
2909 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
2914 /* font scaling does nothing with GDK/Quartz */
2915 add_option (S_("Preferences|GUI"), new FontScalingOptions ());
2918 /* Image cache size */
2920 Gtk::Adjustment *ics = manage (new Gtk::Adjustment(0, 1, 1024, 10)); /* 1 MB to 1GB in steps of 10MB */
2921 HSliderOption *sics = new HSliderOption("waveform-cache-size",
2922 _("Waveform image cache size (megabytes)"),
2924 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
2925 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size)
2927 sics->scale().set_digits (0);
2928 Gtkmm2ext::UI::instance()->set_tip
2929 (sics->tip_widget(),
2930 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
2931 add_option (S_("Preferences|GUI"), sics);
2933 if (!ARDOUR::Profile->get_mixbus()) {
2934 /* Lock GUI timeout */
2936 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
2937 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2938 _("Lock timeout (seconds)"),
2940 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
2941 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds)
2943 slts->scale().set_digits (0);
2944 Gtkmm2ext::UI::instance()->set_tip
2945 (slts->tip_widget(),
2946 _("Lock GUI after this many idle seconds (zero to never lock)"));
2947 add_option (S_("Preferences|GUI"), slts);
2950 /* The names of these controls must be the same as those given in MixerStrip
2951 for the actual widgets being controlled.
2953 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
2954 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2955 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
2956 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
2957 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
2958 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2961 S_("Preferences|GUI"),
2962 new VisibilityOption (
2964 &_mixer_strip_visibility,
2965 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
2966 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
2970 add_option (S_("Preferences|GUI"),
2972 "default-narrow_ms",
2973 _("Use narrow strips in the mixer by default"),
2974 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
2975 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
2978 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2980 ComboOption<float>* mht = new ComboOption<float> (
2982 _("Peak hold time"),
2983 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
2984 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
2987 mht->add (MeterHoldOff, _("off"));
2988 mht->add (MeterHoldShort, _("short"));
2989 mht->add (MeterHoldMedium, _("medium"));
2990 mht->add (MeterHoldLong, _("long"));
2992 add_option (S_("Preferences|Metering"), mht);
2994 ComboOption<float>* mfo = new ComboOption<float> (
2997 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2998 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
3001 mfo->add (METER_FALLOFF_OFF, _("off"));
3002 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
3003 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
3004 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
3005 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
3006 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
3007 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
3009 add_option (S_("Preferences|Metering"), mfo);
3011 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
3012 "meter-line-up-level",
3013 _("Meter line-up level; 0dBu"),
3014 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
3015 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
3018 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3019 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3020 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3021 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3023 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."));
3025 add_option (S_("Preferences|Metering"), mlu);
3027 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
3028 "meter-line-up-din",
3029 _("IEC1/DIN Meter line-up level; 0dBu"),
3030 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
3031 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
3034 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3035 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3036 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3037 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3039 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
3041 add_option (S_("Preferences|Metering"), mld);
3043 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
3044 "meter-vu-standard",
3045 _("VU Meter standard"),
3046 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
3047 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
3050 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
3051 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
3052 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
3053 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
3055 add_option (S_("Preferences|Metering"), mvu);
3057 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
3058 HSliderOption *mpks = new HSliderOption("meter-peak",
3059 _("Peak threshold [dBFS]"),
3061 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
3062 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak)
3066 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3067 "meter-type-master",
3068 _("Default Meter Type for Master Bus"),
3069 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3070 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3072 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3073 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3074 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3075 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3076 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3077 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3078 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3079 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3081 add_option (S_("Preferences|Metering"), mtm);
3084 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3086 _("Default Meter Type for Busses"),
3087 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3088 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3090 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3091 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3092 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3093 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3094 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3095 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3096 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3097 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3099 add_option (S_("Preferences|Metering"), mtb);
3101 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3103 _("Default Meter Type for Tracks"),
3104 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3105 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3107 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3108 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3110 add_option (S_("Preferences|Metering"), mtt);
3113 Gtkmm2ext::UI::instance()->set_tip
3114 (mpks->tip_widget(),
3115 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
3117 add_option (S_("Preferences|Metering"), mpks);
3119 add_option (S_("Preferences|Metering"),
3122 _("LED meter style"),
3123 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3124 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3127 /* and now the theme manager */
3129 ThemeManager* tm = manage (new ThemeManager);
3130 add_page (_("Theme"), *tm);
3132 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3133 parameter_changed ("send-ltc");
3134 parameter_changed ("sync-source");
3135 parameter_changed ("use-monitor-bus");
3139 RCOptionEditor::parameter_changed (string const & p)
3141 OptionEditor::parameter_changed (p);
3143 if (p == "use-monitor-bus") {
3144 bool const s = Config->get_use_monitor_bus ();
3146 /* we can't use this if we don't have a monitor bus */
3147 Config->set_solo_control_is_listen_control (false);
3149 _solo_control_is_listen_control->set_sensitive (s);
3150 _listen_position->set_sensitive (s);
3151 } else if (p == "sync-source") {
3152 _sync_source->set_sensitive (true);
3154 _sync_source->set_sensitive (!_session->config.get_external_sync());
3156 switch(Config->get_sync_source()) {
3159 _sync_genlock->set_sensitive (true);
3160 _sync_framerate->set_sensitive (true);
3161 _sync_source_2997->set_sensitive (true);
3164 _sync_genlock->set_sensitive (false);
3165 _sync_framerate->set_sensitive (false);
3166 _sync_source_2997->set_sensitive (false);
3169 } else if (p == "send-ltc") {
3170 bool const s = Config->get_send_ltc ();
3171 _ltc_send_continuously->set_sensitive (s);
3172 _ltc_volume_slider->set_sensitive (s);
3176 void RCOptionEditor::ltc_generator_volume_changed () {
3177 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
3180 void RCOptionEditor::plugin_scan_refresh () {
3181 PluginManager::instance().refresh();
3184 void RCOptionEditor::clear_vst_cache () {
3185 PluginManager::instance().clear_vst_cache();
3188 void RCOptionEditor::clear_vst_blacklist () {
3189 PluginManager::instance().clear_vst_blacklist();
3192 void RCOptionEditor::clear_au_cache () {
3193 PluginManager::instance().clear_au_cache();
3196 void RCOptionEditor::clear_au_blacklist () {
3197 PluginManager::instance().clear_au_blacklist();
3200 void RCOptionEditor::edit_lxvst_path () {
3201 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
3202 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3203 *this, _("Set Linux VST Search Path"),
3204 _rc_config->get_plugin_path_lxvst(),
3205 PluginManager::instance().get_default_lxvst_path()
3207 ResponseType r = (ResponseType) pd->run ();
3209 if (r == RESPONSE_ACCEPT) {
3210 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
3215 void RCOptionEditor::edit_vst_path () {
3216 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3217 *this, _("Set Windows VST Search Path"),
3218 _rc_config->get_plugin_path_vst(),
3219 PluginManager::instance().get_default_windows_vst_path()
3221 ResponseType r = (ResponseType) pd->run ();
3223 if (r == RESPONSE_ACCEPT) {
3224 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
3231 RCOptionEditor::populate_sync_options ()
3233 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3235 _sync_source->clear ();
3237 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3238 _sync_source->add (*i, sync_source_to_string (*i));
3241 if (sync_opts.empty()) {
3242 _sync_source->set_sensitive(false);
3244 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3245 _rc_config->set_sync_source(sync_opts.front());
3249 parameter_changed ("sync-source");
3253 RCOptionEditor::use_own_window (bool and_fill_it)
3255 bool new_window = !own_window();
3257 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
3259 if (win && new_window) {
3260 win->set_name ("PreferencesWindow");
3261 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);