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 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
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 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
2741 add_option (_("Transport"), tsf);
2743 tsf = new BoolOption (
2745 _("Play loop is a transport mode"),
2746 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
2747 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
2749 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2750 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
2751 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
2752 add_option (_("Transport"), tsf);
2754 tsf = new BoolOption (
2755 "stop-recording-on-xrun",
2756 _("Stop recording when an xrun occurs"),
2757 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
2758 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
2760 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2761 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
2763 add_option (_("Transport"), tsf);
2765 tsf = new BoolOption (
2766 "create-xrun-marker",
2767 _("Create markers where xruns occur"),
2768 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
2769 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
2771 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
2772 add_option (_("Transport"), tsf);
2774 tsf = new BoolOption (
2775 "stop-at-session-end",
2776 _("Stop at the end of the session"),
2777 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
2778 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
2780 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2781 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
2782 "when it reaches the current session end marker\n\n"
2783 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
2785 add_option (_("Transport"), tsf);
2787 tsf = new BoolOption (
2789 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
2790 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
2791 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
2793 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2794 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
2795 "preventing any need to do a transport locate at the end of the loop\n\n"
2796 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
2797 "which will often cause a small click or delay"), PROGRAM_NAME));
2798 add_option (_("Transport"), tsf);
2800 tsf = new BoolOption (
2801 "disable-disarm-during-roll",
2802 _("Disable per-track record disarm while rolling"),
2803 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
2804 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
2806 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"));
2807 add_option (_("Transport"), tsf);
2809 tsf = new BoolOption (
2811 _("12dB gain reduction during fast-forward and fast-rewind"),
2812 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
2813 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2815 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
2816 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2817 add_option (_("Transport"), tsf);
2819 ComboOption<float>* psc = new ComboOption<float> (
2822 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
2823 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
2825 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
2826 (_("The amount of preroll (in seconds) to apply when <b>Play with Preroll</b> is initiated.\n\n"
2827 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
2828 psc->add (0.0, _("0 (no pre-roll)"));
2829 psc->add (0.1, _("0.1 second"));
2830 psc->add (0.25, _("0.25 second"));
2831 psc->add (0.5, _("0.5 second"));
2832 psc->add (1.0, _("1.0 second"));
2833 psc->add (2.0, _("2.0 seconds"));
2834 add_option (_("Transport"), psc);
2836 add_option (_("Sync"), new OptionEditorHeading (S_("Synchronization and Slave Options")));
2838 _sync_source = new ComboOption<SyncSource> (
2840 _("External timecode source"),
2841 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
2842 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
2845 add_option (_("Sync"), _sync_source);
2847 _sync_framerate = new BoolOption (
2848 "timecode-sync-frame-rate",
2849 _("Match session video frame rate to external timecode"),
2850 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
2851 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
2853 Gtkmm2ext::UI::instance()->set_tip
2854 (_sync_framerate->tip_widget(),
2855 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
2856 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
2857 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
2858 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
2859 "timecode standard and the session standard."), PROGRAM_NAME));
2861 add_option (_("Sync"), _sync_framerate);
2863 _sync_genlock = new BoolOption (
2864 "timecode-source-is-synced",
2865 _("Sync-lock timecode to clock (disable drift compensation)"),
2866 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
2867 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
2869 Gtkmm2ext::UI::instance()->set_tip
2870 (_sync_genlock->tip_widget(),
2871 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
2872 "Sync Lock indicates that the selected external timecode source shares clock-sync "
2873 "(Black & Burst, Wordclock, etc) with the audio interface. "
2874 "This option disables drift compensation. The transport speed is fixed at 1.0. "
2875 "Vari-speed LTC will be ignored and cause drift."
2877 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
2878 "timecode sources shares clock sync."
2882 add_option (_("Sync"), _sync_genlock);
2884 _sync_source_2997 = new BoolOption (
2885 "timecode-source-2997",
2886 _("Lock to 29.9700 fps instead of 30000/1001"),
2887 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
2888 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
2890 Gtkmm2ext::UI::instance()->set_tip
2891 (_sync_source_2997->tip_widget(),
2892 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
2893 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
2894 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
2895 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
2896 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
2897 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
2900 add_option (_("Sync"), _sync_source_2997);
2902 add_option (_("Sync/LTC"), new OptionEditorHeading (S_("LTC Reader")));
2904 _ltc_port = new ComboStringOption (
2906 _("LTC incoming port"),
2907 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
2908 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
2911 vector<string> physical_inputs;
2912 physical_inputs.push_back (_("None"));
2913 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
2914 _ltc_port->set_popdown_strings (physical_inputs);
2916 populate_sync_options ();
2917 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
2919 add_option (_("Sync/LTC"), _ltc_port);
2921 add_option (_("Sync/LTC"), new OptionEditorHeading (S_("LTC Generator")));
2923 add_option (_("Sync/LTC"),
2926 _("Enable LTC generator"),
2927 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
2928 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
2931 _ltc_send_continuously = new BoolOption (
2932 "ltc-send-continuously",
2933 _("Send LTC while stopped"),
2934 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
2935 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
2937 Gtkmm2ext::UI::instance()->set_tip
2938 (_ltc_send_continuously->tip_widget(),
2939 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
2940 add_option (_("Sync/LTC"), _ltc_send_continuously);
2942 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"),
2943 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_output_volume),
2944 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_output_volume),
2948 Gtkmm2ext::UI::instance()->set_tip
2949 (_ltc_volume_slider->tip_widget(),
2950 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
2952 add_option (_("Sync/LTC"), _ltc_volume_slider);
2955 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Beat Clock (Mclk) Generator")));
2957 add_option (_("Sync/MIDI"),
2960 _("Enable Mclk generator"),
2961 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2962 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2965 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC) Generator")));
2967 add_option (_("Sync/MIDI"),
2970 _("Enable MTC Generator"),
2971 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2972 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2975 add_option (_("Sync/MIDI"),
2976 new SpinOption<int> (
2977 "mtc-qf-speed-tolerance",
2978 _("Percentage either side of normal transport speed to transmit MTC"),
2979 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2980 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2984 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Machine Control (MMC)")));
2986 add_option (_("Sync/MIDI"),
2989 _("Respond to MMC commands"),
2990 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2991 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2994 add_option (_("Sync/MIDI"),
2997 _("Send MMC commands"),
2998 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2999 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
3002 add_option (_("Sync/MIDI"),
3003 new SpinOption<uint8_t> (
3004 "mmc-receive-device-id",
3005 _("Inbound MMC device ID"),
3006 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
3007 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
3011 add_option (_("Sync/MIDI"),
3012 new SpinOption<uint8_t> (
3013 "mmc-send-device-id",
3014 _("Outbound MMC device ID"),
3015 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
3016 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
3021 /* Control Surfaces */
3023 add_option (_("Control Surfaces"), new OptionEditorHeading (_("Control Surfaces")));
3024 add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
3027 add_option (_("MIDI Ports"), new OptionEditorHeading (_("MIDI Port Options")));
3029 add_option (_("MIDI Ports"),
3031 "get-midi-input-follows-selection",
3032 _("MIDI input follows MIDI track selection"),
3033 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
3034 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
3037 add_option (_("MIDI Ports"), new MidiPortOptions ());
3038 add_option (_("MIDI Ports"), new OptionEditorBlank ());
3042 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3043 add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
3044 add_option (_("Plugins"),
3045 new RcActionButton (_("Scan for Plugins"),
3046 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3050 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
3052 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3053 bo = new BoolOption (
3054 "show-plugin-scan-window",
3055 _("Always Display Plugin Scan Progress"),
3056 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
3057 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
3059 add_option (_("Plugins"), bo);
3060 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3061 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
3064 bo = new BoolOption (
3065 "plugins-stop-with-transport",
3066 _("Silence plugins when the transport is stopped"),
3067 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
3068 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
3070 add_option (_("Plugins"), bo);
3071 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3072 _("<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."));
3074 bo = new BoolOption (
3075 "new-plugins-active",
3076 _("Make new plugins active"),
3077 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
3078 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
3080 add_option (_("Plugins"), bo);
3081 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3082 _("<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"));
3084 #if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
3085 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
3087 add_option (_("Plugins/VST"),
3088 new RcActionButton (_("Scan for Plugins"),
3089 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3092 #if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
3093 bo = new BoolOption (
3095 _("Enable Mac VST support (requires restart or re-scan)"),
3096 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
3097 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
3099 add_option (_("Plugins/VST"), bo);
3102 bo = new BoolOption (
3103 "discover-vst-on-start",
3104 _("Scan for [new] VST Plugins on Application Start"),
3105 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
3106 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
3108 add_option (_("Plugins/VST"), bo);
3109 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3110 _("<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"));
3112 #ifdef WINDOWS_VST_SUPPORT
3113 // currently verbose logging is only implemented for Windows VST.
3114 bo = new BoolOption (
3115 "verbose-plugin-scan",
3116 _("Verbose Plugin Scan"),
3117 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
3118 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
3120 add_option (_("Plugins/VST"), bo);
3121 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3122 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
3125 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
3127 add_option (_("Plugins/VST"),
3128 new RcActionButton (_("Clear"),
3129 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
3132 add_option (_("Plugins/VST"),
3133 new RcActionButton (_("Clear"),
3134 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
3135 _("VST Blacklist:")));
3138 #ifdef LXVST_SUPPORT
3139 add_option (_("Plugins/VST"),
3140 new RcActionButton (_("Edit"),
3141 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
3142 _("Linux VST Path:")));
3144 add_option (_("Plugins/VST"),
3145 new RcConfigDisplay (
3146 "plugin-path-lxvst",
3148 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
3152 #ifdef WINDOWS_VST_SUPPORT
3153 add_option (_("Plugins/VST"),
3154 new RcActionButton (_("Edit"),
3155 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
3156 _("Windows VST Path:")));
3157 add_option (_("Plugins/VST"),
3158 new RcConfigDisplay (
3161 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
3165 #ifdef AUDIOUNIT_SUPPORT
3167 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
3169 add_option (_("Plugins/Audio Unit"),
3170 new RcActionButton (_("Scan for Plugins"),
3171 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3174 bo = new BoolOption (
3175 "discover-audio-units",
3176 _("Scan for [new] AudioUnit Plugins on Application Start"),
3177 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
3178 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
3180 add_option (_("Plugins/Audio Unit"), bo);
3181 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3182 _("<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."));
3184 add_option (_("Plugins/Audio Unit"),
3185 new RcActionButton (_("Clear"),
3186 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
3189 add_option (_("Plugins/Audio Unit"),
3190 new RcActionButton (_("Clear"),
3191 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
3192 _("AU Blacklist:")));
3195 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
3196 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
3197 add_option (_("Plugins"),
3199 "open-gui-after-adding-plugin",
3200 _("Automatically open the plugin GUI when adding a new plugin"),
3201 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
3202 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3205 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3206 add_option (_("Plugins"),
3208 "show-inline-display-by-default",
3209 _("Show Plugin Inline Display on Mixerstrip by default"),
3210 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3211 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3214 _plugin_prefer_inline = new BoolOption (
3215 "prefer-inline-over-gui",
3216 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3217 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3218 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3220 add_option (_("Plugins"), _plugin_prefer_inline);
3223 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3225 bo = new BoolOption (
3226 "ask-replace-instrument",
3227 _("Ask to replace existing instrument plugin"),
3228 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3229 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3231 add_option (_("Plugins"), bo);
3233 bo = new BoolOption (
3234 "ask-setup_instrument",
3235 _("Interactively configure instrument plugins on insert"),
3236 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3237 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3239 add_option (_("Plugins"), bo);
3240 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3241 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3244 add_option (_("Plugins"), new OptionEditorBlank ());
3247 #if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
3248 add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Graphics Acceleration")));
3251 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3252 BoolOption* bgc = new BoolOption (
3253 "cairo-image-surface",
3254 _("Disable Graphics Hardware Acceleration (requires restart)"),
3255 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3256 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3259 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3260 _("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));
3261 add_option (S_("Preferences|GUI"), bgc);
3264 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3265 BoolOption* bgo = new BoolOption (
3267 _("Possibly improve slow graphical performance (requires restart)"),
3268 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3269 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3272 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));
3273 add_option (S_("Preferences|GUI"), bgo);
3275 add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Graphical User Interface")));
3277 add_option (S_("Preferences|GUI"),
3280 _("Highlight widgets on mouseover"),
3281 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3282 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3285 add_option (S_("Preferences|GUI"),
3288 _("Show tooltips if mouse hovers over a control"),
3289 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3290 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3293 add_option (S_("Preferences|GUI"),
3295 "super-rapid-clock-update",
3296 _("Update transport clock display at FPS instead of every 100ms"),
3297 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3298 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3301 add_option (S_("Preferences|GUI"),
3304 _("Blink Rec-Arm buttons"),
3305 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_rec_arm),
3306 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_rec_arm)
3311 /* font scaling does nothing with GDK/Quartz */
3312 add_option (S_("Preferences|GUI"), new FontScalingOptions ());
3315 /* Image cache size */
3317 HSliderOption *sics = new HSliderOption ("waveform-cache-size",
3318 _("Waveform image cache size (megabytes)"),
3319 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
3320 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size),
3321 1, 1024, 10 /* 1 MB to 1GB in steps of 10MB */
3323 sics->scale().set_digits (0);
3324 Gtkmm2ext::UI::instance()->set_tip (
3326 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
3327 add_option (S_("Preferences|GUI"), sics);
3329 if (!ARDOUR::Profile->get_mixbus()) {
3330 /* Lock GUI timeout */
3332 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
3333 _("Lock timeout (seconds)"),
3334 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
3335 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds),
3338 slts->scale().set_digits (0);
3339 Gtkmm2ext::UI::instance()->set_tip (
3341 _("Lock GUI after this many idle seconds (zero to never lock)"));
3342 add_option (S_("Preferences|GUI"), slts);
3345 add_option (_("GUI/Editor"), new OptionEditorHeading (_("Editor UI Options")));
3346 add_option (_("GUI/Editor"),
3348 "show-name-highlight",
3349 _("Use name highlight bars in region displays (requires a restart)"),
3350 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3351 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3354 add_option (_("GUI/Editor"),
3356 "color-regions-using-track-color",
3357 _("Region color follows track color"),
3358 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_color_regions_using_track_color),
3359 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_color_regions_using_track_color)
3362 add_option (_("GUI/Editor"),
3364 "show-waveform-clipping",
3365 _("Show waveform clipping"),
3366 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveform_clipping),
3367 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveform_clipping)
3371 add_option (_("GUI/Editor"), new OptionEditorHeading (_("Waveforms")));
3373 if (!Profile->get_mixbus()) {
3374 add_option (_("GUI/Editor"),
3377 _("Show waveforms in regions"),
3378 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
3379 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
3383 add_option (_("GUI/Editor"),
3385 "show-waveforms-while-recording",
3386 _("Show waveforms while recording"),
3387 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
3388 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
3391 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
3393 _("Waveform scale"),
3394 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
3395 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
3398 wfs->add (Linear, _("linear"));
3399 wfs->add (Logarithmic, _("logarithmic"));
3401 add_option (_("GUI/Editor"), wfs);
3403 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
3405 _("Waveform shape"),
3406 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
3407 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
3410 wfsh->add (Traditional, _("traditional"));
3411 wfsh->add (Rectified, _("rectified"));
3413 add_option (_("GUI/Editor"), wfsh);
3415 add_option (_("GUI/Editor"), new ClipLevelOptions ());
3418 add_option (_("GUI/Editor"), new OptionEditorBlank ());
3420 /* The names of these controls must be the same as those given in MixerStrip
3421 for the actual widgets being controlled.
3423 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3424 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3425 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3426 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3427 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3428 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3429 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3431 add_option (_("GUI/Mixer"),
3432 new VisibilityOption (
3434 &_mixer_strip_visibility,
3435 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3436 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3440 add_option (_("GUI/Mixer"),
3442 "default-narrow_ms",
3443 _("Use narrow strips in the mixer by default"),
3444 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3445 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3448 add_option (_("GUI/Mixer"), new OptionEditorBlank ());
3451 OptionEditorHeading* i18n_head = new OptionEditorHeading (_("Internationalization"));
3453 add_option (_("GUI/Translation"), i18n_head);
3455 bo = new BoolOption (
3456 "enable-translation",
3457 _("Use translations"),
3458 sigc::ptr_fun (ARDOUR::translations_are_enabled),
3459 sigc::ptr_fun (ARDOUR::set_translations_enabled)
3462 bo->set_note (string_compose (_("These settings will only take effect after %1 is restarted (if available for your language preferences)."), PROGRAM_NAME));
3464 add_option (_("GUI/Translation"), bo);
3466 _l10n = new ComboOption<ARDOUR::LocaleMode> (
3469 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_locale_mode),
3470 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_locale_mode)
3473 _l10n->add (ARDOUR::SET_LC_ALL, _("Set complete locale"));
3474 _l10n->add (ARDOUR::SET_LC_MESSAGES, _("Enable only message translation"));
3475 _l10n->add (ARDOUR::SET_LC_MESSAGES_AND_LC_NUMERIC, _("Translate messages and format numeric format"));
3476 _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."));
3478 add_option (_("GUI/Translation"), _l10n);
3479 parameter_changed ("enable-translation");
3480 #endif // ENABLE_NLS
3482 add_option (_("GUI/Keyboard"), new OptionEditorHeading (_("Keyboard")));
3483 add_option (_("GUI/Keyboard"), new KeyboardOptions);
3485 add_option (_("GUI/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items")));
3487 add_option (_("GUI/Toolbar"),
3489 "show-toolbar-selclock",
3490 _("Display Selection Clock"),
3491 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
3492 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
3495 if (!ARDOUR::Profile->get_small_screen()) {
3496 add_option (_("GUI/Toolbar"),
3498 "show-secondary-clock",
3499 _("Display Secondary Clock"),
3500 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
3501 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
3505 add_option (_("GUI/Toolbar"),
3507 "show-mini-timeline",
3508 _("Display Navigation Timeline"),
3509 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
3510 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
3513 add_option (_("GUI/Toolbar"),
3515 "show-editor-meter",
3516 _("Display Master Level Meter"),
3517 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
3518 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
3521 add_option (_("GUI/Toolbar"),
3522 new ColumVisibilityOption (
3523 "action-table-columns", _("Lua Action Script Button Visibility"), 4,
3524 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3525 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3528 add_option (_("GUI/Toolbar"), new OptionEditorBlank ());
3530 add_option (_("GUI/Quirks"), new OptionEditorHeading (_("Various Workarounds for Windowing Systems")));
3531 add_option (_("GUI/Quirks"),
3533 "use-wm-visibility",
3534 _("Use Window Manager/Desktop visibility information"),
3535 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3536 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3540 bo = new BoolOption (
3541 "all-floating-windows-are-dialogs",
3542 _("All floating windows are dialogs"),
3543 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_all_floating_windows_are_dialogs),
3544 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_all_floating_windows_are_dialogs)
3546 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (), string_compose (
3547 _("Mark all floating windows to be type \"Dialog\" rather than using \"Utility\" for some.\n"
3548 "This may help with some window managers. This requires a restart of %1 to take effect"),
3550 add_option (_("GUI/Quirks"), bo);
3552 bo = new BoolOption (
3553 "transients-follow-front",
3554 _("Transient windows follow front window."),
3555 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_transients_follow_front),
3556 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_transients_follow_front)
3558 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (), string_compose (
3559 _("Make transient windows follow the front window when toggling between the editor and mixer.\n"
3560 "This requires a restart of %1 to take effect"), PROGRAM_NAME));
3561 add_option (_("GUI/Quirks"), bo);
3564 if (!Profile->get_mixbus()) {
3565 bo = new BoolOption (
3566 "floating-monitor-section",
3567 _("Float detached monitor-section window"),
3568 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_floating_monitor_section),
3569 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_floating_monitor_section)
3571 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (), string_compose (
3572 _("When detaching the monitoring section, mark it as \"Utility\" window to stay in front.\n"
3573 "This requires a restart of %1 to take effect"), PROGRAM_NAME));
3574 add_option (_("GUI/Quirks"), bo);
3577 add_option (_("GUI/Quirks"), new OptionEditorBlank ());
3579 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
3581 ComboOption<float>* mht = new ComboOption<float> (
3583 _("Peak hold time"),
3584 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
3585 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
3588 mht->add (MeterHoldOff, _("off"));
3589 mht->add (MeterHoldShort, _("short"));
3590 mht->add (MeterHoldMedium, _("medium"));
3591 mht->add (MeterHoldLong, _("long"));
3593 add_option (S_("Preferences|Metering"), mht);
3595 ComboOption<float>* mfo = new ComboOption<float> (
3598 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
3599 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
3602 mfo->add (METER_FALLOFF_OFF, _("off"));
3603 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
3604 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
3605 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
3606 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
3607 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
3608 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
3610 add_option (S_("Preferences|Metering"), mfo);
3612 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
3613 "meter-line-up-level",
3614 _("Meter line-up level; 0dBu"),
3615 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
3616 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
3619 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3620 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3621 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3622 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3624 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."));
3626 add_option (S_("Preferences|Metering"), mlu);
3628 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
3629 "meter-line-up-din",
3630 _("IEC1/DIN Meter line-up level; 0dBu"),
3631 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
3632 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
3635 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3636 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3637 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3638 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3640 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
3642 add_option (S_("Preferences|Metering"), mld);
3644 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
3645 "meter-vu-standard",
3646 _("VU Meter standard"),
3647 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
3648 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
3651 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
3652 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
3653 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
3654 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
3656 add_option (S_("Preferences|Metering"), mvu);
3658 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3659 "meter-type-master",
3660 _("Default Meter Type for Master Bus"),
3661 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3662 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3664 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3665 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3666 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3667 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3668 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3669 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3670 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3671 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3673 add_option (S_("Preferences|Metering"), mtm);
3676 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3678 _("Default Meter Type for Busses"),
3679 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3680 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3682 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3683 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3684 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3685 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3686 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3687 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3688 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3689 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3691 add_option (S_("Preferences|Metering"), mtb);
3693 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3695 _("Default Meter Type for Tracks"),
3696 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3697 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3699 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3700 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3702 add_option (S_("Preferences|Metering"), mtt);
3704 HSliderOption *mpks = new HSliderOption("meter-peak",
3705 _("Peak threshold [dBFS]"),
3706 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
3707 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak),
3711 Gtkmm2ext::UI::instance()->set_tip (
3713 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
3715 add_option (S_("Preferences|Metering"), mpks);
3717 add_option (S_("Preferences|Metering"),
3720 _("LED meter style"),
3721 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3722 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3725 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Editor Meters")));
3727 add_option (S_("Preferences|Metering"),
3729 "show-track-meters",
3730 _("Show meters on tracks in the editor"),
3731 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3732 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3735 add_option (S_("Preferences|Metering"),
3737 "editor-stereo-only-meters",
3738 _("Show at most stereo meters in the track-header"),
3739 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3740 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3743 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
3745 add_option (S_("Preferences|Metering"),
3747 "save-export-analysis-image",
3748 _("Save loudness analysis as image file"),
3749 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
3750 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
3753 /* VIDEO Timeline */
3754 add_option (_("Video"), new OptionEditorHeading (_("Video Server")));
3755 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
3757 /* and now the theme manager */
3759 add_option (_("Theme"), new OptionEditorHeading (_("Theme")));
3760 add_option (_("Theme"), new ThemeManager);
3762 add_option (_("Theme/Colors"), new OptionEditorHeading (_("Colors")));
3763 add_option (_("Theme/Colors"), new ColorThemeManager);
3765 Widget::show_all ();
3767 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3768 parameter_changed ("send-ltc");
3769 parameter_changed ("sync-source");
3770 parameter_changed ("use-monitor-bus");
3771 parameter_changed ("open-gui-after-adding-plugin");
3773 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
3775 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
3776 (Gtk::StateType) here !!!
3778 Tabbable::set_state (*node, Stateful::loading_state_version);
3781 set_current_page (_("Misc"));
3785 RCOptionEditor::parameter_changed (string const & p)
3787 OptionEditor::parameter_changed (p);
3789 if (p == "use-monitor-bus") {
3790 bool const s = Config->get_use_monitor_bus ();
3792 /* we can't use this if we don't have a monitor bus */
3793 Config->set_solo_control_is_listen_control (false);
3795 _solo_control_is_listen_control->set_sensitive (s);
3796 _listen_position->set_sensitive (s);
3797 } else if (p == "sync-source") {
3798 _sync_source->set_sensitive (true);
3800 _sync_source->set_sensitive (!_session->config.get_external_sync());
3802 switch(Config->get_sync_source()) {
3805 _sync_genlock->set_sensitive (true);
3806 _sync_framerate->set_sensitive (true);
3807 _sync_source_2997->set_sensitive (true);
3810 _sync_genlock->set_sensitive (false);
3811 _sync_framerate->set_sensitive (false);
3812 _sync_source_2997->set_sensitive (false);
3815 } else if (p == "send-ltc") {
3816 bool const s = Config->get_send_ltc ();
3817 _ltc_send_continuously->set_sensitive (s);
3818 _ltc_volume_slider->set_sensitive (s);
3819 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
3820 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3821 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
3824 } else if (p == "enable-translation") {
3825 _l10n->set_sensitive (ARDOUR::translations_are_enabled ());
3830 void RCOptionEditor::plugin_scan_refresh () {
3831 PluginManager::instance().refresh();
3834 void RCOptionEditor::clear_vst_cache () {
3835 PluginManager::instance().clear_vst_cache();
3838 void RCOptionEditor::clear_vst_blacklist () {
3839 PluginManager::instance().clear_vst_blacklist();
3842 void RCOptionEditor::clear_au_cache () {
3843 PluginManager::instance().clear_au_cache();
3846 void RCOptionEditor::clear_au_blacklist () {
3847 PluginManager::instance().clear_au_blacklist();
3850 void RCOptionEditor::edit_lxvst_path () {
3851 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
3852 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3853 *current_toplevel(), _("Set Linux VST Search Path"),
3854 _rc_config->get_plugin_path_lxvst(),
3855 PluginManager::instance().get_default_lxvst_path()
3857 ResponseType r = (ResponseType) pd->run ();
3859 if (r == RESPONSE_ACCEPT) {
3860 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
3865 void RCOptionEditor::edit_vst_path () {
3866 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3867 *current_toplevel(), _("Set Windows VST Search Path"),
3868 _rc_config->get_plugin_path_vst(),
3869 PluginManager::instance().get_default_windows_vst_path()
3871 ResponseType r = (ResponseType) pd->run ();
3873 if (r == RESPONSE_ACCEPT) {
3874 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
3881 RCOptionEditor::populate_sync_options ()
3883 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3885 _sync_source->clear ();
3887 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3888 _sync_source->add (*i, sync_source_to_string (*i));
3891 if (sync_opts.empty()) {
3892 _sync_source->set_sensitive(false);
3894 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3895 _rc_config->set_sync_source(sync_opts.front());
3899 parameter_changed ("sync-source");
3903 RCOptionEditor::use_own_window (bool and_fill_it)
3905 bool new_window = !own_window ();
3907 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
3909 if (win && new_window) {
3910 win->set_name ("PreferencesWindow");
3911 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
3918 RCOptionEditor::get_state ()
3920 XMLNode* node = new XMLNode (X_("Preferences"));
3921 node->add_child_nocopy (Tabbable::get_state());