2 Copyright (C) 2001-2011 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "gtk2ardour-config.h"
24 #if !defined USE_CAIRO_IMAGE_SURFACE && !defined NDEBUG
25 #define OPTIONAL_CAIRO_IMAGE_SURFACE
28 #include <cairo/cairo.h>
30 #include <boost/algorithm/string.hpp>
32 #include <gtkmm/liststore.h>
33 #include <gtkmm/stock.h>
34 #include <gtkmm/scale.h>
36 #include <gtkmm2ext/utils.h>
37 #include <gtkmm2ext/slider_controller.h>
38 #include <gtkmm2ext/gtk_ui.h>
39 #include <gtkmm2ext/paths_dialog.h>
40 #include <gtkmm2ext/window_title.h>
46 #include "ardour/audio_backend.h"
47 #include "ardour/audioengine.h"
48 #include "ardour/profile.h"
49 #include "ardour/dB.h"
50 #include "ardour/rc_configuration.h"
51 #include "ardour/control_protocol_manager.h"
52 #include "ardour/port_manager.h"
53 #include "ardour/plugin_manager.h"
54 #include "control_protocol/control_protocol.h"
56 #include "canvas/wave_view.h"
58 #include "ardour_dialog.h"
59 #include "ardour_ui.h"
60 #include "ardour_window.h"
61 #include "color_theme_manager.h"
62 #include "gui_thread.h"
64 #include "meter_patterns.h"
65 #include "midi_tracer.h"
66 #include "rc_option_editor.h"
68 #include "theme_manager.h"
70 #include "ui_config.h"
75 using namespace Gtkmm2ext;
77 using namespace ARDOUR;
78 using namespace ARDOUR_UI_UTILS;
80 class ClickOptions : public OptionEditorPageBox, public OptionEditorPage
83 ClickOptions (RCConfiguration* c)
85 , _click_browse_button (_("Browse..."))
86 , _click_emphasis_browse_button (_("Browse..."))
90 Label* l = manage (left_aligned_label (_("Emphasis on first beat:")));
91 _use_emphasis_on_click_check_button.add (*l);
92 t->attach (_use_emphasis_on_click_check_button, 1, 3, 0, 1, FILL);
93 _use_emphasis_on_click_check_button.signal_toggled().connect (
94 sigc::mem_fun (*this, &ClickOptions::use_emphasis_on_click_toggled));
96 l = manage (left_aligned_label (_("Use default Click:")));
97 _use_default_click_check_button.add (*l);
98 t->attach (_use_default_click_check_button, 1, 3, 1, 2, FILL);
99 _use_default_click_check_button.signal_toggled().connect (
100 sigc::mem_fun (*this, &ClickOptions::use_default_click_toggled));
102 l = manage (left_aligned_label (_("Click audio file:")));
103 t->attach (*l, 1, 2, 2, 3, FILL);
104 t->attach (_click_path_entry, 2, 3, 2, 3, FILL);
105 _click_browse_button.signal_clicked ().connect (
106 sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
107 t->attach (_click_browse_button, 3, 4, 2, 3, FILL);
109 l = manage (left_aligned_label (_("Click emphasis audio file:")));
110 t->attach (*l, 1, 2, 3, 4, FILL);
111 t->attach (_click_emphasis_path_entry, 2, 3, 3, 4, FILL);
112 _click_emphasis_browse_button.signal_clicked ().connect (
113 sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
114 t->attach (_click_emphasis_browse_button, 3, 4, 3, 4, FILL);
116 FaderOption* fo = new FaderOption (
118 _("Click gain level"),
119 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
120 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
123 fo->add_to_page (this);
124 fo->set_state_from_config ();
126 _box->pack_start (table, true, true);
128 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
129 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
131 if (_rc_config->get_click_sound ().empty() &&
132 _rc_config->get_click_emphasis_sound().empty()) {
133 _use_default_click_check_button.set_active (true);
134 _use_emphasis_on_click_check_button.set_active (true);
137 _use_default_click_check_button.set_active (false);
138 _use_emphasis_on_click_check_button.set_active (false);
142 void parameter_changed (string const & p)
144 if (p == "click-sound") {
145 _click_path_entry.set_text (_rc_config->get_click_sound());
146 } else if (p == "click-emphasis-sound") {
147 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
148 } else if (p == "use-click-emphasis") {
149 bool x = _rc_config->get_use_click_emphasis ();
150 _use_emphasis_on_click_check_button.set_active (x);
154 void set_state_from_config ()
156 parameter_changed ("click-sound");
157 parameter_changed ("click-emphasis-sound");
158 parameter_changed ("use-click-emphasis");
163 void click_browse_clicked ()
165 SoundFileChooser sfdb (_("Choose Click"));
170 if (sfdb.run () == RESPONSE_OK) {
171 click_chosen (sfdb.get_filename());
175 void click_chosen (string const & path)
177 _click_path_entry.set_text (path);
178 _rc_config->set_click_sound (path);
181 void click_changed ()
183 click_chosen (_click_path_entry.get_text ());
186 void click_emphasis_browse_clicked ()
188 SoundFileChooser sfdb (_("Choose Click Emphasis"));
193 if (sfdb.run () == RESPONSE_OK) {
194 click_emphasis_chosen (sfdb.get_filename());
198 void click_emphasis_chosen (string const & path)
200 _click_emphasis_path_entry.set_text (path);
201 _rc_config->set_click_emphasis_sound (path);
204 void click_emphasis_changed ()
206 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
209 void use_default_click_toggled ()
211 if (_use_default_click_check_button.get_active ()) {
212 _rc_config->set_click_sound ("");
213 _rc_config->set_click_emphasis_sound ("");
214 _click_path_entry.set_sensitive (false);
215 _click_emphasis_path_entry.set_sensitive (false);
216 _click_browse_button.set_sensitive (false);
217 _click_emphasis_browse_button.set_sensitive (false);
219 _click_path_entry.set_sensitive (true);
220 _click_emphasis_path_entry.set_sensitive (true);
221 _click_browse_button.set_sensitive (true);
222 _click_emphasis_browse_button.set_sensitive (true);
226 void use_emphasis_on_click_toggled ()
228 if (_use_emphasis_on_click_check_button.get_active ()) {
229 _rc_config->set_use_click_emphasis(true);
231 _rc_config->set_use_click_emphasis(false);
235 RCConfiguration* _rc_config;
236 CheckButton _use_default_click_check_button;
237 CheckButton _use_emphasis_on_click_check_button;
238 Entry _click_path_entry;
239 Entry _click_emphasis_path_entry;
240 Button _click_browse_button;
241 Button _click_emphasis_browse_button;
244 class UndoOptions : public OptionEditorBox
247 UndoOptions (RCConfiguration* c) :
249 _limit_undo_button (_("Limit undo history to")),
250 _save_undo_button (_("Save undo history of"))
252 Table* t = new Table (2, 3);
255 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
256 _limit_undo_spin.set_range (0, 512);
257 _limit_undo_spin.set_increments (1, 10);
258 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
259 Label* l = manage (left_aligned_label (_("commands")));
260 t->attach (*l, 2, 3, 0, 1);
262 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
263 _save_undo_spin.set_range (0, 512);
264 _save_undo_spin.set_increments (1, 10);
265 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
266 l = manage (left_aligned_label (_("commands")));
267 t->attach (*l, 2, 3, 1, 2);
269 _box->pack_start (*t);
271 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
272 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
273 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
274 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
277 void parameter_changed (string const & p)
279 if (p == "history-depth") {
280 int32_t const d = _rc_config->get_history_depth();
281 _limit_undo_button.set_active (d != 0);
282 _limit_undo_spin.set_sensitive (d != 0);
283 _limit_undo_spin.set_value (d);
284 } else if (p == "save-history") {
285 bool const x = _rc_config->get_save_history ();
286 _save_undo_button.set_active (x);
287 _save_undo_spin.set_sensitive (x);
288 } else if (p == "save-history-depth") {
289 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
293 void set_state_from_config ()
295 parameter_changed ("save-history");
296 parameter_changed ("history-depth");
297 parameter_changed ("save-history-depth");
300 void limit_undo_toggled ()
302 bool const x = _limit_undo_button.get_active ();
303 _limit_undo_spin.set_sensitive (x);
304 int32_t const n = x ? 16 : 0;
305 _limit_undo_spin.set_value (n);
306 _rc_config->set_history_depth (n);
309 void limit_undo_changed ()
311 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
314 void save_undo_toggled ()
316 bool const x = _save_undo_button.get_active ();
317 _rc_config->set_save_history (x);
320 void save_undo_changed ()
322 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
326 RCConfiguration* _rc_config;
327 CheckButton _limit_undo_button;
328 SpinButton _limit_undo_spin;
329 CheckButton _save_undo_button;
330 SpinButton _save_undo_spin;
335 static const struct {
347 { "Key|Shift", GDK_SHIFT_MASK },
348 { "Command", GDK_MOD2_MASK },
349 { "Control", GDK_CONTROL_MASK },
350 { "Option", GDK_MOD1_MASK },
351 { "Command-Shift", GDK_MOD2_MASK|GDK_SHIFT_MASK },
352 { "Command-Option", GDK_MOD2_MASK|GDK_MOD1_MASK },
353 { "Command-Control", GDK_MOD2_MASK|GDK_CONTROL_MASK },
354 { "Command-Option-Control", GDK_MOD2_MASK|GDK_MOD1_MASK|GDK_CONTROL_MASK },
355 { "Option-Control", GDK_MOD1_MASK|GDK_CONTROL_MASK },
356 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
357 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
358 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_MOD2_MASK },
361 { "Key|Shift", GDK_SHIFT_MASK },
362 { "Control", GDK_CONTROL_MASK },
363 { "Alt", GDK_MOD1_MASK },
364 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
365 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
366 { "Control-Windows", GDK_CONTROL_MASK|GDK_MOD4_MASK },
367 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
368 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
369 { "Alt-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
370 { "Alt-Shift-Windows", GDK_MOD1_MASK|GDK_SHIFT_MASK|GDK_MOD4_MASK },
371 { "Mod2", GDK_MOD2_MASK },
372 { "Mod3", GDK_MOD3_MASK },
373 { "Windows", GDK_MOD4_MASK },
374 { "Mod5", GDK_MOD5_MASK },
380 class KeyboardOptions : public OptionEditorBox
384 _delete_button_adjustment (3, 1, 12),
385 _delete_button_spin (_delete_button_adjustment),
386 _edit_button_adjustment (3, 1, 5),
387 _edit_button_spin (_edit_button_adjustment),
388 _insert_note_button_adjustment (3, 1, 5),
389 _insert_note_button_spin (_insert_note_button_adjustment)
391 const std::string restart_msg = _("\nChanges to this setting will only persist after your project has been saved.");
392 /* internationalize and prepare for use with combos */
395 for (int i = 0; modifiers[i].name; ++i) {
396 dumb.push_back (S_(modifiers[i].name));
399 set_popdown_strings (_edit_modifier_combo, dumb);
400 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
401 Gtkmm2ext::UI::instance()->set_tip (_edit_modifier_combo,
402 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
403 for (int x = 0; modifiers[x].name; ++x) {
404 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
405 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
410 Table* t = manage (new Table (5, 11));
416 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
417 l->set_name ("OptionsLabel");
421 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
422 strs.push_back (bf->first);
425 set_popdown_strings (_keyboard_layout_selector, strs);
426 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
427 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
429 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
430 t->attach (_keyboard_layout_selector, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
435 l = manage (left_aligned_label (_("When Clicking:")));
436 l->set_name ("OptionEditorHeading");
437 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
442 l = manage (left_aligned_label (_("Edit using:")));
443 l->set_name ("OptionsLabel");
445 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
446 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
448 l = manage (new Label (_("+ button")));
449 l->set_name ("OptionsLabel");
451 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
452 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
454 _edit_button_spin.set_name ("OptionsEntry");
455 _edit_button_adjustment.set_value (Keyboard::edit_button());
456 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
461 set_popdown_strings (_delete_modifier_combo, dumb);
462 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
463 Gtkmm2ext::UI::instance()->set_tip (_delete_modifier_combo,
464 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
465 for (int x = 0; modifiers[x].name; ++x) {
466 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
467 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
472 l = manage (left_aligned_label (_("Delete using:")));
473 l->set_name ("OptionsLabel");
475 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
476 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
478 l = manage (new Label (_("+ button")));
479 l->set_name ("OptionsLabel");
481 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
482 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
484 _delete_button_spin.set_name ("OptionsEntry");
485 _delete_button_adjustment.set_value (Keyboard::delete_button());
486 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
491 set_popdown_strings (_insert_note_modifier_combo, dumb);
492 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
493 Gtkmm2ext::UI::instance()->set_tip (_insert_note_modifier_combo,
494 (string_compose (_("<b>Recommended Setting: %1 + button 1 (left mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
495 for (int x = 0; modifiers[x].name; ++x) {
496 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
497 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
502 l = manage (left_aligned_label (_("Insert note using:")));
503 l->set_name ("OptionsLabel");
505 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
506 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
508 l = manage (new Label (_("+ button")));
509 l->set_name ("OptionsLabel");
511 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
512 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
514 _insert_note_button_spin.set_name ("OptionsEntry");
515 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
516 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
520 l = manage (left_aligned_label (_("When Beginning a Drag:")));
521 l->set_name ("OptionEditorHeading");
522 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
528 set_popdown_strings (_copy_modifier_combo, dumb);
529 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
530 Gtkmm2ext::UI::instance()->set_tip (_copy_modifier_combo,
531 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
533 Keyboard::secondary_modifier_name (),
535 Keyboard::primary_modifier_name (),
538 for (int x = 0; modifiers[x].name; ++x) {
539 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
540 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
545 l = manage (left_aligned_label (_("Copy items using:")));
546 l->set_name ("OptionsLabel");
548 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
549 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
554 /* constraint modifier */
555 set_popdown_strings (_constraint_modifier_combo, dumb);
556 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
557 std::string mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
558 Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo,
559 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
561 Keyboard::primary_modifier_name (),
563 Keyboard::tertiary_modifier_name (),
566 for (int x = 0; modifiers[x].name; ++x) {
567 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
568 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
573 l = manage (left_aligned_label (_("Constrain drag using:")));
574 l->set_name ("OptionsLabel");
576 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
577 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
583 set_popdown_strings (_push_points_combo, dumb);
584 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
586 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
587 Gtkmm2ext::UI::instance()->set_tip (_push_points_combo,
588 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
589 for (int x = 0; modifiers[x].name; ++x) {
590 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
591 _push_points_combo.set_active_text (S_(modifiers[x].name));
596 l = manage (left_aligned_label (_("Push points using:")));
597 l->set_name ("OptionsLabel");
599 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
600 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
604 l = manage (left_aligned_label (_("When Beginning a Trim:")));
605 l->set_name ("OptionEditorHeading");
606 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
612 set_popdown_strings (_trim_contents_combo, dumb);
613 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
614 Gtkmm2ext::UI::instance()->set_tip (_trim_contents_combo,
615 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
616 for (int x = 0; modifiers[x].name; ++x) {
617 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
618 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
623 l = manage (left_aligned_label (_("Trim contents using:")));
624 l->set_name ("OptionsLabel");
626 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
627 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
633 set_popdown_strings (_trim_anchored_combo, dumb);
634 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
636 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::tertiary_modifier_name ());
637 Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo,
638 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
639 for (int x = 0; modifiers[x].name; ++x) {
640 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
641 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
646 l = manage (left_aligned_label (_("Anchored trim using:")));
647 l->set_name ("OptionsLabel");
649 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
651 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
656 /* jump trim disabled for now
657 set_popdown_strings (_trim_jump_combo, dumb);
658 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
660 for (int x = 0; modifiers[x].name; ++x) {
661 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
662 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
667 l = manage (left_aligned_label (_("Jump after trim using:")));
668 l->set_name ("OptionsLabel");
670 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
672 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
678 /* note resize relative */
679 set_popdown_strings (_note_size_relative_combo, dumb);
680 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
681 Gtkmm2ext::UI::instance()->set_tip (_note_size_relative_combo,
682 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
683 for (int x = 0; modifiers[x].name; ++x) {
684 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
685 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
690 l = manage (left_aligned_label (_("Resize notes relatively using:")));
691 l->set_name ("OptionsLabel");
693 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
695 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
699 l = manage (left_aligned_label (_("While Dragging:")));
700 l->set_name ("OptionEditorHeading");
701 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
707 set_popdown_strings (_snap_modifier_combo, dumb);
708 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
710 mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ());
712 mod_str = Keyboard::secondary_modifier_name();
714 Gtkmm2ext::UI::instance()->set_tip (_snap_modifier_combo,
715 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
716 for (int x = 0; modifiers[x].name; ++x) {
717 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
718 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
723 l = manage (left_aligned_label (_("Ignore snap using:")));
724 l->set_name ("OptionsLabel");
726 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
727 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
733 set_popdown_strings (_snap_delta_combo, dumb);
734 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
736 mod_str = Keyboard::level4_modifier_name ();
738 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::level4_modifier_name ());
740 Gtkmm2ext::UI::instance()->set_tip (_snap_delta_combo,
741 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
742 for (int x = 0; modifiers[x].name; ++x) {
743 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
744 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
749 l = manage (left_aligned_label (_("Snap relatively using:")));
750 l->set_name ("OptionsLabel");
752 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
753 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
757 l = manage (left_aligned_label (_("While Trimming:")));
758 l->set_name ("OptionEditorHeading");
759 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
765 set_popdown_strings (_trim_overlap_combo, dumb);
766 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
768 Gtkmm2ext::UI::instance()->set_tip (_trim_overlap_combo,
769 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
770 for (int x = 0; modifiers[x].name; ++x) {
771 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
772 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
777 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
778 l->set_name ("OptionsLabel");
780 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
781 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
785 l = manage (left_aligned_label (_("While Dragging Control Points:")));
786 l->set_name ("OptionEditorHeading");
787 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
793 set_popdown_strings (_fine_adjust_combo, dumb);
794 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
796 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::secondary_modifier_name ());
797 Gtkmm2ext::UI::instance()->set_tip (_fine_adjust_combo,
798 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
799 for (int x = 0; modifiers[x].name; ++x) {
800 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
801 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
806 l = manage (left_aligned_label (_("Fine adjust using:")));
807 l->set_name ("OptionsLabel");
809 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
810 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
812 _box->pack_start (*t, false, false);
815 void parameter_changed (string const &)
817 /* XXX: these aren't really config options... */
820 void set_state_from_config ()
822 /* XXX: these aren't really config options... */
827 void bindings_changed ()
829 string const txt = _keyboard_layout_selector.get_active_text();
831 /* XXX: config...? for all this keyboard stuff */
833 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
834 if (txt == i->first) {
835 if (Keyboard::load_keybindings (i->second)) {
836 Keyboard::save_keybindings ();
842 void edit_modifier_chosen ()
844 string const txt = _edit_modifier_combo.get_active_text();
846 for (int i = 0; modifiers[i].name; ++i) {
847 if (txt == S_(modifiers[i].name)) {
848 Keyboard::set_edit_modifier (modifiers[i].modifier);
854 void delete_modifier_chosen ()
856 string const txt = _delete_modifier_combo.get_active_text();
858 for (int i = 0; modifiers[i].name; ++i) {
859 if (txt == S_(modifiers[i].name)) {
860 Keyboard::set_delete_modifier (modifiers[i].modifier);
866 void copy_modifier_chosen ()
868 string const txt = _copy_modifier_combo.get_active_text();
870 for (int i = 0; modifiers[i].name; ++i) {
871 if (txt == S_(modifiers[i].name)) {
872 Keyboard::set_copy_modifier (modifiers[i].modifier);
878 void insert_note_modifier_chosen ()
880 string const txt = _insert_note_modifier_combo.get_active_text();
882 for (int i = 0; modifiers[i].name; ++i) {
883 if (txt == S_(modifiers[i].name)) {
884 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
890 void snap_modifier_chosen ()
892 string const txt = _snap_modifier_combo.get_active_text();
894 for (int i = 0; modifiers[i].name; ++i) {
895 if (txt == S_(modifiers[i].name)) {
896 Keyboard::set_snap_modifier (modifiers[i].modifier);
902 void snap_delta_modifier_chosen ()
904 string const txt = _snap_delta_combo.get_active_text();
906 for (int i = 0; modifiers[i].name; ++i) {
907 if (txt == S_(modifiers[i].name)) {
908 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
914 void constraint_modifier_chosen ()
916 string const txt = _constraint_modifier_combo.get_active_text();
918 for (int i = 0; modifiers[i].name; ++i) {
919 if (txt == S_(modifiers[i].name)) {
920 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
926 void trim_contents_modifier_chosen ()
928 string const txt = _trim_contents_combo.get_active_text();
930 for (int i = 0; modifiers[i].name; ++i) {
931 if (txt == S_(modifiers[i].name)) {
932 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
938 void trim_overlap_modifier_chosen ()
940 string const txt = _trim_overlap_combo.get_active_text();
942 for (int i = 0; modifiers[i].name; ++i) {
943 if (txt == S_(modifiers[i].name)) {
944 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
950 void trim_anchored_modifier_chosen ()
952 string const txt = _trim_anchored_combo.get_active_text();
954 for (int i = 0; modifiers[i].name; ++i) {
955 if (txt == S_(modifiers[i].name)) {
956 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
962 void fine_adjust_modifier_chosen ()
964 string const txt = _fine_adjust_combo.get_active_text();
966 for (int i = 0; modifiers[i].name; ++i) {
967 if (txt == S_(modifiers[i].name)) {
968 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
974 void push_points_modifier_chosen ()
976 string const txt = _push_points_combo.get_active_text();
978 for (int i = 0; modifiers[i].name; ++i) {
979 if (txt == S_(modifiers[i].name)) {
980 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
986 void note_size_relative_modifier_chosen ()
988 string const txt = _note_size_relative_combo.get_active_text();
990 for (int i = 0; modifiers[i].name; ++i) {
991 if (txt == S_(modifiers[i].name)) {
992 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
998 void delete_button_changed ()
1000 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
1003 void edit_button_changed ()
1005 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
1008 void insert_note_button_changed ()
1010 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
1013 ComboBoxText _keyboard_layout_selector;
1014 ComboBoxText _edit_modifier_combo;
1015 ComboBoxText _delete_modifier_combo;
1016 ComboBoxText _copy_modifier_combo;
1017 ComboBoxText _insert_note_modifier_combo;
1018 ComboBoxText _snap_modifier_combo;
1019 ComboBoxText _snap_delta_combo;
1020 ComboBoxText _constraint_modifier_combo;
1021 ComboBoxText _trim_contents_combo;
1022 ComboBoxText _trim_overlap_combo;
1023 ComboBoxText _trim_anchored_combo;
1024 ComboBoxText _trim_jump_combo;
1025 ComboBoxText _fine_adjust_combo;
1026 ComboBoxText _push_points_combo;
1027 ComboBoxText _note_size_relative_combo;
1028 Adjustment _delete_button_adjustment;
1029 SpinButton _delete_button_spin;
1030 Adjustment _edit_button_adjustment;
1031 SpinButton _edit_button_spin;
1032 Adjustment _insert_note_button_adjustment;
1033 SpinButton _insert_note_button_spin;
1037 class FontScalingOptions : public OptionEditorBox
1040 FontScalingOptions () :
1041 _dpi_adjustment (100, 50, 250, 1, 5),
1042 _dpi_slider (_dpi_adjustment)
1044 _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.);
1046 Label* l = manage (new Label (_("GUI and Font scaling:")));
1047 l->set_name ("OptionsLabel");
1049 const std::string dflt = _("Default");
1050 const std::string empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
1052 _dpi_slider.set_name("FontScaleSlider");
1053 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1054 _dpi_slider.set_draw_value(false);
1055 _dpi_slider.add_mark(50, Gtk::POS_TOP, empty);
1056 _dpi_slider.add_mark(60, Gtk::POS_TOP, empty);
1057 _dpi_slider.add_mark(70, Gtk::POS_TOP, empty);
1058 _dpi_slider.add_mark(80, Gtk::POS_TOP, empty);
1059 _dpi_slider.add_mark(90, Gtk::POS_TOP, empty);
1060 _dpi_slider.add_mark(100, Gtk::POS_TOP, dflt);
1061 _dpi_slider.add_mark(125, Gtk::POS_TOP, empty);
1062 _dpi_slider.add_mark(150, Gtk::POS_TOP, empty);
1063 _dpi_slider.add_mark(175, Gtk::POS_TOP, empty);
1064 _dpi_slider.add_mark(200, Gtk::POS_TOP, empty);
1065 _dpi_slider.add_mark(225, Gtk::POS_TOP, empty);
1066 _dpi_slider.add_mark(250, Gtk::POS_TOP, empty);
1068 HBox* h = manage (new HBox);
1070 h->pack_start (*l, false, false);
1071 h->pack_start (_dpi_slider, true, true);
1073 _box->pack_start (*h, false, false);
1075 set_note (_("Adjusting the scale requires an application restart to re-layout."));
1077 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
1080 void parameter_changed (string const & p)
1082 if (p == "font-scale") {
1083 _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.);
1087 void set_state_from_config ()
1089 parameter_changed ("font-scale");
1096 UIConfiguration::instance().set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024.));
1097 /* XXX: should be triggered from the parameter changed signal */
1098 UIConfiguration::instance().reset_dpi ();
1101 Adjustment _dpi_adjustment;
1105 class VstTimeOutSliderOption : public OptionEditorBox
1108 VstTimeOutSliderOption (RCConfiguration* c)
1110 , _timeout_adjustment (0, 0, 3000, 50, 50)
1111 , _timeout_slider (_timeout_adjustment)
1113 _timeout_slider.set_digits (0);
1114 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &VstTimeOutSliderOption::timeout_changed));
1116 _timeout_slider.set_draw_value(false);
1117 _timeout_slider.add_mark( 0, Gtk::POS_TOP, _("\u221e")); // infinity
1118 _timeout_slider.add_mark( 300, Gtk::POS_TOP, _("30 sec"));
1119 _timeout_slider.add_mark( 600, Gtk::POS_TOP, _("1 min"));
1120 _timeout_slider.add_mark(1200, Gtk::POS_TOP, _("2 mins"));
1121 _timeout_slider.add_mark(1800, Gtk::POS_TOP, _("3 mins"));
1122 _timeout_slider.add_mark(2400, Gtk::POS_TOP, _("4 mins"));
1123 _timeout_slider.add_mark(3000, Gtk::POS_TOP, _("5 mins"));
1125 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1126 _("Specify the default timeout for plugin instantiation. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1128 Label* l = manage (left_aligned_label (_("Scan Time Out:")));
1129 HBox* h = manage (new HBox);
1131 h->pack_start (*l, false, false);
1132 h->pack_start (_timeout_slider, true, true);
1134 _box->pack_start (*h, false, false);
1137 void parameter_changed (string const & p)
1139 if (p == "vst-scan-timeout") {
1140 int const x = _rc_config->get_vst_scan_timeout();
1141 _timeout_adjustment.set_value (x);
1145 void set_state_from_config ()
1147 parameter_changed ("vst-scan-timeout");
1152 void timeout_changed ()
1154 int x = floor(_timeout_adjustment.get_value());
1155 _rc_config->set_vst_scan_timeout(x);
1158 RCConfiguration* _rc_config;
1159 Adjustment _timeout_adjustment;
1160 HScale _timeout_slider;
1167 class ClipLevelOptions : public OptionEditorBox
1171 : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1172 , _clip_level_slider (_clip_level_adjustment)
1174 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ());
1176 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
1177 l->set_name ("OptionsLabel");
1179 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1180 HBox* h = manage (new HBox);
1182 h->pack_start (*l, false, false);
1183 h->pack_start (_clip_level_slider, true, true);
1185 _box->pack_start (*h, false, false);
1187 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1190 void parameter_changed (string const & p)
1192 if (p == "waveform-clip-level") {
1193 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level());
1197 void set_state_from_config ()
1199 parameter_changed ("waveform-clip-level");
1204 void clip_level_changed ()
1206 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1207 /* XXX: should be triggered from the parameter changed signal */
1208 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1211 Adjustment _clip_level_adjustment;
1212 HScale _clip_level_slider;
1215 class BufferingOptions : public OptionEditorBox
1218 BufferingOptions (RCConfiguration* c)
1220 , _playback_adjustment (5, 1, 60, 1, 4)
1221 , _capture_adjustment (5, 1, 60, 1, 4)
1222 , _playback_slider (_playback_adjustment)
1223 , _capture_slider (_capture_adjustment)
1225 vector<string> presets;
1227 /* these must match the order of the enums for BufferingPreset */
1229 presets.push_back (_("Small sessions (4-16 tracks)"));
1230 presets.push_back (_("Medium sessions (16-64 tracks)"));
1231 presets.push_back (_("Large sessions (64+ tracks)"));
1232 presets.push_back (_("Custom (set by sliders below)"));
1234 set_popdown_strings (_buffering_presets_combo, presets);
1236 Label* l = manage (new Label (_("Preset:")));
1237 l->set_name ("OptionsLabel");
1238 HBox* h = manage (new HBox);
1239 h->set_spacing (12);
1240 h->pack_start (*l, false, false);
1241 h->pack_start (_buffering_presets_combo, true, true);
1242 _box->pack_start (*h, false, false);
1244 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1246 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1248 l = manage (new Label (_("Playback (seconds of buffering):")));
1249 l->set_name ("OptionsLabel");
1251 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1252 h = manage (new HBox);
1254 h->pack_start (*l, false, false);
1255 h->pack_start (_playback_slider, true, true);
1257 _box->pack_start (*h, false, false);
1259 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1261 l = manage (new Label (_("Recording (seconds of buffering):")));
1262 l->set_name ("OptionsLabel");
1264 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1265 h = manage (new HBox);
1267 h->pack_start (*l, false, false);
1268 h->pack_start (_capture_slider, true, true);
1270 _box->pack_start (*h, false, false);
1272 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
1273 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
1276 void parameter_changed (string const & p)
1278 if (p == "buffering-preset") {
1279 switch (_rc_config->get_buffering_preset()) {
1281 _playback_slider.set_sensitive (false);
1282 _capture_slider.set_sensitive (false);
1283 _buffering_presets_combo.set_active (0);
1286 _playback_slider.set_sensitive (false);
1287 _capture_slider.set_sensitive (false);
1288 _buffering_presets_combo.set_active (1);
1291 _playback_slider.set_sensitive (false);
1292 _capture_slider.set_sensitive (false);
1293 _buffering_presets_combo.set_active (2);
1296 _playback_slider.set_sensitive (true);
1297 _capture_slider.set_sensitive (true);
1298 _buffering_presets_combo.set_active (3);
1303 if (p == "playback-buffer-seconds") {
1304 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1305 } else if (p == "capture-buffer-seconds") {
1306 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1310 void set_state_from_config ()
1312 parameter_changed ("buffering-preset");
1313 parameter_changed ("playback-buffer-seconds");
1314 parameter_changed ("capture-buffer-seconds");
1319 void preset_changed ()
1321 int index = _buffering_presets_combo.get_active_row_number ();
1327 _rc_config->set_buffering_preset (Small);
1330 _rc_config->set_buffering_preset (Medium);
1333 _rc_config->set_buffering_preset (Large);
1336 _rc_config->set_buffering_preset (Custom);
1339 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1344 void playback_changed ()
1346 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
1349 void capture_changed ()
1351 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
1354 RCConfiguration* _rc_config;
1355 Adjustment _playback_adjustment;
1356 Adjustment _capture_adjustment;
1357 HScale _playback_slider;
1358 HScale _capture_slider;
1359 ComboBoxText _buffering_presets_combo;
1362 class ControlSurfacesOptions : public OptionEditorPageBox
1365 ControlSurfacesOptions ()
1366 : _ignore_view_change (0)
1368 _store = ListStore::create (_model);
1369 _view.set_model (_store);
1370 _view.append_column (_("Control Surface Protocol"), _model.name);
1371 _view.get_column(0)->set_resizable (true);
1372 _view.get_column(0)->set_expand (true);
1373 _view.append_column_editable (_("Enable"), _model.enabled);
1375 Label* l = manage (new Label (string_compose ("<b>%1</b>", _("Control Surfaces"))));
1376 l->set_alignment (0, 0.5);
1377 l->set_use_markup (true);
1378 _box->pack_start (*l, false, false);
1379 _box->pack_start (_view, false, false);
1381 Gtk::HBox* edit_box = manage (new Gtk::HBox);
1382 edit_box->set_spacing(3);
1383 _box->pack_start (*edit_box, false, false);
1386 Label* label = manage (new Label);
1387 label->set_text (_("Edit the settings for selected protocol (it must be ENABLED first):"));
1388 edit_box->pack_start (*label, false, false);
1391 edit_button = manage (new Button(_("Show Protocol Settings")));
1392 edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
1393 edit_box->pack_start (*edit_button, true, true);
1394 edit_button->set_sensitive (false);
1395 edit_button->show ();
1397 ControlProtocolManager& m = ControlProtocolManager::instance ();
1398 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1399 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1401 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1402 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1403 _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
1406 void parameter_changed (std::string const &)
1411 void set_state_from_config ()
1415 ControlProtocolManager& m = ControlProtocolManager::instance ();
1416 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1418 if (!(*i)->mandatory) {
1419 TreeModel::Row r = *_store->append ();
1420 r[_model.name] = (*i)->name;
1421 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1422 r[_model.protocol_info] = *i;
1429 void protocol_status_changed (ControlProtocolInfo* cpi) {
1431 TreeModel::Children rows = _store->children();
1433 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1434 string n = ((*x)[_model.name]);
1436 if ((*x)[_model.protocol_info] == cpi) {
1437 _ignore_view_change++;
1438 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1439 _ignore_view_change--;
1445 void selection_changed ()
1447 //enable the Edit button when a row is selected for editing
1448 TreeModel::Row row = *(_view.get_selection()->get_selected());
1449 if (row && row[_model.enabled])
1450 edit_button->set_sensitive (true);
1452 edit_button->set_sensitive (false);
1455 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1457 TreeModel::Row r = *i;
1459 if (_ignore_view_change) {
1463 ControlProtocolInfo* cpi = r[_model.protocol_info];
1468 bool const was_enabled = (cpi->protocol != 0);
1469 bool const is_enabled = r[_model.enabled];
1472 if (was_enabled != is_enabled) {
1475 ControlProtocolManager::instance().activate (*cpi);
1477 ControlProtocolManager::instance().deactivate (*cpi);
1481 selection_changed ();
1484 void edit_btn_clicked ()
1487 ControlProtocolInfo* cpi;
1490 row = *(_view.get_selection()->get_selected());
1491 if (!row[_model.enabled]) {
1494 cpi = row[_model.protocol_info];
1495 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1498 Box* box = (Box*) cpi->protocol->get_gui ();
1502 if (box->get_parent()) {
1503 static_cast<ArdourWindow*>(box->get_parent())->present();
1506 WindowTitle title (Glib::get_application_name());
1507 title += row[_model.name];
1508 title += _("Configuration");
1509 /* once created, the window is managed by the surface itself (as ->get_parent())
1510 * Surface's tear_down_gui() is called on session close, when de-activating
1511 * or re-initializing a surface.
1512 * tear_down_gui() hides an deletes the Window if it exists.
1514 ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
1515 win->set_title ("Control Protocol Options");
1521 void edit_clicked (GdkEventButton* ev)
1523 if (ev->type != GDK_2BUTTON_PRESS) {
1530 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1534 ControlSurfacesModelColumns ()
1538 add (protocol_info);
1541 TreeModelColumn<string> name;
1542 TreeModelColumn<bool> enabled;
1543 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1546 Glib::RefPtr<ListStore> _store;
1547 ControlSurfacesModelColumns _model;
1549 PBD::ScopedConnection protocol_status_connection;
1550 uint32_t _ignore_view_change;
1551 Gtk::Button* edit_button;
1554 class VideoTimelineOptions : public OptionEditorPageBox, public OptionEditorPage
1557 VideoTimelineOptions (RCConfiguration* c)
1559 , _show_video_export_info_button (_("Show Video Export Info before export"))
1560 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1561 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1562 , _xjadeo_browse_button (_("Browse..."))
1566 Label* l = manage (new Label (string_compose ("<b>%1</b>", _("Video Server"))));
1567 l->set_use_markup (true);
1568 l->set_alignment (0, 0.5);
1569 t->attach (*l, 0, 4, 0, 1, EXPAND | FILL, FILL | EXPAND, 0, 0);
1571 t->attach (_show_video_export_info_button, 1, 4, 1, 2);
1572 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1573 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1574 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1576 t->attach (_show_video_server_dialog_button, 1, 4, 2, 3);
1577 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1578 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1579 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1581 t->attach (_video_advanced_setup_button, 1, 4, 3, 4, FILL);
1582 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1583 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1584 _("<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."));
1586 l = manage (new Label (_("Video Server URL:")));
1587 l->set_alignment (0, 0.5);
1588 t->attach (*l, 1, 2, 4, 5, FILL);
1589 t->attach (_video_server_url_entry, 2, 4, 4, 5, FILL);
1590 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1591 _("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"));
1593 l = manage (new Label (_("Video Folder:")));
1594 l->set_alignment (0, 0.5);
1595 t->attach (*l, 1, 2, 5, 6, FILL);
1596 t->attach (_video_server_docroot_entry, 2, 4, 5, 6);
1597 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1598 _("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."));
1600 l = manage (new Label (""));
1601 t->attach (*l, 0, 4, 6, 7, EXPAND | FILL);
1603 l = manage (new Label (string_compose ("<b>%1</b>", _("Video Monitor"))));
1604 l->set_use_markup (true);
1605 l->set_alignment (0, 0.5);
1606 t->attach (*l, 0, 4, 7, 8, EXPAND | FILL);
1608 l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"),
1611 #elif defined PLATFORM_WINDOWS
1617 l->set_alignment (0, 0.5);
1618 t->attach (*l, 1, 4, 8, 9, FILL);
1619 t->attach (_custom_xjadeo_path, 2, 3, 9, 10, EXPAND|FILL);
1620 Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart."));
1621 t->attach (_xjadeo_browse_button, 3, 4, 9, 10, FILL);
1623 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1624 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1625 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1626 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1627 _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed));
1628 _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked));
1630 // xjadeo-path is a UIConfig parameter
1631 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &VideoTimelineOptions::parameter_changed));
1633 _box->pack_start (*t, true, true);
1636 void server_url_changed ()
1638 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1641 void server_docroot_changed ()
1643 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1646 void show_video_export_info_toggled ()
1648 bool const x = _show_video_export_info_button.get_active ();
1649 _rc_config->set_show_video_export_info (x);
1652 void show_video_server_dialog_toggled ()
1654 bool const x = _show_video_server_dialog_button.get_active ();
1655 _rc_config->set_show_video_server_dialog (x);
1658 void video_advanced_setup_toggled ()
1660 bool const x = _video_advanced_setup_button.get_active ();
1661 _rc_config->set_video_advanced_setup(x);
1664 void custom_xjadeo_path_changed ()
1666 UIConfiguration::instance().set_xjadeo_binary (_custom_xjadeo_path.get_text());
1669 void xjadeo_browse_clicked ()
1671 Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN);
1672 dialog.set_filename (UIConfiguration::instance().get_xjadeo_binary());
1673 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1674 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1675 if (dialog.run () == Gtk::RESPONSE_OK) {
1676 const std::string& filename = dialog.get_filename();
1677 if (!filename.empty() && (
1679 Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) ||
1681 Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)
1683 UIConfiguration::instance().set_xjadeo_binary (filename);
1688 void parameter_changed (string const & p)
1690 if (p == "video-server-url") {
1691 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1692 } else if (p == "video-server-docroot") {
1693 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1694 } else if (p == "show-video-export-info") {
1695 bool const x = _rc_config->get_show_video_export_info();
1696 _show_video_export_info_button.set_active (x);
1697 } else if (p == "show-video-server-dialog") {
1698 bool const x = _rc_config->get_show_video_server_dialog();
1699 _show_video_server_dialog_button.set_active (x);
1700 } else if (p == "video-advanced-setup") {
1701 bool const x = _rc_config->get_video_advanced_setup();
1702 _video_advanced_setup_button.set_active(x);
1703 _video_server_docroot_entry.set_sensitive(x);
1704 _video_server_url_entry.set_sensitive(x);
1705 } else if (p == "xjadeo-binary") {
1706 _custom_xjadeo_path.set_text (UIConfiguration::instance().get_xjadeo_binary());
1710 void set_state_from_config ()
1712 parameter_changed ("video-server-url");
1713 parameter_changed ("video-server-docroot");
1714 parameter_changed ("video-monitor-setup-dialog");
1715 parameter_changed ("show-video-export-info");
1716 parameter_changed ("show-video-server-dialog");
1717 parameter_changed ("video-advanced-setup");
1718 parameter_changed ("xjadeo-binary");
1722 RCConfiguration* _rc_config;
1723 Entry _video_server_url_entry;
1724 Entry _video_server_docroot_entry;
1725 Entry _custom_xjadeo_path;
1726 CheckButton _show_video_export_info_button;
1727 CheckButton _show_video_server_dialog_button;
1728 CheckButton _video_advanced_setup_button;
1729 Button _xjadeo_browse_button;
1732 class ColumVisibilityOption : public Option
1735 ColumVisibilityOption (string id, string name, uint32_t n_col, sigc::slot<uint32_t> get, sigc::slot<bool, uint32_t> set)
1742 cb = (CheckButton**) malloc (sizeof (CheckButton*) * n_col);
1743 for (uint32_t i = 0; i < n_col; ++i) {
1744 CheckButton* col = manage (new CheckButton (string_compose (_("Column %1"), i + 1)));
1745 col->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ColumVisibilityOption::column_toggled), i));
1746 _hbox.pack_start (*col);
1749 parameter_changed (id);
1752 ~ColumVisibilityOption () {
1756 Gtk::Widget& tip_widget() { return _hbox; }
1758 void set_state_from_config ()
1760 uint32_t c = _get();
1761 for (uint32_t i = 0; i < _n_col; ++i) {
1762 bool en = (c & (1<<i)) ? true : false;
1763 if (cb[i]->get_active () != en) {
1764 cb[i]->set_active (en);
1769 void add_to_page (OptionEditorPage* p)
1771 _heading.add_to_page (p);
1772 add_widget_to_page (p, &_hbox);
1776 void column_toggled (int b) {
1777 uint32_t c = _get();
1779 if (cb[b]->get_active ()) {
1790 OptionEditorHeading _heading;
1794 sigc::slot<uint32_t> _get;
1795 sigc::slot<bool, uint32_t> _set;
1799 /** A class which allows control of visibility of some editor components usign
1800 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1801 * which has the correct members, but with null widget pointers. This
1802 * class allows the user to set visibility of the members, the details
1803 * of which are stored in a configuration variable which can be watched
1804 * by parts of the editor that actually contain the widgets whose visibility
1805 * is being controlled.
1808 class VisibilityOption : public Option
1811 /** @param name User-visible name for this group.
1812 * @param g `Dummy' VisibilityGroup (as described above).
1813 * @param get Method to get the value of the appropriate configuration variable.
1814 * @param set Method to set the value of the appropriate configuration variable.
1816 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1817 : Option (g->get_state_name(), name)
1819 , _visibility_group (g)
1823 /* Watch for changes made by the user to our members */
1824 _visibility_group->VisibilityChanged.connect_same_thread (
1825 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1829 void set_state_from_config ()
1831 /* Set our state from the current configuration */
1832 _visibility_group->set_state (_get ());
1835 void add_to_page (OptionEditorPage* p)
1837 _heading.add_to_page (p);
1838 add_widget_to_page (p, _visibility_group->list_view ());
1841 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1846 /* The user has changed something, so reflect this change
1847 in the RCConfiguration.
1849 _set (_visibility_group->get_state_value ());
1852 OptionEditorHeading _heading;
1853 VisibilityGroup* _visibility_group;
1854 sigc::slot<std::string> _get;
1855 sigc::slot<bool, std::string> _set;
1856 PBD::ScopedConnection _visibility_group_connection;
1860 class MidiPortOptions : public OptionEditorPageBox, public sigc::trackable
1865 setup_midi_port_view (midi_output_view, false);
1866 setup_midi_port_view (midi_input_view, true);
1869 _box->pack_start (*manage (new Label("")), false, false);
1870 input_label.set_markup (string_compose ("<span size=\"large\" weight=\"bold\">%1</span>", _("MIDI Inputs")));
1871 _box->pack_start (input_label, false, false);
1873 Gtk::ScrolledWindow* scroller = manage (new Gtk::ScrolledWindow);
1874 scroller->add (midi_input_view);
1875 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1876 scroller->set_size_request (-1, 180);
1877 _box->pack_start (*scroller, false, false);
1879 _box->pack_start (*manage (new Label("")), false, false);
1880 output_label.set_markup (string_compose ("<span size=\"large\" weight=\"bold\">%1</span>", _("MIDI Outputs")));
1881 _box->pack_start (output_label, false, false);
1883 scroller = manage (new Gtk::ScrolledWindow);
1884 scroller->add (midi_output_view);
1885 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1886 scroller->set_size_request (-1, 180);
1887 _box->pack_start (*scroller, false, false);
1889 midi_output_view.show ();
1890 midi_input_view.show ();
1892 _box->signal_show().connect (sigc::mem_fun (*this, &MidiPortOptions::on_show));
1895 void parameter_changed (string const&) {}
1896 void set_state_from_config() {}
1901 AudioEngine::instance()->PortRegisteredOrUnregistered.connect (connections,
1902 invalidator (*this),
1903 boost::bind (&MidiPortOptions::refill, this),
1905 AudioEngine::instance()->MidiPortInfoChanged.connect (connections,
1906 invalidator (*this),
1907 boost::bind (&MidiPortOptions::refill, this),
1909 AudioEngine::instance()->MidiSelectionPortsChanged.connect (connections,
1910 invalidator (*this),
1911 boost::bind (&MidiPortOptions::refill, this),
1917 if (refill_midi_ports (true, midi_input_view)) {
1918 input_label.show ();
1920 input_label.hide ();
1922 if (refill_midi_ports (false, midi_output_view)) {
1923 output_label.show ();
1925 output_label.hide ();
1930 PBD::ScopedConnectionList connections;
1932 /* MIDI port management */
1933 struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord {
1935 MidiPortColumns () {
1944 Gtk::TreeModelColumn<std::string> pretty_name;
1945 Gtk::TreeModelColumn<bool> music_data;
1946 Gtk::TreeModelColumn<bool> control_data;
1947 Gtk::TreeModelColumn<bool> selection;
1948 Gtk::TreeModelColumn<std::string> name;
1949 Gtk::TreeModelColumn<std::string> filler;
1952 MidiPortColumns midi_port_columns;
1953 Gtk::TreeView midi_input_view;
1954 Gtk::TreeView midi_output_view;
1955 Gtk::Label input_label;
1956 Gtk::Label output_label;
1958 void setup_midi_port_view (Gtk::TreeView&, bool with_selection);
1959 bool refill_midi_ports (bool for_input, Gtk::TreeView&);
1960 void pretty_name_edit (std::string const & path, std::string const & new_text, Gtk::TreeView*);
1961 void midi_music_column_toggled (std::string const & path, Gtk::TreeView*);
1962 void midi_control_column_toggled (std::string const & path, Gtk::TreeView*);
1963 void midi_selection_column_toggled (std::string const & path, Gtk::TreeView*);
1967 MidiPortOptions::setup_midi_port_view (Gtk::TreeView& view, bool with_selection)
1969 int pretty_name_column;
1972 int selection_column;
1973 TreeViewColumn* col;
1976 pretty_name_column = view.append_column_editable (_("Name (click to edit)"), midi_port_columns.pretty_name) - 1;
1978 col = manage (new TreeViewColumn ("", midi_port_columns.music_data));
1979 col->set_alignment (ALIGN_CENTER);
1980 l = manage (new Label (_("Music Data")));
1981 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of music performance data."), PROGRAM_NAME));
1982 col->set_widget (*l);
1984 music_column = view.append_column (*col) - 1;
1986 col = manage (new TreeViewColumn ("", midi_port_columns.control_data));
1987 col->set_alignment (ALIGN_CENTER);
1988 l = manage (new Label (_("Control Data")));
1989 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of control data."), PROGRAM_NAME));
1990 col->set_widget (*l);
1992 control_column = view.append_column (*col) - 1;
1994 if (with_selection) {
1995 col = manage (new TreeViewColumn (_("Follow Selection"), midi_port_columns.selection));
1996 selection_column = view.append_column (*col) - 1;
1997 l = manage (new Label (_("Follow Selection")));
1998 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));
1999 col->set_widget (*l);
2003 /* filler column so that the last real column doesn't expand */
2004 view.append_column ("", midi_port_columns.filler);
2006 CellRendererText* pretty_name_cell = dynamic_cast<CellRendererText*> (view.get_column_cell_renderer (pretty_name_column));
2007 pretty_name_cell->property_editable() = true;
2008 pretty_name_cell->signal_edited().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::pretty_name_edit), &view));
2010 CellRendererToggle* toggle_cell;
2012 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (music_column));
2013 toggle_cell->property_activatable() = true;
2014 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_music_column_toggled), &view));
2016 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (control_column));
2017 toggle_cell->property_activatable() = true;
2018 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_control_column_toggled), &view));
2020 if (with_selection) {
2021 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (selection_column));
2022 toggle_cell->property_activatable() = true;
2023 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_selection_column_toggled), &view));
2026 view.get_selection()->set_mode (SELECTION_NONE);
2027 view.set_tooltip_column (4); /* port "real" name */
2028 view.get_column(0)->set_resizable (true);
2029 view.get_column(0)->set_expand (true);
2033 MidiPortOptions::refill_midi_ports (bool for_input, Gtk::TreeView& view)
2035 using namespace ARDOUR;
2037 std::vector<string> ports;
2039 AudioEngine::instance()->get_known_midi_ports (ports);
2041 if (ports.empty()) {
2046 Glib::RefPtr<ListStore> model = Gtk::ListStore::create (midi_port_columns);
2048 for (vector<string>::const_iterator s = ports.begin(); s != ports.end(); ++s) {
2050 if (AudioEngine::instance()->port_is_mine (*s)) {
2054 PortManager::MidiPortInformation mpi (AudioEngine::instance()->midi_port_information (*s));
2056 if (mpi.pretty_name.empty()) {
2057 /* vanished since get_known_midi_ports() */
2061 if (for_input != mpi.input) {
2065 TreeModel::Row row = *(model->append());
2067 row[midi_port_columns.pretty_name] = mpi.pretty_name;
2068 row[midi_port_columns.music_data] = mpi.properties & MidiPortMusic;
2069 row[midi_port_columns.control_data] = mpi.properties & MidiPortControl;
2070 row[midi_port_columns.selection] = mpi.properties & MidiPortSelection;
2071 row[midi_port_columns.name] = *s;
2074 view.set_model (model);
2080 MidiPortOptions::midi_music_column_toggled (string const & path, TreeView* view)
2082 TreeIter iter = view->get_model()->get_iter (path);
2088 bool new_value = ! bool ((*iter)[midi_port_columns.music_data]);
2090 /* don't reset model - wait for MidiPortInfoChanged signal */
2093 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2095 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2100 MidiPortOptions::midi_control_column_toggled (string const & path, TreeView* view)
2102 TreeIter iter = view->get_model()->get_iter (path);
2108 bool new_value = ! bool ((*iter)[midi_port_columns.control_data]);
2110 /* don't reset model - wait for MidiPortInfoChanged signal */
2113 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2115 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2120 MidiPortOptions::midi_selection_column_toggled (string const & path, TreeView* view)
2122 TreeIter iter = view->get_model()->get_iter (path);
2128 bool new_value = ! bool ((*iter)[midi_port_columns.selection]);
2130 /* don't reset model - wait for MidiSelectionPortsChanged signal */
2133 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2135 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2140 MidiPortOptions::pretty_name_edit (std::string const & path, string const & new_text, Gtk::TreeView* view)
2142 TreeIter iter = view->get_model()->get_iter (path);
2148 boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
2150 ARDOUR::PortEngine::PortHandle ph = backend->get_port_by_name ((*iter)[midi_port_columns.name]);
2152 backend->set_port_property (ph, "http://jackaudio.org/metadata/pretty-name", new_text, "");
2153 (*iter)[midi_port_columns.pretty_name] = new_text;
2161 RCOptionEditor::RCOptionEditor ()
2162 : OptionEditorContainer (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
2163 , Tabbable (*this, _("Preferences")) /* pack self-as-vbox into tabbable */
2164 , _rc_config (Config)
2165 , _mixer_strip_visibility ("mixer-element-visibility")
2167 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
2171 uint32_t hwcpus = hardware_concurrency ();
2173 BoolComboOption* bco;
2176 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
2178 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
2180 _("Signal processing uses"),
2181 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
2182 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
2185 procs->add (-1, _("all but one processor"));
2186 procs->add (0, _("all available processors"));
2188 for (uint32_t i = 1; i <= hwcpus; ++i) {
2189 procs->add (i, string_compose (P_("%1 processor", "%1 processors", i), i));
2192 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
2194 add_option (_("Misc"), procs);
2197 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
2199 add_option (_("Misc"), new UndoOptions (_rc_config));
2201 add_option (_("Misc"),
2203 "verify-remove-last-capture",
2204 _("Verify removal of last capture"),
2205 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
2206 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
2209 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
2211 add_option (_("Misc"),
2213 "periodic-safety-backups",
2214 _("Make periodic backups of the session file"),
2215 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
2216 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
2219 add_option (_("Misc"),
2221 "only-copy-imported-files",
2222 _("Always copy imported files"),
2223 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
2224 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
2227 add_option (_("Misc"), new DirectoryOption (
2228 X_("default-session-parent-dir"),
2229 _("Default folder for new sessions:"),
2230 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
2231 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
2234 add_option (_("Misc"),
2235 new SpinOption<uint32_t> (
2236 "max-recent-sessions",
2237 _("Maximum number of recent sessions"),
2238 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
2239 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
2243 add_option (_("Misc/Click"), new OptionEditorHeading (_("Click")));
2245 add_option (_("Misc/Click"), new ClickOptions (_rc_config));
2247 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
2249 add_option (_("Misc"),
2250 new SpinOption<double> (
2251 "automation-thinning-factor",
2252 _("Thinning factor (larger value => less data)"),
2253 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
2254 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
2258 add_option (_("Misc"),
2259 new SpinOption<double> (
2260 "automation-interval-msecs",
2261 _("Automation sampling interval (milliseconds)"),
2262 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
2263 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
2267 add_option (_("Misc"), new OptionEditorHeading (_("Tempo")));
2271 tsf = new BoolOption (
2272 "allow-non-quarter-pulse",
2273 _("Allow non quarter-note pulse"),
2274 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_allow_non_quarter_pulse),
2275 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_allow_non_quarter_pulse)
2277 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2278 string_compose (_("<b>When enabled</b> %1 will allow tempo to be expressed in divisions per minute\n"
2279 "<b>When disabled</b> %1 will only allow tempo to be expressed in quarter notes per minute"),
2281 add_option (_("Misc"), tsf);
2285 add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options")));
2287 tsf = new BoolOption (
2288 "latched-record-enable",
2289 _("Keep record-enable engaged on stop"),
2290 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
2291 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
2293 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
2294 add_option (_("Transport"), tsf);
2296 tsf = new BoolOption (
2298 _("Play loop is a transport mode"),
2299 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
2300 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
2302 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2303 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
2304 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
2305 add_option (_("Transport"), tsf);
2307 tsf = new BoolOption (
2308 "stop-recording-on-xrun",
2309 _("Stop recording when an xrun occurs"),
2310 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
2311 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
2313 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2314 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
2316 add_option (_("Transport"), tsf);
2318 tsf = new BoolOption (
2319 "create-xrun-marker",
2320 _("Create markers where xruns occur"),
2321 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
2322 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
2324 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
2325 add_option (_("Transport"), tsf);
2327 tsf = new BoolOption (
2328 "stop-at-session-end",
2329 _("Stop at the end of the session"),
2330 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
2331 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
2333 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2334 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
2335 "when it reaches the current session end marker\n\n"
2336 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
2338 add_option (_("Transport"), tsf);
2340 tsf = new BoolOption (
2342 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
2343 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
2344 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
2346 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2347 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
2348 "preventing any need to do a transport locate at the end of the loop\n\n"
2349 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
2350 "which will often cause a small click or delay"), PROGRAM_NAME));
2351 add_option (_("Transport"), tsf);
2353 tsf = new BoolOption (
2354 "disable-disarm-during-roll",
2355 _("Disable per-track record disarm while rolling"),
2356 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
2357 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
2359 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"));
2360 add_option (_("Transport"), tsf);
2362 tsf = new BoolOption (
2364 _("12dB gain reduction during fast-forward and fast-rewind"),
2365 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
2366 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2368 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
2369 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2370 add_option (_("Transport"), tsf);
2372 ComboOption<float>* psc = new ComboOption<float> (
2375 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
2376 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
2378 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
2379 (_("The amount of preroll (in seconds) to apply when <b>Play with Preroll</b> is initiated.\n\n"
2380 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
2381 psc->add (0.0, _("0 (no pre-roll)"));
2382 psc->add (0.1, _("0.1 second"));
2383 psc->add (0.25, _("0.25 second"));
2384 psc->add (0.5, _("0.5 second"));
2385 psc->add (1.0, _("1.0 second"));
2386 psc->add (2.0, _("2.0 seconds"));
2387 add_option (_("Transport"), psc);
2389 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("Synchronization and Slave Options")));
2391 _sync_source = new ComboOption<SyncSource> (
2393 _("External timecode source"),
2394 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
2395 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
2398 add_option (_("Transport/Sync"), _sync_source);
2400 _sync_framerate = new BoolOption (
2401 "timecode-sync-frame-rate",
2402 _("Match session video frame rate to external timecode"),
2403 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
2404 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
2406 Gtkmm2ext::UI::instance()->set_tip
2407 (_sync_framerate->tip_widget(),
2408 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
2409 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
2410 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
2411 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
2412 "timecode standard and the session standard."), PROGRAM_NAME));
2414 add_option (_("Transport/Sync"), _sync_framerate);
2416 _sync_genlock = new BoolOption (
2417 "timecode-source-is-synced",
2418 _("Sync-lock timecode to clock (disable drift compensation)"),
2419 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
2420 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
2422 Gtkmm2ext::UI::instance()->set_tip
2423 (_sync_genlock->tip_widget(),
2424 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
2425 "Sync Lock indicates that the selected external timecode source shares clock-sync "
2426 "(Black & Burst, Wordclock, etc) with the audio interface. "
2427 "This option disables drift compensation. The transport speed is fixed at 1.0. "
2428 "Vari-speed LTC will be ignored and cause drift."
2430 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
2431 "timecode sources shares clock sync."
2435 add_option (_("Transport/Sync"), _sync_genlock);
2437 _sync_source_2997 = new BoolOption (
2438 "timecode-source-2997",
2439 _("Lock to 29.9700 fps instead of 30000/1001"),
2440 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
2441 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
2443 Gtkmm2ext::UI::instance()->set_tip
2444 (_sync_source_2997->tip_widget(),
2445 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
2446 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
2447 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
2448 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
2449 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
2450 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
2453 add_option (_("Transport/Sync"), _sync_source_2997);
2455 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("LTC Reader")));
2457 _ltc_port = new ComboStringOption (
2459 _("LTC incoming port"),
2460 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
2461 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
2464 vector<string> physical_inputs;
2465 physical_inputs.push_back (_("None"));
2466 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
2467 _ltc_port->set_popdown_strings (physical_inputs);
2469 populate_sync_options ();
2470 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
2472 add_option (_("Transport/Sync"), _ltc_port);
2474 // TODO; rather disable this button than not compile it..
2475 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("LTC Generator")));
2477 add_option (_("Transport/Sync"),
2480 _("Enable LTC generator"),
2481 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
2482 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
2485 _ltc_send_continuously = new BoolOption (
2486 "ltc-send-continuously",
2487 _("Send LTC while stopped"),
2488 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
2489 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
2491 Gtkmm2ext::UI::instance()->set_tip
2492 (_ltc_send_continuously->tip_widget(),
2493 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
2494 add_option (_("Transport/Sync"), _ltc_send_continuously);
2496 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
2497 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
2498 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
2499 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
2501 Gtkmm2ext::UI::instance()->set_tip
2502 (_ltc_volume_slider->tip_widget(),
2503 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
2505 add_option (_("Transport/Sync"), _ltc_volume_slider);
2509 add_option (_("Editor"), new OptionEditorHeading (_("Editor Settings")));
2511 add_option (_("Editor"),
2513 "rubberbanding-snaps-to-grid",
2514 _("Make rubberband selection rectangle snap to the grid"),
2515 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2516 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2519 bo = new BoolOption (
2521 _("Name new markers"),
2522 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2523 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2525 add_option (_("Editor"), bo);
2526 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."
2527 "\n\nYou can always rename markers by right-clicking on them"));
2529 add_option (S_("Editor"),
2531 "draggable-playhead",
2532 _("Allow dragging of playhead"),
2533 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2534 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2537 if (!Profile->get_mixbus()) {
2538 add_option (_("Editor"),
2541 _("Show zoom toolbar (if torn off)"),
2542 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_zoom_tools),
2543 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_zoom_tools)
2546 add_option (_("Editor"),
2548 "use-mouse-position-as-zoom-focus-on-scroll",
2549 _("Always use mouse cursor position as zoom focus when zooming using mouse scroll wheel"),
2550 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2551 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2555 add_option (_("Editor"),
2557 "use-time-rulers-to-zoom-with-vertical-drag",
2558 _("Use time rulers area to zoom when clicking and dragging vertically"),
2559 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag),
2560 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag)
2563 add_option (_("Editor"),
2565 "use-double-click-to-zoom-to-selection",
2566 _("Use double mouse click to zoom to selection"),
2567 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection),
2568 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection)
2571 add_option (_("Editor"),
2573 "update-editor-during-summary-drag",
2574 _("Update editor window during drags of the summary"),
2575 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2576 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2579 add_option (_("Editor"),
2581 "autoscroll-editor",
2582 _("Auto-scroll editor window when dragging near its edges"),
2583 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2584 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2587 add_option (_("Editor"),
2588 new BoolComboOption (
2589 "show-region-gain-envelopes",
2590 _("Show gain envelopes in audio regions"),
2592 _("only in Draw and Internal Edit modes"),
2593 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2594 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2597 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2599 add_option (_("Editor"),
2601 "automation-follows-regions",
2602 _("Move relevant automation when audio regions are moved"),
2603 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2604 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2607 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2608 "default-fade-shape",
2609 _("Default fade shape"),
2610 sigc::mem_fun (*_rc_config,
2611 &RCConfiguration::get_default_fade_shape),
2612 sigc::mem_fun (*_rc_config,
2613 &RCConfiguration::set_default_fade_shape)
2616 fadeshape->add (FadeLinear,
2617 _("Linear (for highly correlated material)"));
2618 fadeshape->add (FadeConstantPower, _("Constant power"));
2619 fadeshape->add (FadeSymmetric, _("Symmetric"));
2620 fadeshape->add (FadeSlow, _("Slow"));
2621 fadeshape->add (FadeFast, _("Fast"));
2623 add_option (_("Editor"), fadeshape);
2627 bco = new BoolComboOption (
2628 "use-overlap-equivalency",
2629 _("Regions in edit groups are edited together"),
2630 _("whenever they overlap in time"),
2631 _("only if they have identical length and position"),
2632 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2633 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2636 add_option (_("Editor"), bco);
2639 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2641 _("Layering model"),
2642 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2643 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2646 lm->add (LaterHigher, _("later is higher"));
2647 lm->add (Manual, _("manual layering"));
2648 add_option (_("Editor"), lm);
2650 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2651 "region-selection-after-split",
2652 _("After splitting selected regions, select"),
2653 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2654 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2656 // TODO: decide which of these modes are really useful
2657 rsas->add(None, _("no regions"));
2658 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2659 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2660 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2661 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2662 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2663 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2664 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2666 add_option (_("Editor"), rsas);
2668 add_option (_("Editor/Waveforms"), new OptionEditorHeading (_("Waveforms")));
2670 if (!Profile->get_mixbus()) {
2671 add_option (_("Editor/Waveforms"),
2674 _("Show waveforms in regions"),
2675 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
2676 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
2680 add_option (_("Editor/Waveforms"),
2682 "show-waveforms-while-recording",
2683 _("Show waveforms for audio while it is being recorded"),
2684 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
2685 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
2688 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
2690 _("Waveform scale"),
2691 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
2692 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
2695 wfs->add (Linear, _("linear"));
2696 wfs->add (Logarithmic, _("logarithmic"));
2698 add_option (_("Editor/Waveforms"), wfs);
2700 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
2702 _("Waveform shape"),
2703 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
2704 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
2707 wfsh->add (Traditional, _("traditional"));
2708 wfsh->add (Rectified, _("rectified"));
2710 add_option (_("Editor/Waveforms"), wfsh);
2712 add_option (_("Editor/Waveforms"), new ClipLevelOptions ());
2717 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2719 add_option (_("Audio"), new BufferingOptions (_rc_config));
2721 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2723 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2725 _("Record monitoring handled by"),
2726 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2727 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2730 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2731 mm->add (HardwareMonitoring, _("via Audio Driver"));
2734 string prog (PROGRAM_NAME);
2735 boost::algorithm::to_lower (prog);
2736 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2737 mm->add (ExternalMonitoring, _("audio hardware"));
2739 add_option (_("Audio"), mm);
2741 add_option (_("Audio"),
2743 "tape-machine-mode",
2744 _("Tape machine mode"),
2745 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2746 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2749 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2750 if (!Profile->get_mixbus()) {
2752 add_option (_("Audio"),
2754 "auto-connect-standard-busses",
2755 _("Auto-connect master/monitor busses"),
2756 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2757 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2760 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2761 "input-auto-connect",
2762 _("Connect track inputs"),
2763 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2764 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2767 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2768 iac->add (ManualConnect, _("manually"));
2770 add_option (_("Audio"), iac);
2772 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2773 "output-auto-connect",
2774 _("Connect track and bus outputs"),
2775 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2776 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2779 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2780 oac->add (AutoConnectMaster, _("automatically to master bus"));
2781 oac->add (ManualConnect, _("manually"));
2783 add_option (_("Audio"), oac);
2785 bo = new BoolOption (
2787 _("Use 'Strict-I/O' for new tracks or Busses"),
2788 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2789 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2792 add_option (_("Audio"), bo);
2793 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2794 _("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."));
2798 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2800 add_option (_("Audio"),
2802 "denormal-protection",
2803 _("Use DC bias to protect against denormals"),
2804 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2805 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2808 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2810 _("Processor handling"),
2811 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2812 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2816 dm->add (DenormalNone, _("no processor handling"));
2818 FPU* fpu = FPU::instance();
2820 if (fpu->has_flush_to_zero()) {
2822 dm->add (DenormalFTZ, _("use FlushToZero"));
2823 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2824 _rc_config->set_denormal_model(DenormalNone);
2827 if (fpu->has_denormals_are_zero()) {
2829 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2830 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2831 _rc_config->set_denormal_model(DenormalNone);
2834 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2836 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2837 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2838 _rc_config->set_denormal_model(DenormalNone);
2842 dm->set_sensitive(false);
2845 add_option (_("Audio"), dm);
2847 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2849 add_option (_("Audio"),
2851 "auto-analyse-audio",
2852 _("Enable automatic analysis of audio"),
2853 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2854 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2857 add_option (_("Audio"),
2859 "replicate-missing-region-channels",
2860 _("Replicate missing region channels"),
2861 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2862 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2867 add_option (_("Solo & mute"), new OptionEditorHeading (_("Solo")));
2869 _solo_control_is_listen_control = new BoolOption (
2870 "solo-control-is-listen-control",
2871 _("Solo controls are Listen controls"),
2872 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2873 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2876 add_option (_("Solo & mute"), _solo_control_is_listen_control);
2878 add_option (_("Solo & mute"),
2881 _("Exclusive solo"),
2882 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2883 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2886 add_option (_("Solo & mute"),
2889 _("Show solo muting"),
2890 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2891 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2894 add_option (_("Solo & mute"),
2896 "solo-mute-override",
2897 _("Soloing overrides muting"),
2898 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2899 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2902 add_option (_("Solo & mute"),
2905 _("Solo-in-place mute cut (dB)"),
2906 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2907 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2910 _listen_position = new ComboOption<ListenPosition> (
2912 _("Listen Position"),
2913 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2914 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2917 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2918 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2920 add_option (_("Solo & mute"), _listen_position);
2922 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2924 _("PFL signals come from"),
2925 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2926 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2929 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2930 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2932 add_option (_("Solo & mute"), pp);
2934 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2936 _("AFL signals come from"),
2937 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2938 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2941 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2942 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2944 add_option (_("Solo & mute"), pa);
2946 add_option (_("Solo & mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2948 add_option (_("Solo & mute"),
2950 "mute-affects-pre-fader",
2951 _("Mute affects pre-fader sends"),
2952 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2953 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2956 add_option (_("Solo & mute"),
2958 "mute-affects-post-fader",
2959 _("Mute affects post-fader sends"),
2960 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2961 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2964 add_option (_("Solo & mute"),
2966 "mute-affects-control-outs",
2967 _("Mute affects control outputs"),
2968 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2969 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2972 add_option (_("Solo & mute"),
2974 "mute-affects-main-outs",
2975 _("Mute affects main outputs"),
2976 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2977 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2981 if (!ARDOUR::Profile->get_mixbus()) {
2982 add_option (_("Solo & mute"), new OptionEditorHeading (_("Send Routing")));
2983 add_option (_("Solo & mute"),
2985 "link-send-and-route-panner",
2986 _("Link panners of Aux and External Sends with main panner by default"),
2987 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2988 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2992 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Preferences")));
2994 add_option (_("MIDI"),
2995 new SpinOption<float> (
2997 _("MIDI read-ahead time (seconds)"),
2998 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2999 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
3004 add_option (_("MIDI"),
3005 new SpinOption<int32_t> (
3006 "initial-program-change",
3007 _("Initial program change"),
3008 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
3009 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
3013 add_option (_("MIDI"),
3015 "display-first-midi-bank-as-zero",
3016 _("Display first MIDI bank/program as 0"),
3017 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
3018 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
3021 add_option (_("MIDI"),
3023 "never-display-periodic-midi",
3024 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
3025 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
3026 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
3029 add_option (_("MIDI"),
3032 _("Sound MIDI notes as they are selected in the editor"),
3033 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
3034 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
3037 add_option (_("MIDI"),
3040 _("Send MIDI control feedback"),
3041 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
3042 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
3045 add_option (_("MIDI/Ports"), new OptionEditorHeading (_("MIDI Port Options")));
3047 add_option (_("MIDI/Ports"),
3049 "get-midi-input-follows-selection",
3050 _("MIDI input follows MIDI track selection"),
3051 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
3052 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
3055 add_option (_("MIDI/Ports"), new MidiPortOptions ());
3057 add_option (_("MIDI/Sync"), new OptionEditorHeading (_("MIDI Clock")));
3059 add_option (_("MIDI/Sync"),
3062 _("Send MIDI Clock"),
3063 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
3064 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
3067 add_option (_("MIDI/Sync"), new OptionEditorHeading (_("MIDI Time Code (MTC)")));
3069 add_option (_("MIDI/Sync"),
3072 _("Send MIDI Time Code"),
3073 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
3074 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
3077 add_option (_("MIDI/Sync"),
3078 new SpinOption<int> (
3079 "mtc-qf-speed-tolerance",
3080 _("Percentage either side of normal transport speed to transmit MTC"),
3081 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
3082 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
3086 add_option (_("MIDI/Sync"), new OptionEditorHeading (_("Midi Machine Control (MMC)")));
3088 add_option (_("MIDI/Sync"),
3091 _("Obey MIDI Machine Control commands"),
3092 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
3093 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
3096 add_option (_("MIDI/Sync"),
3099 _("Send MIDI Machine Control commands"),
3100 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
3101 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
3104 add_option (_("MIDI/Sync"),
3105 new SpinOption<uint8_t> (
3106 "mmc-receive-device-id",
3107 _("Inbound MMC device ID"),
3108 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
3109 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
3113 add_option (_("MIDI/Sync"),
3114 new SpinOption<uint8_t> (
3115 "mmc-send-device-id",
3116 _("Outbound MMC device ID"),
3117 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
3118 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
3122 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
3124 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
3125 "midi-audition-synth-uri",
3126 _("Midi Audition Synth (LV2)"),
3127 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
3128 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
3131 audition_synth->add(X_(""), _("None"));
3132 PluginInfoList all_plugs;
3133 PluginManager& manager (PluginManager::instance());
3135 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
3137 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
3138 if (manager.get_status (*i) == PluginManager::Hidden) continue;
3139 if (!(*i)->is_instrument()) continue;
3140 if ((*i)->type != ARDOUR::LV2) continue;
3141 if ((*i)->name.length() > 46) {
3142 audition_synth->add((*i)->unique_id, (*i)->name.substr (0, 44) + "...");
3144 audition_synth->add((*i)->unique_id, (*i)->name);
3149 add_option (_("MIDI"), audition_synth);
3151 /* Control Surfaces */
3153 add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
3155 /* VIDEO Timeline */
3156 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
3158 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3159 add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
3160 add_option (_("Plugins"),
3161 new RcActionButton (_("Scan for Plugins"),
3162 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3166 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
3168 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3169 bo = new BoolOption (
3170 "show-plugin-scan-window",
3171 _("Always Display Plugin Scan Progress"),
3172 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
3173 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
3175 add_option (_("Plugins"), bo);
3176 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3177 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
3180 bo = new BoolOption (
3181 "plugins-stop-with-transport",
3182 _("Silence plugins when the transport is stopped"),
3183 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
3184 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
3186 add_option (_("Plugins"), bo);
3187 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3188 _("<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."));
3190 bo = new BoolOption (
3191 "new-plugins-active",
3192 _("Make new plugins active"),
3193 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
3194 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
3196 add_option (_("Plugins"), bo);
3197 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3198 _("<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"));
3200 #if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
3201 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
3202 add_option (_("Plugins/VST"),
3203 new RcActionButton (_("Scan for Plugins"),
3204 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3206 #if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
3207 bo = new BoolOption (
3209 _("Enable Mac VST support (requires restart or re-scan)"),
3210 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
3211 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
3213 add_option (_("Plugins/VST"), bo);
3216 bo = new BoolOption (
3217 "discover-vst-on-start",
3218 _("Scan for [new] VST Plugins on Application Start"),
3219 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
3220 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
3222 add_option (_("Plugins/VST"), bo);
3223 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3224 _("<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"));
3226 #ifdef WINDOWS_VST_SUPPORT
3227 // currently verbose logging is only implemented for Windows VST.
3228 bo = new BoolOption (
3229 "verbose-plugin-scan",
3230 _("Verbose Plugin Scan"),
3231 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
3232 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
3234 add_option (_("Plugins/VST"), bo);
3235 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3236 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
3239 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
3241 add_option (_("Plugins/VST"),
3242 new RcActionButton (_("Clear"),
3243 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
3246 add_option (_("Plugins/VST"),
3247 new RcActionButton (_("Clear"),
3248 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
3249 _("VST Blacklist:")));
3252 #ifdef LXVST_SUPPORT
3253 add_option (_("Plugins/VST"),
3254 new RcActionButton (_("Edit"),
3255 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
3256 _("Linux VST Path:")));
3258 add_option (_("Plugins/VST"),
3259 new RcConfigDisplay (
3260 "plugin-path-lxvst",
3262 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
3266 #ifdef WINDOWS_VST_SUPPORT
3267 add_option (_("Plugins/VST"),
3268 new RcActionButton (_("Edit"),
3269 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
3270 _("Windows VST Path:")));
3271 add_option (_("Plugins"),
3272 new RcConfigDisplay (
3275 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
3279 #ifdef AUDIOUNIT_SUPPORT
3281 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
3282 add_option (_("Plugins/Audio Unit"),
3283 new RcActionButton (_("Scan for Plugins"),
3284 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3286 bo = new BoolOption (
3287 "discover-audio-units",
3288 _("Scan for [new] AudioUnit Plugins on Application Start"),
3289 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
3290 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
3292 add_option (_("Plugins/Audio Unit"), bo);
3293 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3294 _("<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."));
3296 add_option (_("Plugins/Audio Unit"),
3297 new RcActionButton (_("Clear"),
3298 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
3301 add_option (_("Plugins/Audio Unit"),
3302 new RcActionButton (_("Clear"),
3303 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
3304 _("AU Blacklist:")));
3307 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
3308 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
3309 add_option (_("Plugins"),
3311 "open-gui-after-adding-plugin",
3312 _("Automatically open the plugin GUI when adding a new plugin"),
3313 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
3314 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3317 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3318 add_option (_("Plugins"),
3320 "show-inline-display-by-default",
3321 _("Show Plugin Inline Display on Mixerstrip by default"),
3322 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3323 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3326 _plugin_prefer_inline = new BoolOption (
3327 "prefer-inline-over-gui",
3328 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3329 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3330 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3332 add_option (_("Plugins"), _plugin_prefer_inline);
3335 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3337 bo = new BoolOption (
3338 "ask-replace-instrument",
3339 _("Ask to replace existing instrument plugin"),
3340 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3341 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3343 add_option (_("Plugins"), bo);
3345 bo = new BoolOption (
3346 "ask-setup_instrument",
3347 _("Interactively configure instrument plugins on insert"),
3348 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3349 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3351 add_option (_("Plugins"), bo);
3352 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3353 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3358 #if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
3359 add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Graphics Acceleration")));
3362 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3363 BoolOption* bgc = new BoolOption (
3364 "cairo-image-surface",
3365 _("Disable Graphics Hardware Acceleration (requires restart)"),
3366 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3367 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3370 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3371 _("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));
3372 add_option (S_("Preferences|GUI"), bgc);
3375 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3376 BoolOption* bgo = new BoolOption (
3378 _("Possibly improve slow graphical performance (requires restart)"),
3379 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3380 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3383 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));
3384 add_option (S_("Preferences|GUI"), bgo);
3387 add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Graphical User Interface")));
3388 add_option (S_("Preferences|GUI"),
3390 "use-wm-visibility",
3391 _("Use Window Manager/Desktop visibility information"),
3392 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3393 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3396 add_option (S_("Preferences|GUI"),
3399 _("Graphically indicate mouse pointer hovering over various widgets"),
3400 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3401 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3404 add_option (S_("Preferences|GUI"),
3407 _("Show tooltips if mouse hovers over a control"),
3408 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3409 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3412 add_option (S_("Preferences|GUI"),
3414 "show-name-highlight",
3415 _("Use name highlight bars in region displays (requires a restart)"),
3416 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3417 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3420 add_option (S_("Preferences|GUI"),
3422 "super-rapid-clock-update",
3423 _("Update transport clock display at FPS instead of every 100ms"),
3424 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3425 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3430 /* font scaling does nothing with GDK/Quartz */
3431 add_option (S_("Preferences|GUI"), new FontScalingOptions ());
3434 /* Image cache size */
3436 Gtk::Adjustment *ics = manage (new Gtk::Adjustment(0, 1, 1024, 10)); /* 1 MB to 1GB in steps of 10MB */
3437 HSliderOption *sics = new HSliderOption("waveform-cache-size",
3438 _("Waveform image cache size (megabytes)"),
3440 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
3441 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size)
3443 sics->scale().set_digits (0);
3444 Gtkmm2ext::UI::instance()->set_tip
3445 (sics->tip_widget(),
3446 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
3447 add_option (S_("Preferences|GUI"), sics);
3449 if (!ARDOUR::Profile->get_mixbus()) {
3450 /* Lock GUI timeout */
3452 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
3453 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
3454 _("Lock timeout (seconds)"),
3456 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
3457 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds)
3459 slts->scale().set_digits (0);
3460 Gtkmm2ext::UI::instance()->set_tip
3461 (slts->tip_widget(),
3462 _("Lock GUI after this many idle seconds (zero to never lock)"));
3463 add_option (S_("Preferences|GUI"), slts);
3466 /* The names of these controls must be the same as those given in MixerStrip
3467 for the actual widgets being controlled.
3469 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3470 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3471 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3472 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3473 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3474 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3475 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3478 S_("Preferences|GUI"),
3479 new VisibilityOption (
3481 &_mixer_strip_visibility,
3482 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3483 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3487 add_option (S_("Preferences|GUI"),
3489 "default-narrow_ms",
3490 _("Use narrow strips in the mixer by default"),
3491 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3492 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3496 OptionEditorHeading* i18n_head = new OptionEditorHeading (_("Internationalization"));
3497 i18n_head->set_note (string_compose (_("These settings will only take effect after %1 is restarted (if available for your language preferences)."), PROGRAM_NAME));
3499 add_option (_("GUI/Translation"), i18n_head);
3501 bo = new BoolOption (
3502 "enable-translation",
3503 _("Use translations"),
3504 sigc::ptr_fun (ARDOUR::translations_are_enabled),
3505 sigc::ptr_fun (ARDOUR::set_translations_enabled)
3508 add_option (_("GUI/Translation"), bo);
3510 _l10n = new ComboOption<ARDOUR::LocaleMode> (
3513 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_locale_mode),
3514 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_locale_mode)
3517 _l10n->add (ARDOUR::SET_LC_ALL, _("Set complete locale"));
3518 _l10n->add (ARDOUR::SET_LC_MESSAGES, _("Enable only message translation"));
3519 _l10n->add (ARDOUR::SET_LC_MESSAGES_AND_LC_NUMERIC, _("Translate messages and format numeric format"));
3520 _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."));
3522 add_option (_("GUI/Translation"), _l10n);
3523 parameter_changed ("enable-translation");
3524 #endif // ENABLE_NLS
3526 add_option (_("GUI/Keyboard"), new OptionEditorHeading (_("Keyboard")));
3527 add_option (_("GUI/Keyboard"), new KeyboardOptions);
3529 add_option (_("GUI/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items")));
3531 add_option (_("GUI/Toolbar"),
3533 "show-toolbar-selclock",
3534 _("Display Selection Clock in the Toolbar"),
3535 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
3536 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
3539 if (!ARDOUR::Profile->get_small_screen()) {
3540 add_option (_("GUI/Toolbar"),
3542 "show-secondary-clock",
3543 _("Display Secondary Clock in the Toolbar"),
3544 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
3545 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
3549 add_option (_("GUI/Toolbar"),
3551 "show-mini-timeline",
3552 _("Display Navigation Timeline in the Toolbar"),
3553 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
3554 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
3557 add_option (_("GUI/Toolbar"),
3559 "show-editor-meter",
3560 _("Display Master Level Meter in the Toolbar"),
3561 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
3562 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
3565 add_option (_("GUI/Toolbar"),
3566 new ColumVisibilityOption (
3567 "action-table-columns", _("Lua Action Script Button Visibility"), 4,
3568 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3569 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3573 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
3575 ComboOption<float>* mht = new ComboOption<float> (
3577 _("Peak hold time"),
3578 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
3579 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
3582 mht->add (MeterHoldOff, _("off"));
3583 mht->add (MeterHoldShort, _("short"));
3584 mht->add (MeterHoldMedium, _("medium"));
3585 mht->add (MeterHoldLong, _("long"));
3587 add_option (S_("Preferences|Metering"), mht);
3589 ComboOption<float>* mfo = new ComboOption<float> (
3592 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
3593 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
3596 mfo->add (METER_FALLOFF_OFF, _("off"));
3597 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
3598 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
3599 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
3600 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
3601 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
3602 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
3604 add_option (S_("Preferences|Metering"), mfo);
3606 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
3607 "meter-line-up-level",
3608 _("Meter line-up level; 0dBu"),
3609 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
3610 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
3613 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3614 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3615 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3616 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3618 Gtkmm2ext::UI::instance()->set_tip (mlu->tip_widget(), _("Configure meter-marks and color-knee point for dBFS scale DPM, set reference level for IEC1/Nordic, IEC2 PPM and VU meter."));
3620 add_option (S_("Preferences|Metering"), mlu);
3622 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
3623 "meter-line-up-din",
3624 _("IEC1/DIN Meter line-up level; 0dBu"),
3625 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
3626 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
3629 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3630 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3631 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3632 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3634 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
3636 add_option (S_("Preferences|Metering"), mld);
3638 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
3639 "meter-vu-standard",
3640 _("VU Meter standard"),
3641 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
3642 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
3645 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
3646 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
3647 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
3648 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
3650 add_option (S_("Preferences|Metering"), mvu);
3652 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
3653 HSliderOption *mpks = new HSliderOption("meter-peak",
3654 _("Peak threshold [dBFS]"),
3656 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
3657 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak)
3661 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3662 "meter-type-master",
3663 _("Default Meter Type for Master Bus"),
3664 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3665 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3667 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3668 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3669 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3670 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3671 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3672 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3673 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3674 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3676 add_option (S_("Preferences|Metering"), mtm);
3679 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3681 _("Default Meter Type for Busses"),
3682 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3683 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3685 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3686 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3687 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3688 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3689 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3690 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3691 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3692 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3694 add_option (S_("Preferences|Metering"), mtb);
3696 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3698 _("Default Meter Type for Tracks"),
3699 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3700 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3702 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3703 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3705 add_option (S_("Preferences|Metering"), mtt);
3708 Gtkmm2ext::UI::instance()->set_tip
3709 (mpks->tip_widget(),
3710 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
3712 add_option (S_("Preferences|Metering"), mpks);
3714 add_option (S_("Preferences|Metering"),
3717 _("LED meter style"),
3718 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3719 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3722 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Editor Meters")));
3724 add_option (S_("Preferences|Metering"),
3726 "show-track-meters",
3727 _("Show meters on tracks in the editor"),
3728 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3729 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3732 add_option (S_("Preferences|Metering"),
3734 "editor-stereo-only-meters",
3735 _("Show at most stereo meters in the track-header"),
3736 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3737 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3740 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
3742 add_option (S_("Preferences|Metering"),
3744 "save-export-analysis-image",
3745 _("Save loudness analysis as image file"),
3746 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
3747 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
3750 /* and now the theme manager */
3752 ThemeManager* tm = manage (new ThemeManager);
3753 add_option (_("Theme"), new OptionEditorHeading (_("Theme")));
3754 add_page (_("Theme"), *tm);
3756 add_option (_("Theme/Colors"), new ColorThemeManager);
3758 Widget::show_all ();
3760 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3761 parameter_changed ("send-ltc");
3762 parameter_changed ("sync-source");
3763 parameter_changed ("use-monitor-bus");
3764 parameter_changed ("open-gui-after-adding-plugin");
3766 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
3768 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
3769 (Gtk::StateType) here !!!
3771 Tabbable::set_state (*node, Stateful::loading_state_version);
3776 RCOptionEditor::parameter_changed (string const & p)
3778 OptionEditor::parameter_changed (p);
3780 if (p == "use-monitor-bus") {
3781 bool const s = Config->get_use_monitor_bus ();
3783 /* we can't use this if we don't have a monitor bus */
3784 Config->set_solo_control_is_listen_control (false);
3786 _solo_control_is_listen_control->set_sensitive (s);
3787 _listen_position->set_sensitive (s);
3788 } else if (p == "sync-source") {
3789 _sync_source->set_sensitive (true);
3791 _sync_source->set_sensitive (!_session->config.get_external_sync());
3793 switch(Config->get_sync_source()) {
3796 _sync_genlock->set_sensitive (true);
3797 _sync_framerate->set_sensitive (true);
3798 _sync_source_2997->set_sensitive (true);
3801 _sync_genlock->set_sensitive (false);
3802 _sync_framerate->set_sensitive (false);
3803 _sync_source_2997->set_sensitive (false);
3806 } else if (p == "send-ltc") {
3807 bool const s = Config->get_send_ltc ();
3808 _ltc_send_continuously->set_sensitive (s);
3809 _ltc_volume_slider->set_sensitive (s);
3810 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
3811 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3812 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
3815 } else if (p == "enable-translation") {
3816 _l10n->set_sensitive (ARDOUR::translations_are_enabled ());
3821 void RCOptionEditor::ltc_generator_volume_changed () {
3822 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
3825 void RCOptionEditor::plugin_scan_refresh () {
3826 PluginManager::instance().refresh();
3829 void RCOptionEditor::clear_vst_cache () {
3830 PluginManager::instance().clear_vst_cache();
3833 void RCOptionEditor::clear_vst_blacklist () {
3834 PluginManager::instance().clear_vst_blacklist();
3837 void RCOptionEditor::clear_au_cache () {
3838 PluginManager::instance().clear_au_cache();
3841 void RCOptionEditor::clear_au_blacklist () {
3842 PluginManager::instance().clear_au_blacklist();
3845 void RCOptionEditor::edit_lxvst_path () {
3846 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
3847 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3848 *current_toplevel(), _("Set Linux VST Search Path"),
3849 _rc_config->get_plugin_path_lxvst(),
3850 PluginManager::instance().get_default_lxvst_path()
3852 ResponseType r = (ResponseType) pd->run ();
3854 if (r == RESPONSE_ACCEPT) {
3855 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
3860 void RCOptionEditor::edit_vst_path () {
3861 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3862 *current_toplevel(), _("Set Windows VST Search Path"),
3863 _rc_config->get_plugin_path_vst(),
3864 PluginManager::instance().get_default_windows_vst_path()
3866 ResponseType r = (ResponseType) pd->run ();
3868 if (r == RESPONSE_ACCEPT) {
3869 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
3876 RCOptionEditor::populate_sync_options ()
3878 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3880 _sync_source->clear ();
3882 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3883 _sync_source->add (*i, sync_source_to_string (*i));
3886 if (sync_opts.empty()) {
3887 _sync_source->set_sensitive(false);
3889 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3890 _rc_config->set_sync_source(sync_opts.front());
3894 parameter_changed ("sync-source");
3898 RCOptionEditor::use_own_window (bool and_fill_it)
3900 bool new_window = !own_window ();
3902 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
3904 if (win && new_window) {
3905 win->set_name ("PreferencesWindow");
3906 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
3913 RCOptionEditor::get_state ()
3915 XMLNode* node = new XMLNode (X_("Preferences"));
3916 node->add_child_nocopy (Tabbable::get_state());