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>
46 #include "ardour/audio_backend.h"
47 #include "ardour/audioengine.h"
48 #include "ardour/profile.h"
49 #include "ardour/dB.h"
50 #include "ardour/rc_configuration.h"
51 #include "ardour/control_protocol_manager.h"
52 #include "ardour/port_manager.h"
53 #include "ardour/plugin_manager.h"
54 #include "control_protocol/control_protocol.h"
56 #include "canvas/wave_view.h"
58 #include "ardour_dialog.h"
59 #include "ardour_ui.h"
60 #include "ardour_window.h"
61 #include "color_theme_manager.h"
62 #include "gui_thread.h"
64 #include "meter_patterns.h"
65 #include "midi_tracer.h"
66 #include "rc_option_editor.h"
68 #include "theme_manager.h"
70 #include "ui_config.h"
75 using namespace Gtkmm2ext;
77 using namespace ARDOUR;
78 using namespace ARDOUR_UI_UTILS;
80 class ClickOptions : public OptionEditorMiniPage
83 ClickOptions (RCConfiguration* c)
85 , _click_browse_button (_("Browse..."))
86 , _click_emphasis_browse_button (_("Browse..."))
90 Label* l = manage (left_aligned_label (_("Emphasis on first beat:")));
91 _use_emphasis_on_click_check_button.add (*l);
92 t->attach (_use_emphasis_on_click_check_button, 1, 3, 0, 1, FILL);
93 _use_emphasis_on_click_check_button.signal_toggled().connect (
94 sigc::mem_fun (*this, &ClickOptions::use_emphasis_on_click_toggled));
96 l = manage (left_aligned_label (_("Use built-in default sounds:")));
97 _use_default_click_check_button.add (*l);
98 t->attach (_use_default_click_check_button, 1, 3, 1, 2, FILL);
99 _use_default_click_check_button.signal_toggled().connect (
100 sigc::mem_fun (*this, &ClickOptions::use_default_click_toggled));
102 l = manage (left_aligned_label (_("Audio file:")));
103 t->attach (*l, 1, 2, 2, 3, FILL);
104 t->attach (_click_path_entry, 2, 3, 2, 3, FILL);
105 _click_browse_button.signal_clicked ().connect (
106 sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
107 t->attach (_click_browse_button, 3, 4, 2, 3, FILL);
109 l = manage (left_aligned_label (_("Emphasis audio file:")));
110 t->attach (*l, 1, 2, 3, 4, FILL);
111 t->attach (_click_emphasis_path_entry, 2, 3, 3, 4, FILL);
112 _click_emphasis_browse_button.signal_clicked ().connect (
113 sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
114 t->attach (_click_emphasis_browse_button, 3, 4, 3, 4, FILL);
116 FaderOption* fo = new FaderOption (
119 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
120 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
123 fo->add_to_page (this);
124 fo->set_state_from_config ();
126 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
127 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
129 if (_rc_config->get_click_sound ().empty() &&
130 _rc_config->get_click_emphasis_sound().empty()) {
131 _use_default_click_check_button.set_active (true);
132 _use_emphasis_on_click_check_button.set_active (true);
135 _use_default_click_check_button.set_active (false);
136 _use_emphasis_on_click_check_button.set_active (false);
140 void parameter_changed (string const & p)
142 if (p == "click-sound") {
143 _click_path_entry.set_text (_rc_config->get_click_sound());
144 } else if (p == "click-emphasis-sound") {
145 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
146 } else if (p == "use-click-emphasis") {
147 bool x = _rc_config->get_use_click_emphasis ();
148 _use_emphasis_on_click_check_button.set_active (x);
152 void set_state_from_config ()
154 parameter_changed ("click-sound");
155 parameter_changed ("click-emphasis-sound");
156 parameter_changed ("use-click-emphasis");
161 void click_browse_clicked ()
163 SoundFileChooser sfdb (_("Choose Click"));
168 if (sfdb.run () == RESPONSE_OK) {
169 click_chosen (sfdb.get_filename());
173 void click_chosen (string const & path)
175 _click_path_entry.set_text (path);
176 _rc_config->set_click_sound (path);
179 void click_changed ()
181 click_chosen (_click_path_entry.get_text ());
184 void click_emphasis_browse_clicked ()
186 SoundFileChooser sfdb (_("Choose Click Emphasis"));
191 if (sfdb.run () == RESPONSE_OK) {
192 click_emphasis_chosen (sfdb.get_filename());
196 void click_emphasis_chosen (string const & path)
198 _click_emphasis_path_entry.set_text (path);
199 _rc_config->set_click_emphasis_sound (path);
202 void click_emphasis_changed ()
204 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
207 void use_default_click_toggled ()
209 if (_use_default_click_check_button.get_active ()) {
210 _rc_config->set_click_sound ("");
211 _rc_config->set_click_emphasis_sound ("");
212 _click_path_entry.set_sensitive (false);
213 _click_emphasis_path_entry.set_sensitive (false);
214 _click_browse_button.set_sensitive (false);
215 _click_emphasis_browse_button.set_sensitive (false);
217 _click_path_entry.set_sensitive (true);
218 _click_emphasis_path_entry.set_sensitive (true);
219 _click_browse_button.set_sensitive (true);
220 _click_emphasis_browse_button.set_sensitive (true);
224 void use_emphasis_on_click_toggled ()
226 if (_use_emphasis_on_click_check_button.get_active ()) {
227 _rc_config->set_use_click_emphasis(true);
229 _rc_config->set_use_click_emphasis(false);
233 RCConfiguration* _rc_config;
234 CheckButton _use_default_click_check_button;
235 CheckButton _use_emphasis_on_click_check_button;
236 Entry _click_path_entry;
237 Entry _click_emphasis_path_entry;
238 Button _click_browse_button;
239 Button _click_emphasis_browse_button;
242 class UndoOptions : public OptionEditorComponent
245 UndoOptions (RCConfiguration* c) :
247 _limit_undo_button (_("Limit undo history to")),
248 _save_undo_button (_("Save undo history of"))
250 _limit_undo_spin.set_range (0, 512);
251 _limit_undo_spin.set_increments (1, 10);
253 _save_undo_spin.set_range (0, 512);
254 _save_undo_spin.set_increments (1, 10);
256 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
257 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
258 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
259 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
262 void parameter_changed (string const & p)
264 if (p == "history-depth") {
265 int32_t const d = _rc_config->get_history_depth();
266 _limit_undo_button.set_active (d != 0);
267 _limit_undo_spin.set_sensitive (d != 0);
268 _limit_undo_spin.set_value (d);
269 } else if (p == "save-history") {
270 bool const x = _rc_config->get_save_history ();
271 _save_undo_button.set_active (x);
272 _save_undo_spin.set_sensitive (x);
273 } else if (p == "save-history-depth") {
274 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
278 void set_state_from_config ()
280 parameter_changed ("save-history");
281 parameter_changed ("history-depth");
282 parameter_changed ("save-history-depth");
285 void limit_undo_toggled ()
287 bool const x = _limit_undo_button.get_active ();
288 _limit_undo_spin.set_sensitive (x);
289 int32_t const n = x ? 16 : 0;
290 _limit_undo_spin.set_value (n);
291 _rc_config->set_history_depth (n);
294 void limit_undo_changed ()
296 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
299 void save_undo_toggled ()
301 bool const x = _save_undo_button.get_active ();
302 _rc_config->set_save_history (x);
305 void save_undo_changed ()
307 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
310 void add_to_page (OptionEditorPage* p)
312 int const n = p->table.property_n_rows();
313 Table* t = & p->table;
315 t->resize (n + 2, 3);
317 Label* l = manage (left_aligned_label (_("commands")));
318 HBox* box = manage (new HBox());
319 box->set_spacing (4);
320 box->pack_start (_limit_undo_spin, false, false);
321 box->pack_start (*l, true, true);
322 t->attach (_limit_undo_button, 1, 2, n, n +1, FILL);
323 t->attach (*box, 2, 3, n, n + 1, FILL | EXPAND);
325 l = manage (left_aligned_label (_("commands")));
326 box = manage (new HBox());
327 box->set_spacing (4);
328 box->pack_start (_save_undo_spin, false, false);
329 box->pack_start (*l, true, true);
330 t->attach (_save_undo_button, 1, 2, n + 1, n + 2, FILL);
331 t->attach (*box, 2, 3, n + 1, n + 2, FILL | EXPAND);
334 Gtk::Widget& tip_widget() {
335 return _limit_undo_button; // unused
339 RCConfiguration* _rc_config;
340 CheckButton _limit_undo_button;
341 SpinButton _limit_undo_spin;
342 CheckButton _save_undo_button;
343 SpinButton _save_undo_spin;
347 static const struct {
359 { "Key|Shift", GDK_SHIFT_MASK },
360 { "Command", GDK_MOD2_MASK },
361 { "Control", GDK_CONTROL_MASK },
362 { "Option", GDK_MOD1_MASK },
363 { "Command-Shift", GDK_MOD2_MASK|GDK_SHIFT_MASK },
364 { "Command-Option", GDK_MOD2_MASK|GDK_MOD1_MASK },
365 { "Command-Control", GDK_MOD2_MASK|GDK_CONTROL_MASK },
366 { "Command-Option-Control", GDK_MOD2_MASK|GDK_MOD1_MASK|GDK_CONTROL_MASK },
367 { "Option-Control", GDK_MOD1_MASK|GDK_CONTROL_MASK },
368 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
369 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
370 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_MOD2_MASK },
373 { "Key|Shift", GDK_SHIFT_MASK },
374 { "Control", GDK_CONTROL_MASK },
375 { "Alt", GDK_MOD1_MASK },
376 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
377 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
378 { "Control-Windows", GDK_CONTROL_MASK|GDK_MOD4_MASK },
379 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
380 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
381 { "Alt-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
382 { "Alt-Shift-Windows", GDK_MOD1_MASK|GDK_SHIFT_MASK|GDK_MOD4_MASK },
383 { "Mod2", GDK_MOD2_MASK },
384 { "Mod3", GDK_MOD3_MASK },
385 { "Windows", GDK_MOD4_MASK },
386 { "Mod5", GDK_MOD5_MASK },
392 class KeyboardOptions : public OptionEditorMiniPage
396 _delete_button_adjustment (3, 1, 12),
397 _delete_button_spin (_delete_button_adjustment),
398 _edit_button_adjustment (3, 1, 5),
399 _edit_button_spin (_edit_button_adjustment),
400 _insert_note_button_adjustment (3, 1, 5),
401 _insert_note_button_spin (_insert_note_button_adjustment)
403 const std::string restart_msg = _("\nChanges to this setting will only persist after your project has been saved.");
404 /* internationalize and prepare for use with combos */
407 for (int i = 0; modifiers[i].name; ++i) {
408 dumb.push_back (S_(modifiers[i].name));
411 set_popdown_strings (_edit_modifier_combo, dumb);
412 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
413 Gtkmm2ext::UI::instance()->set_tip (_edit_modifier_combo,
414 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
415 for (int x = 0; modifiers[x].name; ++x) {
416 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
417 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
427 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
428 l->set_name ("OptionsLabel");
432 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
433 strs.push_back (bf->first);
436 set_popdown_strings (_keyboard_layout_selector, strs);
437 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
438 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
440 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
441 t->attach (_keyboard_layout_selector, col + 2, col + 3, row, row + 1, FILL | EXPAND, FILL);
446 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Clicking:"))));
447 l->set_name ("OptionEditorHeading");
448 l->set_use_markup (true);
449 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
454 l = manage (left_aligned_label (_("Edit using:")));
455 l->set_name ("OptionsLabel");
457 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
458 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
460 l = manage (new Label (_("+ button")));
461 l->set_name ("OptionsLabel");
463 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
464 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
466 _edit_button_spin.set_name ("OptionsEntry");
467 _edit_button_adjustment.set_value (Keyboard::edit_button());
468 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
473 set_popdown_strings (_delete_modifier_combo, dumb);
474 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
475 Gtkmm2ext::UI::instance()->set_tip (_delete_modifier_combo,
476 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
477 for (int x = 0; modifiers[x].name; ++x) {
478 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
479 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
484 l = manage (left_aligned_label (_("Delete using:")));
485 l->set_name ("OptionsLabel");
487 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
488 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
490 l = manage (new Label (_("+ button")));
491 l->set_name ("OptionsLabel");
493 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
494 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
496 _delete_button_spin.set_name ("OptionsEntry");
497 _delete_button_adjustment.set_value (Keyboard::delete_button());
498 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
503 set_popdown_strings (_insert_note_modifier_combo, dumb);
504 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
505 Gtkmm2ext::UI::instance()->set_tip (_insert_note_modifier_combo,
506 (string_compose (_("<b>Recommended Setting: %1 + button 1 (left mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
507 for (int x = 0; modifiers[x].name; ++x) {
508 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
509 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
514 l = manage (left_aligned_label (_("Insert note using:")));
515 l->set_name ("OptionsLabel");
517 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
518 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
520 l = manage (new Label (_("+ button")));
521 l->set_name ("OptionsLabel");
523 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
524 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
526 _insert_note_button_spin.set_name ("OptionsEntry");
527 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
528 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
532 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Beginning a Drag:"))));
533 l->set_name ("OptionEditorHeading");
534 l->set_use_markup (true);
535 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
541 set_popdown_strings (_copy_modifier_combo, dumb);
542 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
543 Gtkmm2ext::UI::instance()->set_tip (_copy_modifier_combo,
544 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
546 Keyboard::secondary_modifier_name (),
548 Keyboard::primary_modifier_name (),
551 for (int x = 0; modifiers[x].name; ++x) {
552 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
553 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
558 l = manage (left_aligned_label (_("Copy items using:")));
559 l->set_name ("OptionsLabel");
561 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
562 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
567 /* constraint modifier */
568 set_popdown_strings (_constraint_modifier_combo, dumb);
569 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
570 std::string mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
571 Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo,
572 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
574 Keyboard::primary_modifier_name (),
576 Keyboard::tertiary_modifier_name (),
579 for (int x = 0; modifiers[x].name; ++x) {
580 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
581 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
586 l = manage (left_aligned_label (_("Constrain drag using:")));
587 l->set_name ("OptionsLabel");
589 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
590 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
596 set_popdown_strings (_push_points_combo, dumb);
597 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
599 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
600 Gtkmm2ext::UI::instance()->set_tip (_push_points_combo,
601 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
602 for (int x = 0; modifiers[x].name; ++x) {
603 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
604 _push_points_combo.set_active_text (S_(modifiers[x].name));
609 l = manage (left_aligned_label (_("Push points using:")));
610 l->set_name ("OptionsLabel");
612 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
613 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
617 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Beginning a Trim:"))));
618 l->set_name ("OptionEditorHeading");
619 l->set_use_markup (true);
620 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
626 set_popdown_strings (_trim_contents_combo, dumb);
627 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
628 Gtkmm2ext::UI::instance()->set_tip (_trim_contents_combo,
629 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
630 for (int x = 0; modifiers[x].name; ++x) {
631 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
632 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
637 l = manage (left_aligned_label (_("Trim contents using:")));
638 l->set_name ("OptionsLabel");
640 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
641 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
647 set_popdown_strings (_trim_anchored_combo, dumb);
648 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
650 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::tertiary_modifier_name ());
651 Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo,
652 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
653 for (int x = 0; modifiers[x].name; ++x) {
654 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
655 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
660 l = manage (left_aligned_label (_("Anchored trim using:")));
661 l->set_name ("OptionsLabel");
663 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
665 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
670 /* jump trim disabled for now
671 set_popdown_strings (_trim_jump_combo, dumb);
672 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
674 for (int x = 0; modifiers[x].name; ++x) {
675 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
676 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
681 l = manage (left_aligned_label (_("Jump after trim using:")));
682 l->set_name ("OptionsLabel");
684 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
686 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
692 /* note resize relative */
693 set_popdown_strings (_note_size_relative_combo, dumb);
694 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
695 Gtkmm2ext::UI::instance()->set_tip (_note_size_relative_combo,
696 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
697 for (int x = 0; modifiers[x].name; ++x) {
698 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
699 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
704 l = manage (left_aligned_label (_("Resize notes relatively using:")));
705 l->set_name ("OptionsLabel");
707 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
709 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
713 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Dragging:"))));
714 l->set_name ("OptionEditorHeading");
715 l->set_use_markup (true);
716 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
722 set_popdown_strings (_snap_modifier_combo, dumb);
723 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
725 mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ());
727 mod_str = Keyboard::secondary_modifier_name();
729 Gtkmm2ext::UI::instance()->set_tip (_snap_modifier_combo,
730 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
731 for (int x = 0; modifiers[x].name; ++x) {
732 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
733 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
738 l = manage (left_aligned_label (_("Ignore snap using:")));
739 l->set_name ("OptionsLabel");
741 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
742 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
748 set_popdown_strings (_snap_delta_combo, dumb);
749 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
751 mod_str = Keyboard::level4_modifier_name ();
753 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::level4_modifier_name ());
755 Gtkmm2ext::UI::instance()->set_tip (_snap_delta_combo,
756 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
757 for (int x = 0; modifiers[x].name; ++x) {
758 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
759 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
764 l = manage (left_aligned_label (_("Snap relatively using:")));
765 l->set_name ("OptionsLabel");
767 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
768 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
772 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Trimming:"))));
773 l->set_name ("OptionEditorHeading");
774 l->set_use_markup (true);
775 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
781 set_popdown_strings (_trim_overlap_combo, dumb);
782 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
784 Gtkmm2ext::UI::instance()->set_tip (_trim_overlap_combo,
785 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
786 for (int x = 0; modifiers[x].name; ++x) {
787 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
788 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
793 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
794 l->set_name ("OptionsLabel");
796 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
797 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
801 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Dragging Control Points:"))));
802 l->set_name ("OptionEditorHeading");
803 l->set_use_markup (true);
804 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
810 set_popdown_strings (_fine_adjust_combo, dumb);
811 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
813 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::secondary_modifier_name ());
814 Gtkmm2ext::UI::instance()->set_tip (_fine_adjust_combo,
815 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
816 for (int x = 0; modifiers[x].name; ++x) {
817 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
818 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
823 l = manage (left_aligned_label (_("Fine adjust using:")));
824 l->set_name ("OptionsLabel");
826 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
827 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
830 void parameter_changed (string const &)
832 /* XXX: these aren't really config options... */
835 void set_state_from_config ()
837 /* XXX: these aren't really config options... */
840 void add_to_page (OptionEditorPage* p)
842 int const n = p->table.property_n_rows();
843 p->table.resize (n + 1, 3);
844 p->table.attach (box, 1, 3, n, n + 1, FILL | EXPAND, SHRINK, 0, 0);
849 void bindings_changed ()
851 string const txt = _keyboard_layout_selector.get_active_text();
853 /* XXX: config...? for all this keyboard stuff */
855 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
856 if (txt == i->first) {
857 if (Keyboard::load_keybindings (i->second)) {
858 Keyboard::save_keybindings ();
864 void edit_modifier_chosen ()
866 string const txt = _edit_modifier_combo.get_active_text();
868 for (int i = 0; modifiers[i].name; ++i) {
869 if (txt == S_(modifiers[i].name)) {
870 Keyboard::set_edit_modifier (modifiers[i].modifier);
876 void delete_modifier_chosen ()
878 string const txt = _delete_modifier_combo.get_active_text();
880 for (int i = 0; modifiers[i].name; ++i) {
881 if (txt == S_(modifiers[i].name)) {
882 Keyboard::set_delete_modifier (modifiers[i].modifier);
888 void copy_modifier_chosen ()
890 string const txt = _copy_modifier_combo.get_active_text();
892 for (int i = 0; modifiers[i].name; ++i) {
893 if (txt == S_(modifiers[i].name)) {
894 Keyboard::set_copy_modifier (modifiers[i].modifier);
900 void insert_note_modifier_chosen ()
902 string const txt = _insert_note_modifier_combo.get_active_text();
904 for (int i = 0; modifiers[i].name; ++i) {
905 if (txt == S_(modifiers[i].name)) {
906 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
912 void snap_modifier_chosen ()
914 string const txt = _snap_modifier_combo.get_active_text();
916 for (int i = 0; modifiers[i].name; ++i) {
917 if (txt == S_(modifiers[i].name)) {
918 Keyboard::set_snap_modifier (modifiers[i].modifier);
924 void snap_delta_modifier_chosen ()
926 string const txt = _snap_delta_combo.get_active_text();
928 for (int i = 0; modifiers[i].name; ++i) {
929 if (txt == S_(modifiers[i].name)) {
930 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
936 void constraint_modifier_chosen ()
938 string const txt = _constraint_modifier_combo.get_active_text();
940 for (int i = 0; modifiers[i].name; ++i) {
941 if (txt == S_(modifiers[i].name)) {
942 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
948 void trim_contents_modifier_chosen ()
950 string const txt = _trim_contents_combo.get_active_text();
952 for (int i = 0; modifiers[i].name; ++i) {
953 if (txt == S_(modifiers[i].name)) {
954 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
960 void trim_overlap_modifier_chosen ()
962 string const txt = _trim_overlap_combo.get_active_text();
964 for (int i = 0; modifiers[i].name; ++i) {
965 if (txt == S_(modifiers[i].name)) {
966 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
972 void trim_anchored_modifier_chosen ()
974 string const txt = _trim_anchored_combo.get_active_text();
976 for (int i = 0; modifiers[i].name; ++i) {
977 if (txt == S_(modifiers[i].name)) {
978 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
984 void fine_adjust_modifier_chosen ()
986 string const txt = _fine_adjust_combo.get_active_text();
988 for (int i = 0; modifiers[i].name; ++i) {
989 if (txt == S_(modifiers[i].name)) {
990 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
996 void push_points_modifier_chosen ()
998 string const txt = _push_points_combo.get_active_text();
1000 for (int i = 0; modifiers[i].name; ++i) {
1001 if (txt == S_(modifiers[i].name)) {
1002 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
1008 void note_size_relative_modifier_chosen ()
1010 string const txt = _note_size_relative_combo.get_active_text();
1012 for (int i = 0; modifiers[i].name; ++i) {
1013 if (txt == S_(modifiers[i].name)) {
1014 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
1020 void delete_button_changed ()
1022 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
1025 void edit_button_changed ()
1027 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
1030 void insert_note_button_changed ()
1032 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
1035 ComboBoxText _keyboard_layout_selector;
1036 ComboBoxText _edit_modifier_combo;
1037 ComboBoxText _delete_modifier_combo;
1038 ComboBoxText _copy_modifier_combo;
1039 ComboBoxText _insert_note_modifier_combo;
1040 ComboBoxText _snap_modifier_combo;
1041 ComboBoxText _snap_delta_combo;
1042 ComboBoxText _constraint_modifier_combo;
1043 ComboBoxText _trim_contents_combo;
1044 ComboBoxText _trim_overlap_combo;
1045 ComboBoxText _trim_anchored_combo;
1046 ComboBoxText _trim_jump_combo;
1047 ComboBoxText _fine_adjust_combo;
1048 ComboBoxText _push_points_combo;
1049 ComboBoxText _note_size_relative_combo;
1050 Adjustment _delete_button_adjustment;
1051 SpinButton _delete_button_spin;
1052 Adjustment _edit_button_adjustment;
1053 SpinButton _edit_button_spin;
1054 Adjustment _insert_note_button_adjustment;
1055 SpinButton _insert_note_button_spin;
1059 class FontScalingOptions : public HSliderOption
1062 FontScalingOptions ()
1063 : HSliderOption ("font-scale", _("GUI and Font scaling"),
1064 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_font_scale),
1065 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_font_scale),
1069 const std::string dflt = _("100%");
1070 const std::string empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
1072 _hscale.set_name("FontScaleSlider");
1073 _hscale.set_draw_value(false);
1074 _hscale.add_mark(50, Gtk::POS_TOP, empty);
1075 _hscale.add_mark(60, Gtk::POS_TOP, empty);
1076 _hscale.add_mark(70, Gtk::POS_TOP, empty);
1077 _hscale.add_mark(80, Gtk::POS_TOP, empty);
1078 _hscale.add_mark(90, Gtk::POS_TOP, empty);
1079 _hscale.add_mark(100, Gtk::POS_TOP, dflt);
1080 _hscale.add_mark(125, Gtk::POS_TOP, empty);
1081 _hscale.add_mark(150, Gtk::POS_TOP, empty);
1082 _hscale.add_mark(175, Gtk::POS_TOP, empty);
1083 _hscale.add_mark(200, Gtk::POS_TOP, empty);
1084 _hscale.add_mark(250, Gtk::POS_TOP, empty);
1086 set_note (_("Adjusting the scale requires an application restart to re-layout."));
1091 HSliderOption::changed ();
1092 /* XXX: should be triggered from the parameter changed signal */
1093 UIConfiguration::instance().reset_dpi ();
1097 class VstTimeOutSliderOption : public HSliderOption
1100 VstTimeOutSliderOption (RCConfiguration* c)
1101 : HSliderOption ("vst-scan-timeout", _("Scan Time Out"),
1102 sigc::mem_fun (*c, &RCConfiguration::get_vst_scan_timeout),
1103 sigc::mem_fun (*c, &RCConfiguration::set_vst_scan_timeout),
1106 _label.set_alignment (1.0, 0.5); // match buttons below
1107 _hscale.set_digits (0);
1108 _hscale.set_draw_value(false);
1109 _hscale.add_mark( 0, Gtk::POS_TOP, _("\u221e")); // infinity
1110 _hscale.add_mark( 300, Gtk::POS_TOP, _("30 sec"));
1111 _hscale.add_mark( 600, Gtk::POS_TOP, _("1 min"));
1112 _hscale.add_mark(1200, Gtk::POS_TOP, _("2 mins"));
1113 _hscale.add_mark(1800, Gtk::POS_TOP, _("3 mins"));
1114 _hscale.add_mark(2400, Gtk::POS_TOP, _("4 mins"));
1115 _hscale.add_mark(3000, Gtk::POS_TOP, _("5 mins"));
1117 Gtkmm2ext::UI::instance()->set_tip(_hscale,
1118 _("Specify the default timeout for plugin instantiation. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1122 class ClipLevelOptions : public OptionEditorComponent
1126 : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1127 , _clip_level_slider (_clip_level_adjustment)
1128 , _label (_("Waveform Clip Level (dBFS):"))
1130 _label.set_name ("OptionsLabel");
1132 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ());
1134 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1136 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1139 void parameter_changed (string const & p)
1141 if (p == "waveform-clip-level") {
1142 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level());
1144 if (p == "show-waveform-clipping") {
1145 _clip_level_slider.set_sensitive (UIConfiguration::instance().get_show_waveform_clipping ());
1149 void set_state_from_config ()
1151 parameter_changed ("waveform-clip-level");
1152 parameter_changed ("show-waveform-clipping");
1155 void add_to_page (OptionEditorPage* p) {
1156 add_widgets_to_page (p, &_label, &_clip_level_slider);
1159 Gtk::Widget& tip_widget() {
1160 return _clip_level_slider;
1165 void clip_level_changed ()
1167 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1168 /* XXX: should be triggered from the parameter changed signal */
1169 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1172 Adjustment _clip_level_adjustment;
1173 HScale _clip_level_slider;
1177 class BufferingOptions : public OptionEditorComponent
1180 BufferingOptions (RCConfiguration* c)
1182 , _label (_("Preset:"))
1183 , _playback ("playback-buffer-seconds", _("Playback (seconds of buffering)"),
1184 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_playback_buffer_seconds),
1185 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_playback_buffer_seconds),
1187 , _capture ("capture-buffer-seconds", _("Recording (seconds of buffering)"),
1188 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_capture_buffer_seconds),
1189 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_capture_buffer_seconds),
1192 // TODO use ComboOption
1193 vector<string> presets;
1195 /* these must match the order of the enums for BufferingPreset */
1196 presets.push_back (_("Small sessions (4-16 tracks)"));
1197 presets.push_back (_("Medium sessions (16-64 tracks)"));
1198 presets.push_back (_("Large sessions (64+ tracks)"));
1199 presets.push_back (_("Custom (set by sliders below)"));
1201 set_popdown_strings (_buffering_presets_combo, presets);
1202 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1204 _label.set_name ("OptionsLabel");
1205 _label.set_alignment (0, 0.5);
1209 add_to_page (OptionEditorPage* p)
1211 add_widgets_to_page (p, &_label, &_buffering_presets_combo);
1212 _playback.add_to_page (p);
1213 _capture.add_to_page (p);
1216 void parameter_changed (string const & p)
1218 if (p == "buffering-preset") {
1219 switch (_rc_config->get_buffering_preset()) {
1221 _playback.set_sensitive (false);
1222 _capture.set_sensitive (false);
1223 _buffering_presets_combo.set_active (0);
1226 _playback.set_sensitive (false);
1227 _capture.set_sensitive (false);
1228 _buffering_presets_combo.set_active (1);
1231 _playback.set_sensitive (false);
1232 _capture.set_sensitive (false);
1233 _buffering_presets_combo.set_active (2);
1236 _playback.set_sensitive (true);
1237 _capture.set_sensitive (true);
1238 _buffering_presets_combo.set_active (3);
1242 _playback.parameter_changed (p);
1243 _capture.parameter_changed (p);
1246 void set_state_from_config ()
1248 parameter_changed ("buffering-preset");
1249 _playback.set_state_from_config();
1250 _capture.set_state_from_config();
1253 Gtk::Widget& tip_widget() { return _buffering_presets_combo; }
1257 void preset_changed ()
1259 int index = _buffering_presets_combo.get_active_row_number ();
1265 _rc_config->set_buffering_preset (Small);
1268 _rc_config->set_buffering_preset (Medium);
1271 _rc_config->set_buffering_preset (Large);
1274 _rc_config->set_buffering_preset (Custom);
1277 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1282 RCConfiguration* _rc_config;
1284 HSliderOption _playback;
1285 HSliderOption _capture;
1286 ComboBoxText _buffering_presets_combo;
1289 class ControlSurfacesOptions : public OptionEditorMiniPage
1292 ControlSurfacesOptions ()
1293 : _ignore_view_change (0)
1295 _store = ListStore::create (_model);
1296 _view.set_model (_store);
1297 _view.append_column (_("Control Surface Protocol"), _model.name);
1298 _view.get_column(0)->set_resizable (true);
1299 _view.get_column(0)->set_expand (true);
1300 _view.append_column_editable (_("Enable"), _model.enabled);
1302 Gtk::HBox* edit_box = manage (new Gtk::HBox);
1303 edit_box->set_spacing(3);
1306 Label* label = manage (new Label);
1307 label->set_text (_("Edit the settings for selected protocol (it must be ENABLED first):"));
1308 edit_box->pack_start (*label, false, false);
1311 edit_button = manage (new Button(_("Show Protocol Settings")));
1312 edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
1313 edit_box->pack_start (*edit_button, true, true);
1314 edit_button->set_sensitive (false);
1315 edit_button->show ();
1317 int const n = table.property_n_rows();
1318 table.resize (n + 2, 3);
1319 table.attach (_view, 0, 3, n, n + 1);
1320 table.attach (*edit_box, 0, 3, n + 1, n + 2);
1322 ControlProtocolManager& m = ControlProtocolManager::instance ();
1323 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1324 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1326 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1327 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1328 _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
1331 void parameter_changed (std::string const &)
1336 void set_state_from_config ()
1340 ControlProtocolManager& m = ControlProtocolManager::instance ();
1341 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1343 if (!(*i)->mandatory) {
1344 TreeModel::Row r = *_store->append ();
1345 r[_model.name] = (*i)->name;
1346 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1347 r[_model.protocol_info] = *i;
1354 void protocol_status_changed (ControlProtocolInfo* cpi) {
1356 TreeModel::Children rows = _store->children();
1358 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1359 string n = ((*x)[_model.name]);
1361 if ((*x)[_model.protocol_info] == cpi) {
1362 _ignore_view_change++;
1363 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1364 _ignore_view_change--;
1370 void selection_changed ()
1372 //enable the Edit button when a row is selected for editing
1373 TreeModel::Row row = *(_view.get_selection()->get_selected());
1374 if (row && row[_model.enabled])
1375 edit_button->set_sensitive (true);
1377 edit_button->set_sensitive (false);
1380 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1382 TreeModel::Row r = *i;
1384 if (_ignore_view_change) {
1388 ControlProtocolInfo* cpi = r[_model.protocol_info];
1393 bool const was_enabled = (cpi->protocol != 0);
1394 bool const is_enabled = r[_model.enabled];
1397 if (was_enabled != is_enabled) {
1400 ControlProtocolManager::instance().activate (*cpi);
1402 ControlProtocolManager::instance().deactivate (*cpi);
1406 selection_changed ();
1409 void edit_btn_clicked ()
1412 ControlProtocolInfo* cpi;
1415 row = *(_view.get_selection()->get_selected());
1416 if (!row[_model.enabled]) {
1419 cpi = row[_model.protocol_info];
1420 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1423 Box* box = (Box*) cpi->protocol->get_gui ();
1427 if (box->get_parent()) {
1428 static_cast<ArdourWindow*>(box->get_parent())->present();
1431 WindowTitle title (Glib::get_application_name());
1432 title += row[_model.name];
1433 title += _("Configuration");
1434 /* once created, the window is managed by the surface itself (as ->get_parent())
1435 * Surface's tear_down_gui() is called on session close, when de-activating
1436 * or re-initializing a surface.
1437 * tear_down_gui() hides an deletes the Window if it exists.
1439 ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
1440 win->set_title ("Control Protocol Options");
1446 void edit_clicked (GdkEventButton* ev)
1448 if (ev->type != GDK_2BUTTON_PRESS) {
1455 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1459 ControlSurfacesModelColumns ()
1463 add (protocol_info);
1466 TreeModelColumn<string> name;
1467 TreeModelColumn<bool> enabled;
1468 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1471 Glib::RefPtr<ListStore> _store;
1472 ControlSurfacesModelColumns _model;
1474 PBD::ScopedConnection protocol_status_connection;
1475 uint32_t _ignore_view_change;
1476 Gtk::Button* edit_button;
1479 class VideoTimelineOptions : public OptionEditorMiniPage
1482 VideoTimelineOptions (RCConfiguration* c)
1484 , _show_video_export_info_button (_("Show Video Export Info before export"))
1485 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1486 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1487 , _xjadeo_browse_button (_("Browse..."))
1490 int n = table.property_n_rows();
1492 t->attach (_show_video_export_info_button, 1, 4, n, n + 1);
1493 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1494 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1495 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1498 t->attach (_show_video_server_dialog_button, 1, 4, n, n + 1);
1499 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1500 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1501 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1504 t->attach (_video_advanced_setup_button, 1, 4, n, n + 1, FILL);
1505 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1506 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1507 _("<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."));
1510 Label* l = manage (new Label (_("Video Server URL:")));
1511 l->set_alignment (0, 0.5);
1512 t->attach (*l, 1, 2, n, n + 1, FILL);
1513 t->attach (_video_server_url_entry, 2, 4, n, n + 1, FILL);
1514 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1515 _("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"));
1518 l = manage (new Label (_("Video Folder:")));
1519 l->set_alignment (0, 0.5);
1520 t->attach (*l, 1, 2, n, n + 1, FILL);
1521 t->attach (_video_server_docroot_entry, 2, 4, n, n + 1);
1522 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1523 _("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."));
1526 l = manage (new Label (""));
1527 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1530 l = manage (new Label (string_compose ("<b>%1</b>", _("Video Monitor"))));
1531 l->set_use_markup (true);
1532 l->set_alignment (0, 0.5);
1533 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1536 l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"),
1539 #elif defined PLATFORM_WINDOWS
1545 l->set_alignment (0, 0.5);
1546 t->attach (*l, 1, 4, n, n + 1, FILL);
1549 t->attach (_custom_xjadeo_path, 2, 3, n, n + 1, EXPAND|FILL);
1550 Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart."));
1551 t->attach (_xjadeo_browse_button, 3, 4, n, n + 1, FILL);
1553 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1554 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1555 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1556 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1557 _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed));
1558 _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked));
1560 // xjadeo-path is a UIConfig parameter
1561 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &VideoTimelineOptions::parameter_changed));
1564 void server_url_changed ()
1566 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1569 void server_docroot_changed ()
1571 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1574 void show_video_export_info_toggled ()
1576 bool const x = _show_video_export_info_button.get_active ();
1577 _rc_config->set_show_video_export_info (x);
1580 void show_video_server_dialog_toggled ()
1582 bool const x = _show_video_server_dialog_button.get_active ();
1583 _rc_config->set_show_video_server_dialog (x);
1586 void video_advanced_setup_toggled ()
1588 bool const x = _video_advanced_setup_button.get_active ();
1589 _rc_config->set_video_advanced_setup(x);
1592 void custom_xjadeo_path_changed ()
1594 UIConfiguration::instance().set_xjadeo_binary (_custom_xjadeo_path.get_text());
1597 void xjadeo_browse_clicked ()
1599 Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN);
1600 dialog.set_filename (UIConfiguration::instance().get_xjadeo_binary());
1601 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1602 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1603 if (dialog.run () == Gtk::RESPONSE_OK) {
1604 const std::string& filename = dialog.get_filename();
1605 if (!filename.empty() && (
1607 Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) ||
1609 Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)
1611 UIConfiguration::instance().set_xjadeo_binary (filename);
1616 void parameter_changed (string const & p)
1618 if (p == "video-server-url") {
1619 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1620 } else if (p == "video-server-docroot") {
1621 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1622 } else if (p == "show-video-export-info") {
1623 bool const x = _rc_config->get_show_video_export_info();
1624 _show_video_export_info_button.set_active (x);
1625 } else if (p == "show-video-server-dialog") {
1626 bool const x = _rc_config->get_show_video_server_dialog();
1627 _show_video_server_dialog_button.set_active (x);
1628 } else if (p == "video-advanced-setup") {
1629 bool const x = _rc_config->get_video_advanced_setup();
1630 _video_advanced_setup_button.set_active(x);
1631 _video_server_docroot_entry.set_sensitive(x);
1632 _video_server_url_entry.set_sensitive(x);
1633 } else if (p == "xjadeo-binary") {
1634 _custom_xjadeo_path.set_text (UIConfiguration::instance().get_xjadeo_binary());
1638 void set_state_from_config ()
1640 parameter_changed ("video-server-url");
1641 parameter_changed ("video-server-docroot");
1642 parameter_changed ("video-monitor-setup-dialog");
1643 parameter_changed ("show-video-export-info");
1644 parameter_changed ("show-video-server-dialog");
1645 parameter_changed ("video-advanced-setup");
1646 parameter_changed ("xjadeo-binary");
1650 RCConfiguration* _rc_config;
1651 Entry _video_server_url_entry;
1652 Entry _video_server_docroot_entry;
1653 Entry _custom_xjadeo_path;
1654 CheckButton _show_video_export_info_button;
1655 CheckButton _show_video_server_dialog_button;
1656 CheckButton _video_advanced_setup_button;
1657 Button _xjadeo_browse_button;
1660 class ColumVisibilityOption : public Option
1663 ColumVisibilityOption (string id, string name, uint32_t n_col, sigc::slot<uint32_t> get, sigc::slot<bool, uint32_t> set)
1670 cb = (CheckButton**) malloc (sizeof (CheckButton*) * n_col);
1671 for (uint32_t i = 0; i < n_col; ++i) {
1672 CheckButton* col = manage (new CheckButton (string_compose (_("Column %1"), i + 1)));
1673 col->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ColumVisibilityOption::column_toggled), i));
1674 _hbox.pack_start (*col);
1677 parameter_changed (id);
1680 ~ColumVisibilityOption () {
1684 Gtk::Widget& tip_widget() { return _hbox; }
1686 void set_state_from_config ()
1688 uint32_t c = _get();
1689 for (uint32_t i = 0; i < _n_col; ++i) {
1690 bool en = (c & (1<<i)) ? true : false;
1691 if (cb[i]->get_active () != en) {
1692 cb[i]->set_active (en);
1697 void add_to_page (OptionEditorPage* p)
1699 _heading.add_to_page (p);
1700 add_widget_to_page (p, &_hbox);
1704 void column_toggled (int b) {
1705 uint32_t c = _get();
1707 if (cb[b]->get_active ()) {
1718 OptionEditorHeading _heading;
1722 sigc::slot<uint32_t> _get;
1723 sigc::slot<bool, uint32_t> _set;
1727 /** A class which allows control of visibility of some editor components usign
1728 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1729 * which has the correct members, but with null widget pointers. This
1730 * class allows the user to set visibility of the members, the details
1731 * of which are stored in a configuration variable which can be watched
1732 * by parts of the editor that actually contain the widgets whose visibility
1733 * is being controlled.
1736 class VisibilityOption : public Option
1739 /** @param name User-visible name for this group.
1740 * @param g `Dummy' VisibilityGroup (as described above).
1741 * @param get Method to get the value of the appropriate configuration variable.
1742 * @param set Method to set the value of the appropriate configuration variable.
1744 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1745 : Option (g->get_state_name(), name)
1747 , _visibility_group (g)
1751 /* Watch for changes made by the user to our members */
1752 _visibility_group->VisibilityChanged.connect_same_thread (
1753 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1757 void set_state_from_config ()
1759 /* Set our state from the current configuration */
1760 _visibility_group->set_state (_get ());
1763 void add_to_page (OptionEditorPage* p)
1765 _heading.add_to_page (p);
1766 add_widget_to_page (p, _visibility_group->list_view ());
1769 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1774 /* The user has changed something, so reflect this change
1775 in the RCConfiguration.
1777 _set (_visibility_group->get_state_value ());
1780 OptionEditorHeading _heading;
1781 VisibilityGroup* _visibility_group;
1782 sigc::slot<std::string> _get;
1783 sigc::slot<bool, std::string> _set;
1784 PBD::ScopedConnection _visibility_group_connection;
1788 class MidiPortOptions : public OptionEditorMiniPage, public sigc::trackable
1793 setup_midi_port_view (midi_output_view, false);
1794 setup_midi_port_view (midi_input_view, true);
1796 OptionEditorHeading* h = new OptionEditorHeading (_("MIDI Inputs"));
1797 h->add_to_page (this);
1799 Gtk::ScrolledWindow* scroller = manage (new Gtk::ScrolledWindow);
1800 scroller->add (midi_input_view);
1801 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1802 scroller->set_size_request (-1, 180);
1804 int n = table.property_n_rows();
1805 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1807 h = new OptionEditorHeading (_("MIDI Outputs"));
1808 h->add_to_page (this);
1810 scroller = manage (new Gtk::ScrolledWindow);
1811 scroller->add (midi_output_view);
1812 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1813 scroller->set_size_request (-1, 180);
1815 n = table.property_n_rows();
1816 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1818 midi_output_view.show ();
1819 midi_input_view.show ();
1821 table.signal_show().connect (sigc::mem_fun (*this, &MidiPortOptions::on_show));
1824 void parameter_changed (string const&) {}
1825 void set_state_from_config() {}
1830 AudioEngine::instance()->PortRegisteredOrUnregistered.connect (connections,
1831 invalidator (*this),
1832 boost::bind (&MidiPortOptions::refill, this),
1834 AudioEngine::instance()->MidiPortInfoChanged.connect (connections,
1835 invalidator (*this),
1836 boost::bind (&MidiPortOptions::refill, this),
1838 AudioEngine::instance()->MidiSelectionPortsChanged.connect (connections,
1839 invalidator (*this),
1840 boost::bind (&MidiPortOptions::refill, this),
1846 if (refill_midi_ports (true, midi_input_view)) {
1847 input_label.show ();
1849 input_label.hide ();
1851 if (refill_midi_ports (false, midi_output_view)) {
1852 output_label.show ();
1854 output_label.hide ();
1859 PBD::ScopedConnectionList connections;
1861 /* MIDI port management */
1862 struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord {
1864 MidiPortColumns () {
1873 Gtk::TreeModelColumn<std::string> pretty_name;
1874 Gtk::TreeModelColumn<bool> music_data;
1875 Gtk::TreeModelColumn<bool> control_data;
1876 Gtk::TreeModelColumn<bool> selection;
1877 Gtk::TreeModelColumn<std::string> name;
1878 Gtk::TreeModelColumn<std::string> filler;
1881 MidiPortColumns midi_port_columns;
1882 Gtk::TreeView midi_input_view;
1883 Gtk::TreeView midi_output_view;
1884 Gtk::Label input_label;
1885 Gtk::Label output_label;
1887 void setup_midi_port_view (Gtk::TreeView&, bool with_selection);
1888 bool refill_midi_ports (bool for_input, Gtk::TreeView&);
1889 void pretty_name_edit (std::string const & path, std::string const & new_text, Gtk::TreeView*);
1890 void midi_music_column_toggled (std::string const & path, Gtk::TreeView*);
1891 void midi_control_column_toggled (std::string const & path, Gtk::TreeView*);
1892 void midi_selection_column_toggled (std::string const & path, Gtk::TreeView*);
1896 MidiPortOptions::setup_midi_port_view (Gtk::TreeView& view, bool with_selection)
1898 int pretty_name_column;
1901 int selection_column;
1902 TreeViewColumn* col;
1905 pretty_name_column = view.append_column_editable (_("Name (click to edit)"), midi_port_columns.pretty_name) - 1;
1907 col = manage (new TreeViewColumn ("", midi_port_columns.music_data));
1908 col->set_alignment (ALIGN_CENTER);
1909 l = manage (new Label (_("Music Data")));
1910 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of music performance data."), PROGRAM_NAME));
1911 col->set_widget (*l);
1913 music_column = view.append_column (*col) - 1;
1915 col = manage (new TreeViewColumn ("", midi_port_columns.control_data));
1916 col->set_alignment (ALIGN_CENTER);
1917 l = manage (new Label (_("Control Data")));
1918 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of control data."), PROGRAM_NAME));
1919 col->set_widget (*l);
1921 control_column = view.append_column (*col) - 1;
1923 if (with_selection) {
1924 col = manage (new TreeViewColumn (_("Follow Selection"), midi_port_columns.selection));
1925 selection_column = view.append_column (*col) - 1;
1926 l = manage (new Label (_("Follow Selection")));
1927 set_tooltip (*l, string_compose (_("If ticked, and \"MIDI input follows selection\" is enabled,\n%1 will automatically connect the first selected MIDI track to this port.\n"), PROGRAM_NAME));
1928 col->set_widget (*l);
1932 /* filler column so that the last real column doesn't expand */
1933 view.append_column ("", midi_port_columns.filler);
1935 CellRendererText* pretty_name_cell = dynamic_cast<CellRendererText*> (view.get_column_cell_renderer (pretty_name_column));
1936 pretty_name_cell->property_editable() = true;
1937 pretty_name_cell->signal_edited().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::pretty_name_edit), &view));
1939 CellRendererToggle* toggle_cell;
1941 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (music_column));
1942 toggle_cell->property_activatable() = true;
1943 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_music_column_toggled), &view));
1945 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (control_column));
1946 toggle_cell->property_activatable() = true;
1947 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_control_column_toggled), &view));
1949 if (with_selection) {
1950 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (selection_column));
1951 toggle_cell->property_activatable() = true;
1952 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_selection_column_toggled), &view));
1955 view.get_selection()->set_mode (SELECTION_NONE);
1956 view.set_tooltip_column (4); /* port "real" name */
1957 view.get_column(0)->set_resizable (true);
1958 view.get_column(0)->set_expand (true);
1962 MidiPortOptions::refill_midi_ports (bool for_input, Gtk::TreeView& view)
1964 using namespace ARDOUR;
1966 std::vector<string> ports;
1968 AudioEngine::instance()->get_known_midi_ports (ports);
1970 if (ports.empty()) {
1975 Glib::RefPtr<ListStore> model = Gtk::ListStore::create (midi_port_columns);
1977 for (vector<string>::const_iterator s = ports.begin(); s != ports.end(); ++s) {
1979 if (AudioEngine::instance()->port_is_mine (*s)) {
1983 PortManager::MidiPortInformation mpi (AudioEngine::instance()->midi_port_information (*s));
1985 if (mpi.pretty_name.empty()) {
1986 /* vanished since get_known_midi_ports() */
1990 if (for_input != mpi.input) {
1994 TreeModel::Row row = *(model->append());
1996 row[midi_port_columns.pretty_name] = mpi.pretty_name;
1997 row[midi_port_columns.music_data] = mpi.properties & MidiPortMusic;
1998 row[midi_port_columns.control_data] = mpi.properties & MidiPortControl;
1999 row[midi_port_columns.selection] = mpi.properties & MidiPortSelection;
2000 row[midi_port_columns.name] = *s;
2003 view.set_model (model);
2009 MidiPortOptions::midi_music_column_toggled (string const & path, TreeView* view)
2011 TreeIter iter = view->get_model()->get_iter (path);
2017 bool new_value = ! bool ((*iter)[midi_port_columns.music_data]);
2019 /* don't reset model - wait for MidiPortInfoChanged signal */
2022 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2024 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2029 MidiPortOptions::midi_control_column_toggled (string const & path, TreeView* view)
2031 TreeIter iter = view->get_model()->get_iter (path);
2037 bool new_value = ! bool ((*iter)[midi_port_columns.control_data]);
2039 /* don't reset model - wait for MidiPortInfoChanged signal */
2042 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2044 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2049 MidiPortOptions::midi_selection_column_toggled (string const & path, TreeView* view)
2051 TreeIter iter = view->get_model()->get_iter (path);
2057 bool new_value = ! bool ((*iter)[midi_port_columns.selection]);
2059 /* don't reset model - wait for MidiSelectionPortsChanged signal */
2062 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2064 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2069 MidiPortOptions::pretty_name_edit (std::string const & path, string const & new_text, Gtk::TreeView* view)
2071 TreeIter iter = view->get_model()->get_iter (path);
2077 boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
2079 ARDOUR::PortEngine::PortHandle ph = backend->get_port_by_name ((*iter)[midi_port_columns.name]);
2081 backend->set_port_property (ph, "http://jackaudio.org/metadata/pretty-name", new_text, "");
2082 (*iter)[midi_port_columns.pretty_name] = new_text;
2090 RCOptionEditor::RCOptionEditor ()
2091 : OptionEditorContainer (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
2092 , Tabbable (*this, _("Preferences")) /* pack self-as-vbox into tabbable */
2093 , _rc_config (Config)
2094 , _mixer_strip_visibility ("mixer-element-visibility")
2096 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
2100 uint32_t hwcpus = hardware_concurrency ();
2102 BoolComboOption* bco;
2105 add_option (_("General"), new OptionEditorHeading (_("DSP CPU Utilization")));
2107 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
2109 _("Signal processing uses"),
2110 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
2111 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
2114 procs->add (-1, _("all but one processor"));
2115 procs->add (0, _("all available processors"));
2117 for (uint32_t i = 1; i <= hwcpus; ++i) {
2118 procs->add (i, string_compose (P_("%1 processor", "%1 processors", i), i));
2121 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
2123 add_option (_("General"), procs);
2126 add_option (_("General"), new OptionEditorHeading (S_("Options|Undo")));
2128 add_option (_("General"), new UndoOptions (_rc_config));
2130 add_option (_("General"),
2132 "verify-remove-last-capture",
2133 _("Verify removal of last capture"),
2134 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
2135 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
2138 add_option (_("General"), new OptionEditorHeading (_("Session Management")));
2140 add_option (_("General"),
2142 "periodic-safety-backups",
2143 _("Make periodic backups of the session file"),
2144 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
2145 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
2148 add_option (_("General"),
2150 "only-copy-imported-files",
2151 _("Always copy imported files"),
2152 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
2153 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
2156 add_option (_("General"), new DirectoryOption (
2157 X_("default-session-parent-dir"),
2158 _("Default folder for new sessions:"),
2159 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
2160 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
2163 add_option (_("General"),
2164 new SpinOption<uint32_t> (
2165 "max-recent-sessions",
2166 _("Maximum number of recent sessions"),
2167 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
2168 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
2172 add_option (_("General"), new OptionEditorHeading (_("Automation")));
2174 add_option (_("General"),
2175 new SpinOption<double> (
2176 "automation-thinning-factor",
2177 _("Thinning factor (larger value => less data)"),
2178 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
2179 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
2183 add_option (_("General"),
2184 new SpinOption<double> (
2185 "automation-interval-msecs",
2186 _("Automation sampling interval (milliseconds)"),
2187 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
2188 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
2192 add_option (_("General"), new OptionEditorHeading (_("Tempo")));
2196 tsf = new BoolOption (
2197 "allow-non-quarter-pulse",
2198 _("Allow non quarter-note pulse"),
2199 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_allow_non_quarter_pulse),
2200 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_allow_non_quarter_pulse)
2202 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2203 string_compose (_("<b>When enabled</b> %1 will allow tempo to be expressed in divisions per minute\n"
2204 "<b>When disabled</b> %1 will only allow tempo to be expressed in quarter notes per minute"),
2206 add_option (_("General"), tsf);
2210 add_option (_("General/Translation"), new OptionEditorHeading (_("Internationalization")));
2212 bo = new BoolOption (
2213 "enable-translation",
2214 _("Use translations"),
2215 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2216 sigc::ptr_fun (ARDOUR::set_translations_enabled)
2219 bo->set_note (string_compose (_("These settings will only take effect after %1 is restarted (if available for your language preferences)."), PROGRAM_NAME));
2221 add_option (_("General/Translation"), bo);
2223 _l10n = new ComboOption<ARDOUR::LocaleMode> (
2226 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_locale_mode),
2227 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_locale_mode)
2230 _l10n->add (ARDOUR::SET_LC_ALL, _("Set complete locale"));
2231 _l10n->add (ARDOUR::SET_LC_MESSAGES, _("Enable only message translation"));
2232 _l10n->add (ARDOUR::SET_LC_MESSAGES_AND_LC_NUMERIC, _("Translate messages and format numeric format"));
2233 _l10n->set_note (_("This setting is provided for plugin compatibility. e.g. some plugins on some systems expect the decimal point to be a dot."));
2235 add_option (_("General/Translation"), _l10n);
2236 parameter_changed ("enable-translation");
2237 #endif // ENABLE_NLS
2242 add_option (_("Editor"), new OptionEditorHeading (_("General")));
2244 add_option (_("Editor"),
2246 "rubberbanding-snaps-to-grid",
2247 _("Snap rubberband to grid"),
2248 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2249 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2252 bo = new BoolOption (
2254 _("Prompt for a new marker name"),
2255 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2256 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2258 add_option (_("Editor"), bo);
2259 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."
2260 "\n\nYou can always rename markers by right-clicking on them"));
2262 add_option (_("Editor"),
2264 "draggable-playhead",
2265 _("Allow dragging of playhead"),
2266 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2267 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2270 if (!Profile->get_mixbus()) {
2271 add_option (_("Editor"),
2274 _("Show zoom toolbar (if torn off)"),
2275 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_zoom_tools),
2276 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_zoom_tools)
2279 add_option (_("Editor"),
2281 "use-mouse-position-as-zoom-focus-on-scroll",
2282 _("Zoom to mouse position when zooming with scroll wheel"),
2283 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2284 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2288 add_option (_("Editor"),
2290 "use-time-rulers-to-zoom-with-vertical-drag",
2291 _("Zoom with vertical drag in rulers"),
2292 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag),
2293 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag)
2296 add_option (_("Editor"),
2298 "use-double-click-to-zoom-to-selection",
2299 _("Double click zooms to selection"),
2300 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection),
2301 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection)
2304 add_option (_("Editor"),
2306 "update-editor-during-summary-drag",
2307 _("Update editor window during drags of the summary"),
2308 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2309 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2312 add_option (_("Editor"),
2314 "autoscroll-editor",
2315 _("Auto-scroll editor window when dragging near its edges"),
2316 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2317 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2320 add_option (_("Editor"),
2321 new BoolComboOption (
2322 "show-region-gain-envelopes",
2323 _("Show gain envelopes in audio regions"),
2325 _("only in Draw and Internal Edit modes"),
2326 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2327 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2330 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2332 add_option (_("Editor"),
2334 "automation-follows-regions",
2335 _("Move relevant automation when audio regions are moved"),
2336 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2337 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2340 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2341 "default-fade-shape",
2342 _("Default fade shape"),
2343 sigc::mem_fun (*_rc_config,
2344 &RCConfiguration::get_default_fade_shape),
2345 sigc::mem_fun (*_rc_config,
2346 &RCConfiguration::set_default_fade_shape)
2349 fadeshape->add (FadeLinear,
2350 _("Linear (for highly correlated material)"));
2351 fadeshape->add (FadeConstantPower, _("Constant power"));
2352 fadeshape->add (FadeSymmetric, _("Symmetric"));
2353 fadeshape->add (FadeSlow, _("Slow"));
2354 fadeshape->add (FadeFast, _("Fast"));
2356 add_option (_("Editor"), fadeshape);
2358 bco = new BoolComboOption (
2359 "use-overlap-equivalency",
2360 _("Regions in edit groups are edited together"),
2361 _("whenever they overlap in time"),
2362 _("only if they have identical length and position"),
2363 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2364 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2367 add_option (_("Editor"), bco);
2369 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2371 _("Layering model"),
2372 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2373 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2376 lm->add (LaterHigher, _("later is higher"));
2377 lm->add (Manual, _("manual layering"));
2378 add_option (_("Editor"), lm);
2380 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2381 "region-selection-after-split",
2382 _("After splitting selected regions, select"),
2383 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2384 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2386 // TODO: decide which of these modes are really useful
2387 rsas->add(None, _("no regions"));
2388 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2389 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2390 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2391 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2392 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2393 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2394 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2396 add_option (_("Editor"), rsas);
2398 add_option (_("Editor/Modifiers"), new OptionEditorHeading (_("Modifiers")));
2399 add_option (_("Editor/Modifiers"), new KeyboardOptions);
2401 /* MIXER -- SOLO AND MUTE */
2403 add_option (_("Mixer"), new OptionEditorHeading (_("Solo")));
2405 _solo_control_is_listen_control = new BoolOption (
2406 "solo-control-is-listen-control",
2407 _("Solo controls are Listen controls"),
2408 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2409 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2412 add_option (_("Mixer"), _solo_control_is_listen_control);
2414 add_option (_("Mixer"),
2417 _("Exclusive solo"),
2418 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2419 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2422 add_option (_("Mixer"),
2425 _("Show solo muting"),
2426 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2427 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2430 add_option (_("Mixer"),
2432 "solo-mute-override",
2433 _("Soloing overrides muting"),
2434 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2435 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2438 add_option (_("Mixer"),
2441 _("Solo-in-place mute cut (dB)"),
2442 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2443 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2446 _listen_position = new ComboOption<ListenPosition> (
2448 _("Listen Position"),
2449 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2450 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2453 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2454 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2456 add_option (_("Mixer"), _listen_position);
2458 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2460 _("PFL signals come from"),
2461 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2462 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2465 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2466 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2468 add_option (_("Mixer"), pp);
2470 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2472 _("AFL signals come from"),
2473 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2474 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2477 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2478 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2480 add_option (_("Mixer"), pa);
2482 add_option (_("Mixer"), new OptionEditorHeading (_("Default track / bus muting options")));
2484 add_option (_("Mixer"),
2486 "mute-affects-pre-fader",
2487 _("Mute affects pre-fader sends"),
2488 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2489 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2492 add_option (_("Mixer"),
2494 "mute-affects-post-fader",
2495 _("Mute affects post-fader sends"),
2496 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2497 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2500 add_option (_("Mixer"),
2502 "mute-affects-control-outs",
2503 _("Mute affects control outputs"),
2504 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2505 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2508 add_option (_("Mixer"),
2510 "mute-affects-main-outs",
2511 _("Mute affects main outputs"),
2512 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2513 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2517 if (!ARDOUR::Profile->get_mixbus()) {
2518 add_option (_("Mixer"), new OptionEditorHeading (_("Send Routing")));
2519 add_option (_("Mixer"),
2521 "link-send-and-route-panner",
2522 _("Link panners of Aux and External Sends with main panner by default"),
2523 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2524 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2531 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2533 add_option (_("Audio"), new BufferingOptions (_rc_config));
2535 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2537 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2539 _("Record monitoring handled by"),
2540 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2541 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2544 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2545 mm->add (HardwareMonitoring, _("via Audio Driver"));
2548 string prog (PROGRAM_NAME);
2549 boost::algorithm::to_lower (prog);
2550 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2551 mm->add (ExternalMonitoring, _("audio hardware"));
2553 add_option (_("Audio"), mm);
2555 add_option (_("Audio"),
2557 "tape-machine-mode",
2558 _("Tape machine mode"),
2559 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2560 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2563 add_option (_("Audio"), new OptionEditorHeading (_("Track and Bus Connections")));
2564 if (!Profile->get_mixbus()) {
2566 add_option (_("Audio"),
2568 "auto-connect-standard-busses",
2569 _("Auto-connect master/monitor busses"),
2570 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2571 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2574 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2575 "input-auto-connect",
2576 _("Connect track inputs"),
2577 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2578 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2581 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2582 iac->add (ManualConnect, _("manually"));
2584 add_option (_("Audio"), iac);
2586 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2587 "output-auto-connect",
2588 _("Connect track and bus outputs"),
2589 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2590 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2593 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2594 oac->add (AutoConnectMaster, _("automatically to master bus"));
2595 oac->add (ManualConnect, _("manually"));
2597 add_option (_("Audio"), oac);
2599 bo = new BoolOption (
2601 _("Use 'Strict-I/O' for new tracks or Busses"),
2602 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2603 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2606 add_option (_("Audio"), bo);
2607 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2608 _("With strict-i/o enabled, Effect Processors will not modify the number of channels on a track. The number of output channels will always match the number of input channels."));
2612 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2614 add_option (_("Audio"),
2616 "denormal-protection",
2617 _("Use DC bias to protect against denormals"),
2618 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2619 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2622 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2624 _("Processor handling"),
2625 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2626 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2630 dm->add (DenormalNone, _("no processor handling"));
2632 FPU* fpu = FPU::instance();
2634 if (fpu->has_flush_to_zero()) {
2636 dm->add (DenormalFTZ, _("use FlushToZero"));
2637 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2638 _rc_config->set_denormal_model(DenormalNone);
2641 if (fpu->has_denormals_are_zero()) {
2643 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2644 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2645 _rc_config->set_denormal_model(DenormalNone);
2648 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2650 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2651 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2652 _rc_config->set_denormal_model(DenormalNone);
2656 dm->set_sensitive(false);
2659 add_option (_("Audio"), dm);
2661 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2663 add_option (_("Audio"),
2665 "auto-analyse-audio",
2666 _("Enable automatic analysis of audio"),
2667 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2668 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2671 add_option (_("Audio"),
2673 "replicate-missing-region-channels",
2674 _("Replicate missing region channels"),
2675 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2676 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2681 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Preferences")));
2683 add_option (_("MIDI"),
2684 new SpinOption<float> (
2686 _("MIDI read-ahead time (seconds)"),
2687 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2688 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2693 add_option (_("MIDI"),
2694 new SpinOption<int32_t> (
2695 "initial-program-change",
2696 _("Initial program change"),
2697 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2698 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2702 add_option (_("MIDI"),
2704 "display-first-midi-bank-as-zero",
2705 _("Display first MIDI bank/program as 0"),
2706 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2707 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2710 add_option (_("MIDI"),
2712 "never-display-periodic-midi",
2713 _("Don't display periodic (MTC, MMC) SysEx messages in MIDI Regions"),
2714 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
2715 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
2718 add_option (_("MIDI"),
2721 _("Sound MIDI notes as they are selected in the editor"),
2722 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2723 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2726 add_option (_("MIDI"),
2729 _("Send MIDI control feedback"),
2730 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2731 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2734 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Audition")));
2736 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2737 "midi-audition-synth-uri",
2738 _("MIDI Audition Synth (LV2)"),
2739 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2740 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2743 audition_synth->add(X_(""), _("None"));
2744 PluginInfoList all_plugs;
2745 PluginManager& manager (PluginManager::instance());
2747 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2749 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2750 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2751 if (!(*i)->is_instrument()) continue;
2752 if ((*i)->type != ARDOUR::LV2) continue;
2753 if ((*i)->name.length() > 46) {
2754 audition_synth->add((*i)->unique_id, (*i)->name.substr (0, 44) + "...");
2756 audition_synth->add((*i)->unique_id, (*i)->name);
2761 add_option (_("MIDI"), audition_synth);
2765 add_option (_("Metronome"), new OptionEditorHeading (_("Metronome")));
2766 add_option (_("Metronome"), new ClickOptions (_rc_config));
2769 /* TRANSPORT & Sync */
2771 add_option (_("Transport"), new OptionEditorHeading (_("General")));
2773 tsf = new BoolOption (
2774 "stop-at-session-end",
2775 _("Stop at the end of the session"),
2776 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
2777 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
2779 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2780 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
2781 "when it reaches the current session end marker\n\n"
2782 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
2784 add_option (_("Transport"), tsf);
2786 tsf = new BoolOption (
2787 "latched-record-enable",
2788 _("Keep record-enable engaged on stop"),
2789 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
2790 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
2792 add_option (_("Transport"), tsf);
2794 tsf = new BoolOption (
2795 "disable-disarm-during-roll",
2796 _("Disable per-track record disarm while rolling"),
2797 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
2798 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
2800 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"));
2801 add_option (_("Transport"), tsf);
2803 tsf = new BoolOption (
2805 _("12dB gain reduction during fast-forward and fast-rewind"),
2806 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
2807 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2809 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
2810 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2811 add_option (_("Transport"), tsf);
2813 ComboOption<float>* psc = new ComboOption<float> (
2816 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
2817 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
2819 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
2820 (_("The amount of preroll (in seconds) to apply when <b>Play with Preroll</b> is initiated.\n\n"
2821 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
2822 psc->add (0.0, _("0 (no pre-roll)"));
2823 psc->add (0.1, _("0.1 second"));
2824 psc->add (0.25, _("0.25 second"));
2825 psc->add (0.5, _("0.5 second"));
2826 psc->add (1.0, _("1.0 second"));
2827 psc->add (2.0, _("2.0 seconds"));
2828 add_option (_("Transport"), psc);
2831 add_option (_("Transport"), new OptionEditorHeading (_("Looping")));
2833 tsf = new BoolOption (
2835 _("Play loop is a transport mode"),
2836 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
2837 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
2839 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2840 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
2841 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
2842 add_option (_("Transport"), tsf);
2844 tsf = new BoolOption (
2846 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
2847 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
2848 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
2850 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2851 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
2852 "preventing any need to do a transport locate at the end of the loop\n\n"
2853 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
2854 "which will often cause a small click or delay"), PROGRAM_NAME));
2855 add_option (_("Transport"), tsf);
2857 add_option (_("Transport"), new OptionEditorHeading (_("Dropout (xrun) handling")));
2858 tsf = new BoolOption (
2859 "stop-recording-on-xrun",
2860 _("Stop recording when an xrun occurs"),
2861 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
2862 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
2864 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2865 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
2867 add_option (_("Transport"), tsf);
2869 tsf = new BoolOption (
2870 "create-xrun-marker",
2871 _("Create markers where xruns occur"),
2872 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
2873 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
2875 add_option (_("Transport"), tsf);
2877 add_option (_("Sync"), new OptionEditorHeading (_("Synchronization and Slave Options")));
2879 _sync_source = new ComboOption<SyncSource> (
2881 _("External timecode source"),
2882 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
2883 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
2886 add_option (_("Sync"), _sync_source);
2888 _sync_framerate = new BoolOption (
2889 "timecode-sync-frame-rate",
2890 _("Match session video frame rate to external timecode"),
2891 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
2892 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
2894 Gtkmm2ext::UI::instance()->set_tip
2895 (_sync_framerate->tip_widget(),
2896 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
2897 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
2898 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
2899 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
2900 "timecode standard and the session standard."), PROGRAM_NAME));
2902 add_option (_("Sync"), _sync_framerate);
2904 _sync_genlock = new BoolOption (
2905 "timecode-source-is-synced",
2906 _("Sync-lock timecode to clock (disable drift compensation)"),
2907 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
2908 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
2910 Gtkmm2ext::UI::instance()->set_tip
2911 (_sync_genlock->tip_widget(),
2912 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
2913 "Sync Lock indicates that the selected external timecode source shares clock-sync "
2914 "(Black & Burst, Wordclock, etc) with the audio interface. "
2915 "This option disables drift compensation. The transport speed is fixed at 1.0. "
2916 "Vari-speed LTC will be ignored and cause drift."
2918 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
2919 "timecode sources shares clock sync."
2923 add_option (_("Sync"), _sync_genlock);
2925 _sync_source_2997 = new BoolOption (
2926 "timecode-source-2997",
2927 _("Lock to 29.9700 fps instead of 30000/1001"),
2928 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
2929 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
2931 Gtkmm2ext::UI::instance()->set_tip
2932 (_sync_source_2997->tip_widget(),
2933 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
2934 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
2935 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
2936 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
2937 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
2938 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
2941 add_option (_("Sync"), _sync_source_2997);
2943 add_option (_("Sync/LTC"), new OptionEditorHeading (_("LTC Reader")));
2945 _ltc_port = new ComboStringOption (
2947 _("LTC incoming port"),
2948 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
2949 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
2952 vector<string> physical_inputs;
2953 physical_inputs.push_back (_("None"));
2954 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
2955 _ltc_port->set_popdown_strings (physical_inputs);
2957 populate_sync_options ();
2958 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
2960 add_option (_("Sync/LTC"), _ltc_port);
2962 add_option (_("Sync/LTC"), new OptionEditorHeading (_("LTC Generator")));
2964 add_option (_("Sync/LTC"),
2967 _("Enable LTC generator"),
2968 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
2969 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
2972 _ltc_send_continuously = new BoolOption (
2973 "ltc-send-continuously",
2974 _("Send LTC while stopped"),
2975 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
2976 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
2978 Gtkmm2ext::UI::instance()->set_tip
2979 (_ltc_send_continuously->tip_widget(),
2980 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
2981 add_option (_("Sync/LTC"), _ltc_send_continuously);
2983 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"),
2984 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_output_volume),
2985 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_output_volume),
2989 Gtkmm2ext::UI::instance()->set_tip
2990 (_ltc_volume_slider->tip_widget(),
2991 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
2993 add_option (_("Sync/LTC"), _ltc_volume_slider);
2996 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Beat Clock (Mclk) Generator")));
2998 add_option (_("Sync/MIDI"),
3001 _("Enable Mclk generator"),
3002 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
3003 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
3006 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC) Generator")));
3008 add_option (_("Sync/MIDI"),
3011 _("Enable MTC Generator"),
3012 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
3013 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
3016 add_option (_("Sync/MIDI"),
3017 new SpinOption<int> (
3018 "mtc-qf-speed-tolerance",
3019 _("Percentage either side of normal transport speed to transmit MTC"),
3020 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
3021 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
3025 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Machine Control (MMC)")));
3027 add_option (_("Sync/MIDI"),
3030 _("Respond to MMC commands"),
3031 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
3032 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
3035 add_option (_("Sync/MIDI"),
3038 _("Send MMC commands"),
3039 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
3040 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
3043 add_option (_("Sync/MIDI"),
3044 new SpinOption<uint8_t> (
3045 "mmc-receive-device-id",
3046 _("Inbound MMC device ID"),
3047 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
3048 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
3052 add_option (_("Sync/MIDI"),
3053 new SpinOption<uint8_t> (
3054 "mmc-send-device-id",
3055 _("Outbound MMC device ID"),
3056 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
3057 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
3062 /* Control Surfaces */
3064 add_option (_("Control Surfaces"), new OptionEditorHeading (_("Control Surfaces")));
3065 add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
3068 add_option (_("MIDI Ports"), new OptionEditorHeading (_("MIDI Port Options")));
3070 add_option (_("MIDI Ports"),
3072 "get-midi-input-follows-selection",
3073 _("MIDI input follows MIDI track selection"),
3074 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
3075 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
3078 add_option (_("MIDI Ports"), new MidiPortOptions ());
3079 add_option (_("MIDI Ports"), new OptionEditorBlank ());
3083 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3084 add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
3085 add_option (_("Plugins"),
3086 new RcActionButton (_("Scan for Plugins"),
3087 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3091 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
3093 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3094 bo = new BoolOption (
3095 "show-plugin-scan-window",
3096 _("Always Display Plugin Scan Progress"),
3097 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
3098 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
3100 add_option (_("Plugins"), bo);
3101 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3102 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
3105 bo = new BoolOption (
3106 "plugins-stop-with-transport",
3107 _("Silence plugins when the transport is stopped"),
3108 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
3109 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
3111 add_option (_("Plugins"), bo);
3112 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3113 _("<b>When enabled</b> plugins will be reset at transport stop. When disabled plugins will be left unchanged at transport stop.\n\nThis mostly affects plugins with a \"tail\" like Reverbs."));
3115 bo = new BoolOption (
3116 "new-plugins-active",
3117 _("Make new plugins active"),
3118 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
3119 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
3121 add_option (_("Plugins"), bo);
3122 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3123 _("<b>When enabled</b> plugins will be activated when they are added to tracks/busses. When disabled plugins will be left inactive when they are added to tracks/busses"));
3125 #if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
3126 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
3128 add_option (_("Plugins/VST"),
3129 new RcActionButton (_("Scan for Plugins"),
3130 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3133 #if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
3134 bo = new BoolOption (
3136 _("Enable Mac VST support (requires restart or re-scan)"),
3137 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
3138 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
3140 add_option (_("Plugins/VST"), bo);
3143 bo = new BoolOption (
3144 "discover-vst-on-start",
3145 _("Scan for [new] VST Plugins on Application Start"),
3146 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
3147 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
3149 add_option (_("Plugins/VST"), bo);
3150 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3151 _("<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"));
3153 #ifdef WINDOWS_VST_SUPPORT
3154 // currently verbose logging is only implemented for Windows VST.
3155 bo = new BoolOption (
3156 "verbose-plugin-scan",
3157 _("Verbose Plugin Scan"),
3158 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
3159 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
3161 add_option (_("Plugins/VST"), bo);
3162 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3163 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
3166 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
3168 add_option (_("Plugins/VST"),
3169 new RcActionButton (_("Clear"),
3170 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
3173 add_option (_("Plugins/VST"),
3174 new RcActionButton (_("Clear"),
3175 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
3176 _("VST Blacklist:")));
3179 #ifdef LXVST_SUPPORT
3180 add_option (_("Plugins/VST"),
3181 new RcActionButton (_("Edit"),
3182 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
3183 _("Linux VST Path:")));
3185 add_option (_("Plugins/VST"),
3186 new RcConfigDisplay (
3187 "plugin-path-lxvst",
3189 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
3193 #ifdef WINDOWS_VST_SUPPORT
3194 add_option (_("Plugins/VST"),
3195 new RcActionButton (_("Edit"),
3196 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
3197 _("Windows VST Path:")));
3198 add_option (_("Plugins/VST"),
3199 new RcConfigDisplay (
3202 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
3206 #ifdef AUDIOUNIT_SUPPORT
3208 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
3210 add_option (_("Plugins/Audio Unit"),
3211 new RcActionButton (_("Scan for Plugins"),
3212 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3215 bo = new BoolOption (
3216 "discover-audio-units",
3217 _("Scan for [new] AudioUnit Plugins on Application Start"),
3218 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
3219 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
3221 add_option (_("Plugins/Audio Unit"), bo);
3222 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3223 _("<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."));
3225 add_option (_("Plugins/Audio Unit"),
3226 new RcActionButton (_("Clear"),
3227 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
3230 add_option (_("Plugins/Audio Unit"),
3231 new RcActionButton (_("Clear"),
3232 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
3233 _("AU Blacklist:")));
3236 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
3237 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
3238 add_option (_("Plugins"),
3240 "open-gui-after-adding-plugin",
3241 _("Automatically open the plugin GUI when adding a new plugin"),
3242 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
3243 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3246 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3247 add_option (_("Plugins"),
3249 "show-inline-display-by-default",
3250 _("Show Plugin Inline Display on Mixerstrip by default"),
3251 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3252 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3255 _plugin_prefer_inline = new BoolOption (
3256 "prefer-inline-over-gui",
3257 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3258 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3259 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3261 add_option (_("Plugins"), _plugin_prefer_inline);
3264 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3266 bo = new BoolOption (
3267 "ask-replace-instrument",
3268 _("Ask to replace existing instrument plugin"),
3269 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3270 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3272 add_option (_("Plugins"), bo);
3274 bo = new BoolOption (
3275 "ask-setup_instrument",
3276 _("Interactively configure instrument plugins on insert"),
3277 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3278 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3280 add_option (_("Plugins"), bo);
3281 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3282 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3285 add_option (_("Plugins"), new OptionEditorBlank ());
3288 #if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
3289 add_option (_("Appearance"), new OptionEditorHeading (_("Graphics Acceleration")));
3292 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3293 BoolOption* bgc = new BoolOption (
3294 "cairo-image-surface",
3295 _("Disable Graphics Hardware Acceleration (requires restart)"),
3296 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3297 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3300 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3301 _("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));
3302 add_option (_("Appearance"), bgc);
3305 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3306 BoolOption* bgo = new BoolOption (
3308 _("Possibly improve slow graphical performance (requires restart)"),
3309 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3310 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3313 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));
3314 add_option (_("Appearance"), bgo);
3316 add_option (_("Appearance"), new OptionEditorHeading (_("Graphical User Interface")));
3318 add_option (_("Appearance"),
3321 _("Highlight widgets on mouseover"),
3322 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3323 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3326 add_option (_("Appearance"),
3329 _("Show tooltips if mouse hovers over a control"),
3330 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3331 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3334 bo = new BoolOption (
3335 "super-rapid-clock-update",
3336 _("Update clocks at TC Frame rate"),
3337 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3338 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3340 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3341 _("<b>When enabled</b> clock displays are updated every Timecode Frame (fps).\n\n"
3342 "<b>When disabled</b> clock displays are updated only every 100ms."
3344 add_option (_("Appearance"), bo);
3346 add_option (_("Appearance"),
3349 _("Blink Rec-Arm buttons"),
3350 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_rec_arm),
3351 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_rec_arm)
3356 /* font scaling does nothing with GDK/Quartz */
3357 add_option (_("Appearance"), new FontScalingOptions ());
3360 /* Image cache size */
3362 HSliderOption *sics = new HSliderOption ("waveform-cache-size",
3363 _("Waveform image cache size (megabytes)"),
3364 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
3365 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size),
3366 1, 1024, 10 /* 1 MB to 1GB in steps of 10MB */
3368 sics->scale().set_digits (0);
3369 Gtkmm2ext::UI::instance()->set_tip (
3371 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
3372 add_option (_("Appearance"), sics);
3374 if (!ARDOUR::Profile->get_mixbus()) {
3375 /* Lock GUI timeout */
3377 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
3378 _("Lock timeout (seconds)"),
3379 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
3380 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds),
3383 slts->scale().set_digits (0);
3384 Gtkmm2ext::UI::instance()->set_tip (
3386 _("Lock GUI after this many idle seconds (zero to never lock)"));
3387 add_option (_("Appearance"), slts);
3390 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("General")));
3391 add_option (_("Appearance/Editor"),
3393 "show-name-highlight",
3394 _("Use name highlight bars in region displays (requires a restart)"),
3395 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3396 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3399 add_option (_("Appearance/Editor"),
3401 "color-regions-using-track-color",
3402 _("Region color follows track color"),
3403 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_color_regions_using_track_color),
3404 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_color_regions_using_track_color)
3407 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Waveforms")));
3409 if (!Profile->get_mixbus()) {
3410 add_option (_("Appearance/Editor"),
3413 _("Show waveforms in regions"),
3414 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
3415 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
3419 add_option (_("Appearance/Editor"),
3421 "show-waveforms-while-recording",
3422 _("Show waveforms while recording"),
3423 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
3424 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
3427 add_option (_("Appearance/Editor"),
3429 "show-waveform-clipping",
3430 _("Show waveform clipping"),
3431 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveform_clipping),
3432 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveform_clipping)
3435 add_option (_("Appearance/Editor"), new ClipLevelOptions ());
3437 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
3439 _("Waveform scale"),
3440 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
3441 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
3444 wfs->add (Linear, _("linear"));
3445 wfs->add (Logarithmic, _("logarithmic"));
3447 add_option (_("Appearance/Editor"), wfs);
3449 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
3451 _("Waveform shape"),
3452 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
3453 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
3456 wfsh->add (Traditional, _("traditional"));
3457 wfsh->add (Rectified, _("rectified"));
3459 add_option (_("Appearance/Editor"), wfsh);
3461 add_option (_("Appearance/Editor"), new OptionEditorBlank ());
3463 /* The names of these controls must be the same as those given in MixerStrip
3464 for the actual widgets being controlled.
3466 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3467 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3468 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3469 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3470 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3471 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3472 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3474 add_option (_("Appearance/Mixer"),
3475 new VisibilityOption (
3477 &_mixer_strip_visibility,
3478 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3479 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3483 add_option (_("Appearance/Mixer"),
3485 "default-narrow_ms",
3486 _("Use narrow strips in the mixer by default"),
3487 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3488 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3491 add_option (_("Appearance/Mixer"), new OptionEditorBlank ());
3493 add_option (_("Appearance/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items")));
3495 add_option (_("Appearance/Toolbar"),
3497 "show-toolbar-selclock",
3498 _("Display Selection Clock"),
3499 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
3500 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
3503 if (!ARDOUR::Profile->get_small_screen()) {
3504 add_option (_("Appearance/Toolbar"),
3506 "show-secondary-clock",
3507 _("Display Secondary Clock"),
3508 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
3509 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
3513 add_option (_("Appearance/Toolbar"),
3515 "show-mini-timeline",
3516 _("Display Navigation Timeline"),
3517 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
3518 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
3521 add_option (_("Appearance/Toolbar"),
3523 "show-editor-meter",
3524 _("Display Master Level Meter"),
3525 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
3526 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
3529 add_option (_("Appearance/Toolbar"),
3530 new ColumVisibilityOption (
3531 "action-table-columns", _("Lua Action Script Button Visibility"), 4,
3532 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3533 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3536 add_option (_("Appearance/Toolbar"), new OptionEditorBlank ());
3539 OptionEditorHeading* quirks_head = new OptionEditorHeading (_("Various Workarounds for Windowing Systems"));
3541 quirks_head->set_note (string_compose (_("These settings will only take effect after %1 is restarted."), PROGRAM_NAME));
3543 /* and now the theme manager */
3545 add_option (_("Appearance/Colors"), new OptionEditorHeading (_("Colors")));
3546 add_option (_("Appearance/Colors"), new ColorThemeManager);
3548 add_option (_("Appearance/Theme"), new OptionEditorHeading (_("Theme")));
3549 add_option (_("Appearance/Theme"), new ThemeManager);
3551 add_option (_("Appearance/Quirks"), quirks_head);
3553 add_option (_("Appearance/Quirks"),
3555 "use-wm-visibility",
3556 _("Use Window Manager/Desktop visibility information"),
3557 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3558 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3562 bo = new BoolOption (
3563 "all-floating-windows-are-dialogs",
3564 _("All floating windows are dialogs"),
3565 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_all_floating_windows_are_dialogs),
3566 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_all_floating_windows_are_dialogs)
3568 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (), string_compose (
3569 _("Mark all floating windows to be type \"Dialog\" rather than using \"Utility\" for some.\n"
3570 "This may help with some window managers. This requires a restart of %1 to take effect"),
3572 add_option (_("Appearance/Quirks"), bo);
3574 bo = new BoolOption (
3575 "transients-follow-front",
3576 _("Transient windows follow front window."),
3577 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_transients_follow_front),
3578 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_transients_follow_front)
3580 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (), string_compose (
3581 _("Make transient windows follow the front window when toggling between the editor and mixer.\n"
3582 "This requires a restart of %1 to take effect"), PROGRAM_NAME));
3583 add_option (_("Appearance/Quirks"), bo);
3586 if (!Profile->get_mixbus()) {
3587 bo = new BoolOption (
3588 "floating-monitor-section",
3589 _("Float detached monitor-section window"),
3590 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_floating_monitor_section),
3591 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_floating_monitor_section)
3593 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (), string_compose (
3594 _("When detaching the monitoring section, mark it as \"Utility\" window to stay in front.\n"
3595 "This requires a restart of %1 to take effect"), PROGRAM_NAME));
3596 add_option (_("Appearance/Quirks"), bo);
3599 add_option (_("Appearance/Quirks"), new OptionEditorBlank ());
3605 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
3607 ComboOption<float>* mht = new ComboOption<float> (
3609 _("Peak hold time"),
3610 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
3611 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
3614 mht->add (MeterHoldOff, _("off"));
3615 mht->add (MeterHoldShort, _("short"));
3616 mht->add (MeterHoldMedium, _("medium"));
3617 mht->add (MeterHoldLong, _("long"));
3619 add_option (S_("Preferences|Metering"), mht);
3621 ComboOption<float>* mfo = new ComboOption<float> (
3624 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
3625 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
3628 mfo->add (METER_FALLOFF_OFF, _("off"));
3629 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
3630 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
3631 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
3632 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
3633 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
3634 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
3636 add_option (S_("Preferences|Metering"), mfo);
3638 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
3639 "meter-line-up-level",
3640 _("Meter line-up level; 0dBu"),
3641 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
3642 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
3645 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3646 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3647 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3648 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3650 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."));
3652 add_option (S_("Preferences|Metering"), mlu);
3654 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
3655 "meter-line-up-din",
3656 _("IEC1/DIN Meter line-up level; 0dBu"),
3657 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
3658 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
3661 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3662 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3663 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3664 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3666 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
3668 add_option (S_("Preferences|Metering"), mld);
3670 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
3671 "meter-vu-standard",
3672 _("VU Meter standard"),
3673 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
3674 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
3677 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
3678 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
3679 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
3680 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
3682 add_option (S_("Preferences|Metering"), mvu);
3684 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3685 "meter-type-master",
3686 _("Default Meter Type for Master Bus"),
3687 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3688 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3690 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3691 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3692 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3693 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3694 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3695 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3696 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3697 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3699 add_option (S_("Preferences|Metering"), mtm);
3702 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3704 _("Default Meter Type for Busses"),
3705 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3706 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3708 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3709 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3710 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3711 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3712 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3713 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3714 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3715 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3717 add_option (S_("Preferences|Metering"), mtb);
3719 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3721 _("Default Meter Type for Tracks"),
3722 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3723 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3725 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3726 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3728 add_option (S_("Preferences|Metering"), mtt);
3730 HSliderOption *mpks = new HSliderOption("meter-peak",
3731 _("Peak threshold [dBFS]"),
3732 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
3733 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak),
3737 Gtkmm2ext::UI::instance()->set_tip (
3739 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
3741 add_option (S_("Preferences|Metering"), mpks);
3743 add_option (S_("Preferences|Metering"),
3746 _("LED meter style"),
3747 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3748 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3751 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Editor Meters")));
3753 add_option (S_("Preferences|Metering"),
3755 "show-track-meters",
3756 _("Show meters on tracks in the editor"),
3757 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3758 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3761 add_option (S_("Preferences|Metering"),
3763 "editor-stereo-only-meters",
3764 _("Show at most stereo meters in the track-header"),
3765 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3766 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3769 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
3771 add_option (S_("Preferences|Metering"),
3773 "save-export-analysis-image",
3774 _("Save loudness analysis as image file"),
3775 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
3776 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
3778 /* VIDEO Timeline */
3779 add_option (_("Video"), new OptionEditorHeading (_("Video Server")));
3780 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
3782 Widget::show_all ();
3784 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3785 parameter_changed ("send-ltc");
3786 parameter_changed ("sync-source");
3787 parameter_changed ("use-monitor-bus");
3788 parameter_changed ("open-gui-after-adding-plugin");
3790 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
3792 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
3793 (Gtk::StateType) here !!!
3795 Tabbable::set_state (*node, Stateful::loading_state_version);
3798 set_current_page (_("General"));
3802 RCOptionEditor::parameter_changed (string const & p)
3804 OptionEditor::parameter_changed (p);
3806 if (p == "use-monitor-bus") {
3807 bool const s = Config->get_use_monitor_bus ();
3809 /* we can't use this if we don't have a monitor bus */
3810 Config->set_solo_control_is_listen_control (false);
3812 _solo_control_is_listen_control->set_sensitive (s);
3813 _listen_position->set_sensitive (s);
3814 } else if (p == "sync-source") {
3815 _sync_source->set_sensitive (true);
3817 _sync_source->set_sensitive (!_session->config.get_external_sync());
3819 switch(Config->get_sync_source()) {
3822 _sync_genlock->set_sensitive (true);
3823 _sync_framerate->set_sensitive (true);
3824 _sync_source_2997->set_sensitive (true);
3827 _sync_genlock->set_sensitive (false);
3828 _sync_framerate->set_sensitive (false);
3829 _sync_source_2997->set_sensitive (false);
3832 } else if (p == "send-ltc") {
3833 bool const s = Config->get_send_ltc ();
3834 _ltc_send_continuously->set_sensitive (s);
3835 _ltc_volume_slider->set_sensitive (s);
3836 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
3837 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3838 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
3841 } else if (p == "enable-translation") {
3842 _l10n->set_sensitive (ARDOUR::translations_are_enabled ());
3847 void RCOptionEditor::plugin_scan_refresh () {
3848 PluginManager::instance().refresh();
3851 void RCOptionEditor::clear_vst_cache () {
3852 PluginManager::instance().clear_vst_cache();
3855 void RCOptionEditor::clear_vst_blacklist () {
3856 PluginManager::instance().clear_vst_blacklist();
3859 void RCOptionEditor::clear_au_cache () {
3860 PluginManager::instance().clear_au_cache();
3863 void RCOptionEditor::clear_au_blacklist () {
3864 PluginManager::instance().clear_au_blacklist();
3867 void RCOptionEditor::edit_lxvst_path () {
3868 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
3869 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3870 *current_toplevel(), _("Set Linux VST Search Path"),
3871 _rc_config->get_plugin_path_lxvst(),
3872 PluginManager::instance().get_default_lxvst_path()
3874 ResponseType r = (ResponseType) pd->run ();
3876 if (r == RESPONSE_ACCEPT) {
3877 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
3882 void RCOptionEditor::edit_vst_path () {
3883 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3884 *current_toplevel(), _("Set Windows VST Search Path"),
3885 _rc_config->get_plugin_path_vst(),
3886 PluginManager::instance().get_default_windows_vst_path()
3888 ResponseType r = (ResponseType) pd->run ();
3890 if (r == RESPONSE_ACCEPT) {
3891 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
3898 RCOptionEditor::populate_sync_options ()
3900 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3902 _sync_source->clear ();
3904 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3905 _sync_source->add (*i, sync_source_to_string (*i));
3908 if (sync_opts.empty()) {
3909 _sync_source->set_sensitive(false);
3911 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3912 _rc_config->set_sync_source(sync_opts.front());
3916 parameter_changed ("sync-source");
3920 RCOptionEditor::use_own_window (bool and_fill_it)
3922 bool new_window = !own_window ();
3924 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
3926 if (win && new_window) {
3927 win->set_name ("PreferencesWindow");
3928 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
3935 RCOptionEditor::get_state ()
3937 XMLNode* node = new XMLNode (X_("Preferences"));
3938 node->add_child_nocopy (Tabbable::get_state());