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/Click"), new OptionEditorHeading (_("Click")));
2169 add_option (_("Misc/Click"), new ClickOptions (_rc_config));
2171 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
2173 add_option (_("Misc"),
2174 new SpinOption<double> (
2175 "automation-thinning-factor",
2176 _("Thinning factor (larger value => less data)"),
2177 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
2178 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
2182 add_option (_("Misc"),
2183 new SpinOption<double> (
2184 "automation-interval-msecs",
2185 _("Automation sampling interval (milliseconds)"),
2186 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
2187 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
2191 add_option (_("Misc"), new OptionEditorHeading (_("Tempo")));
2195 tsf = new BoolOption (
2196 "allow-non-quarter-pulse",
2197 _("Allow non quarter-note pulse"),
2198 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_allow_non_quarter_pulse),
2199 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_allow_non_quarter_pulse)
2201 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2202 string_compose (_("<b>When enabled</b> %1 will allow tempo to be expressed in divisions per minute\n"
2203 "<b>When disabled</b> %1 will only allow tempo to be expressed in quarter notes per minute"),
2205 add_option (_("Misc"), tsf);
2209 add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options")));
2211 tsf = new BoolOption (
2212 "latched-record-enable",
2213 _("Keep record-enable engaged on stop"),
2214 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
2215 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
2217 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
2218 add_option (_("Transport"), tsf);
2220 tsf = new BoolOption (
2222 _("Play loop is a transport mode"),
2223 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
2224 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
2226 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2227 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
2228 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
2229 add_option (_("Transport"), tsf);
2231 tsf = new BoolOption (
2232 "stop-recording-on-xrun",
2233 _("Stop recording when an xrun occurs"),
2234 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
2235 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
2237 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2238 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
2240 add_option (_("Transport"), tsf);
2242 tsf = new BoolOption (
2243 "create-xrun-marker",
2244 _("Create markers where xruns occur"),
2245 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
2246 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
2248 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
2249 add_option (_("Transport"), tsf);
2251 tsf = new BoolOption (
2252 "stop-at-session-end",
2253 _("Stop at the end of the session"),
2254 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
2255 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
2257 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2258 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
2259 "when it reaches the current session end marker\n\n"
2260 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
2262 add_option (_("Transport"), tsf);
2264 tsf = new BoolOption (
2266 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
2267 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
2268 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
2270 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2271 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
2272 "preventing any need to do a transport locate at the end of the loop\n\n"
2273 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
2274 "which will often cause a small click or delay"), PROGRAM_NAME));
2275 add_option (_("Transport"), tsf);
2277 tsf = new BoolOption (
2278 "disable-disarm-during-roll",
2279 _("Disable per-track record disarm while rolling"),
2280 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
2281 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
2283 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"));
2284 add_option (_("Transport"), tsf);
2286 tsf = new BoolOption (
2288 _("12dB gain reduction during fast-forward and fast-rewind"),
2289 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
2290 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2292 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
2293 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2294 add_option (_("Transport"), tsf);
2296 ComboOption<float>* psc = new ComboOption<float> (
2299 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
2300 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
2302 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
2303 (_("The amount of preroll (in seconds) to apply when <b>Play with Preroll</b> is initiated.\n\n"
2304 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
2305 psc->add (0.0, _("0 (no pre-roll)"));
2306 psc->add (0.1, _("0.1 second"));
2307 psc->add (0.25, _("0.25 second"));
2308 psc->add (0.5, _("0.5 second"));
2309 psc->add (1.0, _("1.0 second"));
2310 psc->add (2.0, _("2.0 seconds"));
2311 add_option (_("Transport"), psc);
2313 add_option (_("Sync"), new OptionEditorHeading (S_("Synchronization and Slave Options")));
2315 _sync_source = new ComboOption<SyncSource> (
2317 _("External timecode source"),
2318 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
2319 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
2322 add_option (_("Sync"), _sync_source);
2324 _sync_framerate = new BoolOption (
2325 "timecode-sync-frame-rate",
2326 _("Match session video frame rate to external timecode"),
2327 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
2328 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
2330 Gtkmm2ext::UI::instance()->set_tip
2331 (_sync_framerate->tip_widget(),
2332 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
2333 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
2334 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
2335 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
2336 "timecode standard and the session standard."), PROGRAM_NAME));
2338 add_option (_("Sync"), _sync_framerate);
2340 _sync_genlock = new BoolOption (
2341 "timecode-source-is-synced",
2342 _("Sync-lock timecode to clock (disable drift compensation)"),
2343 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
2344 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
2346 Gtkmm2ext::UI::instance()->set_tip
2347 (_sync_genlock->tip_widget(),
2348 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
2349 "Sync Lock indicates that the selected external timecode source shares clock-sync "
2350 "(Black & Burst, Wordclock, etc) with the audio interface. "
2351 "This option disables drift compensation. The transport speed is fixed at 1.0. "
2352 "Vari-speed LTC will be ignored and cause drift."
2354 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
2355 "timecode sources shares clock sync."
2359 add_option (_("Sync"), _sync_genlock);
2361 _sync_source_2997 = new BoolOption (
2362 "timecode-source-2997",
2363 _("Lock to 29.9700 fps instead of 30000/1001"),
2364 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
2365 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
2367 Gtkmm2ext::UI::instance()->set_tip
2368 (_sync_source_2997->tip_widget(),
2369 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
2370 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
2371 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
2372 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
2373 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
2374 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
2377 add_option (_("Sync"), _sync_source_2997);
2379 add_option (_("Sync/LTC"), new OptionEditorHeading (S_("LTC Reader")));
2381 _ltc_port = new ComboStringOption (
2383 _("LTC incoming port"),
2384 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
2385 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
2388 vector<string> physical_inputs;
2389 physical_inputs.push_back (_("None"));
2390 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
2391 _ltc_port->set_popdown_strings (physical_inputs);
2393 populate_sync_options ();
2394 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
2396 add_option (_("Sync/LTC"), _ltc_port);
2398 add_option (_("Sync/LTC"), new OptionEditorHeading (S_("LTC Generator")));
2400 add_option (_("Sync/LTC"),
2403 _("Enable LTC generator"),
2404 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
2405 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
2408 _ltc_send_continuously = new BoolOption (
2409 "ltc-send-continuously",
2410 _("Send LTC while stopped"),
2411 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
2412 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
2414 Gtkmm2ext::UI::instance()->set_tip
2415 (_ltc_send_continuously->tip_widget(),
2416 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
2417 add_option (_("Sync/LTC"), _ltc_send_continuously);
2419 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"),
2420 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_output_volume),
2421 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_output_volume),
2425 Gtkmm2ext::UI::instance()->set_tip
2426 (_ltc_volume_slider->tip_widget(),
2427 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
2429 add_option (_("Sync/LTC"), _ltc_volume_slider);
2432 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Clock")));
2434 add_option (_("Sync/MIDI"),
2437 _("Send MIDI Clock"),
2438 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2439 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2442 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC)")));
2444 add_option (_("Sync/MIDI"),
2447 _("Send MIDI Time Code"),
2448 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2449 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2452 add_option (_("Sync/MIDI"),
2453 new SpinOption<int> (
2454 "mtc-qf-speed-tolerance",
2455 _("Percentage either side of normal transport speed to transmit MTC"),
2456 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2457 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2461 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("Midi Machine Control (MMC)")));
2463 add_option (_("Sync/MIDI"),
2466 _("Obey MIDI Machine Control commands"),
2467 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2468 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2471 add_option (_("Sync/MIDI"),
2474 _("Send MIDI Machine Control commands"),
2475 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2476 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2479 add_option (_("Sync/MIDI"),
2480 new SpinOption<uint8_t> (
2481 "mmc-receive-device-id",
2482 _("Inbound MMC device ID"),
2483 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2484 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2488 add_option (_("Sync/MIDI"),
2489 new SpinOption<uint8_t> (
2490 "mmc-send-device-id",
2491 _("Outbound MMC device ID"),
2492 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2493 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2500 add_option (_("Editing"), new OptionEditorHeading (_("Editor Settings")));
2502 add_option (_("Editing"),
2504 "rubberbanding-snaps-to-grid",
2505 _("Make rubberband selection rectangle snap to the grid"),
2506 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2507 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2510 bo = new BoolOption (
2512 _("Name new markers"),
2513 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2514 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2516 add_option (_("Editing"), bo);
2517 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."
2518 "\n\nYou can always rename markers by right-clicking on them"));
2520 add_option (S_("Editing"),
2522 "draggable-playhead",
2523 _("Allow dragging of playhead"),
2524 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2525 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2528 if (!Profile->get_mixbus()) {
2529 add_option (_("Editing"),
2532 _("Show zoom toolbar (if torn off)"),
2533 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_zoom_tools),
2534 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_zoom_tools)
2537 add_option (_("Editing"),
2539 "use-mouse-position-as-zoom-focus-on-scroll",
2540 _("Always use mouse cursor position as zoom focus when zooming using mouse scroll wheel"),
2541 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2542 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2546 add_option (_("Editing"),
2548 "use-time-rulers-to-zoom-with-vertical-drag",
2549 _("Use time rulers area to zoom when clicking and dragging vertically"),
2550 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag),
2551 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag)
2554 add_option (_("Editing"),
2556 "use-double-click-to-zoom-to-selection",
2557 _("Use double mouse click to zoom to selection"),
2558 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection),
2559 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection)
2562 add_option (_("Editing"),
2564 "update-editor-during-summary-drag",
2565 _("Update editor window during drags of the summary"),
2566 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2567 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2570 add_option (_("Editing"),
2572 "autoscroll-editor",
2573 _("Auto-scroll editor window when dragging near its edges"),
2574 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2575 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2578 add_option (_("Editing"),
2579 new BoolComboOption (
2580 "show-region-gain-envelopes",
2581 _("Show gain envelopes in audio regions"),
2583 _("only in Draw and Internal Edit modes"),
2584 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2585 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2588 add_option (_("Editing"), new OptionEditorHeading (_("Editor Behavior")));
2590 add_option (_("Editing"),
2592 "automation-follows-regions",
2593 _("Move relevant automation when audio regions are moved"),
2594 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2595 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2598 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2599 "default-fade-shape",
2600 _("Default fade shape"),
2601 sigc::mem_fun (*_rc_config,
2602 &RCConfiguration::get_default_fade_shape),
2603 sigc::mem_fun (*_rc_config,
2604 &RCConfiguration::set_default_fade_shape)
2607 fadeshape->add (FadeLinear,
2608 _("Linear (for highly correlated material)"));
2609 fadeshape->add (FadeConstantPower, _("Constant power"));
2610 fadeshape->add (FadeSymmetric, _("Symmetric"));
2611 fadeshape->add (FadeSlow, _("Slow"));
2612 fadeshape->add (FadeFast, _("Fast"));
2614 add_option (_("Editing"), fadeshape);
2616 bco = new BoolComboOption (
2617 "use-overlap-equivalency",
2618 _("Regions in edit groups are edited together"),
2619 _("whenever they overlap in time"),
2620 _("only if they have identical length and position"),
2621 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2622 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2625 add_option (_("Editing"), bco);
2627 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2629 _("Layering model"),
2630 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2631 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2634 lm->add (LaterHigher, _("later is higher"));
2635 lm->add (Manual, _("manual layering"));
2636 add_option (_("Editing"), lm);
2638 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2639 "region-selection-after-split",
2640 _("After splitting selected regions, select"),
2641 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2642 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2644 // TODO: decide which of these modes are really useful
2645 rsas->add(None, _("no regions"));
2646 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2647 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2648 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2649 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2650 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2651 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2652 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2654 add_option (_("Editing"), rsas);
2658 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2660 add_option (_("Audio"), new BufferingOptions (_rc_config));
2662 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2664 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2666 _("Record monitoring handled by"),
2667 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2668 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2671 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2672 mm->add (HardwareMonitoring, _("via Audio Driver"));
2675 string prog (PROGRAM_NAME);
2676 boost::algorithm::to_lower (prog);
2677 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2678 mm->add (ExternalMonitoring, _("audio hardware"));
2680 add_option (_("Audio"), mm);
2682 add_option (_("Audio"),
2684 "tape-machine-mode",
2685 _("Tape machine mode"),
2686 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2687 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2690 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2691 if (!Profile->get_mixbus()) {
2693 add_option (_("Audio"),
2695 "auto-connect-standard-busses",
2696 _("Auto-connect master/monitor busses"),
2697 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2698 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2701 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2702 "input-auto-connect",
2703 _("Connect track inputs"),
2704 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2705 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2708 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2709 iac->add (ManualConnect, _("manually"));
2711 add_option (_("Audio"), iac);
2713 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2714 "output-auto-connect",
2715 _("Connect track and bus outputs"),
2716 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2717 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2720 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2721 oac->add (AutoConnectMaster, _("automatically to master bus"));
2722 oac->add (ManualConnect, _("manually"));
2724 add_option (_("Audio"), oac);
2726 bo = new BoolOption (
2728 _("Use 'Strict-I/O' for new tracks or Busses"),
2729 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2730 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2733 add_option (_("Audio"), bo);
2734 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2735 _("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."));
2739 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2741 add_option (_("Audio"),
2743 "denormal-protection",
2744 _("Use DC bias to protect against denormals"),
2745 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2746 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2749 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2751 _("Processor handling"),
2752 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2753 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2757 dm->add (DenormalNone, _("no processor handling"));
2759 FPU* fpu = FPU::instance();
2761 if (fpu->has_flush_to_zero()) {
2763 dm->add (DenormalFTZ, _("use FlushToZero"));
2764 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2765 _rc_config->set_denormal_model(DenormalNone);
2768 if (fpu->has_denormals_are_zero()) {
2770 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2771 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2772 _rc_config->set_denormal_model(DenormalNone);
2775 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2777 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2778 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2779 _rc_config->set_denormal_model(DenormalNone);
2783 dm->set_sensitive(false);
2786 add_option (_("Audio"), dm);
2788 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2790 add_option (_("Audio"),
2792 "auto-analyse-audio",
2793 _("Enable automatic analysis of audio"),
2794 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2795 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2798 add_option (_("Audio"),
2800 "replicate-missing-region-channels",
2801 _("Replicate missing region channels"),
2802 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2803 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2808 add_option (_("Solo & mute"), new OptionEditorHeading (_("Solo")));
2810 _solo_control_is_listen_control = new BoolOption (
2811 "solo-control-is-listen-control",
2812 _("Solo controls are Listen controls"),
2813 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2814 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2817 add_option (_("Solo & mute"), _solo_control_is_listen_control);
2819 add_option (_("Solo & mute"),
2822 _("Exclusive solo"),
2823 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2824 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2827 add_option (_("Solo & mute"),
2830 _("Show solo muting"),
2831 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2832 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2835 add_option (_("Solo & mute"),
2837 "solo-mute-override",
2838 _("Soloing overrides muting"),
2839 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2840 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2843 add_option (_("Solo & mute"),
2846 _("Solo-in-place mute cut (dB)"),
2847 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2848 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2851 _listen_position = new ComboOption<ListenPosition> (
2853 _("Listen Position"),
2854 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2855 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2858 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2859 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2861 add_option (_("Solo & mute"), _listen_position);
2863 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2865 _("PFL signals come from"),
2866 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2867 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2870 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2871 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2873 add_option (_("Solo & mute"), pp);
2875 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2877 _("AFL signals come from"),
2878 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2879 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2882 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2883 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2885 add_option (_("Solo & mute"), pa);
2887 add_option (_("Solo & mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2889 add_option (_("Solo & mute"),
2891 "mute-affects-pre-fader",
2892 _("Mute affects pre-fader sends"),
2893 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2894 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2897 add_option (_("Solo & mute"),
2899 "mute-affects-post-fader",
2900 _("Mute affects post-fader sends"),
2901 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2902 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2905 add_option (_("Solo & mute"),
2907 "mute-affects-control-outs",
2908 _("Mute affects control outputs"),
2909 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2910 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2913 add_option (_("Solo & mute"),
2915 "mute-affects-main-outs",
2916 _("Mute affects main outputs"),
2917 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2918 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2922 if (!ARDOUR::Profile->get_mixbus()) {
2923 add_option (_("Solo & mute"), new OptionEditorHeading (_("Send Routing")));
2924 add_option (_("Solo & mute"),
2926 "link-send-and-route-panner",
2927 _("Link panners of Aux and External Sends with main panner by default"),
2928 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2929 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2933 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Preferences")));
2935 add_option (_("MIDI"),
2936 new SpinOption<float> (
2938 _("MIDI read-ahead time (seconds)"),
2939 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2940 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2945 add_option (_("MIDI"),
2946 new SpinOption<int32_t> (
2947 "initial-program-change",
2948 _("Initial program change"),
2949 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2950 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2954 add_option (_("MIDI"),
2956 "display-first-midi-bank-as-zero",
2957 _("Display first MIDI bank/program as 0"),
2958 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2959 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2962 add_option (_("MIDI"),
2964 "never-display-periodic-midi",
2965 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2966 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
2967 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
2970 add_option (_("MIDI"),
2973 _("Sound MIDI notes as they are selected in the editor"),
2974 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2975 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2978 add_option (_("MIDI"),
2981 _("Send MIDI control feedback"),
2982 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2983 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2986 add_option (_("MIDI/Ports"), new OptionEditorHeading (_("MIDI Port Options")));
2988 add_option (_("MIDI/Ports"),
2990 "get-midi-input-follows-selection",
2991 _("MIDI input follows MIDI track selection"),
2992 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
2993 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
2996 add_option (_("MIDI/Ports"), new MidiPortOptions ());
2997 add_option (_("MIDI/Ports"), new OptionEditorBlank ());
2998 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
3000 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
3001 "midi-audition-synth-uri",
3002 _("Midi Audition Synth (LV2)"),
3003 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
3004 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
3007 audition_synth->add(X_(""), _("None"));
3008 PluginInfoList all_plugs;
3009 PluginManager& manager (PluginManager::instance());
3011 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
3013 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
3014 if (manager.get_status (*i) == PluginManager::Hidden) continue;
3015 if (!(*i)->is_instrument()) continue;
3016 if ((*i)->type != ARDOUR::LV2) continue;
3017 if ((*i)->name.length() > 46) {
3018 audition_synth->add((*i)->unique_id, (*i)->name.substr (0, 44) + "...");
3020 audition_synth->add((*i)->unique_id, (*i)->name);
3025 add_option (_("MIDI"), audition_synth);
3027 /* Control Surfaces */
3029 add_option (_("Control Surfaces"), new OptionEditorHeading (_("Control Surfaces")));
3030 add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
3032 /* VIDEO Timeline */
3033 add_option (_("Video"), new OptionEditorHeading (_("Video Server")));
3034 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
3036 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3037 add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
3038 add_option (_("Plugins"),
3039 new RcActionButton (_("Scan for Plugins"),
3040 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3044 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
3046 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3047 bo = new BoolOption (
3048 "show-plugin-scan-window",
3049 _("Always Display Plugin Scan Progress"),
3050 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
3051 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
3053 add_option (_("Plugins"), bo);
3054 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3055 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
3058 bo = new BoolOption (
3059 "plugins-stop-with-transport",
3060 _("Silence plugins when the transport is stopped"),
3061 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
3062 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
3064 add_option (_("Plugins"), bo);
3065 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3066 _("<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."));
3068 bo = new BoolOption (
3069 "new-plugins-active",
3070 _("Make new plugins active"),
3071 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
3072 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
3074 add_option (_("Plugins"), bo);
3075 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3076 _("<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"));
3078 #if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
3079 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
3081 add_option (_("Plugins/VST"),
3082 new RcActionButton (_("Scan for Plugins"),
3083 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3086 #if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
3087 bo = new BoolOption (
3089 _("Enable Mac VST support (requires restart or re-scan)"),
3090 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
3091 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
3093 add_option (_("Plugins/VST"), bo);
3096 bo = new BoolOption (
3097 "discover-vst-on-start",
3098 _("Scan for [new] VST Plugins on Application Start"),
3099 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
3100 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
3102 add_option (_("Plugins/VST"), bo);
3103 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3104 _("<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"));
3106 #ifdef WINDOWS_VST_SUPPORT
3107 // currently verbose logging is only implemented for Windows VST.
3108 bo = new BoolOption (
3109 "verbose-plugin-scan",
3110 _("Verbose Plugin Scan"),
3111 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
3112 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
3114 add_option (_("Plugins/VST"), bo);
3115 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3116 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
3119 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
3121 add_option (_("Plugins/VST"),
3122 new RcActionButton (_("Clear"),
3123 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
3126 add_option (_("Plugins/VST"),
3127 new RcActionButton (_("Clear"),
3128 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
3129 _("VST Blacklist:")));
3132 #ifdef LXVST_SUPPORT
3133 add_option (_("Plugins/VST"),
3134 new RcActionButton (_("Edit"),
3135 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
3136 _("Linux VST Path:")));
3138 add_option (_("Plugins/VST"),
3139 new RcConfigDisplay (
3140 "plugin-path-lxvst",
3142 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
3146 #ifdef WINDOWS_VST_SUPPORT
3147 add_option (_("Plugins/VST"),
3148 new RcActionButton (_("Edit"),
3149 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
3150 _("Windows VST Path:")));
3151 add_option (_("Plugins/VST"),
3152 new RcConfigDisplay (
3155 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
3159 #ifdef AUDIOUNIT_SUPPORT
3161 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
3163 add_option (_("Plugins/Audio Unit"),
3164 new RcActionButton (_("Scan for Plugins"),
3165 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3168 bo = new BoolOption (
3169 "discover-audio-units",
3170 _("Scan for [new] AudioUnit Plugins on Application Start"),
3171 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
3172 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
3174 add_option (_("Plugins/Audio Unit"), bo);
3175 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3176 _("<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."));
3178 add_option (_("Plugins/Audio Unit"),
3179 new RcActionButton (_("Clear"),
3180 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
3183 add_option (_("Plugins/Audio Unit"),
3184 new RcActionButton (_("Clear"),
3185 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
3186 _("AU Blacklist:")));
3189 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
3190 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
3191 add_option (_("Plugins"),
3193 "open-gui-after-adding-plugin",
3194 _("Automatically open the plugin GUI when adding a new plugin"),
3195 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
3196 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3199 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3200 add_option (_("Plugins"),
3202 "show-inline-display-by-default",
3203 _("Show Plugin Inline Display on Mixerstrip by default"),
3204 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3205 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3208 _plugin_prefer_inline = new BoolOption (
3209 "prefer-inline-over-gui",
3210 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3211 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3212 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3214 add_option (_("Plugins"), _plugin_prefer_inline);
3217 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3219 bo = new BoolOption (
3220 "ask-replace-instrument",
3221 _("Ask to replace existing instrument plugin"),
3222 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3223 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3225 add_option (_("Plugins"), bo);
3227 bo = new BoolOption (
3228 "ask-setup_instrument",
3229 _("Interactively configure instrument plugins on insert"),
3230 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3231 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3233 add_option (_("Plugins"), bo);
3234 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3235 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3238 add_option (_("Plugins"), new OptionEditorBlank ());
3241 #if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
3242 add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Graphics Acceleration")));
3245 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3246 BoolOption* bgc = new BoolOption (
3247 "cairo-image-surface",
3248 _("Disable Graphics Hardware Acceleration (requires restart)"),
3249 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3250 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3253 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3254 _("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));
3255 add_option (S_("Preferences|GUI"), bgc);
3258 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3259 BoolOption* bgo = new BoolOption (
3261 _("Possibly improve slow graphical performance (requires restart)"),
3262 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3263 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3266 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));
3267 add_option (S_("Preferences|GUI"), bgo);
3269 add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Graphical User Interface")));
3271 add_option (S_("Preferences|GUI"),
3274 _("Graphically indicate mouse pointer hovering over various widgets"),
3275 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3276 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3279 add_option (S_("Preferences|GUI"),
3282 _("Show tooltips if mouse hovers over a control"),
3283 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3284 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3287 add_option (S_("Preferences|GUI"),
3289 "super-rapid-clock-update",
3290 _("Update transport clock display at FPS instead of every 100ms"),
3291 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3292 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3295 add_option (S_("Preferences|GUI"),
3298 _("Blink Rec-Arm buttons"),
3299 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_rec_arm),
3300 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_rec_arm)
3305 /* font scaling does nothing with GDK/Quartz */
3306 add_option (S_("Preferences|GUI"), new FontScalingOptions ());
3309 /* Image cache size */
3311 HSliderOption *sics = new HSliderOption ("waveform-cache-size",
3312 _("Waveform image cache size (megabytes)"),
3313 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
3314 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size),
3315 1, 1024, 10 /* 1 MB to 1GB in steps of 10MB */
3317 sics->scale().set_digits (0);
3318 Gtkmm2ext::UI::instance()->set_tip (
3320 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
3321 add_option (S_("Preferences|GUI"), sics);
3323 if (!ARDOUR::Profile->get_mixbus()) {
3324 /* Lock GUI timeout */
3326 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
3327 _("Lock timeout (seconds)"),
3328 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
3329 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds),
3332 slts->scale().set_digits (0);
3333 Gtkmm2ext::UI::instance()->set_tip (
3335 _("Lock GUI after this many idle seconds (zero to never lock)"));
3336 add_option (S_("Preferences|GUI"), slts);
3339 add_option (_("GUI/Editor"), new OptionEditorHeading (_("Editor UI Options")));
3340 add_option (_("GUI/Editor"),
3342 "show-name-highlight",
3343 _("Use name highlight bars in region displays (requires a restart)"),
3344 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3345 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3348 add_option (_("GUI/Editor"),
3350 "color-regions-using-track-color",
3351 _("Color regions using their track's color"),
3352 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_color_regions_using_track_color),
3353 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_color_regions_using_track_color)
3356 add_option (_("GUI/Editor"),
3358 "show-waveform-clipping",
3359 _("Show waveform clipping"),
3360 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveform_clipping),
3361 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveform_clipping)
3365 add_option (_("GUI/Editor"), new OptionEditorHeading (_("Waveforms")));
3367 if (!Profile->get_mixbus()) {
3368 add_option (_("GUI/Editor"),
3371 _("Show waveforms in regions"),
3372 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
3373 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
3377 add_option (_("GUI/Editor"),
3379 "show-waveforms-while-recording",
3380 _("Show waveforms for audio while it is being recorded"),
3381 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
3382 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
3385 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
3387 _("Waveform scale"),
3388 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
3389 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
3392 wfs->add (Linear, _("linear"));
3393 wfs->add (Logarithmic, _("logarithmic"));
3395 add_option (_("GUI/Editor"), wfs);
3397 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
3399 _("Waveform shape"),
3400 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
3401 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
3404 wfsh->add (Traditional, _("traditional"));
3405 wfsh->add (Rectified, _("rectified"));
3407 add_option (_("GUI/Editor"), wfsh);
3409 add_option (_("GUI/Editor"), new ClipLevelOptions ());
3412 add_option (_("GUI/Editor"), new OptionEditorBlank ());
3414 /* The names of these controls must be the same as those given in MixerStrip
3415 for the actual widgets being controlled.
3417 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3418 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3419 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3420 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3421 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3422 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3423 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3425 add_option (_("GUI/Mixer"),
3426 new VisibilityOption (
3428 &_mixer_strip_visibility,
3429 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3430 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3434 add_option (_("GUI/Mixer"),
3436 "default-narrow_ms",
3437 _("Use narrow strips in the mixer by default"),
3438 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3439 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3442 add_option (_("GUI/Mixer"), new OptionEditorBlank ());
3445 OptionEditorHeading* i18n_head = new OptionEditorHeading (_("Internationalization"));
3447 add_option (_("GUI/Translation"), i18n_head);
3449 bo = new BoolOption (
3450 "enable-translation",
3451 _("Use translations"),
3452 sigc::ptr_fun (ARDOUR::translations_are_enabled),
3453 sigc::ptr_fun (ARDOUR::set_translations_enabled)
3456 bo->set_note (string_compose (_("These settings will only take effect after %1 is restarted (if available for your language preferences)."), PROGRAM_NAME));
3458 add_option (_("GUI/Translation"), bo);
3460 _l10n = new ComboOption<ARDOUR::LocaleMode> (
3463 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_locale_mode),
3464 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_locale_mode)
3467 _l10n->add (ARDOUR::SET_LC_ALL, _("Set complete locale"));
3468 _l10n->add (ARDOUR::SET_LC_MESSAGES, _("Enable only message translation"));
3469 _l10n->add (ARDOUR::SET_LC_MESSAGES_AND_LC_NUMERIC, _("Translate messages and format numeric format"));
3470 _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."));
3472 add_option (_("GUI/Translation"), _l10n);
3473 parameter_changed ("enable-translation");
3474 #endif // ENABLE_NLS
3476 add_option (_("GUI/Keyboard"), new OptionEditorHeading (_("Keyboard")));
3477 add_option (_("GUI/Keyboard"), new KeyboardOptions);
3479 add_option (_("GUI/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items")));
3481 add_option (_("GUI/Toolbar"),
3483 "show-toolbar-selclock",
3484 _("Display Selection Clock in the Toolbar"),
3485 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
3486 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
3489 if (!ARDOUR::Profile->get_small_screen()) {
3490 add_option (_("GUI/Toolbar"),
3492 "show-secondary-clock",
3493 _("Display Secondary Clock in the Toolbar"),
3494 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
3495 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
3499 add_option (_("GUI/Toolbar"),
3501 "show-mini-timeline",
3502 _("Display Navigation Timeline in the Toolbar"),
3503 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
3504 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
3507 add_option (_("GUI/Toolbar"),
3509 "show-editor-meter",
3510 _("Display Master Level Meter in the Toolbar"),
3511 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
3512 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
3515 add_option (_("GUI/Toolbar"),
3516 new ColumVisibilityOption (
3517 "action-table-columns", _("Lua Action Script Button Visibility"), 4,
3518 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3519 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3522 add_option (_("GUI/Toolbar"), new OptionEditorBlank ());
3524 add_option (_("GUI/Quirks"), new OptionEditorHeading (_("Various Quirks for Windowing systems")));
3525 add_option (_("GUI/Quirks"),
3527 "use-wm-visibility",
3528 _("Use Window Manager/Desktop visibility information"),
3529 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3530 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3534 bo = new BoolOption (
3535 "all-floating-windows-are-dialogs",
3536 _("All floating windows are dialogs"),
3537 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_all_floating_windows_are_dialogs),
3538 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_all_floating_windows_are_dialogs)
3540 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (), string_compose (
3541 _("Mark all floating windows to be type \"Dialog\" rather than using \"Utility\" for some.\n"
3542 "This may help with some window managers. This requires a restart of %1 to take effect"),
3544 add_option (_("GUI/Quirks"), bo);
3546 bo = new BoolOption (
3547 "transients-follow-front",
3548 _("Transient windows follow front window."),
3549 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_transients_follow_front),
3550 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_transients_follow_front)
3552 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (), string_compose (
3553 _("Make transient windows follow the front window when toggling between the editor and mixer.\n"
3554 "This requires a restart of %1 to take effect"), PROGRAM_NAME));
3555 add_option (_("GUI/Quirks"), bo);
3558 if (!Profile->get_mixbus()) {
3559 bo = new BoolOption (
3560 "floating-monitor-section",
3561 _("Float detached monitor-section window"),
3562 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_floating_monitor_section),
3563 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_floating_monitor_section)
3565 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (), string_compose (
3566 _("When detaching the monitoring section, mark it as \"Utility\" window to stay in front.\n"
3567 "This requires a restart of %1 to take effect"), PROGRAM_NAME));
3568 add_option (_("GUI/Quirks"), bo);
3571 add_option (_("GUI/Quirks"), new OptionEditorBlank ());
3573 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
3575 ComboOption<float>* mht = new ComboOption<float> (
3577 _("Peak hold time"),
3578 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
3579 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
3582 mht->add (MeterHoldOff, _("off"));
3583 mht->add (MeterHoldShort, _("short"));
3584 mht->add (MeterHoldMedium, _("medium"));
3585 mht->add (MeterHoldLong, _("long"));
3587 add_option (S_("Preferences|Metering"), mht);
3589 ComboOption<float>* mfo = new ComboOption<float> (
3592 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
3593 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
3596 mfo->add (METER_FALLOFF_OFF, _("off"));
3597 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
3598 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
3599 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
3600 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
3601 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
3602 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
3604 add_option (S_("Preferences|Metering"), mfo);
3606 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
3607 "meter-line-up-level",
3608 _("Meter line-up level; 0dBu"),
3609 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
3610 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
3613 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3614 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3615 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3616 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3618 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."));
3620 add_option (S_("Preferences|Metering"), mlu);
3622 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
3623 "meter-line-up-din",
3624 _("IEC1/DIN Meter line-up level; 0dBu"),
3625 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
3626 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
3629 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3630 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3631 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3632 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3634 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
3636 add_option (S_("Preferences|Metering"), mld);
3638 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
3639 "meter-vu-standard",
3640 _("VU Meter standard"),
3641 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
3642 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
3645 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
3646 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
3647 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
3648 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
3650 add_option (S_("Preferences|Metering"), mvu);
3652 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3653 "meter-type-master",
3654 _("Default Meter Type for Master Bus"),
3655 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3656 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3658 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3659 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3660 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3661 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3662 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3663 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3664 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3665 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3667 add_option (S_("Preferences|Metering"), mtm);
3670 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3672 _("Default Meter Type for Busses"),
3673 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3674 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3676 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3677 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3678 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3679 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3680 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3681 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3682 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3683 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3685 add_option (S_("Preferences|Metering"), mtb);
3687 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3689 _("Default Meter Type for Tracks"),
3690 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3691 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3693 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3694 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3696 add_option (S_("Preferences|Metering"), mtt);
3698 HSliderOption *mpks = new HSliderOption("meter-peak",
3699 _("Peak threshold [dBFS]"),
3700 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
3701 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak),
3705 Gtkmm2ext::UI::instance()->set_tip (
3707 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
3709 add_option (S_("Preferences|Metering"), mpks);
3711 add_option (S_("Preferences|Metering"),
3714 _("LED meter style"),
3715 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3716 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3719 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Editor Meters")));
3721 add_option (S_("Preferences|Metering"),
3723 "show-track-meters",
3724 _("Show meters on tracks in the editor"),
3725 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3726 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3729 add_option (S_("Preferences|Metering"),
3731 "editor-stereo-only-meters",
3732 _("Show at most stereo meters in the track-header"),
3733 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3734 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3737 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
3739 add_option (S_("Preferences|Metering"),
3741 "save-export-analysis-image",
3742 _("Save loudness analysis as image file"),
3743 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
3744 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
3747 /* and now the theme manager */
3749 add_option (_("Theme"), new OptionEditorHeading (_("Theme")));
3750 add_option (_("Theme"), new ThemeManager);
3752 add_option (_("Theme/Colors"), new OptionEditorHeading (_("Colors")));
3753 add_option (_("Theme/Colors"), new ColorThemeManager);
3755 Widget::show_all ();
3757 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3758 parameter_changed ("send-ltc");
3759 parameter_changed ("sync-source");
3760 parameter_changed ("use-monitor-bus");
3761 parameter_changed ("open-gui-after-adding-plugin");
3763 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
3765 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
3766 (Gtk::StateType) here !!!
3768 Tabbable::set_state (*node, Stateful::loading_state_version);
3771 set_current_page (_("Misc"));
3775 RCOptionEditor::parameter_changed (string const & p)
3777 OptionEditor::parameter_changed (p);
3779 if (p == "use-monitor-bus") {
3780 bool const s = Config->get_use_monitor_bus ();
3782 /* we can't use this if we don't have a monitor bus */
3783 Config->set_solo_control_is_listen_control (false);
3785 _solo_control_is_listen_control->set_sensitive (s);
3786 _listen_position->set_sensitive (s);
3787 } else if (p == "sync-source") {
3788 _sync_source->set_sensitive (true);
3790 _sync_source->set_sensitive (!_session->config.get_external_sync());
3792 switch(Config->get_sync_source()) {
3795 _sync_genlock->set_sensitive (true);
3796 _sync_framerate->set_sensitive (true);
3797 _sync_source_2997->set_sensitive (true);
3800 _sync_genlock->set_sensitive (false);
3801 _sync_framerate->set_sensitive (false);
3802 _sync_source_2997->set_sensitive (false);
3805 } else if (p == "send-ltc") {
3806 bool const s = Config->get_send_ltc ();
3807 _ltc_send_continuously->set_sensitive (s);
3808 _ltc_volume_slider->set_sensitive (s);
3809 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
3810 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3811 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
3814 } else if (p == "enable-translation") {
3815 _l10n->set_sensitive (ARDOUR::translations_are_enabled ());
3820 void RCOptionEditor::plugin_scan_refresh () {
3821 PluginManager::instance().refresh();
3824 void RCOptionEditor::clear_vst_cache () {
3825 PluginManager::instance().clear_vst_cache();
3828 void RCOptionEditor::clear_vst_blacklist () {
3829 PluginManager::instance().clear_vst_blacklist();
3832 void RCOptionEditor::clear_au_cache () {
3833 PluginManager::instance().clear_au_cache();
3836 void RCOptionEditor::clear_au_blacklist () {
3837 PluginManager::instance().clear_au_blacklist();
3840 void RCOptionEditor::edit_lxvst_path () {
3841 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
3842 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3843 *current_toplevel(), _("Set Linux VST Search Path"),
3844 _rc_config->get_plugin_path_lxvst(),
3845 PluginManager::instance().get_default_lxvst_path()
3847 ResponseType r = (ResponseType) pd->run ();
3849 if (r == RESPONSE_ACCEPT) {
3850 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
3855 void RCOptionEditor::edit_vst_path () {
3856 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3857 *current_toplevel(), _("Set Windows VST Search Path"),
3858 _rc_config->get_plugin_path_vst(),
3859 PluginManager::instance().get_default_windows_vst_path()
3861 ResponseType r = (ResponseType) pd->run ();
3863 if (r == RESPONSE_ACCEPT) {
3864 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
3871 RCOptionEditor::populate_sync_options ()
3873 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3875 _sync_source->clear ();
3877 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3878 _sync_source->add (*i, sync_source_to_string (*i));
3881 if (sync_opts.empty()) {
3882 _sync_source->set_sensitive(false);
3884 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3885 _rc_config->set_sync_source(sync_opts.front());
3889 parameter_changed ("sync-source");
3893 RCOptionEditor::use_own_window (bool and_fill_it)
3895 bool new_window = !own_window ();
3897 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
3899 if (win && new_window) {
3900 win->set_name ("PreferencesWindow");
3901 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
3908 RCOptionEditor::get_state ()
3910 XMLNode* node = new XMLNode (X_("Preferences"));
3911 node->add_child_nocopy (Tabbable::get_state());