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"
69 #include "ui_config.h"
74 using namespace Gtkmm2ext;
76 using namespace ARDOUR;
77 using namespace ARDOUR_UI_UTILS;
79 class ClickOptions : public OptionEditorMiniPage
82 ClickOptions (RCConfiguration* c)
84 , _click_browse_button (_("Browse..."))
85 , _click_emphasis_browse_button (_("Browse..."))
87 // TODO get rid of GTK -> use OptionEditor Widgets
90 Label* l = manage (left_aligned_label (_("Emphasis on first beat")));
91 _use_emphasis_on_click_check_button.add (*l);
92 t->attach (_use_emphasis_on_click_check_button, 1, 3, 0, 1, FILL);
93 _use_emphasis_on_click_check_button.signal_toggled().connect (
94 sigc::mem_fun (*this, &ClickOptions::use_emphasis_on_click_toggled));
96 l = manage (left_aligned_label (_("Use built-in default sounds")));
97 _use_default_click_check_button.add (*l);
98 t->attach (_use_default_click_check_button, 1, 3, 1, 2, FILL);
99 _use_default_click_check_button.signal_toggled().connect (
100 sigc::mem_fun (*this, &ClickOptions::use_default_click_toggled));
102 l = manage (left_aligned_label (_("Audio file:")));
103 t->attach (*l, 1, 2, 2, 3, FILL);
104 t->attach (_click_path_entry, 2, 3, 2, 3, FILL);
105 _click_browse_button.signal_clicked ().connect (
106 sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
107 t->attach (_click_browse_button, 3, 4, 2, 3, FILL);
109 l = manage (left_aligned_label (_("Emphasis audio file:")));
110 t->attach (*l, 1, 2, 3, 4, FILL);
111 t->attach (_click_emphasis_path_entry, 2, 3, 3, 4, FILL);
112 _click_emphasis_browse_button.signal_clicked ().connect (
113 sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
114 t->attach (_click_emphasis_browse_button, 3, 4, 3, 4, FILL);
116 FaderOption* fo = new FaderOption (
119 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
120 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
123 fo->add_to_page (this);
124 fo->set_state_from_config ();
126 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
127 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
129 if (_rc_config->get_click_sound ().empty() &&
130 _rc_config->get_click_emphasis_sound().empty()) {
131 _use_default_click_check_button.set_active (true);
132 _use_emphasis_on_click_check_button.set_active (true);
135 _use_default_click_check_button.set_active (false);
136 _use_emphasis_on_click_check_button.set_active (false);
140 void parameter_changed (string const & p)
142 if (p == "click-sound") {
143 _click_path_entry.set_text (_rc_config->get_click_sound());
144 } else if (p == "click-emphasis-sound") {
145 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
146 } else if (p == "use-click-emphasis") {
147 bool x = _rc_config->get_use_click_emphasis ();
148 _use_emphasis_on_click_check_button.set_active (x);
152 void set_state_from_config ()
154 parameter_changed ("click-sound");
155 parameter_changed ("click-emphasis-sound");
156 parameter_changed ("use-click-emphasis");
161 void click_browse_clicked ()
163 SoundFileChooser sfdb (_("Choose Click"));
168 if (sfdb.run () == RESPONSE_OK) {
169 click_chosen (sfdb.get_filename());
173 void click_chosen (string const & path)
175 _click_path_entry.set_text (path);
176 _rc_config->set_click_sound (path);
179 void click_changed ()
181 click_chosen (_click_path_entry.get_text ());
184 void click_emphasis_browse_clicked ()
186 SoundFileChooser sfdb (_("Choose Click Emphasis"));
191 if (sfdb.run () == RESPONSE_OK) {
192 click_emphasis_chosen (sfdb.get_filename());
196 void click_emphasis_chosen (string const & path)
198 _click_emphasis_path_entry.set_text (path);
199 _rc_config->set_click_emphasis_sound (path);
202 void click_emphasis_changed ()
204 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
207 void use_default_click_toggled ()
209 if (_use_default_click_check_button.get_active ()) {
210 _rc_config->set_click_sound ("");
211 _rc_config->set_click_emphasis_sound ("");
212 _click_path_entry.set_sensitive (false);
213 _click_emphasis_path_entry.set_sensitive (false);
214 _click_browse_button.set_sensitive (false);
215 _click_emphasis_browse_button.set_sensitive (false);
217 _click_path_entry.set_sensitive (true);
218 _click_emphasis_path_entry.set_sensitive (true);
219 _click_browse_button.set_sensitive (true);
220 _click_emphasis_browse_button.set_sensitive (true);
224 void use_emphasis_on_click_toggled ()
226 if (_use_emphasis_on_click_check_button.get_active ()) {
227 _rc_config->set_use_click_emphasis(true);
229 _rc_config->set_use_click_emphasis(false);
233 RCConfiguration* _rc_config;
234 CheckButton _use_default_click_check_button;
235 CheckButton _use_emphasis_on_click_check_button;
236 Entry _click_path_entry;
237 Entry _click_emphasis_path_entry;
238 Button _click_browse_button;
239 Button _click_emphasis_browse_button;
242 class UndoOptions : public OptionEditorComponent
245 UndoOptions (RCConfiguration* c) :
247 _limit_undo_button (_("Limit undo history to")),
248 _save_undo_button (_("Save undo history of"))
250 // TODO get rid of GTK -> use OptionEditor SpinOption
251 _limit_undo_spin.set_range (0, 512);
252 _limit_undo_spin.set_increments (1, 10);
254 _save_undo_spin.set_range (0, 512);
255 _save_undo_spin.set_increments (1, 10);
257 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
258 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
259 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
260 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
263 void parameter_changed (string const & p)
265 if (p == "history-depth") {
266 int32_t const d = _rc_config->get_history_depth();
267 _limit_undo_button.set_active (d != 0);
268 _limit_undo_spin.set_sensitive (d != 0);
269 _limit_undo_spin.set_value (d);
270 } else if (p == "save-history") {
271 bool const x = _rc_config->get_save_history ();
272 _save_undo_button.set_active (x);
273 _save_undo_spin.set_sensitive (x);
274 } else if (p == "save-history-depth") {
275 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
279 void set_state_from_config ()
281 parameter_changed ("save-history");
282 parameter_changed ("history-depth");
283 parameter_changed ("save-history-depth");
286 void limit_undo_toggled ()
288 bool const x = _limit_undo_button.get_active ();
289 _limit_undo_spin.set_sensitive (x);
290 int32_t const n = x ? 16 : 0;
291 _limit_undo_spin.set_value (n);
292 _rc_config->set_history_depth (n);
295 void limit_undo_changed ()
297 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
300 void save_undo_toggled ()
302 bool const x = _save_undo_button.get_active ();
303 _rc_config->set_save_history (x);
306 void save_undo_changed ()
308 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
311 void add_to_page (OptionEditorPage* p)
313 int const n = p->table.property_n_rows();
314 Table* t = & p->table;
316 t->resize (n + 2, 3);
318 Label* l = manage (left_aligned_label (_("commands")));
319 HBox* box = manage (new HBox());
320 box->set_spacing (4);
321 box->pack_start (_limit_undo_spin, false, false);
322 box->pack_start (*l, true, true);
323 t->attach (_limit_undo_button, 1, 2, n, n +1, FILL);
324 t->attach (*box, 2, 3, n, n + 1, FILL | EXPAND);
326 l = manage (left_aligned_label (_("commands")));
327 box = manage (new HBox());
328 box->set_spacing (4);
329 box->pack_start (_save_undo_spin, false, false);
330 box->pack_start (*l, true, true);
331 t->attach (_save_undo_button, 1, 2, n + 1, n + 2, FILL);
332 t->attach (*box, 2, 3, n + 1, n + 2, FILL | EXPAND);
335 Gtk::Widget& tip_widget() {
336 return _limit_undo_button; // unused
340 RCConfiguration* _rc_config;
341 CheckButton _limit_undo_button;
342 SpinButton _limit_undo_spin;
343 CheckButton _save_undo_button;
344 SpinButton _save_undo_spin;
348 static const struct {
360 { "Key|Shift", GDK_SHIFT_MASK },
361 { "Command", GDK_MOD2_MASK },
362 { "Control", GDK_CONTROL_MASK },
363 { "Option", GDK_MOD1_MASK },
364 { "Command-Shift", GDK_MOD2_MASK|GDK_SHIFT_MASK },
365 { "Command-Option", GDK_MOD2_MASK|GDK_MOD1_MASK },
366 { "Command-Control", GDK_MOD2_MASK|GDK_CONTROL_MASK },
367 { "Command-Option-Control", GDK_MOD2_MASK|GDK_MOD1_MASK|GDK_CONTROL_MASK },
368 { "Option-Control", GDK_MOD1_MASK|GDK_CONTROL_MASK },
369 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
370 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
371 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_MOD2_MASK },
374 { "Key|Shift", GDK_SHIFT_MASK },
375 { "Control", GDK_CONTROL_MASK },
376 { "Alt", GDK_MOD1_MASK },
377 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
378 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
379 { "Control-Windows", GDK_CONTROL_MASK|GDK_MOD4_MASK },
380 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
381 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
382 { "Alt-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
383 { "Alt-Shift-Windows", GDK_MOD1_MASK|GDK_SHIFT_MASK|GDK_MOD4_MASK },
384 { "Mod2", GDK_MOD2_MASK },
385 { "Mod3", GDK_MOD3_MASK },
386 { "Windows", GDK_MOD4_MASK },
387 { "Mod5", GDK_MOD5_MASK },
393 class KeyboardOptions : public OptionEditorMiniPage
397 _delete_button_adjustment (3, 1, 12),
398 _delete_button_spin (_delete_button_adjustment),
399 _edit_button_adjustment (3, 1, 5),
400 _edit_button_spin (_edit_button_adjustment),
401 _insert_note_button_adjustment (3, 1, 5),
402 _insert_note_button_spin (_insert_note_button_adjustment)
404 // TODO get rid of GTK -> use OptionEditor Widgets
406 const std::string restart_msg = _("\nChanges to this setting will only persist after your project has been saved.");
407 /* internationalize and prepare for use with combos */
410 for (int i = 0; modifiers[i].name; ++i) {
411 dumb.push_back (S_(modifiers[i].name));
414 set_popdown_strings (_edit_modifier_combo, dumb);
415 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
416 Gtkmm2ext::UI::instance()->set_tip (_edit_modifier_combo,
417 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
418 for (int x = 0; modifiers[x].name; ++x) {
419 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
420 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
430 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
431 l->set_name ("OptionsLabel");
435 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
436 strs.push_back (bf->first);
439 set_popdown_strings (_keyboard_layout_selector, strs);
440 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
441 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
443 t->attach (*l, col, col + 2, row, row + 1, FILL, FILL);
444 t->attach (_keyboard_layout_selector, col + 2, col + 3, row, row + 1, FILL | EXPAND, FILL);
449 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Clicking:"))));
450 l->set_name ("OptionEditorHeading");
451 l->set_use_markup (true);
452 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
457 l = manage (left_aligned_label (_("Edit using:")));
458 l->set_name ("OptionsLabel");
460 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
461 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
463 l = manage (new Label (_("+ button")));
464 l->set_name ("OptionsLabel");
466 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
467 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, SHRINK , FILL);
469 _edit_button_spin.set_name ("OptionsEntry");
470 _edit_button_adjustment.set_value (Keyboard::edit_button());
471 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
476 set_popdown_strings (_delete_modifier_combo, dumb);
477 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
478 Gtkmm2ext::UI::instance()->set_tip (_delete_modifier_combo,
479 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
480 for (int x = 0; modifiers[x].name; ++x) {
481 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
482 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
487 l = manage (left_aligned_label (_("Delete using:")));
488 l->set_name ("OptionsLabel");
490 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
491 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
493 l = manage (new Label (_("+ button")));
494 l->set_name ("OptionsLabel");
496 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
497 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, SHRINK, FILL);
499 _delete_button_spin.set_name ("OptionsEntry");
500 _delete_button_adjustment.set_value (Keyboard::delete_button());
501 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
506 set_popdown_strings (_insert_note_modifier_combo, dumb);
507 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
508 Gtkmm2ext::UI::instance()->set_tip (_insert_note_modifier_combo,
509 (string_compose (_("<b>Recommended Setting: %1 + button 1 (left mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
510 for (int x = 0; modifiers[x].name; ++x) {
511 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
512 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
517 l = manage (left_aligned_label (_("Insert note using:")));
518 l->set_name ("OptionsLabel");
520 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
521 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
523 l = manage (new Label (_("+ button")));
524 l->set_name ("OptionsLabel");
526 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
527 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, SHRINK, FILL);
529 _insert_note_button_spin.set_name ("OptionsEntry");
530 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
531 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
535 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Beginning a Drag:"))));
536 l->set_name ("OptionEditorHeading");
537 l->set_use_markup (true);
538 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
544 set_popdown_strings (_copy_modifier_combo, dumb);
545 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
546 Gtkmm2ext::UI::instance()->set_tip (_copy_modifier_combo,
547 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
549 Keyboard::secondary_modifier_name (),
551 Keyboard::primary_modifier_name (),
554 for (int x = 0; modifiers[x].name; ++x) {
555 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
556 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
561 l = manage (left_aligned_label (_("Copy items using:")));
562 l->set_name ("OptionsLabel");
564 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
565 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
570 /* constraint modifier */
571 set_popdown_strings (_constraint_modifier_combo, dumb);
572 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
573 std::string mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
574 Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo,
575 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
577 Keyboard::primary_modifier_name (),
579 Keyboard::tertiary_modifier_name (),
582 for (int x = 0; modifiers[x].name; ++x) {
583 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
584 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
589 l = manage (left_aligned_label (_("Constrain drag using:")));
590 l->set_name ("OptionsLabel");
592 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
593 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
599 set_popdown_strings (_push_points_combo, dumb);
600 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
602 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
603 Gtkmm2ext::UI::instance()->set_tip (_push_points_combo,
604 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
605 for (int x = 0; modifiers[x].name; ++x) {
606 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
607 _push_points_combo.set_active_text (S_(modifiers[x].name));
612 l = manage (left_aligned_label (_("Push points using:")));
613 l->set_name ("OptionsLabel");
615 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
616 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
620 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Beginning a Trim:"))));
621 l->set_name ("OptionEditorHeading");
622 l->set_use_markup (true);
623 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
629 set_popdown_strings (_trim_contents_combo, dumb);
630 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
631 Gtkmm2ext::UI::instance()->set_tip (_trim_contents_combo,
632 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
633 for (int x = 0; modifiers[x].name; ++x) {
634 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
635 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
640 l = manage (left_aligned_label (_("Trim contents using:")));
641 l->set_name ("OptionsLabel");
643 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
644 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
650 set_popdown_strings (_trim_anchored_combo, dumb);
651 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
653 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::tertiary_modifier_name ());
654 Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo,
655 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
656 for (int x = 0; modifiers[x].name; ++x) {
657 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
658 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
663 l = manage (left_aligned_label (_("Anchored trim using:")));
664 l->set_name ("OptionsLabel");
666 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
668 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
673 /* jump trim disabled for now
674 set_popdown_strings (_trim_jump_combo, dumb);
675 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
677 for (int x = 0; modifiers[x].name; ++x) {
678 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
679 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
684 l = manage (left_aligned_label (_("Jump after trim using:")));
685 l->set_name ("OptionsLabel");
687 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
689 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
695 /* note resize relative */
696 set_popdown_strings (_note_size_relative_combo, dumb);
697 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
698 Gtkmm2ext::UI::instance()->set_tip (_note_size_relative_combo,
699 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
700 for (int x = 0; modifiers[x].name; ++x) {
701 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
702 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
707 l = manage (left_aligned_label (_("Resize notes relatively using:")));
708 l->set_name ("OptionsLabel");
710 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
712 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
716 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Dragging:"))));
717 l->set_name ("OptionEditorHeading");
718 l->set_use_markup (true);
719 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
725 set_popdown_strings (_snap_modifier_combo, dumb);
726 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
728 mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ());
730 mod_str = Keyboard::secondary_modifier_name();
732 Gtkmm2ext::UI::instance()->set_tip (_snap_modifier_combo,
733 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
734 for (int x = 0; modifiers[x].name; ++x) {
735 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
736 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
741 l = manage (left_aligned_label (_("Ignore snap using:")));
742 l->set_name ("OptionsLabel");
744 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
745 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
751 set_popdown_strings (_snap_delta_combo, dumb);
752 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
754 mod_str = Keyboard::level4_modifier_name ();
756 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::level4_modifier_name ());
758 Gtkmm2ext::UI::instance()->set_tip (_snap_delta_combo,
759 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
760 for (int x = 0; modifiers[x].name; ++x) {
761 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
762 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
767 l = manage (left_aligned_label (_("Snap relatively using:")));
768 l->set_name ("OptionsLabel");
770 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
771 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
775 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Trimming:"))));
776 l->set_name ("OptionEditorHeading");
777 l->set_use_markup (true);
778 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
784 set_popdown_strings (_trim_overlap_combo, dumb);
785 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
787 Gtkmm2ext::UI::instance()->set_tip (_trim_overlap_combo,
788 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
789 for (int x = 0; modifiers[x].name; ++x) {
790 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
791 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
796 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
797 l->set_name ("OptionsLabel");
799 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
800 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
804 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Dragging Control Points:"))));
805 l->set_name ("OptionEditorHeading");
806 l->set_use_markup (true);
807 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
813 set_popdown_strings (_fine_adjust_combo, dumb);
814 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
816 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::secondary_modifier_name ());
817 Gtkmm2ext::UI::instance()->set_tip (_fine_adjust_combo,
818 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
819 for (int x = 0; modifiers[x].name; ++x) {
820 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
821 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
826 l = manage (left_aligned_label (_("Fine adjust using:")));
827 l->set_name ("OptionsLabel");
829 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
830 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
833 void parameter_changed (string const &)
835 /* XXX: these aren't really config options... */
838 void set_state_from_config ()
840 /* XXX: these aren't really config options... */
843 void add_to_page (OptionEditorPage* p)
845 int const n = p->table.property_n_rows();
846 p->table.resize (n + 1, 3);
847 p->table.attach (box, 1, 3, n, n + 1, FILL | EXPAND, SHRINK, 0, 0);
852 void bindings_changed ()
854 string const txt = _keyboard_layout_selector.get_active_text();
856 /* XXX: config...? for all this keyboard stuff */
858 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
859 if (txt == i->first) {
860 if (Keyboard::load_keybindings (i->second)) {
861 Keyboard::save_keybindings ();
867 void edit_modifier_chosen ()
869 string const txt = _edit_modifier_combo.get_active_text();
871 for (int i = 0; modifiers[i].name; ++i) {
872 if (txt == S_(modifiers[i].name)) {
873 Keyboard::set_edit_modifier (modifiers[i].modifier);
879 void delete_modifier_chosen ()
881 string const txt = _delete_modifier_combo.get_active_text();
883 for (int i = 0; modifiers[i].name; ++i) {
884 if (txt == S_(modifiers[i].name)) {
885 Keyboard::set_delete_modifier (modifiers[i].modifier);
891 void copy_modifier_chosen ()
893 string const txt = _copy_modifier_combo.get_active_text();
895 for (int i = 0; modifiers[i].name; ++i) {
896 if (txt == S_(modifiers[i].name)) {
897 Keyboard::set_copy_modifier (modifiers[i].modifier);
903 void insert_note_modifier_chosen ()
905 string const txt = _insert_note_modifier_combo.get_active_text();
907 for (int i = 0; modifiers[i].name; ++i) {
908 if (txt == S_(modifiers[i].name)) {
909 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
915 void snap_modifier_chosen ()
917 string const txt = _snap_modifier_combo.get_active_text();
919 for (int i = 0; modifiers[i].name; ++i) {
920 if (txt == S_(modifiers[i].name)) {
921 Keyboard::set_snap_modifier (modifiers[i].modifier);
927 void snap_delta_modifier_chosen ()
929 string const txt = _snap_delta_combo.get_active_text();
931 for (int i = 0; modifiers[i].name; ++i) {
932 if (txt == S_(modifiers[i].name)) {
933 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
939 void constraint_modifier_chosen ()
941 string const txt = _constraint_modifier_combo.get_active_text();
943 for (int i = 0; modifiers[i].name; ++i) {
944 if (txt == S_(modifiers[i].name)) {
945 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
951 void trim_contents_modifier_chosen ()
953 string const txt = _trim_contents_combo.get_active_text();
955 for (int i = 0; modifiers[i].name; ++i) {
956 if (txt == S_(modifiers[i].name)) {
957 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
963 void trim_overlap_modifier_chosen ()
965 string const txt = _trim_overlap_combo.get_active_text();
967 for (int i = 0; modifiers[i].name; ++i) {
968 if (txt == S_(modifiers[i].name)) {
969 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
975 void trim_anchored_modifier_chosen ()
977 string const txt = _trim_anchored_combo.get_active_text();
979 for (int i = 0; modifiers[i].name; ++i) {
980 if (txt == S_(modifiers[i].name)) {
981 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
987 void fine_adjust_modifier_chosen ()
989 string const txt = _fine_adjust_combo.get_active_text();
991 for (int i = 0; modifiers[i].name; ++i) {
992 if (txt == S_(modifiers[i].name)) {
993 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
999 void push_points_modifier_chosen ()
1001 string const txt = _push_points_combo.get_active_text();
1003 for (int i = 0; modifiers[i].name; ++i) {
1004 if (txt == S_(modifiers[i].name)) {
1005 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
1011 void note_size_relative_modifier_chosen ()
1013 string const txt = _note_size_relative_combo.get_active_text();
1015 for (int i = 0; modifiers[i].name; ++i) {
1016 if (txt == S_(modifiers[i].name)) {
1017 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
1023 void delete_button_changed ()
1025 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
1028 void edit_button_changed ()
1030 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
1033 void insert_note_button_changed ()
1035 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
1038 ComboBoxText _keyboard_layout_selector;
1039 ComboBoxText _edit_modifier_combo;
1040 ComboBoxText _delete_modifier_combo;
1041 ComboBoxText _copy_modifier_combo;
1042 ComboBoxText _insert_note_modifier_combo;
1043 ComboBoxText _snap_modifier_combo;
1044 ComboBoxText _snap_delta_combo;
1045 ComboBoxText _constraint_modifier_combo;
1046 ComboBoxText _trim_contents_combo;
1047 ComboBoxText _trim_overlap_combo;
1048 ComboBoxText _trim_anchored_combo;
1049 ComboBoxText _trim_jump_combo;
1050 ComboBoxText _fine_adjust_combo;
1051 ComboBoxText _push_points_combo;
1052 ComboBoxText _note_size_relative_combo;
1053 Adjustment _delete_button_adjustment;
1054 SpinButton _delete_button_spin;
1055 Adjustment _edit_button_adjustment;
1056 SpinButton _edit_button_spin;
1057 Adjustment _insert_note_button_adjustment;
1058 SpinButton _insert_note_button_spin;
1062 class FontScalingOptions : public HSliderOption
1065 FontScalingOptions ()
1066 : HSliderOption ("font-scale", _("GUI and Font scaling"),
1067 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_font_scale),
1068 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_font_scale),
1072 const std::string dflt = _("100%");
1073 const std::string empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
1075 _hscale.set_name("FontScaleSlider");
1076 _hscale.set_draw_value(false);
1077 _hscale.add_mark(50, Gtk::POS_TOP, empty);
1078 _hscale.add_mark(60, Gtk::POS_TOP, empty);
1079 _hscale.add_mark(70, Gtk::POS_TOP, empty);
1080 _hscale.add_mark(80, Gtk::POS_TOP, empty);
1081 _hscale.add_mark(90, Gtk::POS_TOP, empty);
1082 _hscale.add_mark(100, Gtk::POS_TOP, dflt);
1083 _hscale.add_mark(125, Gtk::POS_TOP, empty);
1084 _hscale.add_mark(150, Gtk::POS_TOP, empty);
1085 _hscale.add_mark(175, Gtk::POS_TOP, empty);
1086 _hscale.add_mark(200, Gtk::POS_TOP, empty);
1087 _hscale.add_mark(250, Gtk::POS_TOP, empty);
1089 set_note (_("Adjusting the scale requires an application restart to re-layout."));
1094 HSliderOption::changed ();
1095 /* XXX: should be triggered from the parameter changed signal */
1096 UIConfiguration::instance().reset_dpi ();
1100 class VstTimeOutSliderOption : public HSliderOption
1103 VstTimeOutSliderOption (RCConfiguration* c)
1104 : HSliderOption ("vst-scan-timeout", _("Scan Time Out"),
1105 sigc::mem_fun (*c, &RCConfiguration::get_vst_scan_timeout),
1106 sigc::mem_fun (*c, &RCConfiguration::set_vst_scan_timeout),
1109 _label.set_alignment (1.0, 0.5); // match buttons below
1110 _hscale.set_digits (0);
1111 _hscale.set_draw_value(false);
1112 _hscale.add_mark( 0, Gtk::POS_TOP, _("\u221e")); // infinity
1113 _hscale.add_mark( 300, Gtk::POS_TOP, _("30 sec"));
1114 _hscale.add_mark( 600, Gtk::POS_TOP, _("1 min"));
1115 _hscale.add_mark(1200, Gtk::POS_TOP, _("2 mins"));
1116 _hscale.add_mark(1800, Gtk::POS_TOP, _("3 mins"));
1117 _hscale.add_mark(2400, Gtk::POS_TOP, _("4 mins"));
1118 _hscale.add_mark(3000, Gtk::POS_TOP, _("5 mins"));
1120 Gtkmm2ext::UI::instance()->set_tip(_hscale,
1121 _("Specify the default timeout for plugin instantiation. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1125 class ClipLevelOptions : public OptionEditorComponent
1129 : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1130 , _clip_level_slider (_clip_level_adjustment)
1131 , _label (_("Waveform Clip Level (dBFS):"))
1133 _label.set_name ("OptionsLabel");
1135 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ());
1137 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1139 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1142 void parameter_changed (string const & p)
1144 if (p == "waveform-clip-level") {
1145 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level());
1147 if (p == "show-waveform-clipping") {
1148 _clip_level_slider.set_sensitive (UIConfiguration::instance().get_show_waveform_clipping ());
1152 void set_state_from_config ()
1154 parameter_changed ("waveform-clip-level");
1155 parameter_changed ("show-waveform-clipping");
1158 void add_to_page (OptionEditorPage* p) {
1159 add_widgets_to_page (p, &_label, &_clip_level_slider);
1162 Gtk::Widget& tip_widget() {
1163 return _clip_level_slider;
1168 void clip_level_changed ()
1170 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1171 /* XXX: should be triggered from the parameter changed signal */
1172 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1175 Adjustment _clip_level_adjustment;
1176 HScale _clip_level_slider;
1180 class BufferingOptions : public OptionEditorComponent
1183 BufferingOptions (RCConfiguration* c)
1185 , _label (_("Preset:"))
1186 , _playback ("playback-buffer-seconds", _("Playback (seconds of buffering)"),
1187 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_playback_buffer_seconds),
1188 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_playback_buffer_seconds),
1190 , _capture ("capture-buffer-seconds", _("Recording (seconds of buffering)"),
1191 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_capture_buffer_seconds),
1192 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_capture_buffer_seconds),
1195 // TODO use ComboOption
1196 vector<string> presets;
1198 /* these must match the order of the enums for BufferingPreset */
1199 presets.push_back (_("Small sessions (4-16 tracks)"));
1200 presets.push_back (_("Medium sessions (16-64 tracks)"));
1201 presets.push_back (_("Large sessions (64+ tracks)"));
1202 presets.push_back (_("Custom (set by sliders below)"));
1204 set_popdown_strings (_buffering_presets_combo, presets);
1205 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1207 _label.set_name ("OptionsLabel");
1208 _label.set_alignment (0, 0.5);
1212 add_to_page (OptionEditorPage* p)
1214 add_widgets_to_page (p, &_label, &_buffering_presets_combo);
1215 _playback.add_to_page (p);
1216 _capture.add_to_page (p);
1219 void parameter_changed (string const & p)
1221 if (p == "buffering-preset") {
1222 switch (_rc_config->get_buffering_preset()) {
1224 _playback.set_sensitive (false);
1225 _capture.set_sensitive (false);
1226 _buffering_presets_combo.set_active (0);
1229 _playback.set_sensitive (false);
1230 _capture.set_sensitive (false);
1231 _buffering_presets_combo.set_active (1);
1234 _playback.set_sensitive (false);
1235 _capture.set_sensitive (false);
1236 _buffering_presets_combo.set_active (2);
1239 _playback.set_sensitive (true);
1240 _capture.set_sensitive (true);
1241 _buffering_presets_combo.set_active (3);
1245 _playback.parameter_changed (p);
1246 _capture.parameter_changed (p);
1249 void set_state_from_config ()
1251 parameter_changed ("buffering-preset");
1252 _playback.set_state_from_config();
1253 _capture.set_state_from_config();
1256 Gtk::Widget& tip_widget() { return _buffering_presets_combo; }
1260 void preset_changed ()
1262 int index = _buffering_presets_combo.get_active_row_number ();
1268 _rc_config->set_buffering_preset (Small);
1271 _rc_config->set_buffering_preset (Medium);
1274 _rc_config->set_buffering_preset (Large);
1277 _rc_config->set_buffering_preset (Custom);
1280 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1285 RCConfiguration* _rc_config;
1287 HSliderOption _playback;
1288 HSliderOption _capture;
1289 ComboBoxText _buffering_presets_combo;
1292 class ControlSurfacesOptions : public OptionEditorMiniPage
1295 ControlSurfacesOptions ()
1296 : _ignore_view_change (0)
1298 _store = ListStore::create (_model);
1299 _view.set_model (_store);
1300 _view.append_column (_("Control Surface Protocol"), _model.name);
1301 _view.get_column(0)->set_resizable (true);
1302 _view.get_column(0)->set_expand (true);
1303 _view.append_column_editable (_("Enable"), _model.enabled);
1305 Gtk::HBox* edit_box = manage (new Gtk::HBox);
1306 edit_box->set_spacing(3);
1309 Label* label = manage (new Label);
1310 label->set_text (_("Edit the settings for selected protocol (it must be ENABLED first):"));
1311 edit_box->pack_start (*label, false, false);
1314 edit_button = manage (new Button(_("Show Protocol Settings")));
1315 edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
1316 edit_box->pack_start (*edit_button, true, true);
1317 edit_button->set_sensitive (false);
1318 edit_button->show ();
1320 int const n = table.property_n_rows();
1321 table.resize (n + 2, 3);
1322 table.attach (_view, 0, 3, n, n + 1);
1323 table.attach (*edit_box, 0, 3, n + 1, n + 2);
1325 ControlProtocolManager& m = ControlProtocolManager::instance ();
1326 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1327 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1329 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1330 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1331 _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
1334 void parameter_changed (std::string const &)
1339 void set_state_from_config ()
1343 ControlProtocolManager& m = ControlProtocolManager::instance ();
1344 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1346 if (!(*i)->mandatory) {
1347 TreeModel::Row r = *_store->append ();
1348 r[_model.name] = (*i)->name;
1349 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1350 r[_model.protocol_info] = *i;
1357 void protocol_status_changed (ControlProtocolInfo* cpi) {
1359 TreeModel::Children rows = _store->children();
1361 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1362 string n = ((*x)[_model.name]);
1364 if ((*x)[_model.protocol_info] == cpi) {
1365 _ignore_view_change++;
1366 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1367 _ignore_view_change--;
1373 void selection_changed ()
1375 //enable the Edit button when a row is selected for editing
1376 TreeModel::Row row = *(_view.get_selection()->get_selected());
1377 if (row && row[_model.enabled])
1378 edit_button->set_sensitive (true);
1380 edit_button->set_sensitive (false);
1383 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1385 TreeModel::Row r = *i;
1387 if (_ignore_view_change) {
1391 ControlProtocolInfo* cpi = r[_model.protocol_info];
1396 bool const was_enabled = (cpi->protocol != 0);
1397 bool const is_enabled = r[_model.enabled];
1400 if (was_enabled != is_enabled) {
1403 ControlProtocolManager::instance().activate (*cpi);
1405 ControlProtocolManager::instance().deactivate (*cpi);
1409 selection_changed ();
1412 void edit_btn_clicked ()
1415 ControlProtocolInfo* cpi;
1418 row = *(_view.get_selection()->get_selected());
1419 if (!row[_model.enabled]) {
1422 cpi = row[_model.protocol_info];
1423 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1426 Box* box = (Box*) cpi->protocol->get_gui ();
1430 if (box->get_parent()) {
1431 static_cast<ArdourWindow*>(box->get_parent())->present();
1434 WindowTitle title (Glib::get_application_name());
1435 title += row[_model.name];
1436 title += _("Configuration");
1437 /* once created, the window is managed by the surface itself (as ->get_parent())
1438 * Surface's tear_down_gui() is called on session close, when de-activating
1439 * or re-initializing a surface.
1440 * tear_down_gui() hides an deletes the Window if it exists.
1442 ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
1443 win->set_title ("Control Protocol Options");
1449 void edit_clicked (GdkEventButton* ev)
1451 if (ev->type != GDK_2BUTTON_PRESS) {
1458 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1462 ControlSurfacesModelColumns ()
1466 add (protocol_info);
1469 TreeModelColumn<string> name;
1470 TreeModelColumn<bool> enabled;
1471 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1474 Glib::RefPtr<ListStore> _store;
1475 ControlSurfacesModelColumns _model;
1477 PBD::ScopedConnection protocol_status_connection;
1478 uint32_t _ignore_view_change;
1479 Gtk::Button* edit_button;
1482 class VideoTimelineOptions : public OptionEditorMiniPage
1485 VideoTimelineOptions (RCConfiguration* c)
1487 , _show_video_export_info_button (_("Show Video Export Info before export"))
1488 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1489 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1490 , _xjadeo_browse_button (_("Browse..."))
1493 int n = table.property_n_rows();
1495 t->attach (_show_video_export_info_button, 1, 4, n, n + 1);
1496 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1497 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1498 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1501 t->attach (_show_video_server_dialog_button, 1, 4, n, n + 1);
1502 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1503 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1504 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1507 t->attach (_video_advanced_setup_button, 1, 4, n, n + 1, FILL);
1508 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1509 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1510 _("<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."));
1513 Label* l = manage (new Label (_("Video Server URL:")));
1514 l->set_alignment (0, 0.5);
1515 t->attach (*l, 1, 2, n, n + 1, FILL);
1516 t->attach (_video_server_url_entry, 2, 4, n, n + 1, FILL);
1517 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1518 _("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"));
1521 l = manage (new Label (_("Video Folder:")));
1522 l->set_alignment (0, 0.5);
1523 t->attach (*l, 1, 2, n, n + 1, FILL);
1524 t->attach (_video_server_docroot_entry, 2, 4, n, n + 1);
1525 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1526 _("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."));
1529 l = manage (new Label (""));
1530 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1533 l = manage (new Label (string_compose ("<b>%1</b>", _("Video Monitor"))));
1534 l->set_use_markup (true);
1535 l->set_alignment (0, 0.5);
1536 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1539 l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"),
1542 #elif defined PLATFORM_WINDOWS
1548 l->set_alignment (0, 0.5);
1549 t->attach (*l, 1, 4, n, n + 1, FILL);
1552 t->attach (_custom_xjadeo_path, 2, 3, n, n + 1, EXPAND|FILL);
1553 Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart."));
1554 t->attach (_xjadeo_browse_button, 3, 4, n, n + 1, FILL);
1556 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1557 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1558 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1559 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1560 _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed));
1561 _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked));
1563 // xjadeo-path is a UIConfig parameter
1564 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &VideoTimelineOptions::parameter_changed));
1567 void server_url_changed ()
1569 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1572 void server_docroot_changed ()
1574 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1577 void show_video_export_info_toggled ()
1579 bool const x = _show_video_export_info_button.get_active ();
1580 _rc_config->set_show_video_export_info (x);
1583 void show_video_server_dialog_toggled ()
1585 bool const x = _show_video_server_dialog_button.get_active ();
1586 _rc_config->set_show_video_server_dialog (x);
1589 void video_advanced_setup_toggled ()
1591 bool const x = _video_advanced_setup_button.get_active ();
1592 _rc_config->set_video_advanced_setup(x);
1595 void custom_xjadeo_path_changed ()
1597 UIConfiguration::instance().set_xjadeo_binary (_custom_xjadeo_path.get_text());
1600 void xjadeo_browse_clicked ()
1602 Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN);
1603 dialog.set_filename (UIConfiguration::instance().get_xjadeo_binary());
1604 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1605 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1606 if (dialog.run () == Gtk::RESPONSE_OK) {
1607 const std::string& filename = dialog.get_filename();
1608 if (!filename.empty() && (
1610 Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) ||
1612 Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)
1614 UIConfiguration::instance().set_xjadeo_binary (filename);
1619 void parameter_changed (string const & p)
1621 if (p == "video-server-url") {
1622 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1623 } else if (p == "video-server-docroot") {
1624 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1625 } else if (p == "show-video-export-info") {
1626 bool const x = _rc_config->get_show_video_export_info();
1627 _show_video_export_info_button.set_active (x);
1628 } else if (p == "show-video-server-dialog") {
1629 bool const x = _rc_config->get_show_video_server_dialog();
1630 _show_video_server_dialog_button.set_active (x);
1631 } else if (p == "video-advanced-setup") {
1632 bool const x = _rc_config->get_video_advanced_setup();
1633 _video_advanced_setup_button.set_active(x);
1634 _video_server_docroot_entry.set_sensitive(x);
1635 _video_server_url_entry.set_sensitive(x);
1636 } else if (p == "xjadeo-binary") {
1637 _custom_xjadeo_path.set_text (UIConfiguration::instance().get_xjadeo_binary());
1641 void set_state_from_config ()
1643 parameter_changed ("video-server-url");
1644 parameter_changed ("video-server-docroot");
1645 parameter_changed ("video-monitor-setup-dialog");
1646 parameter_changed ("show-video-export-info");
1647 parameter_changed ("show-video-server-dialog");
1648 parameter_changed ("video-advanced-setup");
1649 parameter_changed ("xjadeo-binary");
1653 RCConfiguration* _rc_config;
1654 Entry _video_server_url_entry;
1655 Entry _video_server_docroot_entry;
1656 Entry _custom_xjadeo_path;
1657 CheckButton _show_video_export_info_button;
1658 CheckButton _show_video_server_dialog_button;
1659 CheckButton _video_advanced_setup_button;
1660 Button _xjadeo_browse_button;
1663 class ColumVisibilityOption : public Option
1666 ColumVisibilityOption (string id, string name, uint32_t n_col, sigc::slot<uint32_t> get, sigc::slot<bool, uint32_t> set)
1673 cb = (CheckButton**) malloc (sizeof (CheckButton*) * n_col);
1674 for (uint32_t i = 0; i < n_col; ++i) {
1675 CheckButton* col = manage (new CheckButton (string_compose (_("Column %1"), i + 1)));
1676 col->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ColumVisibilityOption::column_toggled), i));
1677 _hbox.pack_start (*col);
1680 parameter_changed (id);
1683 ~ColumVisibilityOption () {
1687 Gtk::Widget& tip_widget() { return _hbox; }
1689 void set_state_from_config ()
1691 uint32_t c = _get();
1692 for (uint32_t i = 0; i < _n_col; ++i) {
1693 bool en = (c & (1<<i)) ? true : false;
1694 if (cb[i]->get_active () != en) {
1695 cb[i]->set_active (en);
1700 void add_to_page (OptionEditorPage* p)
1702 _heading.add_to_page (p);
1703 add_widget_to_page (p, &_hbox);
1707 void column_toggled (int b) {
1708 uint32_t c = _get();
1710 if (cb[b]->get_active ()) {
1721 OptionEditorHeading _heading;
1725 sigc::slot<uint32_t> _get;
1726 sigc::slot<bool, uint32_t> _set;
1730 /** A class which allows control of visibility of some editor components usign
1731 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1732 * which has the correct members, but with null widget pointers. This
1733 * class allows the user to set visibility of the members, the details
1734 * of which are stored in a configuration variable which can be watched
1735 * by parts of the editor that actually contain the widgets whose visibility
1736 * is being controlled.
1739 class VisibilityOption : public Option
1742 /** @param name User-visible name for this group.
1743 * @param g `Dummy' VisibilityGroup (as described above).
1744 * @param get Method to get the value of the appropriate configuration variable.
1745 * @param set Method to set the value of the appropriate configuration variable.
1747 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1748 : Option (g->get_state_name(), name)
1750 , _visibility_group (g)
1754 /* Watch for changes made by the user to our members */
1755 _visibility_group->VisibilityChanged.connect_same_thread (
1756 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1760 void set_state_from_config ()
1762 /* Set our state from the current configuration */
1763 _visibility_group->set_state (_get ());
1766 void add_to_page (OptionEditorPage* p)
1768 _heading.add_to_page (p);
1769 add_widget_to_page (p, _visibility_group->list_view ());
1772 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1777 /* The user has changed something, so reflect this change
1778 in the RCConfiguration.
1780 _set (_visibility_group->get_state_value ());
1783 OptionEditorHeading _heading;
1784 VisibilityGroup* _visibility_group;
1785 sigc::slot<std::string> _get;
1786 sigc::slot<bool, std::string> _set;
1787 PBD::ScopedConnection _visibility_group_connection;
1791 class MidiPortOptions : public OptionEditorMiniPage, public sigc::trackable
1796 setup_midi_port_view (midi_output_view, false);
1797 setup_midi_port_view (midi_input_view, true);
1799 OptionEditorHeading* h = new OptionEditorHeading (_("MIDI Inputs"));
1800 h->add_to_page (this);
1802 Gtk::ScrolledWindow* scroller = manage (new Gtk::ScrolledWindow);
1803 scroller->add (midi_input_view);
1804 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1805 scroller->set_size_request (-1, 180);
1807 int n = table.property_n_rows();
1808 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1810 h = new OptionEditorHeading (_("MIDI Outputs"));
1811 h->add_to_page (this);
1813 scroller = manage (new Gtk::ScrolledWindow);
1814 scroller->add (midi_output_view);
1815 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1816 scroller->set_size_request (-1, 180);
1818 n = table.property_n_rows();
1819 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1821 midi_output_view.show ();
1822 midi_input_view.show ();
1824 table.signal_show().connect (sigc::mem_fun (*this, &MidiPortOptions::on_show));
1827 void parameter_changed (string const&) {}
1828 void set_state_from_config() {}
1833 AudioEngine::instance()->PortRegisteredOrUnregistered.connect (connections,
1834 invalidator (*this),
1835 boost::bind (&MidiPortOptions::refill, this),
1837 AudioEngine::instance()->MidiPortInfoChanged.connect (connections,
1838 invalidator (*this),
1839 boost::bind (&MidiPortOptions::refill, this),
1841 AudioEngine::instance()->MidiSelectionPortsChanged.connect (connections,
1842 invalidator (*this),
1843 boost::bind (&MidiPortOptions::refill, this),
1849 if (refill_midi_ports (true, midi_input_view)) {
1850 input_label.show ();
1852 input_label.hide ();
1854 if (refill_midi_ports (false, midi_output_view)) {
1855 output_label.show ();
1857 output_label.hide ();
1862 PBD::ScopedConnectionList connections;
1864 /* MIDI port management */
1865 struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord {
1867 MidiPortColumns () {
1876 Gtk::TreeModelColumn<std::string> pretty_name;
1877 Gtk::TreeModelColumn<bool> music_data;
1878 Gtk::TreeModelColumn<bool> control_data;
1879 Gtk::TreeModelColumn<bool> selection;
1880 Gtk::TreeModelColumn<std::string> name;
1881 Gtk::TreeModelColumn<std::string> filler;
1884 MidiPortColumns midi_port_columns;
1885 Gtk::TreeView midi_input_view;
1886 Gtk::TreeView midi_output_view;
1887 Gtk::Label input_label;
1888 Gtk::Label output_label;
1890 void setup_midi_port_view (Gtk::TreeView&, bool with_selection);
1891 bool refill_midi_ports (bool for_input, Gtk::TreeView&);
1892 void pretty_name_edit (std::string const & path, std::string const & new_text, Gtk::TreeView*);
1893 void midi_music_column_toggled (std::string const & path, Gtk::TreeView*);
1894 void midi_control_column_toggled (std::string const & path, Gtk::TreeView*);
1895 void midi_selection_column_toggled (std::string const & path, Gtk::TreeView*);
1899 MidiPortOptions::setup_midi_port_view (Gtk::TreeView& view, bool with_selection)
1901 int pretty_name_column;
1904 int selection_column;
1905 TreeViewColumn* col;
1908 pretty_name_column = view.append_column_editable (_("Name (click to edit)"), midi_port_columns.pretty_name) - 1;
1910 col = manage (new TreeViewColumn ("", midi_port_columns.music_data));
1911 col->set_alignment (ALIGN_CENTER);
1912 l = manage (new Label (_("Music Data")));
1913 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of music performance data."), PROGRAM_NAME));
1914 col->set_widget (*l);
1916 music_column = view.append_column (*col) - 1;
1918 col = manage (new TreeViewColumn ("", midi_port_columns.control_data));
1919 col->set_alignment (ALIGN_CENTER);
1920 l = manage (new Label (_("Control Data")));
1921 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of control data."), PROGRAM_NAME));
1922 col->set_widget (*l);
1924 control_column = view.append_column (*col) - 1;
1926 if (with_selection) {
1927 col = manage (new TreeViewColumn (_("Follow Selection"), midi_port_columns.selection));
1928 selection_column = view.append_column (*col) - 1;
1929 l = manage (new Label (_("Follow Selection")));
1930 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));
1931 col->set_widget (*l);
1935 /* filler column so that the last real column doesn't expand */
1936 view.append_column ("", midi_port_columns.filler);
1938 CellRendererText* pretty_name_cell = dynamic_cast<CellRendererText*> (view.get_column_cell_renderer (pretty_name_column));
1939 pretty_name_cell->property_editable() = true;
1940 pretty_name_cell->signal_edited().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::pretty_name_edit), &view));
1942 CellRendererToggle* toggle_cell;
1944 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (music_column));
1945 toggle_cell->property_activatable() = true;
1946 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_music_column_toggled), &view));
1948 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (control_column));
1949 toggle_cell->property_activatable() = true;
1950 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_control_column_toggled), &view));
1952 if (with_selection) {
1953 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (selection_column));
1954 toggle_cell->property_activatable() = true;
1955 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_selection_column_toggled), &view));
1958 view.get_selection()->set_mode (SELECTION_NONE);
1959 view.set_tooltip_column (4); /* port "real" name */
1960 view.get_column(0)->set_resizable (true);
1961 view.get_column(0)->set_expand (true);
1965 MidiPortOptions::refill_midi_ports (bool for_input, Gtk::TreeView& view)
1967 using namespace ARDOUR;
1969 std::vector<string> ports;
1971 AudioEngine::instance()->get_known_midi_ports (ports);
1973 if (ports.empty()) {
1978 Glib::RefPtr<ListStore> model = Gtk::ListStore::create (midi_port_columns);
1980 for (vector<string>::const_iterator s = ports.begin(); s != ports.end(); ++s) {
1982 if (AudioEngine::instance()->port_is_mine (*s)) {
1986 PortManager::MidiPortInformation mpi (AudioEngine::instance()->midi_port_information (*s));
1988 if (mpi.pretty_name.empty()) {
1989 /* vanished since get_known_midi_ports() */
1993 if (for_input != mpi.input) {
1997 TreeModel::Row row = *(model->append());
1999 row[midi_port_columns.pretty_name] = mpi.pretty_name;
2000 row[midi_port_columns.music_data] = mpi.properties & MidiPortMusic;
2001 row[midi_port_columns.control_data] = mpi.properties & MidiPortControl;
2002 row[midi_port_columns.selection] = mpi.properties & MidiPortSelection;
2003 row[midi_port_columns.name] = *s;
2006 view.set_model (model);
2012 MidiPortOptions::midi_music_column_toggled (string const & path, TreeView* view)
2014 TreeIter iter = view->get_model()->get_iter (path);
2020 bool new_value = ! bool ((*iter)[midi_port_columns.music_data]);
2022 /* don't reset model - wait for MidiPortInfoChanged signal */
2025 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2027 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2032 MidiPortOptions::midi_control_column_toggled (string const & path, TreeView* view)
2034 TreeIter iter = view->get_model()->get_iter (path);
2040 bool new_value = ! bool ((*iter)[midi_port_columns.control_data]);
2042 /* don't reset model - wait for MidiPortInfoChanged signal */
2045 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2047 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2052 MidiPortOptions::midi_selection_column_toggled (string const & path, TreeView* view)
2054 TreeIter iter = view->get_model()->get_iter (path);
2060 bool new_value = ! bool ((*iter)[midi_port_columns.selection]);
2062 /* don't reset model - wait for MidiSelectionPortsChanged signal */
2065 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2067 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2072 MidiPortOptions::pretty_name_edit (std::string const & path, string const & new_text, Gtk::TreeView* view)
2074 TreeIter iter = view->get_model()->get_iter (path);
2080 boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
2082 ARDOUR::PortEngine::PortHandle ph = backend->get_port_by_name ((*iter)[midi_port_columns.name]);
2084 backend->set_port_property (ph, "http://jackaudio.org/metadata/pretty-name", new_text, "");
2085 (*iter)[midi_port_columns.pretty_name] = new_text;
2093 RCOptionEditor::RCOptionEditor ()
2094 : OptionEditorContainer (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
2095 , Tabbable (*this, _("Preferences")) /* pack self-as-vbox into tabbable */
2096 , _rc_config (Config)
2097 , _mixer_strip_visibility ("mixer-element-visibility")
2099 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
2103 uint32_t hwcpus = hardware_concurrency ();
2105 BoolComboOption* bco;
2108 add_option (_("General"), new OptionEditorHeading (_("DSP CPU Utilization")));
2110 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
2112 _("Signal processing uses"),
2113 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
2114 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
2117 procs->add (-1, _("all but one processor"));
2118 procs->add (0, _("all available processors"));
2120 for (uint32_t i = 1; i <= hwcpus; ++i) {
2121 procs->add (i, string_compose (P_("%1 processor", "%1 processors", i), i));
2124 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
2126 add_option (_("General"), procs);
2129 add_option (_("General"), new OptionEditorHeading (S_("Options|Undo")));
2131 add_option (_("General"), new UndoOptions (_rc_config));
2133 add_option (_("General"),
2135 "verify-remove-last-capture",
2136 _("Verify removal of last capture"),
2137 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
2138 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
2141 add_option (_("General"), new OptionEditorHeading (_("Session Management")));
2143 add_option (_("General"),
2145 "periodic-safety-backups",
2146 _("Make periodic backups of the session file"),
2147 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
2148 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
2151 add_option (_("General"),
2153 "only-copy-imported-files",
2154 _("Always copy imported files"),
2155 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
2156 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
2159 add_option (_("General"), new DirectoryOption (
2160 X_("default-session-parent-dir"),
2161 _("Default folder for new sessions:"),
2162 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
2163 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
2166 add_option (_("General"),
2167 new SpinOption<uint32_t> (
2168 "max-recent-sessions",
2169 _("Maximum number of recent sessions"),
2170 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
2171 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
2175 add_option (_("General"), new OptionEditorHeading (_("Automation")));
2177 add_option (_("General"),
2178 new SpinOption<double> (
2179 "automation-thinning-factor",
2180 _("Thinning factor (larger value => less data)"),
2181 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
2182 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
2186 add_option (_("General"),
2187 new SpinOption<double> (
2188 "automation-interval-msecs",
2189 _("Automation sampling interval (milliseconds)"),
2190 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
2191 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
2195 add_option (_("General"), new OptionEditorHeading (_("Tempo")));
2199 tsf = new BoolOption (
2200 "allow-non-quarter-pulse",
2201 _("Allow non quarter-note pulse"),
2202 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_allow_non_quarter_pulse),
2203 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_allow_non_quarter_pulse)
2205 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2206 string_compose (_("<b>When enabled</b> %1 will allow tempo to be expressed in divisions per minute\n"
2207 "<b>When disabled</b> %1 will only allow tempo to be expressed in quarter notes per minute"),
2209 add_option (_("General"), tsf);
2213 add_option (_("General/Translation"), new OptionEditorHeading (_("Internationalization")));
2215 bo = new BoolOption (
2216 "enable-translation",
2217 _("Use translations"),
2218 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2219 sigc::ptr_fun (ARDOUR::set_translations_enabled)
2222 bo->set_note (string_compose (_("These settings will only take effect after %1 is restarted (if available for your language preferences)."), PROGRAM_NAME));
2224 add_option (_("General/Translation"), bo);
2226 _l10n = new ComboOption<ARDOUR::LocaleMode> (
2229 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_locale_mode),
2230 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_locale_mode)
2233 _l10n->add (ARDOUR::SET_LC_ALL, _("Set complete locale"));
2234 _l10n->add (ARDOUR::SET_LC_MESSAGES, _("Enable only message translation"));
2235 _l10n->add (ARDOUR::SET_LC_MESSAGES_AND_LC_NUMERIC, _("Translate messages and format numeric format"));
2236 _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."));
2238 add_option (_("General/Translation"), _l10n);
2239 parameter_changed ("enable-translation");
2240 #endif // ENABLE_NLS
2245 add_option (_("Editor"), new OptionEditorHeading (_("General")));
2247 add_option (_("Editor"),
2249 "rubberbanding-snaps-to-grid",
2250 _("Snap rubberband to grid"),
2251 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2252 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2255 bo = new BoolOption (
2257 _("Prompt for a new marker name"),
2258 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2259 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2261 add_option (_("Editor"), bo);
2262 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."
2263 "\n\nYou can always rename markers by right-clicking on them"));
2265 add_option (_("Editor"),
2267 "draggable-playhead",
2268 _("Allow dragging of playhead"),
2269 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2270 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2273 if (!Profile->get_mixbus()) {
2275 add_option (_("Editor"),
2277 "use-mouse-position-as-zoom-focus-on-scroll",
2278 _("Zoom to mouse position when zooming with scroll wheel"),
2279 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2280 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2284 add_option (_("Editor"),
2286 "use-time-rulers-to-zoom-with-vertical-drag",
2287 _("Zoom with vertical drag in rulers"),
2288 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag),
2289 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag)
2292 add_option (_("Editor"),
2294 "use-double-click-to-zoom-to-selection",
2295 _("Double click zooms to selection"),
2296 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection),
2297 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection)
2300 add_option (_("Editor"),
2302 "update-editor-during-summary-drag",
2303 _("Update editor window during drags of the summary"),
2304 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2305 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2308 add_option (_("Editor"),
2310 "autoscroll-editor",
2311 _("Auto-scroll editor window when dragging near its edges"),
2312 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2313 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2316 add_option (_("Editor"),
2317 new BoolComboOption (
2318 "show-region-gain-envelopes",
2319 _("Show gain envelopes in audio regions"),
2321 _("only in Draw and Internal Edit modes"),
2322 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2323 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2326 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2328 add_option (_("Editor"),
2330 "automation-follows-regions",
2331 _("Move relevant automation when audio regions are moved"),
2332 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2333 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2336 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2337 "default-fade-shape",
2338 _("Default fade shape"),
2339 sigc::mem_fun (*_rc_config,
2340 &RCConfiguration::get_default_fade_shape),
2341 sigc::mem_fun (*_rc_config,
2342 &RCConfiguration::set_default_fade_shape)
2345 fadeshape->add (FadeLinear,
2346 _("Linear (for highly correlated material)"));
2347 fadeshape->add (FadeConstantPower, _("Constant power"));
2348 fadeshape->add (FadeSymmetric, _("Symmetric"));
2349 fadeshape->add (FadeSlow, _("Slow"));
2350 fadeshape->add (FadeFast, _("Fast"));
2352 add_option (_("Editor"), fadeshape);
2354 bco = new BoolComboOption (
2355 "use-overlap-equivalency",
2356 _("Regions in edit groups are edited together"),
2357 _("whenever they overlap in time"),
2358 _("only if they have identical length and position"),
2359 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2360 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2363 add_option (_("Editor"), bco);
2365 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2367 _("Layering model"),
2368 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2369 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2372 lm->add (LaterHigher, _("later is higher"));
2373 lm->add (Manual, _("manual layering"));
2374 add_option (_("Editor"), lm);
2376 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2377 "region-selection-after-split",
2378 _("After splitting selected regions, select"),
2379 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2380 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2382 // TODO: decide which of these modes are really useful
2383 rsas->add(None, _("no regions"));
2384 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2385 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2386 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2387 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2388 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2389 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2390 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2392 add_option (_("Editor"), rsas);
2394 add_option (_("Editor/Modifiers"), new OptionEditorHeading (_("Keyboard Modifiers")));
2395 add_option (_("Editor/Modifiers"), new KeyboardOptions);
2396 add_option (_("Editor/Modifiers"), new OptionEditorBlank ());
2398 /* MIXER -- SOLO AND MUTE */
2400 add_option (_("Mixer"), new OptionEditorHeading (_("Solo")));
2402 _solo_control_is_listen_control = new BoolOption (
2403 "solo-control-is-listen-control",
2404 _("Solo controls are Listen controls"),
2405 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2406 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2409 add_option (_("Mixer"), _solo_control_is_listen_control);
2411 add_option (_("Mixer"),
2414 _("Exclusive solo"),
2415 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2416 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2419 add_option (_("Mixer"),
2422 _("Show solo muting"),
2423 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2424 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2427 add_option (_("Mixer"),
2429 "solo-mute-override",
2430 _("Soloing overrides muting"),
2431 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2432 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2435 add_option (_("Mixer"),
2438 _("Solo-in-place mute cut (dB)"),
2439 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2440 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2443 _listen_position = new ComboOption<ListenPosition> (
2445 _("Listen Position"),
2446 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2447 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2450 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2451 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2453 add_option (_("Mixer"), _listen_position);
2455 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2457 _("PFL signals come from"),
2458 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2459 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2462 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2463 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2465 add_option (_("Mixer"), pp);
2467 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2469 _("AFL signals come from"),
2470 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2471 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2474 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2475 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2477 add_option (_("Mixer"), pa);
2479 add_option (_("Mixer"), new OptionEditorHeading (_("Default track / bus muting options")));
2481 add_option (_("Mixer"),
2483 "mute-affects-pre-fader",
2484 _("Mute affects pre-fader sends"),
2485 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2486 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2489 add_option (_("Mixer"),
2491 "mute-affects-post-fader",
2492 _("Mute affects post-fader sends"),
2493 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2494 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2497 add_option (_("Mixer"),
2499 "mute-affects-control-outs",
2500 _("Mute affects control outputs"),
2501 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2502 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2505 add_option (_("Mixer"),
2507 "mute-affects-main-outs",
2508 _("Mute affects main outputs"),
2509 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2510 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2514 if (!ARDOUR::Profile->get_mixbus()) {
2515 add_option (_("Mixer"), new OptionEditorHeading (_("Send Routing")));
2516 add_option (_("Mixer"),
2518 "link-send-and-route-panner",
2519 _("Link panners of Aux and External Sends with main panner by default"),
2520 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2521 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2528 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2530 add_option (_("Audio"), new BufferingOptions (_rc_config));
2532 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2534 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2536 _("Record monitoring handled by"),
2537 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2538 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2541 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2542 mm->add (HardwareMonitoring, _("via Audio Driver"));
2545 string prog (PROGRAM_NAME);
2546 boost::algorithm::to_lower (prog);
2547 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2548 mm->add (ExternalMonitoring, _("audio hardware"));
2550 add_option (_("Audio"), mm);
2552 add_option (_("Audio"),
2554 "tape-machine-mode",
2555 _("Tape machine mode"),
2556 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2557 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2560 add_option (_("Audio"), new OptionEditorHeading (_("Track and Bus Connections")));
2561 if (!Profile->get_mixbus()) {
2563 add_option (_("Audio"),
2565 "auto-connect-standard-busses",
2566 _("Auto-connect master/monitor busses"),
2567 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2568 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2571 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2572 "input-auto-connect",
2573 _("Connect track inputs"),
2574 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2575 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2578 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2579 iac->add (ManualConnect, _("manually"));
2581 add_option (_("Audio"), iac);
2583 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2584 "output-auto-connect",
2585 _("Connect track and bus outputs"),
2586 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2587 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2590 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2591 oac->add (AutoConnectMaster, _("automatically to master bus"));
2592 oac->add (ManualConnect, _("manually"));
2594 add_option (_("Audio"), oac);
2596 bo = new BoolOption (
2598 _("Use 'Strict-I/O' for new tracks or Busses"),
2599 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2600 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2603 add_option (_("Audio"), bo);
2604 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2605 _("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."));
2609 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2611 add_option (_("Audio"),
2613 "denormal-protection",
2614 _("Use DC bias to protect against denormals"),
2615 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2616 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2619 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2621 _("Processor handling"),
2622 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2623 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2627 dm->add (DenormalNone, _("no processor handling"));
2629 FPU* fpu = FPU::instance();
2631 if (fpu->has_flush_to_zero()) {
2633 dm->add (DenormalFTZ, _("use FlushToZero"));
2634 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2635 _rc_config->set_denormal_model(DenormalNone);
2638 if (fpu->has_denormals_are_zero()) {
2640 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2641 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2642 _rc_config->set_denormal_model(DenormalNone);
2645 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2647 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2648 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2649 _rc_config->set_denormal_model(DenormalNone);
2653 dm->set_sensitive(false);
2656 add_option (_("Audio"), dm);
2658 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2660 add_option (_("Audio"),
2662 "auto-analyse-audio",
2663 _("Enable automatic analysis of audio"),
2664 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2665 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2668 add_option (_("Audio"),
2670 "replicate-missing-region-channels",
2671 _("Replicate missing region channels"),
2672 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2673 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2678 add_option (_("MIDI"), new OptionEditorHeading (_("Buffering")));
2680 add_option (_("MIDI"),
2681 new SpinOption<float> (
2683 _("MIDI read-ahead time (seconds)"),
2684 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2685 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2690 add_option (_("MIDI"), new OptionEditorHeading (_("Session")));
2692 add_option (_("MIDI"),
2693 new SpinOption<int32_t> (
2694 "initial-program-change",
2695 _("Initial program change"),
2696 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2697 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2701 add_option (_("MIDI"), new OptionEditorHeading (_("Display")));
2703 add_option (_("MIDI"),
2705 "display-first-midi-bank-as-zero",
2706 _("Display first MIDI bank/program as 0"),
2707 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2708 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2711 add_option (_("MIDI"),
2713 "never-display-periodic-midi",
2714 _("Don't display periodic (MTC, MMC) SysEx messages in MIDI Regions"),
2715 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
2716 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
2720 add_option (_("MIDI"),
2723 _("Send MIDI control feedback"),
2724 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2725 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2729 add_option (_("MIDI"), new OptionEditorHeading (_("Audition")));
2731 add_option (_("MIDI"),
2734 _("Sound MIDI notes as they are selected in the editor"),
2735 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2736 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2739 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2740 "midi-audition-synth-uri",
2741 _("MIDI Audition Synth (LV2)"),
2742 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2743 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2746 audition_synth->add(X_(""), _("None"));
2747 PluginInfoList all_plugs;
2748 PluginManager& manager (PluginManager::instance());
2750 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2752 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2753 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2754 if (!(*i)->is_instrument()) continue;
2755 if ((*i)->type != ARDOUR::LV2) continue;
2756 if ((*i)->name.length() > 46) {
2757 audition_synth->add((*i)->unique_id, (*i)->name.substr (0, 44) + "...");
2759 audition_synth->add((*i)->unique_id, (*i)->name);
2764 add_option (_("MIDI"), audition_synth);
2768 add_option (_("Metronome"), new OptionEditorHeading (_("Metronome")));
2769 add_option (_("Metronome"), new ClickOptions (_rc_config));
2773 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2775 ComboOption<float>* mht = new ComboOption<float> (
2777 _("Peak hold time"),
2778 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
2779 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
2782 mht->add (MeterHoldOff, _("off"));
2783 mht->add (MeterHoldShort, _("short"));
2784 mht->add (MeterHoldMedium, _("medium"));
2785 mht->add (MeterHoldLong, _("long"));
2787 add_option (S_("Preferences|Metering"), mht);
2789 ComboOption<float>* mfo = new ComboOption<float> (
2792 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2793 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2796 mfo->add (METER_FALLOFF_OFF, _("off"));
2797 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2798 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2799 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2800 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2801 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2802 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
2804 add_option (S_("Preferences|Metering"), mfo);
2806 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2807 "meter-line-up-level",
2808 _("Meter line-up level; 0dBu"),
2809 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
2810 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
2813 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2814 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2815 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2816 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2818 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."));
2820 add_option (S_("Preferences|Metering"), mlu);
2822 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2823 "meter-line-up-din",
2824 _("IEC1/DIN Meter line-up level; 0dBu"),
2825 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
2826 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
2829 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2830 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2831 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2832 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2834 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2836 add_option (S_("Preferences|Metering"), mld);
2838 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2839 "meter-vu-standard",
2840 _("VU Meter standard"),
2841 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
2842 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
2845 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2846 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2847 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2848 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2850 add_option (S_("Preferences|Metering"), mvu);
2852 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
2853 "meter-type-master",
2854 _("Default Meter Type for Master Bus"),
2855 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
2856 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
2858 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2859 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2860 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2861 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2862 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2863 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2864 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2865 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
2867 add_option (S_("Preferences|Metering"), mtm);
2870 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
2872 _("Default Meter Type for Busses"),
2873 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
2874 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
2876 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2877 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2878 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2879 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2880 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2881 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2882 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2883 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
2885 add_option (S_("Preferences|Metering"), mtb);
2887 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
2889 _("Default Meter Type for Tracks"),
2890 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
2891 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
2893 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2894 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
2896 add_option (S_("Preferences|Metering"), mtt);
2898 HSliderOption *mpks = new HSliderOption("meter-peak",
2899 _("Peak threshold [dBFS]"),
2900 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
2901 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak),
2905 Gtkmm2ext::UI::instance()->set_tip (
2907 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
2909 add_option (S_("Preferences|Metering"), mpks);
2911 add_option (S_("Preferences|Metering"),
2914 _("LED meter style"),
2915 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
2916 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
2919 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
2921 add_option (S_("Preferences|Metering"),
2923 "save-export-analysis-image",
2924 _("Save loudness analysis as image file"),
2925 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
2926 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
2929 /* TRANSPORT & Sync */
2931 add_option (_("Transport"), new OptionEditorHeading (_("General")));
2933 tsf = new BoolOption (
2934 "stop-at-session-end",
2935 _("Stop at the end of the session"),
2936 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
2937 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
2939 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2940 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
2941 "when it reaches the current session end marker\n\n"
2942 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
2944 add_option (_("Transport"), tsf);
2946 tsf = new BoolOption (
2947 "latched-record-enable",
2948 _("Keep record-enable engaged on stop"),
2949 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
2950 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
2952 add_option (_("Transport"), tsf);
2954 tsf = new BoolOption (
2955 "disable-disarm-during-roll",
2956 _("Disable per-track record disarm while rolling"),
2957 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
2958 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
2960 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"));
2961 add_option (_("Transport"), tsf);
2963 tsf = new BoolOption (
2965 _("12dB gain reduction during fast-forward and fast-rewind"),
2966 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
2967 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2969 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
2970 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2971 add_option (_("Transport"), tsf);
2973 ComboOption<float>* psc = new ComboOption<float> (
2976 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
2977 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
2979 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
2980 (_("The amount of preroll (in seconds) to apply when <b>Play with Preroll</b> is initiated.\n\n"
2981 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
2982 psc->add (0.0, _("0 (no pre-roll)"));
2983 psc->add (0.1, _("0.1 second"));
2984 psc->add (0.25, _("0.25 second"));
2985 psc->add (0.5, _("0.5 second"));
2986 psc->add (1.0, _("1.0 second"));
2987 psc->add (2.0, _("2.0 seconds"));
2988 add_option (_("Transport"), psc);
2991 add_option (_("Transport"), new OptionEditorHeading (_("Looping")));
2993 tsf = new BoolOption (
2995 _("Play loop is a transport mode"),
2996 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
2997 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
2999 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
3000 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
3001 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
3002 add_option (_("Transport"), tsf);
3004 tsf = new BoolOption (
3006 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
3007 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
3008 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
3010 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
3011 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
3012 "preventing any need to do a transport locate at the end of the loop\n\n"
3013 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
3014 "which will often cause a small click or delay"), PROGRAM_NAME));
3015 add_option (_("Transport"), tsf);
3017 add_option (_("Transport"), new OptionEditorHeading (_("Dropout (xrun) handling")));
3018 tsf = new BoolOption (
3019 "stop-recording-on-xrun",
3020 _("Stop recording when an xrun occurs"),
3021 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
3022 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
3024 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
3025 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
3027 add_option (_("Transport"), tsf);
3029 tsf = new BoolOption (
3030 "create-xrun-marker",
3031 _("Create markers where xruns occur"),
3032 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
3033 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
3035 add_option (_("Transport"), tsf);
3040 add_option (_("Sync"), new OptionEditorHeading (_("External Syncronization")));
3042 _sync_source = new ComboOption<SyncSource> (
3044 _("External timecode source"),
3045 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
3046 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
3049 add_option (_("Sync"), _sync_source);
3051 _sync_framerate = new BoolOption (
3052 "timecode-sync-frame-rate",
3053 _("Match session video frame rate to external timecode"),
3054 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
3055 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
3057 Gtkmm2ext::UI::instance()->set_tip
3058 (_sync_framerate->tip_widget(),
3059 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
3060 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
3061 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
3062 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
3063 "timecode standard and the session standard."), PROGRAM_NAME));
3065 add_option (_("Sync"), _sync_framerate);
3067 _sync_genlock = new BoolOption (
3068 "timecode-source-is-synced",
3069 _("Sync-lock timecode to clock (disable drift compensation)"),
3070 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
3071 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
3073 Gtkmm2ext::UI::instance()->set_tip
3074 (_sync_genlock->tip_widget(),
3075 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
3076 "Sync Lock indicates that the selected external timecode source shares clock-sync "
3077 "(Black & Burst, Wordclock, etc) with the audio interface. "
3078 "This option disables drift compensation. The transport speed is fixed at 1.0. "
3079 "Vari-speed LTC will be ignored and cause drift."
3081 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
3082 "timecode sources shares clock sync."
3086 add_option (_("Sync"), _sync_genlock);
3088 _sync_source_2997 = new BoolOption (
3089 "timecode-source-2997",
3090 _("Lock to 29.9700 fps instead of 30000/1001"),
3091 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
3092 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
3094 Gtkmm2ext::UI::instance()->set_tip
3095 (_sync_source_2997->tip_widget(),
3096 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
3097 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
3098 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
3099 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
3100 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
3101 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
3104 add_option (_("Sync"), _sync_source_2997);
3106 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Reader")));
3108 _ltc_port = new ComboStringOption (
3110 _("LTC incoming port"),
3111 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
3112 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
3115 vector<string> physical_inputs;
3116 physical_inputs.push_back (_("None"));
3117 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
3118 _ltc_port->set_popdown_strings (physical_inputs);
3120 populate_sync_options ();
3121 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
3123 add_option (_("Sync/LTC"), _ltc_port);
3125 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Generator")));
3127 add_option (_("Sync/LTC"),
3130 _("Enable LTC generator"),
3131 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
3132 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
3135 _ltc_send_continuously = new BoolOption (
3136 "ltc-send-continuously",
3137 _("Send LTC while stopped"),
3138 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
3139 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
3141 Gtkmm2ext::UI::instance()->set_tip
3142 (_ltc_send_continuously->tip_widget(),
3143 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
3144 add_option (_("Sync/LTC"), _ltc_send_continuously);
3146 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"),
3147 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_output_volume),
3148 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_output_volume),
3152 Gtkmm2ext::UI::instance()->set_tip
3153 (_ltc_volume_slider->tip_widget(),
3154 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
3156 add_option (_("Sync/LTC"), _ltc_volume_slider);
3159 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Beat Clock (Mclk) Generator")));
3161 add_option (_("Sync/MIDI"),
3164 _("Enable Mclk generator"),
3165 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
3166 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
3169 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC) Generator")));
3171 add_option (_("Sync/MIDI"),
3174 _("Enable MTC Generator"),
3175 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
3176 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
3179 add_option (_("Sync/MIDI"),
3180 new SpinOption<int> (
3181 "mtc-qf-speed-tolerance",
3182 _("Percentage either side of normal transport speed to transmit MTC"),
3183 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
3184 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
3188 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Machine Control (MMC)")));
3190 add_option (_("Sync/MIDI"),
3193 _("Respond to MMC commands"),
3194 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
3195 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
3198 add_option (_("Sync/MIDI"),
3201 _("Send MMC commands"),
3202 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
3203 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
3206 add_option (_("Sync/MIDI"),
3207 new SpinOption<uint8_t> (
3208 "mmc-receive-device-id",
3209 _("Inbound MMC device ID"),
3210 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
3211 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
3215 add_option (_("Sync/MIDI"),
3216 new SpinOption<uint8_t> (
3217 "mmc-send-device-id",
3218 _("Outbound MMC device ID"),
3219 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
3220 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
3225 /* Control Surfaces */
3227 add_option (_("Control Surfaces"), new OptionEditorHeading (_("Control Surfaces")));
3228 add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
3231 add_option (_("MIDI Ports"), new OptionEditorHeading (_("MIDI Port Options")));
3233 add_option (_("MIDI Ports"),
3235 "get-midi-input-follows-selection",
3236 _("MIDI input follows MIDI track selection"),
3237 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
3238 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
3241 add_option (_("MIDI Ports"), new MidiPortOptions ());
3242 add_option (_("MIDI Ports"), new OptionEditorBlank ());
3246 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3247 add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
3248 add_option (_("Plugins"),
3249 new RcActionButton (_("Scan for Plugins"),
3250 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3254 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
3256 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3257 bo = new BoolOption (
3258 "show-plugin-scan-window",
3259 _("Always Display Plugin Scan Progress"),
3260 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
3261 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
3263 add_option (_("Plugins"), bo);
3264 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3265 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
3268 bo = new BoolOption (
3269 "plugins-stop-with-transport",
3270 _("Silence plugins when the transport is stopped"),
3271 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
3272 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
3274 add_option (_("Plugins"), bo);
3275 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3276 _("<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."));
3278 bo = new BoolOption (
3279 "new-plugins-active",
3280 _("Make new plugins active"),
3281 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
3282 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
3284 add_option (_("Plugins"), bo);
3285 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3286 _("<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"));
3288 #if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
3289 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
3291 add_option (_("Plugins/VST"),
3292 new RcActionButton (_("Scan for Plugins"),
3293 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3296 #if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
3297 bo = new BoolOption (
3299 _("Enable Mac VST support (requires restart or re-scan)"),
3300 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
3301 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
3303 add_option (_("Plugins/VST"), bo);
3306 bo = new BoolOption (
3307 "discover-vst-on-start",
3308 _("Scan for [new] VST Plugins on Application Start"),
3309 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
3310 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
3312 add_option (_("Plugins/VST"), bo);
3313 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3314 _("<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"));
3316 #ifdef WINDOWS_VST_SUPPORT
3317 // currently verbose logging is only implemented for Windows VST.
3318 bo = new BoolOption (
3319 "verbose-plugin-scan",
3320 _("Verbose Plugin Scan"),
3321 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
3322 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
3324 add_option (_("Plugins/VST"), bo);
3325 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3326 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
3329 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
3331 add_option (_("Plugins/VST"),
3332 new RcActionButton (_("Clear"),
3333 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
3336 add_option (_("Plugins/VST"),
3337 new RcActionButton (_("Clear"),
3338 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
3339 _("VST Blacklist:")));
3342 #ifdef LXVST_SUPPORT
3343 add_option (_("Plugins/VST"),
3344 new RcActionButton (_("Edit"),
3345 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
3346 _("Linux VST Path:")));
3348 add_option (_("Plugins/VST"),
3349 new RcConfigDisplay (
3350 "plugin-path-lxvst",
3352 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
3356 #ifdef WINDOWS_VST_SUPPORT
3357 add_option (_("Plugins/VST"),
3358 new RcActionButton (_("Edit"),
3359 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
3360 _("Windows VST Path:")));
3361 add_option (_("Plugins/VST"),
3362 new RcConfigDisplay (
3365 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
3369 #ifdef AUDIOUNIT_SUPPORT
3371 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
3373 add_option (_("Plugins/Audio Unit"),
3374 new RcActionButton (_("Scan for Plugins"),
3375 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3378 bo = new BoolOption (
3379 "discover-audio-units",
3380 _("Scan for [new] AudioUnit Plugins on Application Start"),
3381 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
3382 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
3384 add_option (_("Plugins/Audio Unit"), bo);
3385 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3386 _("<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."));
3388 add_option (_("Plugins/Audio Unit"),
3389 new RcActionButton (_("Clear"),
3390 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
3393 add_option (_("Plugins/Audio Unit"),
3394 new RcActionButton (_("Clear"),
3395 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
3396 _("AU Blacklist:")));
3399 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
3400 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
3401 add_option (_("Plugins"),
3403 "open-gui-after-adding-plugin",
3404 _("Automatically open the plugin GUI when adding a new plugin"),
3405 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
3406 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3409 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3410 add_option (_("Plugins"),
3412 "show-inline-display-by-default",
3413 _("Show Plugin Inline Display on Mixerstrip by default"),
3414 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3415 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3418 _plugin_prefer_inline = new BoolOption (
3419 "prefer-inline-over-gui",
3420 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3421 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3422 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3424 add_option (_("Plugins"), _plugin_prefer_inline);
3427 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3429 bo = new BoolOption (
3430 "ask-replace-instrument",
3431 _("Ask to replace existing instrument plugin"),
3432 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3433 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3435 add_option (_("Plugins"), bo);
3437 bo = new BoolOption (
3438 "ask-setup_instrument",
3439 _("Interactively configure instrument plugins on insert"),
3440 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3441 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3443 add_option (_("Plugins"), bo);
3444 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3445 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3448 add_option (_("Plugins"), new OptionEditorBlank ());
3451 #if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
3452 add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Graphics Acceleration")));
3455 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3456 BoolOption* bgc = new BoolOption (
3457 "cairo-image-surface",
3458 _("Disable Graphics Hardware Acceleration (requires restart)"),
3459 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3460 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3463 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3464 _("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));
3465 add_option (S_("Preferences|GUI"), bgc);
3468 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3469 BoolOption* bgo = new BoolOption (
3471 _("Possibly improve slow graphical performance (requires restart)"),
3472 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3473 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3476 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));
3477 add_option (S_("Preferences|GUI"), bgo);
3479 add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Graphical User Interface")));
3481 add_option (S_("Preferences|GUI"),
3484 _("Highlight widgets on mouseover"),
3485 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3486 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3489 add_option (S_("Preferences|GUI"),
3492 _("Show tooltips if mouse hovers over a control"),
3493 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3494 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3497 bo = new BoolOption (
3498 "super-rapid-clock-update",
3499 _("Update clocks at TC Frame rate"),
3500 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3501 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3503 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3504 _("<b>When enabled</b> clock displays are updated every Timecode Frame (fps).\n\n"
3505 "<b>When disabled</b> clock displays are updated only every 100ms."
3507 add_option (S_("Preferences|GUI"), bo);
3509 add_option (S_("Preferences|GUI"),
3512 _("Blink Rec-Arm buttons"),
3513 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_rec_arm),
3514 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_rec_arm)
3519 /* font scaling does nothing with GDK/Quartz */
3520 add_option (S_("Preferences|GUI"), new FontScalingOptions ());
3523 /* Image cache size */
3525 HSliderOption *sics = new HSliderOption ("waveform-cache-size",
3526 _("Waveform image cache size (megabytes)"),
3527 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
3528 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size),
3529 1, 1024, 10 /* 1 MB to 1GB in steps of 10MB */
3531 sics->scale().set_digits (0);
3532 Gtkmm2ext::UI::instance()->set_tip (
3534 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
3535 add_option (S_("Preferences|GUI"), sics);
3537 if (!ARDOUR::Profile->get_mixbus()) {
3538 /* Lock GUI timeout */
3540 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
3541 _("Lock timeout (seconds)"),
3542 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
3543 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds),
3546 slts->scale().set_digits (0);
3547 Gtkmm2ext::UI::instance()->set_tip (
3549 _("Lock GUI after this many idle seconds (zero to never lock)"));
3550 add_option (S_("Preferences|GUI"), slts);
3553 add_option (_("GUI/Editor"), new OptionEditorHeading (_("General")));
3554 add_option (_("GUI/Editor"),
3556 "show-name-highlight",
3557 _("Use name highlight bars in region displays (requires a restart)"),
3558 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3559 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3562 add_option (_("GUI/Editor"),
3564 "color-regions-using-track-color",
3565 _("Region color follows track color"),
3566 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_color_regions_using_track_color),
3567 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_color_regions_using_track_color)
3570 add_option (_("GUI/Editor"), new OptionEditorHeading (_("Waveforms")));
3572 if (!Profile->get_mixbus()) {
3573 add_option (_("GUI/Editor"),
3576 _("Show waveforms in regions"),
3577 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
3578 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
3582 add_option (_("GUI/Editor"),
3584 "show-waveforms-while-recording",
3585 _("Show waveforms while recording"),
3586 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
3587 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
3590 add_option (_("GUI/Editor"),
3592 "show-waveform-clipping",
3593 _("Show waveform clipping"),
3594 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveform_clipping),
3595 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveform_clipping)
3598 add_option (_("GUI/Editor"), new ClipLevelOptions ());
3600 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
3602 _("Waveform scale"),
3603 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
3604 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
3607 wfs->add (Linear, _("linear"));
3608 wfs->add (Logarithmic, _("logarithmic"));
3610 add_option (_("GUI/Editor"), wfs);
3612 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
3614 _("Waveform shape"),
3615 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
3616 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
3619 wfsh->add (Traditional, _("traditional"));
3620 wfsh->add (Rectified, _("rectified"));
3622 add_option (_("GUI/Editor"), wfsh);
3624 add_option (_("GUI/Editor"), new OptionEditorHeading (_("Editor Meters")));
3626 add_option (_("GUI/Editor"),
3628 "show-track-meters",
3629 _("Show meters in track headers"),
3630 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3631 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3634 add_option (_("GUI/Editor"),
3636 "editor-stereo-only-meters",
3637 _("Limit track header meters to stereo"),
3638 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3639 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3642 add_option (_("GUI/Editor"), new OptionEditorBlank ());
3644 /* The names of these controls must be the same as those given in MixerStrip
3645 for the actual widgets being controlled.
3647 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3648 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3649 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3650 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3651 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3652 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3653 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3655 add_option (_("GUI/Mixer"),
3656 new VisibilityOption (
3658 &_mixer_strip_visibility,
3659 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3660 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3664 add_option (_("GUI/Mixer"),
3666 "default-narrow_ms",
3667 _("Use narrow strips in the mixer by default"),
3668 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3669 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3672 add_option (_("GUI/Mixer"), new OptionEditorBlank ());
3674 add_option (_("GUI/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items")));
3676 add_option (_("GUI/Toolbar"),
3678 "show-toolbar-selclock",
3679 _("Display Selection Clock"),
3680 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
3681 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
3684 if (!ARDOUR::Profile->get_small_screen()) {
3685 add_option (_("GUI/Toolbar"),
3687 "show-secondary-clock",
3688 _("Display Secondary Clock"),
3689 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
3690 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
3694 add_option (_("GUI/Toolbar"),
3696 "show-mini-timeline",
3697 _("Display Navigation Timeline"),
3698 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
3699 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
3702 add_option (_("GUI/Toolbar"),
3704 "show-editor-meter",
3705 _("Display Master Level Meter"),
3706 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
3707 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
3710 add_option (_("GUI/Toolbar"),
3711 new ColumVisibilityOption (
3712 "action-table-columns", _("Lua Action Script Button Visibility"), 4,
3713 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3714 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3717 add_option (_("GUI/Toolbar"), new OptionEditorBlank ());
3720 OptionEditorHeading* quirks_head = new OptionEditorHeading (_("Various Workarounds for Windowing Systems"));
3722 quirks_head->set_note (string_compose (_("These settings will only take effect after %1 is restarted."), PROGRAM_NAME));
3724 /* and now the theme manager */
3726 add_option (_("GUI/Theme"), new OptionEditorHeading (_("Theme")));
3728 add_option (_("GUI/Theme"), new BoolOption (
3730 _("Draw \"flat\" buttons"),
3731 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_flat_buttons),
3732 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_flat_buttons)
3735 add_option (_("GUI/Theme"), new BoolOption (
3737 _("LED meter style"),
3738 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3739 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3743 HSliderOption *gui_hs = new HSliderOption(
3744 "timeline-item-gradient-depth",
3745 _("Waveforms color gradient depth"),
3746 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_gradient_depth),
3747 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_gradient_depth),
3750 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3751 add_option (_("GUI/Theme"), gui_hs);
3753 gui_hs = new HSliderOption(
3754 "timeline-item-gradient-depth",
3755 _("Timeline item gradient depth"),
3756 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_timeline_item_gradient_depth),
3757 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_timeline_item_gradient_depth),
3760 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3761 add_option (_("GUI/Theme"), gui_hs);
3763 vector<string> icon_sets = ::get_icon_sets ();
3764 if (icon_sets.size() > 1) {
3765 ComboOption<std::string>* io = new ComboOption<std::string> (
3766 "icon-set", _("Icon Set"),
3767 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_icon_set),
3768 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_icon_set)
3770 for (vector<string>::const_iterator i = icon_sets.begin (); i != icon_sets.end (); ++i) {
3773 add_option (_("GUI/Theme"), io);
3776 add_option (_("GUI/Colors"), new OptionEditorHeading (_("Colors")));
3777 add_option (_("GUI/Colors"), new ColorThemeManager);
3778 add_option (_("GUI/Colors"), new OptionEditorBlank ());
3782 add_option (_("GUI/Quirks"), quirks_head);
3784 add_option (_("GUI/Quirks"),
3786 "use-wm-visibility",
3787 _("Use Window Manager/Desktop visibility information"),
3788 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3789 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3793 bo = new BoolOption (
3794 "all-floating-windows-are-dialogs",
3795 _("All floating windows are dialogs"),
3796 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_all_floating_windows_are_dialogs),
3797 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_all_floating_windows_are_dialogs)
3799 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (), string_compose (
3800 _("Mark all floating windows to be type \"Dialog\" rather than using \"Utility\" for some.\n"
3801 "This may help with some window managers. This requires a restart of %1 to take effect"),
3803 add_option (_("GUI/Quirks"), bo);
3805 bo = new BoolOption (
3806 "transients-follow-front",
3807 _("Transient windows follow front window."),
3808 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_transients_follow_front),
3809 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_transients_follow_front)
3811 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (), string_compose (
3812 _("Make transient windows follow the front window when toggling between the editor and mixer.\n"
3813 "This requires a restart of %1 to take effect"), PROGRAM_NAME));
3814 add_option (_("GUI/Quirks"), bo);
3817 if (!Profile->get_mixbus()) {
3818 bo = new BoolOption (
3819 "floating-monitor-section",
3820 _("Float detached monitor-section window"),
3821 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_floating_monitor_section),
3822 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_floating_monitor_section)
3824 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (), string_compose (
3825 _("When detaching the monitoring section, mark it as \"Utility\" window to stay in front.\n"
3826 "This requires a restart of %1 to take effect"), PROGRAM_NAME));
3827 add_option (_("GUI/Quirks"), bo);
3830 add_option (_("GUI/Quirks"), new OptionEditorBlank ());
3832 /* VIDEO Timeline */
3833 add_option (_("Video"), new OptionEditorHeading (_("Video Server")));
3834 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
3836 Widget::show_all ();
3838 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3839 parameter_changed ("send-ltc");
3840 parameter_changed ("sync-source");
3841 parameter_changed ("use-monitor-bus");
3842 parameter_changed ("open-gui-after-adding-plugin");
3844 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
3846 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
3847 (Gtk::StateType) here !!!
3849 Tabbable::set_state (*node, Stateful::loading_state_version);
3852 set_current_page (_("General"));
3856 RCOptionEditor::parameter_changed (string const & p)
3858 OptionEditor::parameter_changed (p);
3860 if (p == "use-monitor-bus") {
3861 bool const s = Config->get_use_monitor_bus ();
3863 /* we can't use this if we don't have a monitor bus */
3864 Config->set_solo_control_is_listen_control (false);
3866 _solo_control_is_listen_control->set_sensitive (s);
3867 _listen_position->set_sensitive (s);
3868 } else if (p == "sync-source") {
3869 _sync_source->set_sensitive (true);
3871 _sync_source->set_sensitive (!_session->config.get_external_sync());
3873 switch(Config->get_sync_source()) {
3876 _sync_genlock->set_sensitive (true);
3877 _sync_framerate->set_sensitive (true);
3878 _sync_source_2997->set_sensitive (true);
3881 _sync_genlock->set_sensitive (false);
3882 _sync_framerate->set_sensitive (false);
3883 _sync_source_2997->set_sensitive (false);
3886 } else if (p == "send-ltc") {
3887 bool const s = Config->get_send_ltc ();
3888 _ltc_send_continuously->set_sensitive (s);
3889 _ltc_volume_slider->set_sensitive (s);
3890 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
3891 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3892 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
3895 } else if (p == "enable-translation") {
3896 _l10n->set_sensitive (ARDOUR::translations_are_enabled ());
3901 void RCOptionEditor::plugin_scan_refresh () {
3902 PluginManager::instance().refresh();
3905 void RCOptionEditor::clear_vst_cache () {
3906 PluginManager::instance().clear_vst_cache();
3909 void RCOptionEditor::clear_vst_blacklist () {
3910 PluginManager::instance().clear_vst_blacklist();
3913 void RCOptionEditor::clear_au_cache () {
3914 PluginManager::instance().clear_au_cache();
3917 void RCOptionEditor::clear_au_blacklist () {
3918 PluginManager::instance().clear_au_blacklist();
3921 void RCOptionEditor::edit_lxvst_path () {
3922 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
3923 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3924 *current_toplevel(), _("Set Linux VST Search Path"),
3925 _rc_config->get_plugin_path_lxvst(),
3926 PluginManager::instance().get_default_lxvst_path()
3928 ResponseType r = (ResponseType) pd->run ();
3930 if (r == RESPONSE_ACCEPT) {
3931 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
3936 void RCOptionEditor::edit_vst_path () {
3937 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3938 *current_toplevel(), _("Set Windows VST Search Path"),
3939 _rc_config->get_plugin_path_vst(),
3940 PluginManager::instance().get_default_windows_vst_path()
3942 ResponseType r = (ResponseType) pd->run ();
3944 if (r == RESPONSE_ACCEPT) {
3945 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
3952 RCOptionEditor::populate_sync_options ()
3954 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3956 _sync_source->clear ();
3958 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3959 _sync_source->add (*i, sync_source_to_string (*i));
3962 if (sync_opts.empty()) {
3963 _sync_source->set_sensitive(false);
3965 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3966 _rc_config->set_sync_source(sync_opts.front());
3970 parameter_changed ("sync-source");
3974 RCOptionEditor::use_own_window (bool and_fill_it)
3976 bool new_window = !own_window ();
3978 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
3980 if (win && new_window) {
3981 win->set_name ("PreferencesWindow");
3982 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
3989 RCOptionEditor::get_state ()
3991 XMLNode* node = new XMLNode (X_("Preferences"));
3992 node->add_child_nocopy (Tabbable::get_state());