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 default Click:")));
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 (_("Click 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 (_("Click 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 (
118 _("Click gain level"),
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());
1146 void set_state_from_config ()
1148 parameter_changed ("waveform-clip-level");
1151 void add_to_page (OptionEditorPage* p) {
1152 add_widgets_to_page (p, &_label, &_clip_level_slider);
1155 Gtk::Widget& tip_widget() {
1156 return _clip_level_slider;
1161 void clip_level_changed ()
1163 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1164 /* XXX: should be triggered from the parameter changed signal */
1165 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1168 Adjustment _clip_level_adjustment;
1169 HScale _clip_level_slider;
1173 class BufferingOptions : public OptionEditorComponent
1176 BufferingOptions (RCConfiguration* c)
1178 , _label (_("Preset:"))
1179 , _playback ("playback-buffer-seconds", _("Playback (seconds of buffering)"),
1180 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_playback_buffer_seconds),
1181 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_playback_buffer_seconds),
1183 , _capture ("capture-buffer-seconds", _("Recording (seconds of buffering)"),
1184 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_capture_buffer_seconds),
1185 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_capture_buffer_seconds),
1188 // TODO use ComboOption
1189 vector<string> presets;
1191 /* these must match the order of the enums for BufferingPreset */
1192 presets.push_back (_("Small sessions (4-16 tracks)"));
1193 presets.push_back (_("Medium sessions (16-64 tracks)"));
1194 presets.push_back (_("Large sessions (64+ tracks)"));
1195 presets.push_back (_("Custom (set by sliders below)"));
1197 set_popdown_strings (_buffering_presets_combo, presets);
1198 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1200 _label.set_name ("OptionsLabel");
1201 _label.set_alignment (0, 0.5);
1205 add_to_page (OptionEditorPage* p)
1207 add_widgets_to_page (p, &_label, &_buffering_presets_combo);
1208 _playback.add_to_page (p);
1209 _capture.add_to_page (p);
1212 void parameter_changed (string const & p)
1214 if (p == "buffering-preset") {
1215 switch (_rc_config->get_buffering_preset()) {
1217 _playback.set_sensitive (false);
1218 _capture.set_sensitive (false);
1219 _buffering_presets_combo.set_active (0);
1222 _playback.set_sensitive (false);
1223 _capture.set_sensitive (false);
1224 _buffering_presets_combo.set_active (1);
1227 _playback.set_sensitive (false);
1228 _capture.set_sensitive (false);
1229 _buffering_presets_combo.set_active (2);
1232 _playback.set_sensitive (true);
1233 _capture.set_sensitive (true);
1234 _buffering_presets_combo.set_active (3);
1238 _playback.parameter_changed (p);
1239 _capture.parameter_changed (p);
1242 void set_state_from_config ()
1244 parameter_changed ("buffering-preset");
1245 _playback.set_state_from_config();
1246 _capture.set_state_from_config();
1249 Gtk::Widget& tip_widget() { return _buffering_presets_combo; }
1253 void preset_changed ()
1255 int index = _buffering_presets_combo.get_active_row_number ();
1261 _rc_config->set_buffering_preset (Small);
1264 _rc_config->set_buffering_preset (Medium);
1267 _rc_config->set_buffering_preset (Large);
1270 _rc_config->set_buffering_preset (Custom);
1273 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1278 RCConfiguration* _rc_config;
1280 HSliderOption _playback;
1281 HSliderOption _capture;
1282 ComboBoxText _buffering_presets_combo;
1285 class ControlSurfacesOptions : public OptionEditorMiniPage
1288 ControlSurfacesOptions ()
1289 : _ignore_view_change (0)
1291 _store = ListStore::create (_model);
1292 _view.set_model (_store);
1293 _view.append_column (_("Control Surface Protocol"), _model.name);
1294 _view.get_column(0)->set_resizable (true);
1295 _view.get_column(0)->set_expand (true);
1296 _view.append_column_editable (_("Enable"), _model.enabled);
1298 Gtk::HBox* edit_box = manage (new Gtk::HBox);
1299 edit_box->set_spacing(3);
1302 Label* label = manage (new Label);
1303 label->set_text (_("Edit the settings for selected protocol (it must be ENABLED first):"));
1304 edit_box->pack_start (*label, false, false);
1307 edit_button = manage (new Button(_("Show Protocol Settings")));
1308 edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
1309 edit_box->pack_start (*edit_button, true, true);
1310 edit_button->set_sensitive (false);
1311 edit_button->show ();
1313 int const n = table.property_n_rows();
1314 table.resize (n + 2, 3);
1315 table.attach (_view, 0, 3, n, n + 1);
1316 table.attach (*edit_box, 0, 3, n + 1, n + 2);
1318 ControlProtocolManager& m = ControlProtocolManager::instance ();
1319 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1320 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1322 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1323 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1324 _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
1327 void parameter_changed (std::string const &)
1332 void set_state_from_config ()
1336 ControlProtocolManager& m = ControlProtocolManager::instance ();
1337 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1339 if (!(*i)->mandatory) {
1340 TreeModel::Row r = *_store->append ();
1341 r[_model.name] = (*i)->name;
1342 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1343 r[_model.protocol_info] = *i;
1350 void protocol_status_changed (ControlProtocolInfo* cpi) {
1352 TreeModel::Children rows = _store->children();
1354 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1355 string n = ((*x)[_model.name]);
1357 if ((*x)[_model.protocol_info] == cpi) {
1358 _ignore_view_change++;
1359 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1360 _ignore_view_change--;
1366 void selection_changed ()
1368 //enable the Edit button when a row is selected for editing
1369 TreeModel::Row row = *(_view.get_selection()->get_selected());
1370 if (row && row[_model.enabled])
1371 edit_button->set_sensitive (true);
1373 edit_button->set_sensitive (false);
1376 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1378 TreeModel::Row r = *i;
1380 if (_ignore_view_change) {
1384 ControlProtocolInfo* cpi = r[_model.protocol_info];
1389 bool const was_enabled = (cpi->protocol != 0);
1390 bool const is_enabled = r[_model.enabled];
1393 if (was_enabled != is_enabled) {
1396 ControlProtocolManager::instance().activate (*cpi);
1398 ControlProtocolManager::instance().deactivate (*cpi);
1402 selection_changed ();
1405 void edit_btn_clicked ()
1408 ControlProtocolInfo* cpi;
1411 row = *(_view.get_selection()->get_selected());
1412 if (!row[_model.enabled]) {
1415 cpi = row[_model.protocol_info];
1416 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1419 Box* box = (Box*) cpi->protocol->get_gui ();
1423 if (box->get_parent()) {
1424 static_cast<ArdourWindow*>(box->get_parent())->present();
1427 WindowTitle title (Glib::get_application_name());
1428 title += row[_model.name];
1429 title += _("Configuration");
1430 /* once created, the window is managed by the surface itself (as ->get_parent())
1431 * Surface's tear_down_gui() is called on session close, when de-activating
1432 * or re-initializing a surface.
1433 * tear_down_gui() hides an deletes the Window if it exists.
1435 ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
1436 win->set_title ("Control Protocol Options");
1442 void edit_clicked (GdkEventButton* ev)
1444 if (ev->type != GDK_2BUTTON_PRESS) {
1451 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1455 ControlSurfacesModelColumns ()
1459 add (protocol_info);
1462 TreeModelColumn<string> name;
1463 TreeModelColumn<bool> enabled;
1464 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1467 Glib::RefPtr<ListStore> _store;
1468 ControlSurfacesModelColumns _model;
1470 PBD::ScopedConnection protocol_status_connection;
1471 uint32_t _ignore_view_change;
1472 Gtk::Button* edit_button;
1475 class VideoTimelineOptions : public OptionEditorMiniPage
1478 VideoTimelineOptions (RCConfiguration* c)
1480 , _show_video_export_info_button (_("Show Video Export Info before export"))
1481 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1482 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1483 , _xjadeo_browse_button (_("Browse..."))
1486 int n = table.property_n_rows();
1488 t->attach (_show_video_export_info_button, 1, 4, n, n + 1);
1489 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1490 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1491 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1494 t->attach (_show_video_server_dialog_button, 1, 4, n, n + 1);
1495 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1496 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1497 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1500 t->attach (_video_advanced_setup_button, 1, 4, n, n + 1, FILL);
1501 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1502 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1503 _("<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."));
1506 Label* l = manage (new Label (_("Video Server URL:")));
1507 l->set_alignment (0, 0.5);
1508 t->attach (*l, 1, 2, n, n + 1, FILL);
1509 t->attach (_video_server_url_entry, 2, 4, n, n + 1, FILL);
1510 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1511 _("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"));
1514 l = manage (new Label (_("Video Folder:")));
1515 l->set_alignment (0, 0.5);
1516 t->attach (*l, 1, 2, n, n + 1, FILL);
1517 t->attach (_video_server_docroot_entry, 2, 4, n, n + 1);
1518 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1519 _("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."));
1522 l = manage (new Label (""));
1523 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1526 l = manage (new Label (string_compose ("<b>%1</b>", _("Video Monitor"))));
1527 l->set_use_markup (true);
1528 l->set_alignment (0, 0.5);
1529 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1532 l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"),
1535 #elif defined PLATFORM_WINDOWS
1541 l->set_alignment (0, 0.5);
1542 t->attach (*l, 1, 4, n, n + 1, FILL);
1545 t->attach (_custom_xjadeo_path, 2, 3, n, n + 1, EXPAND|FILL);
1546 Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart."));
1547 t->attach (_xjadeo_browse_button, 3, 4, n, n + 1, FILL);
1549 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1550 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1551 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1552 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1553 _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed));
1554 _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked));
1556 // xjadeo-path is a UIConfig parameter
1557 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &VideoTimelineOptions::parameter_changed));
1560 void server_url_changed ()
1562 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1565 void server_docroot_changed ()
1567 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1570 void show_video_export_info_toggled ()
1572 bool const x = _show_video_export_info_button.get_active ();
1573 _rc_config->set_show_video_export_info (x);
1576 void show_video_server_dialog_toggled ()
1578 bool const x = _show_video_server_dialog_button.get_active ();
1579 _rc_config->set_show_video_server_dialog (x);
1582 void video_advanced_setup_toggled ()
1584 bool const x = _video_advanced_setup_button.get_active ();
1585 _rc_config->set_video_advanced_setup(x);
1588 void custom_xjadeo_path_changed ()
1590 UIConfiguration::instance().set_xjadeo_binary (_custom_xjadeo_path.get_text());
1593 void xjadeo_browse_clicked ()
1595 Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN);
1596 dialog.set_filename (UIConfiguration::instance().get_xjadeo_binary());
1597 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1598 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1599 if (dialog.run () == Gtk::RESPONSE_OK) {
1600 const std::string& filename = dialog.get_filename();
1601 if (!filename.empty() && (
1603 Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) ||
1605 Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)
1607 UIConfiguration::instance().set_xjadeo_binary (filename);
1612 void parameter_changed (string const & p)
1614 if (p == "video-server-url") {
1615 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1616 } else if (p == "video-server-docroot") {
1617 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1618 } else if (p == "show-video-export-info") {
1619 bool const x = _rc_config->get_show_video_export_info();
1620 _show_video_export_info_button.set_active (x);
1621 } else if (p == "show-video-server-dialog") {
1622 bool const x = _rc_config->get_show_video_server_dialog();
1623 _show_video_server_dialog_button.set_active (x);
1624 } else if (p == "video-advanced-setup") {
1625 bool const x = _rc_config->get_video_advanced_setup();
1626 _video_advanced_setup_button.set_active(x);
1627 _video_server_docroot_entry.set_sensitive(x);
1628 _video_server_url_entry.set_sensitive(x);
1629 } else if (p == "xjadeo-binary") {
1630 _custom_xjadeo_path.set_text (UIConfiguration::instance().get_xjadeo_binary());
1634 void set_state_from_config ()
1636 parameter_changed ("video-server-url");
1637 parameter_changed ("video-server-docroot");
1638 parameter_changed ("video-monitor-setup-dialog");
1639 parameter_changed ("show-video-export-info");
1640 parameter_changed ("show-video-server-dialog");
1641 parameter_changed ("video-advanced-setup");
1642 parameter_changed ("xjadeo-binary");
1646 RCConfiguration* _rc_config;
1647 Entry _video_server_url_entry;
1648 Entry _video_server_docroot_entry;
1649 Entry _custom_xjadeo_path;
1650 CheckButton _show_video_export_info_button;
1651 CheckButton _show_video_server_dialog_button;
1652 CheckButton _video_advanced_setup_button;
1653 Button _xjadeo_browse_button;
1656 class ColumVisibilityOption : public Option
1659 ColumVisibilityOption (string id, string name, uint32_t n_col, sigc::slot<uint32_t> get, sigc::slot<bool, uint32_t> set)
1666 cb = (CheckButton**) malloc (sizeof (CheckButton*) * n_col);
1667 for (uint32_t i = 0; i < n_col; ++i) {
1668 CheckButton* col = manage (new CheckButton (string_compose (_("Column %1"), i + 1)));
1669 col->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ColumVisibilityOption::column_toggled), i));
1670 _hbox.pack_start (*col);
1673 parameter_changed (id);
1676 ~ColumVisibilityOption () {
1680 Gtk::Widget& tip_widget() { return _hbox; }
1682 void set_state_from_config ()
1684 uint32_t c = _get();
1685 for (uint32_t i = 0; i < _n_col; ++i) {
1686 bool en = (c & (1<<i)) ? true : false;
1687 if (cb[i]->get_active () != en) {
1688 cb[i]->set_active (en);
1693 void add_to_page (OptionEditorPage* p)
1695 _heading.add_to_page (p);
1696 add_widget_to_page (p, &_hbox);
1700 void column_toggled (int b) {
1701 uint32_t c = _get();
1703 if (cb[b]->get_active ()) {
1714 OptionEditorHeading _heading;
1718 sigc::slot<uint32_t> _get;
1719 sigc::slot<bool, uint32_t> _set;
1723 /** A class which allows control of visibility of some editor components usign
1724 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1725 * which has the correct members, but with null widget pointers. This
1726 * class allows the user to set visibility of the members, the details
1727 * of which are stored in a configuration variable which can be watched
1728 * by parts of the editor that actually contain the widgets whose visibility
1729 * is being controlled.
1732 class VisibilityOption : public Option
1735 /** @param name User-visible name for this group.
1736 * @param g `Dummy' VisibilityGroup (as described above).
1737 * @param get Method to get the value of the appropriate configuration variable.
1738 * @param set Method to set the value of the appropriate configuration variable.
1740 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1741 : Option (g->get_state_name(), name)
1743 , _visibility_group (g)
1747 /* Watch for changes made by the user to our members */
1748 _visibility_group->VisibilityChanged.connect_same_thread (
1749 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1753 void set_state_from_config ()
1755 /* Set our state from the current configuration */
1756 _visibility_group->set_state (_get ());
1759 void add_to_page (OptionEditorPage* p)
1761 _heading.add_to_page (p);
1762 add_widget_to_page (p, _visibility_group->list_view ());
1765 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1770 /* The user has changed something, so reflect this change
1771 in the RCConfiguration.
1773 _set (_visibility_group->get_state_value ());
1776 OptionEditorHeading _heading;
1777 VisibilityGroup* _visibility_group;
1778 sigc::slot<std::string> _get;
1779 sigc::slot<bool, std::string> _set;
1780 PBD::ScopedConnection _visibility_group_connection;
1784 class MidiPortOptions : public OptionEditorMiniPage, public sigc::trackable
1789 setup_midi_port_view (midi_output_view, false);
1790 setup_midi_port_view (midi_input_view, true);
1792 OptionEditorHeading* h = new OptionEditorHeading (_("MIDI Inputs"));
1793 h->add_to_page (this);
1795 Gtk::ScrolledWindow* scroller = manage (new Gtk::ScrolledWindow);
1796 scroller->add (midi_input_view);
1797 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1798 scroller->set_size_request (-1, 180);
1800 int n = table.property_n_rows();
1801 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1803 h = new OptionEditorHeading (_("MIDI Outputs"));
1804 h->add_to_page (this);
1806 scroller = manage (new Gtk::ScrolledWindow);
1807 scroller->add (midi_output_view);
1808 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1809 scroller->set_size_request (-1, 180);
1811 n = table.property_n_rows();
1812 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1814 midi_output_view.show ();
1815 midi_input_view.show ();
1817 table.signal_show().connect (sigc::mem_fun (*this, &MidiPortOptions::on_show));
1820 void parameter_changed (string const&) {}
1821 void set_state_from_config() {}
1826 AudioEngine::instance()->PortRegisteredOrUnregistered.connect (connections,
1827 invalidator (*this),
1828 boost::bind (&MidiPortOptions::refill, this),
1830 AudioEngine::instance()->MidiPortInfoChanged.connect (connections,
1831 invalidator (*this),
1832 boost::bind (&MidiPortOptions::refill, this),
1834 AudioEngine::instance()->MidiSelectionPortsChanged.connect (connections,
1835 invalidator (*this),
1836 boost::bind (&MidiPortOptions::refill, this),
1842 if (refill_midi_ports (true, midi_input_view)) {
1843 input_label.show ();
1845 input_label.hide ();
1847 if (refill_midi_ports (false, midi_output_view)) {
1848 output_label.show ();
1850 output_label.hide ();
1855 PBD::ScopedConnectionList connections;
1857 /* MIDI port management */
1858 struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord {
1860 MidiPortColumns () {
1869 Gtk::TreeModelColumn<std::string> pretty_name;
1870 Gtk::TreeModelColumn<bool> music_data;
1871 Gtk::TreeModelColumn<bool> control_data;
1872 Gtk::TreeModelColumn<bool> selection;
1873 Gtk::TreeModelColumn<std::string> name;
1874 Gtk::TreeModelColumn<std::string> filler;
1877 MidiPortColumns midi_port_columns;
1878 Gtk::TreeView midi_input_view;
1879 Gtk::TreeView midi_output_view;
1880 Gtk::Label input_label;
1881 Gtk::Label output_label;
1883 void setup_midi_port_view (Gtk::TreeView&, bool with_selection);
1884 bool refill_midi_ports (bool for_input, Gtk::TreeView&);
1885 void pretty_name_edit (std::string const & path, std::string const & new_text, Gtk::TreeView*);
1886 void midi_music_column_toggled (std::string const & path, Gtk::TreeView*);
1887 void midi_control_column_toggled (std::string const & path, Gtk::TreeView*);
1888 void midi_selection_column_toggled (std::string const & path, Gtk::TreeView*);
1892 MidiPortOptions::setup_midi_port_view (Gtk::TreeView& view, bool with_selection)
1894 int pretty_name_column;
1897 int selection_column;
1898 TreeViewColumn* col;
1901 pretty_name_column = view.append_column_editable (_("Name (click to edit)"), midi_port_columns.pretty_name) - 1;
1903 col = manage (new TreeViewColumn ("", midi_port_columns.music_data));
1904 col->set_alignment (ALIGN_CENTER);
1905 l = manage (new Label (_("Music Data")));
1906 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of music performance data."), PROGRAM_NAME));
1907 col->set_widget (*l);
1909 music_column = view.append_column (*col) - 1;
1911 col = manage (new TreeViewColumn ("", midi_port_columns.control_data));
1912 col->set_alignment (ALIGN_CENTER);
1913 l = manage (new Label (_("Control Data")));
1914 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of control data."), PROGRAM_NAME));
1915 col->set_widget (*l);
1917 control_column = view.append_column (*col) - 1;
1919 if (with_selection) {
1920 col = manage (new TreeViewColumn (_("Follow Selection"), midi_port_columns.selection));
1921 selection_column = view.append_column (*col) - 1;
1922 l = manage (new Label (_("Follow Selection")));
1923 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));
1924 col->set_widget (*l);
1928 /* filler column so that the last real column doesn't expand */
1929 view.append_column ("", midi_port_columns.filler);
1931 CellRendererText* pretty_name_cell = dynamic_cast<CellRendererText*> (view.get_column_cell_renderer (pretty_name_column));
1932 pretty_name_cell->property_editable() = true;
1933 pretty_name_cell->signal_edited().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::pretty_name_edit), &view));
1935 CellRendererToggle* toggle_cell;
1937 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (music_column));
1938 toggle_cell->property_activatable() = true;
1939 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_music_column_toggled), &view));
1941 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (control_column));
1942 toggle_cell->property_activatable() = true;
1943 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_control_column_toggled), &view));
1945 if (with_selection) {
1946 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (selection_column));
1947 toggle_cell->property_activatable() = true;
1948 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_selection_column_toggled), &view));
1951 view.get_selection()->set_mode (SELECTION_NONE);
1952 view.set_tooltip_column (4); /* port "real" name */
1953 view.get_column(0)->set_resizable (true);
1954 view.get_column(0)->set_expand (true);
1958 MidiPortOptions::refill_midi_ports (bool for_input, Gtk::TreeView& view)
1960 using namespace ARDOUR;
1962 std::vector<string> ports;
1964 AudioEngine::instance()->get_known_midi_ports (ports);
1966 if (ports.empty()) {
1971 Glib::RefPtr<ListStore> model = Gtk::ListStore::create (midi_port_columns);
1973 for (vector<string>::const_iterator s = ports.begin(); s != ports.end(); ++s) {
1975 if (AudioEngine::instance()->port_is_mine (*s)) {
1979 PortManager::MidiPortInformation mpi (AudioEngine::instance()->midi_port_information (*s));
1981 if (mpi.pretty_name.empty()) {
1982 /* vanished since get_known_midi_ports() */
1986 if (for_input != mpi.input) {
1990 TreeModel::Row row = *(model->append());
1992 row[midi_port_columns.pretty_name] = mpi.pretty_name;
1993 row[midi_port_columns.music_data] = mpi.properties & MidiPortMusic;
1994 row[midi_port_columns.control_data] = mpi.properties & MidiPortControl;
1995 row[midi_port_columns.selection] = mpi.properties & MidiPortSelection;
1996 row[midi_port_columns.name] = *s;
1999 view.set_model (model);
2005 MidiPortOptions::midi_music_column_toggled (string const & path, TreeView* view)
2007 TreeIter iter = view->get_model()->get_iter (path);
2013 bool new_value = ! bool ((*iter)[midi_port_columns.music_data]);
2015 /* don't reset model - wait for MidiPortInfoChanged signal */
2018 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2020 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2025 MidiPortOptions::midi_control_column_toggled (string const & path, TreeView* view)
2027 TreeIter iter = view->get_model()->get_iter (path);
2033 bool new_value = ! bool ((*iter)[midi_port_columns.control_data]);
2035 /* don't reset model - wait for MidiPortInfoChanged signal */
2038 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2040 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2045 MidiPortOptions::midi_selection_column_toggled (string const & path, TreeView* view)
2047 TreeIter iter = view->get_model()->get_iter (path);
2053 bool new_value = ! bool ((*iter)[midi_port_columns.selection]);
2055 /* don't reset model - wait for MidiSelectionPortsChanged signal */
2058 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2060 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2065 MidiPortOptions::pretty_name_edit (std::string const & path, string const & new_text, Gtk::TreeView* view)
2067 TreeIter iter = view->get_model()->get_iter (path);
2073 boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
2075 ARDOUR::PortEngine::PortHandle ph = backend->get_port_by_name ((*iter)[midi_port_columns.name]);
2077 backend->set_port_property (ph, "http://jackaudio.org/metadata/pretty-name", new_text, "");
2078 (*iter)[midi_port_columns.pretty_name] = new_text;
2086 RCOptionEditor::RCOptionEditor ()
2087 : OptionEditorContainer (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
2088 , Tabbable (*this, _("Preferences")) /* pack self-as-vbox into tabbable */
2089 , _rc_config (Config)
2090 , _mixer_strip_visibility ("mixer-element-visibility")
2092 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
2096 uint32_t hwcpus = hardware_concurrency ();
2098 BoolComboOption* bco;
2101 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
2103 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
2105 _("Signal processing uses"),
2106 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
2107 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
2110 procs->add (-1, _("all but one processor"));
2111 procs->add (0, _("all available processors"));
2113 for (uint32_t i = 1; i <= hwcpus; ++i) {
2114 procs->add (i, string_compose (P_("%1 processor", "%1 processors", i), i));
2117 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
2119 add_option (_("Misc"), procs);
2122 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
2124 add_option (_("Misc"), new UndoOptions (_rc_config));
2126 add_option (_("Misc"),
2128 "verify-remove-last-capture",
2129 _("Verify removal of last capture"),
2130 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
2131 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
2134 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
2136 add_option (_("Misc"),
2138 "periodic-safety-backups",
2139 _("Make periodic backups of the session file"),
2140 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
2141 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
2144 add_option (_("Misc"),
2146 "only-copy-imported-files",
2147 _("Always copy imported files"),
2148 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
2149 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
2152 add_option (_("Misc"), new DirectoryOption (
2153 X_("default-session-parent-dir"),
2154 _("Default folder for new sessions:"),
2155 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
2156 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
2159 add_option (_("Misc"),
2160 new SpinOption<uint32_t> (
2161 "max-recent-sessions",
2162 _("Maximum number of recent sessions"),
2163 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
2164 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
2168 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
2170 add_option (_("Misc"),
2171 new SpinOption<double> (
2172 "automation-thinning-factor",
2173 _("Thinning factor (larger value => less data)"),
2174 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
2175 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
2179 add_option (_("Misc"),
2180 new SpinOption<double> (
2181 "automation-interval-msecs",
2182 _("Automation sampling interval (milliseconds)"),
2183 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
2184 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
2188 add_option (_("Misc"), new OptionEditorHeading (_("Tempo")));
2192 tsf = new BoolOption (
2193 "allow-non-quarter-pulse",
2194 _("Allow non quarter-note pulse"),
2195 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_allow_non_quarter_pulse),
2196 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_allow_non_quarter_pulse)
2198 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2199 string_compose (_("<b>When enabled</b> %1 will allow tempo to be expressed in divisions per minute\n"
2200 "<b>When disabled</b> %1 will only allow tempo to be expressed in quarter notes per minute"),
2202 add_option (_("Misc"), tsf);
2206 add_option (_("Editor"), new OptionEditorHeading (_("Editor Settings")));
2208 add_option (_("Editor"),
2210 "rubberbanding-snaps-to-grid",
2211 _("Snap rubberband to grid"),
2212 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2213 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2216 bo = new BoolOption (
2218 _("Name new markers"),
2219 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2220 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2222 add_option (_("Editor"), bo);
2223 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."
2224 "\n\nYou can always rename markers by right-clicking on them"));
2226 add_option (S_("Editor"),
2228 "draggable-playhead",
2229 _("Allow dragging of playhead"),
2230 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2231 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2234 if (!Profile->get_mixbus()) {
2235 add_option (_("Editor"),
2238 _("Show zoom toolbar (if torn off)"),
2239 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_zoom_tools),
2240 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_zoom_tools)
2243 add_option (_("Editor"),
2245 "use-mouse-position-as-zoom-focus-on-scroll",
2246 _("Zoom to mouse position when zooming with scroll wheel"),
2247 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2248 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2252 add_option (_("Editor"),
2254 "use-time-rulers-to-zoom-with-vertical-drag",
2255 _("Zoom with vertical drag in rulers"),
2256 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag),
2257 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag)
2260 add_option (_("Editor"),
2262 "use-double-click-to-zoom-to-selection",
2263 _("Double click zooms to selection"),
2264 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection),
2265 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection)
2268 add_option (_("Editor"),
2270 "update-editor-during-summary-drag",
2271 _("Update editor window during drags of the summary"),
2272 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2273 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2276 add_option (_("Editor"),
2278 "autoscroll-editor",
2279 _("Auto-scroll editor window when dragging near its edges"),
2280 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2281 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2284 add_option (_("Editor"),
2285 new BoolComboOption (
2286 "show-region-gain-envelopes",
2287 _("Show gain envelopes in audio regions"),
2289 _("only in Draw and Internal Edit modes"),
2290 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2291 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2294 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2296 add_option (_("Editor"),
2298 "automation-follows-regions",
2299 _("Move relevant automation when audio regions are moved"),
2300 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2301 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2304 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2305 "default-fade-shape",
2306 _("Default fade shape"),
2307 sigc::mem_fun (*_rc_config,
2308 &RCConfiguration::get_default_fade_shape),
2309 sigc::mem_fun (*_rc_config,
2310 &RCConfiguration::set_default_fade_shape)
2313 fadeshape->add (FadeLinear,
2314 _("Linear (for highly correlated material)"));
2315 fadeshape->add (FadeConstantPower, _("Constant power"));
2316 fadeshape->add (FadeSymmetric, _("Symmetric"));
2317 fadeshape->add (FadeSlow, _("Slow"));
2318 fadeshape->add (FadeFast, _("Fast"));
2320 add_option (_("Editor"), fadeshape);
2322 bco = new BoolComboOption (
2323 "use-overlap-equivalency",
2324 _("Regions in edit groups are edited together"),
2325 _("whenever they overlap in time"),
2326 _("only if they have identical length and position"),
2327 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2328 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2331 add_option (_("Editor"), bco);
2333 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2335 _("Layering model"),
2336 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2337 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2340 lm->add (LaterHigher, _("later is higher"));
2341 lm->add (Manual, _("manual layering"));
2342 add_option (_("Editor"), lm);
2344 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2345 "region-selection-after-split",
2346 _("After splitting selected regions, select"),
2347 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2348 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2350 // TODO: decide which of these modes are really useful
2351 rsas->add(None, _("no regions"));
2352 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2353 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2354 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2355 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2356 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2357 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2358 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2360 add_option (_("Editor"), rsas);
2362 /* MIXER -- SOLO AND MUTE */
2364 add_option (_("Mixer"), new OptionEditorHeading (_("Solo")));
2366 _solo_control_is_listen_control = new BoolOption (
2367 "solo-control-is-listen-control",
2368 _("Solo controls are Listen controls"),
2369 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2370 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2373 add_option (_("Mixer"), _solo_control_is_listen_control);
2375 add_option (_("Mixer"),
2378 _("Exclusive solo"),
2379 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2380 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2383 add_option (_("Mixer"),
2386 _("Show solo muting"),
2387 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2388 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2391 add_option (_("Mixer"),
2393 "solo-mute-override",
2394 _("Soloing overrides muting"),
2395 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2396 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2399 add_option (_("Mixer"),
2402 _("Solo-in-place mute cut (dB)"),
2403 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2404 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2407 _listen_position = new ComboOption<ListenPosition> (
2409 _("Listen Position"),
2410 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2411 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2414 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2415 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2417 add_option (_("Mixer"), _listen_position);
2419 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2421 _("PFL signals come from"),
2422 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2423 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2426 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2427 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2429 add_option (_("Mixer"), pp);
2431 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2433 _("AFL signals come from"),
2434 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2435 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2438 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2439 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2441 add_option (_("Mixer"), pa);
2443 add_option (_("Mixer"), new OptionEditorHeading (_("Default track / bus muting options")));
2445 add_option (_("Mixer"),
2447 "mute-affects-pre-fader",
2448 _("Mute affects pre-fader sends"),
2449 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2450 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2453 add_option (_("Mixer"),
2455 "mute-affects-post-fader",
2456 _("Mute affects post-fader sends"),
2457 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2458 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2461 add_option (_("Mixer"),
2463 "mute-affects-control-outs",
2464 _("Mute affects control outputs"),
2465 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2466 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2469 add_option (_("Mixer"),
2471 "mute-affects-main-outs",
2472 _("Mute affects main outputs"),
2473 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2474 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2478 if (!ARDOUR::Profile->get_mixbus()) {
2479 add_option (_("Mixer"), new OptionEditorHeading (_("Send Routing")));
2480 add_option (_("Mixer"),
2482 "link-send-and-route-panner",
2483 _("Link panners of Aux and External Sends with main panner by default"),
2484 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2485 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2492 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2494 add_option (_("Audio"), new BufferingOptions (_rc_config));
2496 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2498 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2500 _("Record monitoring handled by"),
2501 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2502 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2505 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2506 mm->add (HardwareMonitoring, _("via Audio Driver"));
2509 string prog (PROGRAM_NAME);
2510 boost::algorithm::to_lower (prog);
2511 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2512 mm->add (ExternalMonitoring, _("audio hardware"));
2514 add_option (_("Audio"), mm);
2516 add_option (_("Audio"),
2518 "tape-machine-mode",
2519 _("Tape machine mode"),
2520 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2521 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2524 add_option (_("Audio"), new OptionEditorHeading (_("Track and Bus Connections")));
2525 if (!Profile->get_mixbus()) {
2527 add_option (_("Audio"),
2529 "auto-connect-standard-busses",
2530 _("Auto-connect master/monitor busses"),
2531 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2532 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2535 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2536 "input-auto-connect",
2537 _("Connect track inputs"),
2538 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2539 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2542 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2543 iac->add (ManualConnect, _("manually"));
2545 add_option (_("Audio"), iac);
2547 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2548 "output-auto-connect",
2549 _("Connect track and bus outputs"),
2550 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2551 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2554 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2555 oac->add (AutoConnectMaster, _("automatically to master bus"));
2556 oac->add (ManualConnect, _("manually"));
2558 add_option (_("Audio"), oac);
2560 bo = new BoolOption (
2562 _("Use 'Strict-I/O' for new tracks or Busses"),
2563 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2564 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2567 add_option (_("Audio"), bo);
2568 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2569 _("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."));
2573 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2575 add_option (_("Audio"),
2577 "denormal-protection",
2578 _("Use DC bias to protect against denormals"),
2579 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2580 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2583 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2585 _("Processor handling"),
2586 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2587 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2591 dm->add (DenormalNone, _("no processor handling"));
2593 FPU* fpu = FPU::instance();
2595 if (fpu->has_flush_to_zero()) {
2597 dm->add (DenormalFTZ, _("use FlushToZero"));
2598 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2599 _rc_config->set_denormal_model(DenormalNone);
2602 if (fpu->has_denormals_are_zero()) {
2604 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2605 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2606 _rc_config->set_denormal_model(DenormalNone);
2609 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2611 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2612 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2613 _rc_config->set_denormal_model(DenormalNone);
2617 dm->set_sensitive(false);
2620 add_option (_("Audio"), dm);
2622 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2624 add_option (_("Audio"),
2626 "auto-analyse-audio",
2627 _("Enable automatic analysis of audio"),
2628 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2629 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2632 add_option (_("Audio"),
2634 "replicate-missing-region-channels",
2635 _("Replicate missing region channels"),
2636 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2637 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2642 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Preferences")));
2644 add_option (_("MIDI"),
2645 new SpinOption<float> (
2647 _("MIDI read-ahead time (seconds)"),
2648 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2649 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2654 add_option (_("MIDI"),
2655 new SpinOption<int32_t> (
2656 "initial-program-change",
2657 _("Initial program change"),
2658 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2659 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2663 add_option (_("MIDI"),
2665 "display-first-midi-bank-as-zero",
2666 _("Display first MIDI bank/program as 0"),
2667 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2668 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2671 add_option (_("MIDI"),
2673 "never-display-periodic-midi",
2674 _("Don't display periodic (MTC, MMC) SysEx messages in MIDI Regions"),
2675 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
2676 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
2679 add_option (_("MIDI"),
2682 _("Sound MIDI notes as they are selected in the editor"),
2683 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2684 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2687 add_option (_("MIDI"),
2690 _("Send MIDI control feedback"),
2691 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2692 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2695 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Audition")));
2697 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2698 "midi-audition-synth-uri",
2699 _("MIDI Audition Synth (LV2)"),
2700 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2701 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2704 audition_synth->add(X_(""), _("None"));
2705 PluginInfoList all_plugs;
2706 PluginManager& manager (PluginManager::instance());
2708 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2710 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2711 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2712 if (!(*i)->is_instrument()) continue;
2713 if ((*i)->type != ARDOUR::LV2) continue;
2714 if ((*i)->name.length() > 46) {
2715 audition_synth->add((*i)->unique_id, (*i)->name.substr (0, 44) + "...");
2717 audition_synth->add((*i)->unique_id, (*i)->name);
2722 add_option (_("MIDI"), audition_synth);
2726 add_option (_("Metronome"), new OptionEditorHeading (_("Click")));
2727 add_option (_("Metronome"), new ClickOptions (_rc_config));
2730 /* TRANSPORT & Sync */
2732 add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options")));
2734 tsf = new BoolOption (
2735 "latched-record-enable",
2736 _("Keep record-enable engaged on stop"),
2737 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
2738 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
2740 add_option (_("Transport"), tsf);
2742 tsf = new BoolOption (
2744 _("Play loop is a transport mode"),
2745 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
2746 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
2748 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2749 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
2750 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
2751 add_option (_("Transport"), tsf);
2753 tsf = new BoolOption (
2754 "stop-recording-on-xrun",
2755 _("Stop recording when an xrun occurs"),
2756 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
2757 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
2759 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2760 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
2762 add_option (_("Transport"), tsf);
2764 tsf = new BoolOption (
2765 "create-xrun-marker",
2766 _("Create markers where xruns occur"),
2767 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
2768 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
2770 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
2771 add_option (_("Transport"), tsf);
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 (
2788 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
2789 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
2790 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
2792 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2793 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
2794 "preventing any need to do a transport locate at the end of the loop\n\n"
2795 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
2796 "which will often cause a small click or delay"), PROGRAM_NAME));
2797 add_option (_("Transport"), tsf);
2799 tsf = new BoolOption (
2800 "disable-disarm-during-roll",
2801 _("Disable per-track record disarm while rolling"),
2802 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
2803 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
2805 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"));
2806 add_option (_("Transport"), tsf);
2808 tsf = new BoolOption (
2810 _("12dB gain reduction during fast-forward and fast-rewind"),
2811 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
2812 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2814 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
2815 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2816 add_option (_("Transport"), tsf);
2818 ComboOption<float>* psc = new ComboOption<float> (
2821 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
2822 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
2824 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
2825 (_("The amount of preroll (in seconds) to apply when <b>Play with Preroll</b> is initiated.\n\n"
2826 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
2827 psc->add (0.0, _("0 (no pre-roll)"));
2828 psc->add (0.1, _("0.1 second"));
2829 psc->add (0.25, _("0.25 second"));
2830 psc->add (0.5, _("0.5 second"));
2831 psc->add (1.0, _("1.0 second"));
2832 psc->add (2.0, _("2.0 seconds"));
2833 add_option (_("Transport"), psc);
2835 add_option (_("Sync"), new OptionEditorHeading (S_("Synchronization and Slave Options")));
2837 _sync_source = new ComboOption<SyncSource> (
2839 _("External timecode source"),
2840 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
2841 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
2844 add_option (_("Sync"), _sync_source);
2846 _sync_framerate = new BoolOption (
2847 "timecode-sync-frame-rate",
2848 _("Match session video frame rate to external timecode"),
2849 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
2850 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
2852 Gtkmm2ext::UI::instance()->set_tip
2853 (_sync_framerate->tip_widget(),
2854 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
2855 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
2856 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
2857 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
2858 "timecode standard and the session standard."), PROGRAM_NAME));
2860 add_option (_("Sync"), _sync_framerate);
2862 _sync_genlock = new BoolOption (
2863 "timecode-source-is-synced",
2864 _("Sync-lock timecode to clock (disable drift compensation)"),
2865 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
2866 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
2868 Gtkmm2ext::UI::instance()->set_tip
2869 (_sync_genlock->tip_widget(),
2870 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
2871 "Sync Lock indicates that the selected external timecode source shares clock-sync "
2872 "(Black & Burst, Wordclock, etc) with the audio interface. "
2873 "This option disables drift compensation. The transport speed is fixed at 1.0. "
2874 "Vari-speed LTC will be ignored and cause drift."
2876 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
2877 "timecode sources shares clock sync."
2881 add_option (_("Sync"), _sync_genlock);
2883 _sync_source_2997 = new BoolOption (
2884 "timecode-source-2997",
2885 _("Lock to 29.9700 fps instead of 30000/1001"),
2886 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
2887 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
2889 Gtkmm2ext::UI::instance()->set_tip
2890 (_sync_source_2997->tip_widget(),
2891 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
2892 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
2893 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
2894 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
2895 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
2896 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
2899 add_option (_("Sync"), _sync_source_2997);
2901 add_option (_("Sync/LTC"), new OptionEditorHeading (S_("LTC Reader")));
2903 _ltc_port = new ComboStringOption (
2905 _("LTC incoming port"),
2906 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
2907 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
2910 vector<string> physical_inputs;
2911 physical_inputs.push_back (_("None"));
2912 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
2913 _ltc_port->set_popdown_strings (physical_inputs);
2915 populate_sync_options ();
2916 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
2918 add_option (_("Sync/LTC"), _ltc_port);
2920 add_option (_("Sync/LTC"), new OptionEditorHeading (S_("LTC Generator")));
2922 add_option (_("Sync/LTC"),
2925 _("Enable LTC generator"),
2926 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
2927 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
2930 _ltc_send_continuously = new BoolOption (
2931 "ltc-send-continuously",
2932 _("Send LTC while stopped"),
2933 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
2934 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
2936 Gtkmm2ext::UI::instance()->set_tip
2937 (_ltc_send_continuously->tip_widget(),
2938 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
2939 add_option (_("Sync/LTC"), _ltc_send_continuously);
2941 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"),
2942 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_output_volume),
2943 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_output_volume),
2947 Gtkmm2ext::UI::instance()->set_tip
2948 (_ltc_volume_slider->tip_widget(),
2949 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
2951 add_option (_("Sync/LTC"), _ltc_volume_slider);
2954 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Beat Clock (Mclk) Generator")));
2956 add_option (_("Sync/MIDI"),
2959 _("Enable Mclk generator"),
2960 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2961 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2964 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC) Generator")));
2966 add_option (_("Sync/MIDI"),
2969 _("Enable MTC Generator"),
2970 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2971 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2974 add_option (_("Sync/MIDI"),
2975 new SpinOption<int> (
2976 "mtc-qf-speed-tolerance",
2977 _("Percentage either side of normal transport speed to transmit MTC"),
2978 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2979 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2983 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Machine Control (MMC)")));
2985 add_option (_("Sync/MIDI"),
2988 _("Respond to MMC commands"),
2989 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2990 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2993 add_option (_("Sync/MIDI"),
2996 _("Send MMC commands"),
2997 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2998 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
3001 add_option (_("Sync/MIDI"),
3002 new SpinOption<uint8_t> (
3003 "mmc-receive-device-id",
3004 _("Inbound MMC device ID"),
3005 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
3006 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
3010 add_option (_("Sync/MIDI"),
3011 new SpinOption<uint8_t> (
3012 "mmc-send-device-id",
3013 _("Outbound MMC device ID"),
3014 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
3015 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
3020 /* Control Surfaces */
3022 add_option (_("Control Surfaces"), new OptionEditorHeading (_("Control Surfaces")));
3023 add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
3026 add_option (_("MIDI Ports"), new OptionEditorHeading (_("MIDI Port Options")));
3028 add_option (_("MIDI Ports"),
3030 "get-midi-input-follows-selection",
3031 _("MIDI input follows MIDI track selection"),
3032 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
3033 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
3036 add_option (_("MIDI Ports"), new MidiPortOptions ());
3037 add_option (_("MIDI Ports"), new OptionEditorBlank ());
3041 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3042 add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
3043 add_option (_("Plugins"),
3044 new RcActionButton (_("Scan for Plugins"),
3045 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3049 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
3051 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3052 bo = new BoolOption (
3053 "show-plugin-scan-window",
3054 _("Always Display Plugin Scan Progress"),
3055 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
3056 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
3058 add_option (_("Plugins"), bo);
3059 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3060 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
3063 bo = new BoolOption (
3064 "plugins-stop-with-transport",
3065 _("Silence plugins when the transport is stopped"),
3066 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
3067 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
3069 add_option (_("Plugins"), bo);
3070 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3071 _("<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."));
3073 bo = new BoolOption (
3074 "new-plugins-active",
3075 _("Make new plugins active"),
3076 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
3077 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
3079 add_option (_("Plugins"), bo);
3080 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3081 _("<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"));
3083 #if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
3084 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
3086 add_option (_("Plugins/VST"),
3087 new RcActionButton (_("Scan for Plugins"),
3088 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3091 #if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
3092 bo = new BoolOption (
3094 _("Enable Mac VST support (requires restart or re-scan)"),
3095 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
3096 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
3098 add_option (_("Plugins/VST"), bo);
3101 bo = new BoolOption (
3102 "discover-vst-on-start",
3103 _("Scan for [new] VST Plugins on Application Start"),
3104 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
3105 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
3107 add_option (_("Plugins/VST"), bo);
3108 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3109 _("<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"));
3111 #ifdef WINDOWS_VST_SUPPORT
3112 // currently verbose logging is only implemented for Windows VST.
3113 bo = new BoolOption (
3114 "verbose-plugin-scan",
3115 _("Verbose Plugin Scan"),
3116 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
3117 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
3119 add_option (_("Plugins/VST"), bo);
3120 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3121 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
3124 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
3126 add_option (_("Plugins/VST"),
3127 new RcActionButton (_("Clear"),
3128 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
3131 add_option (_("Plugins/VST"),
3132 new RcActionButton (_("Clear"),
3133 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
3134 _("VST Blacklist:")));
3137 #ifdef LXVST_SUPPORT
3138 add_option (_("Plugins/VST"),
3139 new RcActionButton (_("Edit"),
3140 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
3141 _("Linux VST Path:")));
3143 add_option (_("Plugins/VST"),
3144 new RcConfigDisplay (
3145 "plugin-path-lxvst",
3147 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
3151 #ifdef WINDOWS_VST_SUPPORT
3152 add_option (_("Plugins/VST"),
3153 new RcActionButton (_("Edit"),
3154 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
3155 _("Windows VST Path:")));
3156 add_option (_("Plugins/VST"),
3157 new RcConfigDisplay (
3160 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
3164 #ifdef AUDIOUNIT_SUPPORT
3166 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
3168 add_option (_("Plugins/Audio Unit"),
3169 new RcActionButton (_("Scan for Plugins"),
3170 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3173 bo = new BoolOption (
3174 "discover-audio-units",
3175 _("Scan for [new] AudioUnit Plugins on Application Start"),
3176 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
3177 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
3179 add_option (_("Plugins/Audio Unit"), bo);
3180 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3181 _("<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."));
3183 add_option (_("Plugins/Audio Unit"),
3184 new RcActionButton (_("Clear"),
3185 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
3188 add_option (_("Plugins/Audio Unit"),
3189 new RcActionButton (_("Clear"),
3190 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
3191 _("AU Blacklist:")));
3194 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
3195 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
3196 add_option (_("Plugins"),
3198 "open-gui-after-adding-plugin",
3199 _("Automatically open the plugin GUI when adding a new plugin"),
3200 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
3201 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3204 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3205 add_option (_("Plugins"),
3207 "show-inline-display-by-default",
3208 _("Show Plugin Inline Display on Mixerstrip by default"),
3209 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3210 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3213 _plugin_prefer_inline = new BoolOption (
3214 "prefer-inline-over-gui",
3215 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3216 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3217 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3219 add_option (_("Plugins"), _plugin_prefer_inline);
3222 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3224 bo = new BoolOption (
3225 "ask-replace-instrument",
3226 _("Ask to replace existing instrument plugin"),
3227 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3228 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3230 add_option (_("Plugins"), bo);
3232 bo = new BoolOption (
3233 "ask-setup_instrument",
3234 _("Interactively configure instrument plugins on insert"),
3235 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3236 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3238 add_option (_("Plugins"), bo);
3239 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3240 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3243 add_option (_("Plugins"), new OptionEditorBlank ());
3246 #if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
3247 add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Graphics Acceleration")));
3250 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3251 BoolOption* bgc = new BoolOption (
3252 "cairo-image-surface",
3253 _("Disable Graphics Hardware Acceleration (requires restart)"),
3254 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3255 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3258 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3259 _("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));
3260 add_option (S_("Preferences|GUI"), bgc);
3263 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3264 BoolOption* bgo = new BoolOption (
3266 _("Possibly improve slow graphical performance (requires restart)"),
3267 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3268 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3271 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));
3272 add_option (S_("Preferences|GUI"), bgo);
3274 add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Graphical User Interface")));
3276 add_option (S_("Preferences|GUI"),
3279 _("Highlight widgets on mouseover"),
3280 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3281 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3284 add_option (S_("Preferences|GUI"),
3287 _("Show tooltips if mouse hovers over a control"),
3288 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3289 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3292 bo = new BoolOption (
3293 "super-rapid-clock-update",
3294 _("Update clocks at TC Frame rate"),
3295 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3296 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3298 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3299 _("<b>When enabled</b> clock displays are updated every Timecode Frame (fps).\n\n"
3300 "<b>When disabled</b> clock displays are updated only every 100ms."
3302 add_option (S_("Preferences|GUI"), bo);
3304 add_option (S_("Preferences|GUI"),
3307 _("Blink Rec-Arm buttons"),
3308 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_rec_arm),
3309 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_rec_arm)
3314 /* font scaling does nothing with GDK/Quartz */
3315 add_option (S_("Preferences|GUI"), new FontScalingOptions ());
3318 /* Image cache size */
3320 HSliderOption *sics = new HSliderOption ("waveform-cache-size",
3321 _("Waveform image cache size (megabytes)"),
3322 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
3323 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size),
3324 1, 1024, 10 /* 1 MB to 1GB in steps of 10MB */
3326 sics->scale().set_digits (0);
3327 Gtkmm2ext::UI::instance()->set_tip (
3329 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
3330 add_option (S_("Preferences|GUI"), sics);
3332 if (!ARDOUR::Profile->get_mixbus()) {
3333 /* Lock GUI timeout */
3335 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
3336 _("Lock timeout (seconds)"),
3337 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
3338 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds),
3341 slts->scale().set_digits (0);
3342 Gtkmm2ext::UI::instance()->set_tip (
3344 _("Lock GUI after this many idle seconds (zero to never lock)"));
3345 add_option (S_("Preferences|GUI"), slts);
3348 add_option (_("GUI/Editor"), new OptionEditorHeading (_("Editor UI Options")));
3349 add_option (_("GUI/Editor"),
3351 "show-name-highlight",
3352 _("Use name highlight bars in region displays (requires a restart)"),
3353 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3354 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3357 add_option (_("GUI/Editor"),
3359 "color-regions-using-track-color",
3360 _("Region color follows track color"),
3361 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_color_regions_using_track_color),
3362 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_color_regions_using_track_color)
3365 add_option (_("GUI/Editor"),
3367 "show-waveform-clipping",
3368 _("Show waveform clipping"),
3369 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveform_clipping),
3370 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveform_clipping)
3374 add_option (_("GUI/Editor"), new OptionEditorHeading (_("Waveforms")));
3376 if (!Profile->get_mixbus()) {
3377 add_option (_("GUI/Editor"),
3380 _("Show waveforms in regions"),
3381 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
3382 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
3386 add_option (_("GUI/Editor"),
3388 "show-waveforms-while-recording",
3389 _("Show waveforms while recording"),
3390 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
3391 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
3394 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
3396 _("Waveform scale"),
3397 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
3398 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
3401 wfs->add (Linear, _("linear"));
3402 wfs->add (Logarithmic, _("logarithmic"));
3404 add_option (_("GUI/Editor"), wfs);
3406 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
3408 _("Waveform shape"),
3409 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
3410 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
3413 wfsh->add (Traditional, _("traditional"));
3414 wfsh->add (Rectified, _("rectified"));
3416 add_option (_("GUI/Editor"), wfsh);
3418 add_option (_("GUI/Editor"), new ClipLevelOptions ());
3421 add_option (_("GUI/Editor"), new OptionEditorBlank ());
3423 /* The names of these controls must be the same as those given in MixerStrip
3424 for the actual widgets being controlled.
3426 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3427 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3428 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3429 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3430 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3431 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3432 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3434 add_option (_("GUI/Mixer"),
3435 new VisibilityOption (
3437 &_mixer_strip_visibility,
3438 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3439 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3443 add_option (_("GUI/Mixer"),
3445 "default-narrow_ms",
3446 _("Use narrow strips in the mixer by default"),
3447 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3448 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3451 add_option (_("GUI/Mixer"), new OptionEditorBlank ());
3454 OptionEditorHeading* i18n_head = new OptionEditorHeading (_("Internationalization"));
3456 add_option (_("GUI/Translation"), i18n_head);
3458 bo = new BoolOption (
3459 "enable-translation",
3460 _("Use translations"),
3461 sigc::ptr_fun (ARDOUR::translations_are_enabled),
3462 sigc::ptr_fun (ARDOUR::set_translations_enabled)
3465 bo->set_note (string_compose (_("These settings will only take effect after %1 is restarted (if available for your language preferences)."), PROGRAM_NAME));
3467 add_option (_("GUI/Translation"), bo);
3469 _l10n = new ComboOption<ARDOUR::LocaleMode> (
3472 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_locale_mode),
3473 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_locale_mode)
3476 _l10n->add (ARDOUR::SET_LC_ALL, _("Set complete locale"));
3477 _l10n->add (ARDOUR::SET_LC_MESSAGES, _("Enable only message translation"));
3478 _l10n->add (ARDOUR::SET_LC_MESSAGES_AND_LC_NUMERIC, _("Translate messages and format numeric format"));
3479 _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."));
3481 add_option (_("GUI/Translation"), _l10n);
3482 parameter_changed ("enable-translation");
3483 #endif // ENABLE_NLS
3485 add_option (_("GUI/Keyboard"), new OptionEditorHeading (_("Keyboard")));
3486 add_option (_("GUI/Keyboard"), new KeyboardOptions);
3488 add_option (_("GUI/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items")));
3490 add_option (_("GUI/Toolbar"),
3492 "show-toolbar-selclock",
3493 _("Display Selection Clock"),
3494 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
3495 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
3498 if (!ARDOUR::Profile->get_small_screen()) {
3499 add_option (_("GUI/Toolbar"),
3501 "show-secondary-clock",
3502 _("Display Secondary Clock"),
3503 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
3504 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
3508 add_option (_("GUI/Toolbar"),
3510 "show-mini-timeline",
3511 _("Display Navigation Timeline"),
3512 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
3513 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
3516 add_option (_("GUI/Toolbar"),
3518 "show-editor-meter",
3519 _("Display Master Level Meter"),
3520 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
3521 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
3524 add_option (_("GUI/Toolbar"),
3525 new ColumVisibilityOption (
3526 "action-table-columns", _("Lua Action Script Button Visibility"), 4,
3527 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3528 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3531 add_option (_("GUI/Toolbar"), new OptionEditorBlank ());
3533 add_option (_("GUI/Quirks"), new OptionEditorHeading (_("Various Workarounds for Windowing Systems")));
3534 add_option (_("GUI/Quirks"),
3536 "use-wm-visibility",
3537 _("Use Window Manager/Desktop visibility information"),
3538 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3539 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3543 bo = new BoolOption (
3544 "all-floating-windows-are-dialogs",
3545 _("All floating windows are dialogs"),
3546 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_all_floating_windows_are_dialogs),
3547 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_all_floating_windows_are_dialogs)
3549 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (), string_compose (
3550 _("Mark all floating windows to be type \"Dialog\" rather than using \"Utility\" for some.\n"
3551 "This may help with some window managers. This requires a restart of %1 to take effect"),
3553 add_option (_("GUI/Quirks"), bo);
3555 bo = new BoolOption (
3556 "transients-follow-front",
3557 _("Transient windows follow front window."),
3558 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_transients_follow_front),
3559 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_transients_follow_front)
3561 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (), string_compose (
3562 _("Make transient windows follow the front window when toggling between the editor and mixer.\n"
3563 "This requires a restart of %1 to take effect"), PROGRAM_NAME));
3564 add_option (_("GUI/Quirks"), bo);
3567 if (!Profile->get_mixbus()) {
3568 bo = new BoolOption (
3569 "floating-monitor-section",
3570 _("Float detached monitor-section window"),
3571 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_floating_monitor_section),
3572 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_floating_monitor_section)
3574 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (), string_compose (
3575 _("When detaching the monitoring section, mark it as \"Utility\" window to stay in front.\n"
3576 "This requires a restart of %1 to take effect"), PROGRAM_NAME));
3577 add_option (_("GUI/Quirks"), bo);
3580 add_option (_("GUI/Quirks"), new OptionEditorBlank ());
3582 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
3584 ComboOption<float>* mht = new ComboOption<float> (
3586 _("Peak hold time"),
3587 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
3588 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
3591 mht->add (MeterHoldOff, _("off"));
3592 mht->add (MeterHoldShort, _("short"));
3593 mht->add (MeterHoldMedium, _("medium"));
3594 mht->add (MeterHoldLong, _("long"));
3596 add_option (S_("Preferences|Metering"), mht);
3598 ComboOption<float>* mfo = new ComboOption<float> (
3601 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
3602 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
3605 mfo->add (METER_FALLOFF_OFF, _("off"));
3606 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
3607 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
3608 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
3609 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
3610 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
3611 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
3613 add_option (S_("Preferences|Metering"), mfo);
3615 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
3616 "meter-line-up-level",
3617 _("Meter line-up level; 0dBu"),
3618 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
3619 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
3622 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3623 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3624 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3625 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3627 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."));
3629 add_option (S_("Preferences|Metering"), mlu);
3631 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
3632 "meter-line-up-din",
3633 _("IEC1/DIN Meter line-up level; 0dBu"),
3634 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
3635 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
3638 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3639 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3640 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3641 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3643 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
3645 add_option (S_("Preferences|Metering"), mld);
3647 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
3648 "meter-vu-standard",
3649 _("VU Meter standard"),
3650 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
3651 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
3654 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
3655 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
3656 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
3657 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
3659 add_option (S_("Preferences|Metering"), mvu);
3661 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3662 "meter-type-master",
3663 _("Default Meter Type for Master Bus"),
3664 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3665 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3667 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3668 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3669 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3670 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3671 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3672 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3673 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3674 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3676 add_option (S_("Preferences|Metering"), mtm);
3679 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3681 _("Default Meter Type for Busses"),
3682 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3683 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3685 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3686 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3687 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3688 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3689 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3690 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3691 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3692 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3694 add_option (S_("Preferences|Metering"), mtb);
3696 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3698 _("Default Meter Type for Tracks"),
3699 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3700 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3702 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3703 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3705 add_option (S_("Preferences|Metering"), mtt);
3707 HSliderOption *mpks = new HSliderOption("meter-peak",
3708 _("Peak threshold [dBFS]"),
3709 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
3710 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak),
3714 Gtkmm2ext::UI::instance()->set_tip (
3716 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
3718 add_option (S_("Preferences|Metering"), mpks);
3720 add_option (S_("Preferences|Metering"),
3723 _("LED meter style"),
3724 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3725 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3728 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Editor Meters")));
3730 add_option (S_("Preferences|Metering"),
3732 "show-track-meters",
3733 _("Show meters on tracks in the editor"),
3734 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3735 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3738 add_option (S_("Preferences|Metering"),
3740 "editor-stereo-only-meters",
3741 _("Show at most stereo meters in the track-header"),
3742 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3743 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3746 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
3748 add_option (S_("Preferences|Metering"),
3750 "save-export-analysis-image",
3751 _("Save loudness analysis as image file"),
3752 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
3753 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
3756 /* VIDEO Timeline */
3757 add_option (_("Video"), new OptionEditorHeading (_("Video Server")));
3758 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
3760 /* and now the theme manager */
3762 add_option (_("Theme"), new OptionEditorHeading (_("Theme")));
3763 add_option (_("Theme"), new ThemeManager);
3765 add_option (_("Theme/Colors"), new OptionEditorHeading (_("Colors")));
3766 add_option (_("Theme/Colors"), new ColorThemeManager);
3768 Widget::show_all ();
3770 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3771 parameter_changed ("send-ltc");
3772 parameter_changed ("sync-source");
3773 parameter_changed ("use-monitor-bus");
3774 parameter_changed ("open-gui-after-adding-plugin");
3776 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
3778 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
3779 (Gtk::StateType) here !!!
3781 Tabbable::set_state (*node, Stateful::loading_state_version);
3784 set_current_page (_("Misc"));
3788 RCOptionEditor::parameter_changed (string const & p)
3790 OptionEditor::parameter_changed (p);
3792 if (p == "use-monitor-bus") {
3793 bool const s = Config->get_use_monitor_bus ();
3795 /* we can't use this if we don't have a monitor bus */
3796 Config->set_solo_control_is_listen_control (false);
3798 _solo_control_is_listen_control->set_sensitive (s);
3799 _listen_position->set_sensitive (s);
3800 } else if (p == "sync-source") {
3801 _sync_source->set_sensitive (true);
3803 _sync_source->set_sensitive (!_session->config.get_external_sync());
3805 switch(Config->get_sync_source()) {
3808 _sync_genlock->set_sensitive (true);
3809 _sync_framerate->set_sensitive (true);
3810 _sync_source_2997->set_sensitive (true);
3813 _sync_genlock->set_sensitive (false);
3814 _sync_framerate->set_sensitive (false);
3815 _sync_source_2997->set_sensitive (false);
3818 } else if (p == "send-ltc") {
3819 bool const s = Config->get_send_ltc ();
3820 _ltc_send_continuously->set_sensitive (s);
3821 _ltc_volume_slider->set_sensitive (s);
3822 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
3823 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3824 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
3827 } else if (p == "enable-translation") {
3828 _l10n->set_sensitive (ARDOUR::translations_are_enabled ());
3833 void RCOptionEditor::plugin_scan_refresh () {
3834 PluginManager::instance().refresh();
3837 void RCOptionEditor::clear_vst_cache () {
3838 PluginManager::instance().clear_vst_cache();
3841 void RCOptionEditor::clear_vst_blacklist () {
3842 PluginManager::instance().clear_vst_blacklist();
3845 void RCOptionEditor::clear_au_cache () {
3846 PluginManager::instance().clear_au_cache();
3849 void RCOptionEditor::clear_au_blacklist () {
3850 PluginManager::instance().clear_au_blacklist();
3853 void RCOptionEditor::edit_lxvst_path () {
3854 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
3855 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3856 *current_toplevel(), _("Set Linux VST Search Path"),
3857 _rc_config->get_plugin_path_lxvst(),
3858 PluginManager::instance().get_default_lxvst_path()
3860 ResponseType r = (ResponseType) pd->run ();
3862 if (r == RESPONSE_ACCEPT) {
3863 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
3868 void RCOptionEditor::edit_vst_path () {
3869 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3870 *current_toplevel(), _("Set Windows VST Search Path"),
3871 _rc_config->get_plugin_path_vst(),
3872 PluginManager::instance().get_default_windows_vst_path()
3874 ResponseType r = (ResponseType) pd->run ();
3876 if (r == RESPONSE_ACCEPT) {
3877 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
3884 RCOptionEditor::populate_sync_options ()
3886 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3888 _sync_source->clear ();
3890 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3891 _sync_source->add (*i, sync_source_to_string (*i));
3894 if (sync_opts.empty()) {
3895 _sync_source->set_sensitive(false);
3897 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3898 _rc_config->set_sync_source(sync_opts.front());
3902 parameter_changed ("sync-source");
3906 RCOptionEditor::use_own_window (bool and_fill_it)
3908 bool new_window = !own_window ();
3910 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
3912 if (win && new_window) {
3913 win->set_name ("PreferencesWindow");
3914 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
3921 RCOptionEditor::get_state ()
3923 XMLNode* node = new XMLNode (X_("Preferences"));
3924 node->add_child_nocopy (Tabbable::get_state());