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 OptionEditorBox
83 ClickOptions (RCConfiguration* c)
85 , _click_browse_button (_("Browse..."))
86 , _click_emphasis_browse_button (_("Browse..."))
88 Table* t = manage (new Table (4, 3));
91 Label* l = manage (left_aligned_label (_("Emphasis on first beat:")));
92 t->attach (*l, 0, 1, 1, 2, FILL);
93 t->attach (_use_emphasis_on_click_check_button, 1, 2, 1, 2, FILL);
94 _use_emphasis_on_click_check_button.signal_toggled().connect (
95 sigc::mem_fun (*this, &ClickOptions::use_emphasis_on_click_toggled));
97 l = manage (left_aligned_label (_("Use default Click:")));
98 t->attach (*l, 0, 1, 0, 1, FILL);
99 t->attach (_use_default_click_check_button, 1, 2, 0, 1, FILL);
100 _use_default_click_check_button.signal_toggled().connect (
101 sigc::mem_fun (*this, &ClickOptions::use_default_click_toggled));
103 l = manage (left_aligned_label (_("Click audio file:")));
104 t->attach (*l, 0, 1, 2, 3, FILL);
105 t->attach (_click_path_entry, 1, 2, 2, 3, FILL);
106 _click_browse_button.signal_clicked ().connect (
107 sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
108 t->attach (_click_browse_button, 2, 3, 2, 3, FILL);
110 l = manage (left_aligned_label (_("Click emphasis audio file:")));
111 t->attach (*l, 0, 1, 3, 4, FILL);
112 t->attach (_click_emphasis_path_entry, 1, 2, 3, 4, FILL);
113 _click_emphasis_browse_button.signal_clicked ().connect (
114 sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
115 t->attach (_click_emphasis_browse_button, 2, 3, 3, 4, FILL);
117 _box->pack_start (*t, true, false);
119 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
120 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
122 if (_rc_config->get_click_sound ().empty() &&
123 _rc_config->get_click_emphasis_sound().empty()) {
124 _use_default_click_check_button.set_active (true);
125 _use_emphasis_on_click_check_button.set_active (true);
128 _use_default_click_check_button.set_active (false);
129 _use_emphasis_on_click_check_button.set_active (false);
133 void parameter_changed (string const & p)
135 if (p == "click-sound") {
136 _click_path_entry.set_text (_rc_config->get_click_sound());
137 } else if (p == "click-emphasis-sound") {
138 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
139 } else if (p == "use-click-emphasis") {
140 bool x = _rc_config->get_use_click_emphasis ();
141 _use_emphasis_on_click_check_button.set_active (x);
145 void set_state_from_config ()
147 parameter_changed ("click-sound");
148 parameter_changed ("click-emphasis-sound");
149 parameter_changed ("use-click-emphasis");
154 void click_browse_clicked ()
156 SoundFileChooser sfdb (_("Choose Click"));
161 if (sfdb.run () == RESPONSE_OK) {
162 click_chosen (sfdb.get_filename());
166 void click_chosen (string const & path)
168 _click_path_entry.set_text (path);
169 _rc_config->set_click_sound (path);
172 void click_changed ()
174 click_chosen (_click_path_entry.get_text ());
177 void click_emphasis_browse_clicked ()
179 SoundFileChooser sfdb (_("Choose Click Emphasis"));
184 if (sfdb.run () == RESPONSE_OK) {
185 click_emphasis_chosen (sfdb.get_filename());
189 void click_emphasis_chosen (string const & path)
191 _click_emphasis_path_entry.set_text (path);
192 _rc_config->set_click_emphasis_sound (path);
195 void click_emphasis_changed ()
197 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
200 void use_default_click_toggled ()
202 if (_use_default_click_check_button.get_active ()) {
203 _rc_config->set_click_sound ("");
204 _rc_config->set_click_emphasis_sound ("");
205 _click_path_entry.set_sensitive (false);
206 _click_emphasis_path_entry.set_sensitive (false);
207 _click_browse_button.set_sensitive (false);
208 _click_emphasis_browse_button.set_sensitive (false);
210 _click_path_entry.set_sensitive (true);
211 _click_emphasis_path_entry.set_sensitive (true);
212 _click_browse_button.set_sensitive (true);
213 _click_emphasis_browse_button.set_sensitive (true);
217 void use_emphasis_on_click_toggled ()
219 if (_use_emphasis_on_click_check_button.get_active ()) {
220 _rc_config->set_use_click_emphasis(true);
222 _rc_config->set_use_click_emphasis(false);
226 RCConfiguration* _rc_config;
227 CheckButton _use_default_click_check_button;
228 CheckButton _use_emphasis_on_click_check_button;
229 Entry _click_path_entry;
230 Entry _click_emphasis_path_entry;
231 Button _click_browse_button;
232 Button _click_emphasis_browse_button;
235 class UndoOptions : public OptionEditorBox
238 UndoOptions (RCConfiguration* c) :
240 _limit_undo_button (_("Limit undo history to")),
241 _save_undo_button (_("Save undo history of"))
243 Table* t = new Table (2, 3);
246 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
247 _limit_undo_spin.set_range (0, 512);
248 _limit_undo_spin.set_increments (1, 10);
249 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
250 Label* l = manage (left_aligned_label (_("commands")));
251 t->attach (*l, 2, 3, 0, 1);
253 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
254 _save_undo_spin.set_range (0, 512);
255 _save_undo_spin.set_increments (1, 10);
256 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
257 l = manage (left_aligned_label (_("commands")));
258 t->attach (*l, 2, 3, 1, 2);
260 _box->pack_start (*t);
262 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
263 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
264 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
265 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
268 void parameter_changed (string const & p)
270 if (p == "history-depth") {
271 int32_t const d = _rc_config->get_history_depth();
272 _limit_undo_button.set_active (d != 0);
273 _limit_undo_spin.set_sensitive (d != 0);
274 _limit_undo_spin.set_value (d);
275 } else if (p == "save-history") {
276 bool const x = _rc_config->get_save_history ();
277 _save_undo_button.set_active (x);
278 _save_undo_spin.set_sensitive (x);
279 } else if (p == "save-history-depth") {
280 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
284 void set_state_from_config ()
286 parameter_changed ("save-history");
287 parameter_changed ("history-depth");
288 parameter_changed ("save-history-depth");
291 void limit_undo_toggled ()
293 bool const x = _limit_undo_button.get_active ();
294 _limit_undo_spin.set_sensitive (x);
295 int32_t const n = x ? 16 : 0;
296 _limit_undo_spin.set_value (n);
297 _rc_config->set_history_depth (n);
300 void limit_undo_changed ()
302 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
305 void save_undo_toggled ()
307 bool const x = _save_undo_button.get_active ();
308 _rc_config->set_save_history (x);
311 void save_undo_changed ()
313 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
317 RCConfiguration* _rc_config;
318 CheckButton _limit_undo_button;
319 SpinButton _limit_undo_spin;
320 CheckButton _save_undo_button;
321 SpinButton _save_undo_spin;
326 static const struct {
338 { "Key|Shift", GDK_SHIFT_MASK },
339 { "Command", GDK_MOD2_MASK },
340 { "Control", GDK_CONTROL_MASK },
341 { "Option", GDK_MOD1_MASK },
342 { "Command-Shift", GDK_MOD2_MASK|GDK_SHIFT_MASK },
343 { "Command-Option", GDK_MOD2_MASK|GDK_MOD1_MASK },
344 { "Command-Control", GDK_MOD2_MASK|GDK_CONTROL_MASK },
345 { "Command-Option-Control", GDK_MOD2_MASK|GDK_MOD1_MASK|GDK_CONTROL_MASK },
346 { "Option-Control", GDK_MOD1_MASK|GDK_CONTROL_MASK },
347 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
348 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
349 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_MOD2_MASK },
352 { "Key|Shift", GDK_SHIFT_MASK },
353 { "Control", GDK_CONTROL_MASK },
354 { "Alt", GDK_MOD1_MASK },
355 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
356 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
357 { "Control-Windows", GDK_CONTROL_MASK|GDK_MOD4_MASK },
358 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
359 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
360 { "Alt-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
361 { "Alt-Shift-Windows", GDK_MOD1_MASK|GDK_SHIFT_MASK|GDK_MOD4_MASK },
362 { "Mod2", GDK_MOD2_MASK },
363 { "Mod3", GDK_MOD3_MASK },
364 { "Windows", GDK_MOD4_MASK },
365 { "Mod5", GDK_MOD5_MASK },
371 class KeyboardOptions : public OptionEditorBox
375 _delete_button_adjustment (3, 1, 12),
376 _delete_button_spin (_delete_button_adjustment),
377 _edit_button_adjustment (3, 1, 5),
378 _edit_button_spin (_edit_button_adjustment),
379 _insert_note_button_adjustment (3, 1, 5),
380 _insert_note_button_spin (_insert_note_button_adjustment)
382 const std::string restart_msg = _("\nChanges to this setting will only persist after your project has been saved.");
383 /* internationalize and prepare for use with combos */
386 for (int i = 0; modifiers[i].name; ++i) {
387 dumb.push_back (S_(modifiers[i].name));
390 set_popdown_strings (_edit_modifier_combo, dumb);
391 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
392 Gtkmm2ext::UI::instance()->set_tip (_edit_modifier_combo,
393 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
394 for (int x = 0; modifiers[x].name; ++x) {
395 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
396 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
401 Table* t = manage (new Table (5, 11));
407 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
408 l->set_name ("OptionsLabel");
412 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
413 strs.push_back (bf->first);
416 set_popdown_strings (_keyboard_layout_selector, strs);
417 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
418 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
420 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
421 t->attach (_keyboard_layout_selector, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
426 l = manage (left_aligned_label (_("When Clicking:")));
427 l->set_name ("OptionEditorHeading");
428 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
433 l = manage (left_aligned_label (_("Edit using:")));
434 l->set_name ("OptionsLabel");
436 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
437 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
439 l = manage (new Label (_("+ button")));
440 l->set_name ("OptionsLabel");
442 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
443 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
445 _edit_button_spin.set_name ("OptionsEntry");
446 _edit_button_adjustment.set_value (Keyboard::edit_button());
447 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
452 set_popdown_strings (_delete_modifier_combo, dumb);
453 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
454 Gtkmm2ext::UI::instance()->set_tip (_delete_modifier_combo,
455 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
456 for (int x = 0; modifiers[x].name; ++x) {
457 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
458 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
463 l = manage (left_aligned_label (_("Delete using:")));
464 l->set_name ("OptionsLabel");
466 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
467 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
469 l = manage (new Label (_("+ button")));
470 l->set_name ("OptionsLabel");
472 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
473 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
475 _delete_button_spin.set_name ("OptionsEntry");
476 _delete_button_adjustment.set_value (Keyboard::delete_button());
477 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
482 set_popdown_strings (_insert_note_modifier_combo, dumb);
483 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
484 Gtkmm2ext::UI::instance()->set_tip (_insert_note_modifier_combo,
485 (string_compose (_("<b>Recommended Setting: %1 + button 1 (left mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
486 for (int x = 0; modifiers[x].name; ++x) {
487 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
488 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
493 l = manage (left_aligned_label (_("Insert note using:")));
494 l->set_name ("OptionsLabel");
496 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
497 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
499 l = manage (new Label (_("+ button")));
500 l->set_name ("OptionsLabel");
502 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
503 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
505 _insert_note_button_spin.set_name ("OptionsEntry");
506 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
507 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
511 l = manage (left_aligned_label (_("When Beginning a Drag:")));
512 l->set_name ("OptionEditorHeading");
513 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
519 set_popdown_strings (_copy_modifier_combo, dumb);
520 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
521 Gtkmm2ext::UI::instance()->set_tip (_copy_modifier_combo,
522 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
524 Keyboard::secondary_modifier_name (),
526 Keyboard::primary_modifier_name (),
529 for (int x = 0; modifiers[x].name; ++x) {
530 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
531 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
536 l = manage (left_aligned_label (_("Copy items using:")));
537 l->set_name ("OptionsLabel");
539 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
540 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
545 /* constraint modifier */
546 set_popdown_strings (_constraint_modifier_combo, dumb);
547 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
548 std::string mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
549 Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo,
550 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
552 Keyboard::primary_modifier_name (),
554 Keyboard::tertiary_modifier_name (),
557 for (int x = 0; modifiers[x].name; ++x) {
558 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
559 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
564 l = manage (left_aligned_label (_("Constrain drag using:")));
565 l->set_name ("OptionsLabel");
567 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
568 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
574 set_popdown_strings (_push_points_combo, dumb);
575 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
577 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
578 Gtkmm2ext::UI::instance()->set_tip (_push_points_combo,
579 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
580 for (int x = 0; modifiers[x].name; ++x) {
581 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
582 _push_points_combo.set_active_text (S_(modifiers[x].name));
587 l = manage (left_aligned_label (_("Push points using:")));
588 l->set_name ("OptionsLabel");
590 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
591 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
595 l = manage (left_aligned_label (_("When Beginning a Trim:")));
596 l->set_name ("OptionEditorHeading");
597 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
603 set_popdown_strings (_trim_contents_combo, dumb);
604 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
605 Gtkmm2ext::UI::instance()->set_tip (_trim_contents_combo,
606 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
607 for (int x = 0; modifiers[x].name; ++x) {
608 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
609 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
614 l = manage (left_aligned_label (_("Trim contents using:")));
615 l->set_name ("OptionsLabel");
617 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
618 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
624 set_popdown_strings (_trim_anchored_combo, dumb);
625 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
627 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::tertiary_modifier_name ());
628 Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo,
629 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
630 for (int x = 0; modifiers[x].name; ++x) {
631 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
632 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
637 l = manage (left_aligned_label (_("Anchored trim using:")));
638 l->set_name ("OptionsLabel");
640 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
642 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
647 /* jump trim disabled for now
648 set_popdown_strings (_trim_jump_combo, dumb);
649 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
651 for (int x = 0; modifiers[x].name; ++x) {
652 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
653 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
658 l = manage (left_aligned_label (_("Jump after trim using:")));
659 l->set_name ("OptionsLabel");
661 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
663 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
669 /* note resize relative */
670 set_popdown_strings (_note_size_relative_combo, dumb);
671 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
672 Gtkmm2ext::UI::instance()->set_tip (_note_size_relative_combo,
673 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
674 for (int x = 0; modifiers[x].name; ++x) {
675 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
676 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
681 l = manage (left_aligned_label (_("Resize notes relatively using:")));
682 l->set_name ("OptionsLabel");
684 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
686 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
690 l = manage (left_aligned_label (_("While Dragging:")));
691 l->set_name ("OptionEditorHeading");
692 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
698 set_popdown_strings (_snap_modifier_combo, dumb);
699 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
701 mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ());
703 mod_str = Keyboard::secondary_modifier_name();
705 Gtkmm2ext::UI::instance()->set_tip (_snap_modifier_combo,
706 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
707 for (int x = 0; modifiers[x].name; ++x) {
708 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
709 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
714 l = manage (left_aligned_label (_("Ignore snap using:")));
715 l->set_name ("OptionsLabel");
717 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
718 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
724 set_popdown_strings (_snap_delta_combo, dumb);
725 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
727 mod_str = Keyboard::level4_modifier_name ();
729 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::level4_modifier_name ());
731 Gtkmm2ext::UI::instance()->set_tip (_snap_delta_combo,
732 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
733 for (int x = 0; modifiers[x].name; ++x) {
734 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
735 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
740 l = manage (left_aligned_label (_("Snap relatively using:")));
741 l->set_name ("OptionsLabel");
743 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
744 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
748 l = manage (left_aligned_label (_("While Trimming:")));
749 l->set_name ("OptionEditorHeading");
750 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
756 set_popdown_strings (_trim_overlap_combo, dumb);
757 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
759 Gtkmm2ext::UI::instance()->set_tip (_trim_overlap_combo,
760 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
761 for (int x = 0; modifiers[x].name; ++x) {
762 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
763 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
768 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
769 l->set_name ("OptionsLabel");
771 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
772 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
776 l = manage (left_aligned_label (_("While Dragging Control Points:")));
777 l->set_name ("OptionEditorHeading");
778 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
784 set_popdown_strings (_fine_adjust_combo, dumb);
785 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
787 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::secondary_modifier_name ());
788 Gtkmm2ext::UI::instance()->set_tip (_fine_adjust_combo,
789 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
790 for (int x = 0; modifiers[x].name; ++x) {
791 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
792 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
797 l = manage (left_aligned_label (_("Fine adjust using:")));
798 l->set_name ("OptionsLabel");
800 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
801 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
803 _box->pack_start (*t, false, false);
806 void parameter_changed (string const &)
808 /* XXX: these aren't really config options... */
811 void set_state_from_config ()
813 /* XXX: these aren't really config options... */
818 void bindings_changed ()
820 string const txt = _keyboard_layout_selector.get_active_text();
822 /* XXX: config...? for all this keyboard stuff */
824 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
825 if (txt == i->first) {
826 if (Keyboard::load_keybindings (i->second)) {
827 Keyboard::save_keybindings ();
833 void edit_modifier_chosen ()
835 string const txt = _edit_modifier_combo.get_active_text();
837 for (int i = 0; modifiers[i].name; ++i) {
838 if (txt == S_(modifiers[i].name)) {
839 Keyboard::set_edit_modifier (modifiers[i].modifier);
845 void delete_modifier_chosen ()
847 string const txt = _delete_modifier_combo.get_active_text();
849 for (int i = 0; modifiers[i].name; ++i) {
850 if (txt == S_(modifiers[i].name)) {
851 Keyboard::set_delete_modifier (modifiers[i].modifier);
857 void copy_modifier_chosen ()
859 string const txt = _copy_modifier_combo.get_active_text();
861 for (int i = 0; modifiers[i].name; ++i) {
862 if (txt == S_(modifiers[i].name)) {
863 Keyboard::set_copy_modifier (modifiers[i].modifier);
869 void insert_note_modifier_chosen ()
871 string const txt = _insert_note_modifier_combo.get_active_text();
873 for (int i = 0; modifiers[i].name; ++i) {
874 if (txt == S_(modifiers[i].name)) {
875 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
881 void snap_modifier_chosen ()
883 string const txt = _snap_modifier_combo.get_active_text();
885 for (int i = 0; modifiers[i].name; ++i) {
886 if (txt == S_(modifiers[i].name)) {
887 Keyboard::set_snap_modifier (modifiers[i].modifier);
893 void snap_delta_modifier_chosen ()
895 string const txt = _snap_delta_combo.get_active_text();
897 for (int i = 0; modifiers[i].name; ++i) {
898 if (txt == S_(modifiers[i].name)) {
899 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
905 void constraint_modifier_chosen ()
907 string const txt = _constraint_modifier_combo.get_active_text();
909 for (int i = 0; modifiers[i].name; ++i) {
910 if (txt == S_(modifiers[i].name)) {
911 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
917 void trim_contents_modifier_chosen ()
919 string const txt = _trim_contents_combo.get_active_text();
921 for (int i = 0; modifiers[i].name; ++i) {
922 if (txt == S_(modifiers[i].name)) {
923 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
929 void trim_overlap_modifier_chosen ()
931 string const txt = _trim_overlap_combo.get_active_text();
933 for (int i = 0; modifiers[i].name; ++i) {
934 if (txt == S_(modifiers[i].name)) {
935 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
941 void trim_anchored_modifier_chosen ()
943 string const txt = _trim_anchored_combo.get_active_text();
945 for (int i = 0; modifiers[i].name; ++i) {
946 if (txt == S_(modifiers[i].name)) {
947 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
953 void fine_adjust_modifier_chosen ()
955 string const txt = _fine_adjust_combo.get_active_text();
957 for (int i = 0; modifiers[i].name; ++i) {
958 if (txt == S_(modifiers[i].name)) {
959 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
965 void push_points_modifier_chosen ()
967 string const txt = _push_points_combo.get_active_text();
969 for (int i = 0; modifiers[i].name; ++i) {
970 if (txt == S_(modifiers[i].name)) {
971 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
977 void note_size_relative_modifier_chosen ()
979 string const txt = _note_size_relative_combo.get_active_text();
981 for (int i = 0; modifiers[i].name; ++i) {
982 if (txt == S_(modifiers[i].name)) {
983 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
989 void delete_button_changed ()
991 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
994 void edit_button_changed ()
996 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
999 void insert_note_button_changed ()
1001 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
1004 ComboBoxText _keyboard_layout_selector;
1005 ComboBoxText _edit_modifier_combo;
1006 ComboBoxText _delete_modifier_combo;
1007 ComboBoxText _copy_modifier_combo;
1008 ComboBoxText _insert_note_modifier_combo;
1009 ComboBoxText _snap_modifier_combo;
1010 ComboBoxText _snap_delta_combo;
1011 ComboBoxText _constraint_modifier_combo;
1012 ComboBoxText _trim_contents_combo;
1013 ComboBoxText _trim_overlap_combo;
1014 ComboBoxText _trim_anchored_combo;
1015 ComboBoxText _trim_jump_combo;
1016 ComboBoxText _fine_adjust_combo;
1017 ComboBoxText _push_points_combo;
1018 ComboBoxText _note_size_relative_combo;
1019 Adjustment _delete_button_adjustment;
1020 SpinButton _delete_button_spin;
1021 Adjustment _edit_button_adjustment;
1022 SpinButton _edit_button_spin;
1023 Adjustment _insert_note_button_adjustment;
1024 SpinButton _insert_note_button_spin;
1028 class FontScalingOptions : public OptionEditorBox
1031 FontScalingOptions () :
1032 _dpi_adjustment (100, 50, 250, 1, 5),
1033 _dpi_slider (_dpi_adjustment)
1035 _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.);
1037 Label* l = manage (new Label (_("GUI and Font scaling:")));
1038 l->set_name ("OptionsLabel");
1040 const std::string dflt = _("Default");
1041 const std::string empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
1043 _dpi_slider.set_name("FontScaleSlider");
1044 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1045 _dpi_slider.set_draw_value(false);
1046 _dpi_slider.add_mark(50, Gtk::POS_TOP, empty);
1047 _dpi_slider.add_mark(60, Gtk::POS_TOP, empty);
1048 _dpi_slider.add_mark(70, Gtk::POS_TOP, empty);
1049 _dpi_slider.add_mark(80, Gtk::POS_TOP, empty);
1050 _dpi_slider.add_mark(90, Gtk::POS_TOP, empty);
1051 _dpi_slider.add_mark(100, Gtk::POS_TOP, dflt);
1052 _dpi_slider.add_mark(125, Gtk::POS_TOP, empty);
1053 _dpi_slider.add_mark(150, Gtk::POS_TOP, empty);
1054 _dpi_slider.add_mark(175, Gtk::POS_TOP, empty);
1055 _dpi_slider.add_mark(200, Gtk::POS_TOP, empty);
1056 _dpi_slider.add_mark(225, Gtk::POS_TOP, empty);
1057 _dpi_slider.add_mark(250, Gtk::POS_TOP, empty);
1059 HBox* h = manage (new HBox);
1061 h->pack_start (*l, false, false);
1062 h->pack_start (_dpi_slider, true, true);
1064 _box->pack_start (*h, false, false);
1066 set_note (_("Adjusting the scale requires an application restart to re-layout."));
1068 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
1071 void parameter_changed (string const & p)
1073 if (p == "font-scale") {
1074 _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.);
1078 void set_state_from_config ()
1080 parameter_changed ("font-scale");
1087 UIConfiguration::instance().set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024.));
1088 /* XXX: should be triggered from the parameter changed signal */
1089 UIConfiguration::instance().reset_dpi ();
1092 Adjustment _dpi_adjustment;
1096 class VstTimeOutSliderOption : public OptionEditorBox
1099 VstTimeOutSliderOption (RCConfiguration* c)
1101 , _timeout_adjustment (0, 0, 3000, 50, 50)
1102 , _timeout_slider (_timeout_adjustment)
1104 _timeout_slider.set_digits (0);
1105 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &VstTimeOutSliderOption::timeout_changed));
1107 _timeout_slider.set_draw_value(false);
1108 _timeout_slider.add_mark( 0, Gtk::POS_TOP, _("\u221e")); // infinity
1109 _timeout_slider.add_mark( 300, Gtk::POS_TOP, _("30 sec"));
1110 _timeout_slider.add_mark( 600, Gtk::POS_TOP, _("1 min"));
1111 _timeout_slider.add_mark(1200, Gtk::POS_TOP, _("2 mins"));
1112 _timeout_slider.add_mark(1800, Gtk::POS_TOP, _("3 mins"));
1113 _timeout_slider.add_mark(2400, Gtk::POS_TOP, _("4 mins"));
1114 _timeout_slider.add_mark(3000, Gtk::POS_TOP, _("5 mins"));
1116 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1117 _("Specify the default timeout for plugin instantiation. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1119 Label* l = manage (left_aligned_label (_("Scan Time Out:")));
1120 HBox* h = manage (new HBox);
1122 h->pack_start (*l, false, false);
1123 h->pack_start (_timeout_slider, true, true);
1125 _box->pack_start (*h, false, false);
1128 void parameter_changed (string const & p)
1130 if (p == "vst-scan-timeout") {
1131 int const x = _rc_config->get_vst_scan_timeout();
1132 _timeout_adjustment.set_value (x);
1136 void set_state_from_config ()
1138 parameter_changed ("vst-scan-timeout");
1143 void timeout_changed ()
1145 int x = floor(_timeout_adjustment.get_value());
1146 _rc_config->set_vst_scan_timeout(x);
1149 RCConfiguration* _rc_config;
1150 Adjustment _timeout_adjustment;
1151 HScale _timeout_slider;
1158 class ClipLevelOptions : public OptionEditorBox
1162 : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1163 , _clip_level_slider (_clip_level_adjustment)
1165 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ());
1167 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
1168 l->set_name ("OptionsLabel");
1170 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1171 HBox* h = manage (new HBox);
1173 h->pack_start (*l, false, false);
1174 h->pack_start (_clip_level_slider, true, true);
1176 _box->pack_start (*h, false, false);
1178 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1181 void parameter_changed (string const & p)
1183 if (p == "waveform-clip-level") {
1184 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level());
1188 void set_state_from_config ()
1190 parameter_changed ("waveform-clip-level");
1195 void clip_level_changed ()
1197 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1198 /* XXX: should be triggered from the parameter changed signal */
1199 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1202 Adjustment _clip_level_adjustment;
1203 HScale _clip_level_slider;
1206 class BufferingOptions : public OptionEditorBox
1209 BufferingOptions (RCConfiguration* c)
1211 , _playback_adjustment (5, 1, 60, 1, 4)
1212 , _capture_adjustment (5, 1, 60, 1, 4)
1213 , _playback_slider (_playback_adjustment)
1214 , _capture_slider (_capture_adjustment)
1216 vector<string> presets;
1218 /* these must match the order of the enums for BufferingPreset */
1220 presets.push_back (_("Small sessions (4-16 tracks)"));
1221 presets.push_back (_("Medium sessions (16-64 tracks)"));
1222 presets.push_back (_("Large sessions (64+ tracks)"));
1223 presets.push_back (_("Custom (set by sliders below)"));
1225 set_popdown_strings (_buffering_presets_combo, presets);
1227 Label* l = manage (new Label (_("Preset:")));
1228 l->set_name ("OptionsLabel");
1229 HBox* h = manage (new HBox);
1230 h->set_spacing (12);
1231 h->pack_start (*l, false, false);
1232 h->pack_start (_buffering_presets_combo, true, true);
1233 _box->pack_start (*h, false, false);
1235 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1237 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1239 l = manage (new Label (_("Playback (seconds of buffering):")));
1240 l->set_name ("OptionsLabel");
1242 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1243 h = manage (new HBox);
1245 h->pack_start (*l, false, false);
1246 h->pack_start (_playback_slider, true, true);
1248 _box->pack_start (*h, false, false);
1250 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1252 l = manage (new Label (_("Recording (seconds of buffering):")));
1253 l->set_name ("OptionsLabel");
1255 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1256 h = manage (new HBox);
1258 h->pack_start (*l, false, false);
1259 h->pack_start (_capture_slider, true, true);
1261 _box->pack_start (*h, false, false);
1263 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
1264 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
1267 void parameter_changed (string const & p)
1269 if (p == "buffering-preset") {
1270 switch (_rc_config->get_buffering_preset()) {
1272 _playback_slider.set_sensitive (false);
1273 _capture_slider.set_sensitive (false);
1274 _buffering_presets_combo.set_active (0);
1277 _playback_slider.set_sensitive (false);
1278 _capture_slider.set_sensitive (false);
1279 _buffering_presets_combo.set_active (1);
1282 _playback_slider.set_sensitive (false);
1283 _capture_slider.set_sensitive (false);
1284 _buffering_presets_combo.set_active (2);
1287 _playback_slider.set_sensitive (true);
1288 _capture_slider.set_sensitive (true);
1289 _buffering_presets_combo.set_active (3);
1294 if (p == "playback-buffer-seconds") {
1295 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1296 } else if (p == "capture-buffer-seconds") {
1297 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1301 void set_state_from_config ()
1303 parameter_changed ("buffering-preset");
1304 parameter_changed ("playback-buffer-seconds");
1305 parameter_changed ("capture-buffer-seconds");
1310 void preset_changed ()
1312 int index = _buffering_presets_combo.get_active_row_number ();
1318 _rc_config->set_buffering_preset (Small);
1321 _rc_config->set_buffering_preset (Medium);
1324 _rc_config->set_buffering_preset (Large);
1327 _rc_config->set_buffering_preset (Custom);
1330 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1335 void playback_changed ()
1337 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
1340 void capture_changed ()
1342 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
1345 RCConfiguration* _rc_config;
1346 Adjustment _playback_adjustment;
1347 Adjustment _capture_adjustment;
1348 HScale _playback_slider;
1349 HScale _capture_slider;
1350 ComboBoxText _buffering_presets_combo;
1353 class ControlSurfacesOptions : public OptionEditorPageBox
1356 ControlSurfacesOptions ()
1357 : _ignore_view_change (0)
1359 _store = ListStore::create (_model);
1360 _view.set_model (_store);
1361 _view.append_column (_("Control Surface Protocol"), _model.name);
1362 _view.get_column(0)->set_resizable (true);
1363 _view.get_column(0)->set_expand (true);
1364 _view.append_column_editable (_("Enabled"), _model.enabled);
1365 _view.append_column_editable (_("Feedback"), _model.feedback);
1367 Label* l = manage (new Label (string_compose ("<b>%1</b>", _("Control Surfaces"))));
1368 l->set_alignment (0, 0.5);
1369 l->set_use_markup (true);
1370 _box->pack_start (*l, false, false);
1371 _box->pack_start (_view, false, false);
1373 Gtk::HBox* edit_box = manage (new Gtk::HBox);
1374 edit_box->set_spacing(3);
1375 _box->pack_start (*edit_box, false, false);
1378 Label* label = manage (new Label);
1379 label->set_text (_("Edit the settings for selected protocol (it must be ENABLED first):"));
1380 edit_box->pack_start (*label, false, false);
1383 edit_button = manage (new Button(_("Show Protocol Settings")));
1384 edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
1385 edit_box->pack_start (*edit_button, true, true);
1386 edit_button->set_sensitive (false);
1387 edit_button->show ();
1389 ControlProtocolManager& m = ControlProtocolManager::instance ();
1390 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1391 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1393 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1394 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1395 _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
1398 void parameter_changed (std::string const &)
1403 void set_state_from_config ()
1407 ControlProtocolManager& m = ControlProtocolManager::instance ();
1408 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1410 if (!(*i)->mandatory) {
1411 TreeModel::Row r = *_store->append ();
1412 r[_model.name] = (*i)->name;
1413 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1414 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
1415 r[_model.protocol_info] = *i;
1422 void protocol_status_changed (ControlProtocolInfo* cpi) {
1424 TreeModel::Children rows = _store->children();
1426 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1427 string n = ((*x)[_model.name]);
1429 if ((*x)[_model.protocol_info] == cpi) {
1430 _ignore_view_change++;
1431 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1432 _ignore_view_change--;
1438 void selection_changed ()
1440 //enable the Edit button when a row is selected for editing
1441 TreeModel::Row row = *(_view.get_selection()->get_selected());
1442 if (row && row[_model.enabled])
1443 edit_button->set_sensitive (true);
1445 edit_button->set_sensitive (false);
1448 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1450 TreeModel::Row r = *i;
1452 if (_ignore_view_change) {
1456 ControlProtocolInfo* cpi = r[_model.protocol_info];
1461 bool const was_enabled = (cpi->protocol != 0);
1462 bool const is_enabled = r[_model.enabled];
1465 if (was_enabled != is_enabled) {
1468 ControlProtocolManager::instance().activate (*cpi);
1470 ControlProtocolManager::instance().deactivate (*cpi);
1474 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
1475 bool const is_feedback = r[_model.feedback];
1477 if (was_feedback != is_feedback && cpi->protocol) {
1478 cpi->protocol->set_feedback (is_feedback);
1480 selection_changed ();
1483 void edit_btn_clicked ()
1486 ControlProtocolInfo* cpi;
1489 row = *(_view.get_selection()->get_selected());
1490 if (!row[_model.enabled]) {
1493 cpi = row[_model.protocol_info];
1494 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1497 Box* box = (Box*) cpi->protocol->get_gui ();
1501 if (box->get_parent()) {
1502 static_cast<ArdourWindow*>(box->get_parent())->present();
1505 WindowTitle title (Glib::get_application_name());
1506 title += row[_model.name];
1507 title += _("Configuration");
1508 /* once created, the window is managed by the surface itself (as ->get_parent())
1509 * Surface's tear_down_gui() is called on session close, when de-activating
1510 * or re-initializing a surface.
1511 * tear_down_gui() hides an deletes the Window if it exists.
1513 ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
1514 win->set_title ("Control Protocol Options");
1520 void edit_clicked (GdkEventButton* ev)
1522 if (ev->type != GDK_2BUTTON_PRESS) {
1529 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1533 ControlSurfacesModelColumns ()
1538 add (protocol_info);
1541 TreeModelColumn<string> name;
1542 TreeModelColumn<bool> enabled;
1543 TreeModelColumn<bool> feedback;
1544 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1547 Glib::RefPtr<ListStore> _store;
1548 ControlSurfacesModelColumns _model;
1550 PBD::ScopedConnection protocol_status_connection;
1551 uint32_t _ignore_view_change;
1552 Gtk::Button* edit_button;
1555 class VideoTimelineOptions : public OptionEditorPageBox
1558 VideoTimelineOptions (RCConfiguration* c)
1560 , _show_video_export_info_button (_("Show Video Export Info before export"))
1561 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1562 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1563 , _xjadeo_browse_button (_("Browse..."))
1565 Table* t = manage (new Table (8, 4));
1566 t->set_spacings (4);
1568 Label* l = manage (new Label (string_compose ("<b>%1</b>", _("Video Server"))));
1569 l->set_use_markup (true);
1570 l->set_alignment (0, 0.5);
1571 t->attach (*l, 0, 4, 0, 1, EXPAND | FILL, FILL | EXPAND, 0, 0);
1573 t->attach (_video_advanced_setup_button, 1, 4, 1, 2);
1574 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1575 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1576 _("<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."));
1578 l = manage (new Label (_("Video Server URL:")));
1579 l->set_alignment (0, 0.5);
1580 t->attach (*l, 1, 2, 2, 3, FILL);
1581 t->attach (_video_server_url_entry, 2, 4, 2, 3, FILL);
1582 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1583 _("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"));
1585 l = manage (new Label (_("Video Folder:")));
1586 l->set_alignment (0, 0.5);
1587 t->attach (*l, 1, 2, 3, 4, FILL);
1588 t->attach (_video_server_docroot_entry, 2, 4, 3, 4);
1589 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1590 _("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."));
1592 t->attach (_show_video_export_info_button, 1, 4, 4, 5);
1593 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1594 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1595 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1597 t->attach (_show_video_server_dialog_button, 1, 4, 5, 6);
1598 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1599 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1600 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1602 l = manage (new Label (""));
1603 t->attach (*l, 0, 4, 6, 7, EXPAND | FILL);
1605 l = manage (new Label (string_compose ("<b>%1</b>", _("Video Monitor"))));
1606 l->set_use_markup (true);
1607 l->set_alignment (0, 0.5);
1608 t->attach (*l, 0, 4, 7, 8, EXPAND | FILL);
1610 l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"),
1613 #elif defined PLATFORM_WINDOWS
1619 l->set_alignment (0, 0.5);
1620 t->attach (*l, 1, 4, 8, 9, FILL);
1621 t->attach (_custom_xjadeo_path, 2, 3, 9, 10);
1622 Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart."));
1623 t->attach (_xjadeo_browse_button, 3, 4, 9, 10, FILL);
1625 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1626 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1627 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1628 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1629 _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed));
1630 _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked));
1632 // xjadeo-path is a UIConfig parameter
1633 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &VideoTimelineOptions::parameter_changed));
1635 _box->pack_start (*t,true,true);
1638 void server_url_changed ()
1640 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1643 void server_docroot_changed ()
1645 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1648 void show_video_export_info_toggled ()
1650 bool const x = _show_video_export_info_button.get_active ();
1651 _rc_config->set_show_video_export_info (x);
1654 void show_video_server_dialog_toggled ()
1656 bool const x = _show_video_server_dialog_button.get_active ();
1657 _rc_config->set_show_video_server_dialog (x);
1660 void video_advanced_setup_toggled ()
1662 bool const x = _video_advanced_setup_button.get_active ();
1663 _rc_config->set_video_advanced_setup(x);
1666 void custom_xjadeo_path_changed ()
1668 UIConfiguration::instance().set_xjadeo_binary (_custom_xjadeo_path.get_text());
1671 void xjadeo_browse_clicked ()
1673 Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN);
1674 dialog.set_filename (UIConfiguration::instance().get_xjadeo_binary());
1675 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1676 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1677 if (dialog.run () == Gtk::RESPONSE_OK) {
1678 const std::string& filename = dialog.get_filename();
1679 if (!filename.empty() && (
1681 Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) ||
1683 Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)
1685 UIConfiguration::instance().set_xjadeo_binary (filename);
1690 void parameter_changed (string const & p)
1692 if (p == "video-server-url") {
1693 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1694 } else if (p == "video-server-docroot") {
1695 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1696 } else if (p == "show-video-export-info") {
1697 bool const x = _rc_config->get_show_video_export_info();
1698 _show_video_export_info_button.set_active (x);
1699 } else if (p == "show-video-server-dialog") {
1700 bool const x = _rc_config->get_show_video_server_dialog();
1701 _show_video_server_dialog_button.set_active (x);
1702 } else if (p == "video-advanced-setup") {
1703 bool const x = _rc_config->get_video_advanced_setup();
1704 _video_advanced_setup_button.set_active(x);
1705 _video_server_docroot_entry.set_sensitive(x);
1706 _video_server_url_entry.set_sensitive(x);
1707 } else if (p == "xjadeo-binary") {
1708 _custom_xjadeo_path.set_text (UIConfiguration::instance().get_xjadeo_binary());
1712 void set_state_from_config ()
1714 parameter_changed ("video-server-url");
1715 parameter_changed ("video-server-docroot");
1716 parameter_changed ("video-monitor-setup-dialog");
1717 parameter_changed ("show-video-export-info");
1718 parameter_changed ("show-video-server-dialog");
1719 parameter_changed ("video-advanced-setup");
1720 parameter_changed ("xjadeo-binary");
1724 RCConfiguration* _rc_config;
1725 Entry _video_server_url_entry;
1726 Entry _video_server_docroot_entry;
1727 Entry _custom_xjadeo_path;
1728 CheckButton _show_video_export_info_button;
1729 CheckButton _show_video_server_dialog_button;
1730 CheckButton _video_advanced_setup_button;
1731 Button _xjadeo_browse_button;
1734 class ColumVisibilityOption : public Option
1737 ColumVisibilityOption (string id, string name, uint32_t n_col, sigc::slot<uint32_t> get, sigc::slot<bool, uint32_t> set)
1744 cb = (CheckButton**) malloc (sizeof (CheckButton*) * n_col);
1745 for (uint32_t i = 0; i < n_col; ++i) {
1746 CheckButton* col = manage (new CheckButton (string_compose (_("Column %1"), i + 1)));
1747 col->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ColumVisibilityOption::column_toggled), i));
1748 _hbox.pack_start (*col);
1751 parameter_changed (id);
1754 ~ColumVisibilityOption () {
1758 Gtk::Widget& tip_widget() { return _hbox; }
1760 void set_state_from_config ()
1762 uint32_t c = _get();
1763 for (uint32_t i = 0; i < _n_col; ++i) {
1764 bool en = (c & (1<<i)) ? true : false;
1765 if (cb[i]->get_active () != en) {
1766 cb[i]->set_active (en);
1771 void add_to_page (OptionEditorPage* p)
1773 _heading.add_to_page (p);
1774 add_widget_to_page (p, &_hbox);
1778 void column_toggled (int b) {
1779 uint32_t c = _get();
1781 if (cb[b]->get_active ()) {
1792 OptionEditorHeading _heading;
1796 sigc::slot<uint32_t> _get;
1797 sigc::slot<bool, uint32_t> _set;
1801 /** A class which allows control of visibility of some editor components usign
1802 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1803 * which has the correct members, but with null widget pointers. This
1804 * class allows the user to set visibility of the members, the details
1805 * of which are stored in a configuration variable which can be watched
1806 * by parts of the editor that actually contain the widgets whose visibility
1807 * is being controlled.
1810 class VisibilityOption : public Option
1813 /** @param name User-visible name for this group.
1814 * @param g `Dummy' VisibilityGroup (as described above).
1815 * @param get Method to get the value of the appropriate configuration variable.
1816 * @param set Method to set the value of the appropriate configuration variable.
1818 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1819 : Option (g->get_state_name(), name)
1821 , _visibility_group (g)
1825 /* Watch for changes made by the user to our members */
1826 _visibility_group->VisibilityChanged.connect_same_thread (
1827 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1831 void set_state_from_config ()
1833 /* Set our state from the current configuration */
1834 _visibility_group->set_state (_get ());
1837 void add_to_page (OptionEditorPage* p)
1839 _heading.add_to_page (p);
1840 add_widget_to_page (p, _visibility_group->list_view ());
1843 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1848 /* The user has changed something, so reflect this change
1849 in the RCConfiguration.
1851 _set (_visibility_group->get_state_value ());
1854 OptionEditorHeading _heading;
1855 VisibilityGroup* _visibility_group;
1856 sigc::slot<std::string> _get;
1857 sigc::slot<bool, std::string> _set;
1858 PBD::ScopedConnection _visibility_group_connection;
1862 class MidiPortOptions : public OptionEditorBox, public sigc::trackable
1867 setup_midi_port_view (midi_output_view, false);
1868 setup_midi_port_view (midi_input_view, true);
1871 _box->pack_start (*manage (new Label("")), false, false);
1872 input_label.set_markup (string_compose ("<span size=\"large\" weight=\"bold\">%1</span>", _("MIDI Inputs")));
1873 _box->pack_start (input_label, false, false);
1875 Gtk::ScrolledWindow* scroller = manage (new Gtk::ScrolledWindow);
1876 scroller->add (midi_input_view);
1877 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1878 scroller->set_size_request (-1, 180);
1879 _box->pack_start (*scroller, false, false);
1881 _box->pack_start (*manage (new Label("")), false, false);
1882 output_label.set_markup (string_compose ("<span size=\"large\" weight=\"bold\">%1</span>", _("MIDI Outputs")));
1883 _box->pack_start (output_label, false, false);
1885 scroller = manage (new Gtk::ScrolledWindow);
1886 scroller->add (midi_output_view);
1887 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1888 scroller->set_size_request (-1, 180);
1889 _box->pack_start (*scroller, false, false);
1891 midi_output_view.show ();
1892 midi_input_view.show ();
1894 _box->signal_show().connect (sigc::mem_fun (*this, &MidiPortOptions::on_show));
1897 void parameter_changed (string const&) {}
1898 void set_state_from_config() {}
1903 AudioEngine::instance()->PortRegisteredOrUnregistered.connect (connections,
1904 invalidator (*this),
1905 boost::bind (&MidiPortOptions::refill, this),
1907 AudioEngine::instance()->MidiPortInfoChanged.connect (connections,
1908 invalidator (*this),
1909 boost::bind (&MidiPortOptions::refill, this),
1911 AudioEngine::instance()->MidiSelectionPortsChanged.connect (connections,
1912 invalidator (*this),
1913 boost::bind (&MidiPortOptions::refill, this),
1919 if (refill_midi_ports (true, midi_input_view)) {
1920 input_label.show ();
1922 input_label.hide ();
1924 if (refill_midi_ports (false, midi_output_view)) {
1925 output_label.show ();
1927 output_label.hide ();
1932 PBD::ScopedConnectionList connections;
1934 /* MIDI port management */
1935 struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord {
1937 MidiPortColumns () {
1946 Gtk::TreeModelColumn<std::string> pretty_name;
1947 Gtk::TreeModelColumn<bool> music_data;
1948 Gtk::TreeModelColumn<bool> control_data;
1949 Gtk::TreeModelColumn<bool> selection;
1950 Gtk::TreeModelColumn<std::string> name;
1951 Gtk::TreeModelColumn<std::string> filler;
1954 MidiPortColumns midi_port_columns;
1955 Gtk::TreeView midi_input_view;
1956 Gtk::TreeView midi_output_view;
1957 Gtk::Label input_label;
1958 Gtk::Label output_label;
1960 void setup_midi_port_view (Gtk::TreeView&, bool with_selection);
1961 bool refill_midi_ports (bool for_input, Gtk::TreeView&);
1962 void pretty_name_edit (std::string const & path, std::string const & new_text, Gtk::TreeView*);
1963 void midi_music_column_toggled (std::string const & path, Gtk::TreeView*);
1964 void midi_control_column_toggled (std::string const & path, Gtk::TreeView*);
1965 void midi_selection_column_toggled (std::string const & path, Gtk::TreeView*);
1969 MidiPortOptions::setup_midi_port_view (Gtk::TreeView& view, bool with_selection)
1971 int pretty_name_column;
1974 int selection_column;
1975 TreeViewColumn* col;
1978 pretty_name_column = view.append_column_editable (_("Name (click to edit)"), midi_port_columns.pretty_name) - 1;
1980 col = manage (new TreeViewColumn ("", midi_port_columns.music_data));
1981 col->set_alignment (ALIGN_CENTER);
1982 l = manage (new Label (_("Music Data")));
1983 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of music performance data."), PROGRAM_NAME));
1984 col->set_widget (*l);
1986 music_column = view.append_column (*col) - 1;
1988 col = manage (new TreeViewColumn ("", midi_port_columns.control_data));
1989 col->set_alignment (ALIGN_CENTER);
1990 l = manage (new Label (_("Control Data")));
1991 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of control data."), PROGRAM_NAME));
1992 col->set_widget (*l);
1994 control_column = view.append_column (*col) - 1;
1996 if (with_selection) {
1997 col = manage (new TreeViewColumn (_("Follow Selection"), midi_port_columns.selection));
1998 selection_column = view.append_column (*col) - 1;
1999 l = manage (new Label (_("Follow Selection")));
2000 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));
2001 col->set_widget (*l);
2005 /* filler column so that the last real column doesn't expand */
2006 view.append_column ("", midi_port_columns.filler);
2008 CellRendererText* pretty_name_cell = dynamic_cast<CellRendererText*> (view.get_column_cell_renderer (pretty_name_column));
2009 pretty_name_cell->property_editable() = true;
2010 pretty_name_cell->signal_edited().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::pretty_name_edit), &view));
2012 CellRendererToggle* toggle_cell;
2014 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (music_column));
2015 toggle_cell->property_activatable() = true;
2016 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_music_column_toggled), &view));
2018 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (control_column));
2019 toggle_cell->property_activatable() = true;
2020 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_control_column_toggled), &view));
2022 if (with_selection) {
2023 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (selection_column));
2024 toggle_cell->property_activatable() = true;
2025 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_selection_column_toggled), &view));
2028 view.get_selection()->set_mode (SELECTION_NONE);
2029 view.set_tooltip_column (4); /* port "real" name */
2030 view.get_column(0)->set_resizable (true);
2031 view.get_column(0)->set_expand (true);
2035 MidiPortOptions::refill_midi_ports (bool for_input, Gtk::TreeView& view)
2037 using namespace ARDOUR;
2039 std::vector<string> ports;
2041 AudioEngine::instance()->get_known_midi_ports (ports);
2043 if (ports.empty()) {
2048 Glib::RefPtr<ListStore> model = Gtk::ListStore::create (midi_port_columns);
2050 for (vector<string>::const_iterator s = ports.begin(); s != ports.end(); ++s) {
2052 if (AudioEngine::instance()->port_is_mine (*s)) {
2056 PortManager::MidiPortInformation mpi (AudioEngine::instance()->midi_port_information (*s));
2058 if (mpi.pretty_name.empty()) {
2059 /* vanished since get_known_midi_ports() */
2063 if (for_input != mpi.input) {
2067 TreeModel::Row row = *(model->append());
2069 row[midi_port_columns.pretty_name] = mpi.pretty_name;
2070 row[midi_port_columns.music_data] = mpi.properties & MidiPortMusic;
2071 row[midi_port_columns.control_data] = mpi.properties & MidiPortControl;
2072 row[midi_port_columns.selection] = mpi.properties & MidiPortSelection;
2073 row[midi_port_columns.name] = *s;
2076 view.set_model (model);
2082 MidiPortOptions::midi_music_column_toggled (string const & path, TreeView* view)
2084 TreeIter iter = view->get_model()->get_iter (path);
2090 bool new_value = ! bool ((*iter)[midi_port_columns.music_data]);
2092 /* don't reset model - wait for MidiPortInfoChanged signal */
2095 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2097 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2102 MidiPortOptions::midi_control_column_toggled (string const & path, TreeView* view)
2104 TreeIter iter = view->get_model()->get_iter (path);
2110 bool new_value = ! bool ((*iter)[midi_port_columns.control_data]);
2112 /* don't reset model - wait for MidiPortInfoChanged signal */
2115 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2117 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2122 MidiPortOptions::midi_selection_column_toggled (string const & path, TreeView* view)
2124 TreeIter iter = view->get_model()->get_iter (path);
2130 bool new_value = ! bool ((*iter)[midi_port_columns.selection]);
2132 /* don't reset model - wait for MidiSelectionPortsChanged signal */
2135 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2137 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2142 MidiPortOptions::pretty_name_edit (std::string const & path, string const & new_text, Gtk::TreeView* view)
2144 TreeIter iter = view->get_model()->get_iter (path);
2150 boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
2152 ARDOUR::PortEngine::PortHandle ph = backend->get_port_by_name ((*iter)[midi_port_columns.name]);
2154 backend->set_port_property (ph, "http://jackaudio.org/metadata/pretty-name", new_text, "");
2155 (*iter)[midi_port_columns.pretty_name] = new_text;
2163 RCOptionEditor::RCOptionEditor ()
2164 : OptionEditorContainer (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
2165 , Tabbable (*this, _("Preferences")) /* pack self-as-vbox into tabbable */
2166 , _rc_config (Config)
2167 , _mixer_strip_visibility ("mixer-element-visibility")
2169 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
2173 uint32_t hwcpus = hardware_concurrency ();
2175 BoolComboOption* bco;
2178 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
2180 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
2182 _("Signal processing uses"),
2183 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
2184 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
2187 procs->add (-1, _("all but one processor"));
2188 procs->add (0, _("all available processors"));
2190 for (uint32_t i = 1; i <= hwcpus; ++i) {
2191 procs->add (i, string_compose (P_("%1 processor", "%1 processors", i), i));
2194 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
2196 add_option (_("Misc"), procs);
2199 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
2201 add_option (_("Misc"), new UndoOptions (_rc_config));
2203 add_option (_("Misc"),
2205 "verify-remove-last-capture",
2206 _("Verify removal of last capture"),
2207 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
2208 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
2211 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
2213 add_option (_("Misc"),
2215 "periodic-safety-backups",
2216 _("Make periodic backups of the session file"),
2217 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
2218 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
2221 add_option (_("Misc"),
2223 "only-copy-imported-files",
2224 _("Always copy imported files"),
2225 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
2226 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
2229 add_option (_("Misc"), new DirectoryOption (
2230 X_("default-session-parent-dir"),
2231 _("Default folder for new sessions:"),
2232 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
2233 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
2236 add_option (_("Misc"),
2237 new SpinOption<uint32_t> (
2238 "max-recent-sessions",
2239 _("Maximum number of recent sessions"),
2240 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
2241 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
2245 add_option (_("Misc/Click"), new OptionEditorHeading (_("Click")));
2247 add_option (_("Misc/Click"), new ClickOptions (_rc_config));
2249 add_option (_("Misc/Click"),
2252 _("Click gain level"),
2253 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
2254 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
2257 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
2259 add_option (_("Misc"),
2260 new SpinOption<double> (
2261 "automation-thinning-factor",
2262 _("Thinning factor (larger value => less data)"),
2263 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
2264 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
2268 add_option (_("Misc"),
2269 new SpinOption<double> (
2270 "automation-interval-msecs",
2271 _("Automation sampling interval (milliseconds)"),
2272 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
2273 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
2277 add_option (_("Misc"), new OptionEditorHeading (_("Tempo")));
2281 tsf = new BoolOption (
2282 "allow-non-quarter-pulse",
2283 _("Allow non quarter-note pulse"),
2284 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_allow_non_quarter_pulse),
2285 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_allow_non_quarter_pulse)
2287 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2288 string_compose (_("<b>When enabled</b> %1 will allow tempo to be expressed in divisions per minute\n"
2289 "<b>When disabled</b> %1 will only allow tempo to be expressed in quarter notes per minute"),
2291 add_option (_("Misc"), tsf);
2295 add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options")));
2297 tsf = new BoolOption (
2298 "latched-record-enable",
2299 _("Keep record-enable engaged on stop"),
2300 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
2301 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
2303 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
2304 add_option (_("Transport"), tsf);
2306 tsf = new BoolOption (
2308 _("Play loop is a transport mode"),
2309 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
2310 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
2312 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2313 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
2314 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
2315 add_option (_("Transport"), tsf);
2317 tsf = new BoolOption (
2318 "stop-recording-on-xrun",
2319 _("Stop recording when an xrun occurs"),
2320 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
2321 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
2323 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2324 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
2326 add_option (_("Transport"), tsf);
2328 tsf = new BoolOption (
2329 "create-xrun-marker",
2330 _("Create markers where xruns occur"),
2331 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
2332 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
2334 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
2335 add_option (_("Transport"), tsf);
2337 tsf = new BoolOption (
2338 "stop-at-session-end",
2339 _("Stop at the end of the session"),
2340 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
2341 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
2343 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2344 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
2345 "when it reaches the current session end marker\n\n"
2346 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
2348 add_option (_("Transport"), tsf);
2350 tsf = new BoolOption (
2352 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
2353 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
2354 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
2356 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2357 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
2358 "preventing any need to do a transport locate at the end of the loop\n\n"
2359 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
2360 "which will often cause a small click or delay"), PROGRAM_NAME));
2361 add_option (_("Transport"), tsf);
2363 tsf = new BoolOption (
2364 "disable-disarm-during-roll",
2365 _("Disable per-track record disarm while rolling"),
2366 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
2367 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
2369 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"));
2370 add_option (_("Transport"), tsf);
2372 tsf = new BoolOption (
2374 _("12dB gain reduction during fast-forward and fast-rewind"),
2375 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
2376 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2378 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
2379 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2380 add_option (_("Transport"), tsf);
2382 ComboOption<float>* psc = new ComboOption<float> (
2385 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
2386 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
2388 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
2389 (_("The amount of preroll (in seconds) to apply when <b>Play with Preroll</b> is initiated.\n\n"
2390 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
2391 psc->add (0.0, _("0 (no pre-roll)"));
2392 psc->add (0.1, _("0.1 second"));
2393 psc->add (0.25, _("0.25 second"));
2394 psc->add (0.5, _("0.5 second"));
2395 psc->add (1.0, _("1.0 second"));
2396 psc->add (2.0, _("2.0 seconds"));
2397 add_option (_("Transport"), psc);
2399 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("Synchronization and Slave Options")));
2401 _sync_source = new ComboOption<SyncSource> (
2403 _("External timecode source"),
2404 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
2405 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
2408 add_option (_("Transport/Sync"), _sync_source);
2410 _sync_framerate = new BoolOption (
2411 "timecode-sync-frame-rate",
2412 _("Match session video frame rate to external timecode"),
2413 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
2414 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
2416 Gtkmm2ext::UI::instance()->set_tip
2417 (_sync_framerate->tip_widget(),
2418 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
2419 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
2420 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
2421 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
2422 "timecode standard and the session standard."), PROGRAM_NAME));
2424 add_option (_("Transport/Sync"), _sync_framerate);
2426 _sync_genlock = new BoolOption (
2427 "timecode-source-is-synced",
2428 _("Sync-lock timecode to clock (disable drift compensation)"),
2429 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
2430 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
2432 Gtkmm2ext::UI::instance()->set_tip
2433 (_sync_genlock->tip_widget(),
2434 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
2435 "Sync Lock indicates that the selected external timecode source shares clock-sync "
2436 "(Black & Burst, Wordclock, etc) with the audio interface. "
2437 "This option disables drift compensation. The transport speed is fixed at 1.0. "
2438 "Vari-speed LTC will be ignored and cause drift."
2440 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
2441 "timecode sources shares clock sync."
2445 add_option (_("Transport/Sync"), _sync_genlock);
2447 _sync_source_2997 = new BoolOption (
2448 "timecode-source-2997",
2449 _("Lock to 29.9700 fps instead of 30000/1001"),
2450 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
2451 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
2453 Gtkmm2ext::UI::instance()->set_tip
2454 (_sync_source_2997->tip_widget(),
2455 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
2456 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
2457 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
2458 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
2459 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
2460 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
2463 add_option (_("Transport/Sync"), _sync_source_2997);
2465 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("LTC Reader")));
2467 _ltc_port = new ComboStringOption (
2469 _("LTC incoming port"),
2470 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
2471 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
2474 vector<string> physical_inputs;
2475 physical_inputs.push_back (_("None"));
2476 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
2477 _ltc_port->set_popdown_strings (physical_inputs);
2479 populate_sync_options ();
2480 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
2482 add_option (_("Transport/Sync"), _ltc_port);
2484 // TODO; rather disable this button than not compile it..
2485 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("LTC Generator")));
2487 add_option (_("Transport/Sync"),
2490 _("Enable LTC generator"),
2491 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
2492 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
2495 _ltc_send_continuously = new BoolOption (
2496 "ltc-send-continuously",
2497 _("Send LTC while stopped"),
2498 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
2499 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
2501 Gtkmm2ext::UI::instance()->set_tip
2502 (_ltc_send_continuously->tip_widget(),
2503 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
2504 add_option (_("Transport/Sync"), _ltc_send_continuously);
2506 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
2507 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
2508 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
2509 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
2511 Gtkmm2ext::UI::instance()->set_tip
2512 (_ltc_volume_slider->tip_widget(),
2513 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
2515 add_option (_("Transport/Sync"), _ltc_volume_slider);
2519 add_option (_("Editor"), new OptionEditorHeading (_("Editor Settings")));
2521 add_option (_("Editor"),
2523 "rubberbanding-snaps-to-grid",
2524 _("Make rubberband selection rectangle snap to the grid"),
2525 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2526 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2529 bo = new BoolOption (
2531 _("Name new markers"),
2532 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2533 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2535 add_option (_("Editor"), bo);
2536 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."
2537 "\n\nYou can always rename markers by right-clicking on them"));
2539 add_option (S_("Editor"),
2541 "draggable-playhead",
2542 _("Allow dragging of playhead"),
2543 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2544 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2547 if (!Profile->get_mixbus()) {
2548 add_option (_("Editor"),
2551 _("Show zoom toolbar (if torn off)"),
2552 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_zoom_tools),
2553 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_zoom_tools)
2556 add_option (_("Editor"),
2558 "use-mouse-position-as-zoom-focus-on-scroll",
2559 _("Always use mouse cursor position as zoom focus when zooming using mouse scroll wheel"),
2560 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2561 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2565 add_option (_("Editor"),
2567 "use-time-rulers-to-zoom-with-vertical-drag",
2568 _("Use time rulers area to zoom when clicking and dragging vertically"),
2569 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag),
2570 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag)
2573 add_option (_("Editor"),
2575 "use-double-click-to-zoom-to-selection",
2576 _("Use double mouse click to zoom to selection"),
2577 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection),
2578 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection)
2581 add_option (_("Editor"),
2583 "update-editor-during-summary-drag",
2584 _("Update editor window during drags of the summary"),
2585 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2586 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2589 add_option (_("Editor"),
2591 "autoscroll-editor",
2592 _("Auto-scroll editor window when dragging near its edges"),
2593 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2594 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2597 add_option (_("Editor"),
2598 new BoolComboOption (
2599 "show-region-gain-envelopes",
2600 _("Show gain envelopes in audio regions"),
2602 _("only in Draw and Internal Edit modes"),
2603 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2604 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2607 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2609 add_option (_("Editor"),
2611 "automation-follows-regions",
2612 _("Move relevant automation when audio regions are moved"),
2613 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2614 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2617 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2618 "default-fade-shape",
2619 _("Default fade shape"),
2620 sigc::mem_fun (*_rc_config,
2621 &RCConfiguration::get_default_fade_shape),
2622 sigc::mem_fun (*_rc_config,
2623 &RCConfiguration::set_default_fade_shape)
2626 fadeshape->add (FadeLinear,
2627 _("Linear (for highly correlated material)"));
2628 fadeshape->add (FadeConstantPower, _("Constant power"));
2629 fadeshape->add (FadeSymmetric, _("Symmetric"));
2630 fadeshape->add (FadeSlow, _("Slow"));
2631 fadeshape->add (FadeFast, _("Fast"));
2633 add_option (_("Editor"), fadeshape);
2637 bco = new BoolComboOption (
2638 "use-overlap-equivalency",
2639 _("Regions in edit groups are edited together"),
2640 _("whenever they overlap in time"),
2641 _("only if they have identical length and position"),
2642 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2643 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2646 add_option (_("Editor"), bco);
2649 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2651 _("Layering model"),
2652 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2653 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2656 lm->add (LaterHigher, _("later is higher"));
2657 lm->add (Manual, _("manual layering"));
2658 add_option (_("Editor"), lm);
2660 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2661 "region-selection-after-split",
2662 _("After splitting selected regions, select"),
2663 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2664 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2666 // TODO: decide which of these modes are really useful
2667 rsas->add(None, _("no regions"));
2668 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2669 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2670 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2671 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2672 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2673 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2674 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2676 add_option (_("Editor"), rsas);
2678 add_option (_("Editor/Waveforms"), new OptionEditorHeading (_("Waveforms")));
2680 if (!Profile->get_mixbus()) {
2681 add_option (_("Editor/Waveforms"),
2684 _("Show waveforms in regions"),
2685 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
2686 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
2690 add_option (_("Editor/Waveforms"),
2692 "show-waveforms-while-recording",
2693 _("Show waveforms for audio while it is being recorded"),
2694 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
2695 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
2698 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
2700 _("Waveform scale"),
2701 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
2702 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
2705 wfs->add (Linear, _("linear"));
2706 wfs->add (Logarithmic, _("logarithmic"));
2708 add_option (_("Editor/Waveforms"), wfs);
2710 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
2712 _("Waveform shape"),
2713 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
2714 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
2717 wfsh->add (Traditional, _("traditional"));
2718 wfsh->add (Rectified, _("rectified"));
2720 add_option (_("Editor/Waveforms"), wfsh);
2722 add_option (_("Editor/Waveforms"), new ClipLevelOptions ());
2727 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2729 add_option (_("Audio"), new BufferingOptions (_rc_config));
2731 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2733 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2735 _("Record monitoring handled by"),
2736 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2737 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2740 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2741 mm->add (HardwareMonitoring, _("via Audio Driver"));
2744 string prog (PROGRAM_NAME);
2745 boost::algorithm::to_lower (prog);
2746 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2747 mm->add (ExternalMonitoring, _("audio hardware"));
2749 add_option (_("Audio"), mm);
2751 add_option (_("Audio"),
2753 "tape-machine-mode",
2754 _("Tape machine mode"),
2755 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2756 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2759 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2760 if (!Profile->get_mixbus()) {
2762 add_option (_("Audio"),
2764 "auto-connect-standard-busses",
2765 _("Auto-connect master/monitor busses"),
2766 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2767 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2770 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2771 "input-auto-connect",
2772 _("Connect track inputs"),
2773 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2774 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2777 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2778 iac->add (ManualConnect, _("manually"));
2780 add_option (_("Audio"), iac);
2782 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2783 "output-auto-connect",
2784 _("Connect track and bus outputs"),
2785 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2786 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2789 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2790 oac->add (AutoConnectMaster, _("automatically to master bus"));
2791 oac->add (ManualConnect, _("manually"));
2793 add_option (_("Audio"), oac);
2795 bo = new BoolOption (
2797 _("Use 'Strict-I/O' for new tracks or Busses"),
2798 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2799 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2802 add_option (_("Audio"), bo);
2803 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2804 _("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."));
2808 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2810 add_option (_("Audio"),
2812 "denormal-protection",
2813 _("Use DC bias to protect against denormals"),
2814 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2815 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2818 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2820 _("Processor handling"),
2821 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2822 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2826 dm->add (DenormalNone, _("no processor handling"));
2828 FPU* fpu = FPU::instance();
2830 if (fpu->has_flush_to_zero()) {
2832 dm->add (DenormalFTZ, _("use FlushToZero"));
2833 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2834 _rc_config->set_denormal_model(DenormalNone);
2837 if (fpu->has_denormals_are_zero()) {
2839 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2840 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2841 _rc_config->set_denormal_model(DenormalNone);
2844 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2846 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2847 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2848 _rc_config->set_denormal_model(DenormalNone);
2852 dm->set_sensitive(false);
2855 add_option (_("Audio"), dm);
2857 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2859 add_option (_("Audio"),
2861 "auto-analyse-audio",
2862 _("Enable automatic analysis of audio"),
2863 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2864 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2867 add_option (_("Audio"),
2869 "replicate-missing-region-channels",
2870 _("Replicate missing region channels"),
2871 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2872 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2877 add_option (_("Solo & mute"), new OptionEditorHeading (_("Solo")));
2879 _solo_control_is_listen_control = new BoolOption (
2880 "solo-control-is-listen-control",
2881 _("Solo controls are Listen controls"),
2882 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2883 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2886 add_option (_("Solo & mute"), _solo_control_is_listen_control);
2888 add_option (_("Solo & mute"),
2891 _("Exclusive solo"),
2892 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2893 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2896 add_option (_("Solo & mute"),
2899 _("Show solo muting"),
2900 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2901 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2904 add_option (_("Solo & mute"),
2906 "solo-mute-override",
2907 _("Soloing overrides muting"),
2908 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2909 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2912 add_option (_("Solo & mute"),
2915 _("Solo-in-place mute cut (dB)"),
2916 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2917 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2920 _listen_position = new ComboOption<ListenPosition> (
2922 _("Listen Position"),
2923 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2924 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2927 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2928 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2930 add_option (_("Solo & mute"), _listen_position);
2932 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2934 _("PFL signals come from"),
2935 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2936 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2939 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2940 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2942 add_option (_("Solo & mute"), pp);
2944 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2946 _("AFL signals come from"),
2947 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2948 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2951 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2952 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2954 add_option (_("Solo & mute"), pa);
2956 add_option (_("Solo & mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2958 add_option (_("Solo & mute"),
2960 "mute-affects-pre-fader",
2961 _("Mute affects pre-fader sends"),
2962 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2963 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2966 add_option (_("Solo & mute"),
2968 "mute-affects-post-fader",
2969 _("Mute affects post-fader sends"),
2970 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2971 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2974 add_option (_("Solo & mute"),
2976 "mute-affects-control-outs",
2977 _("Mute affects control outputs"),
2978 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2979 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2982 add_option (_("Solo & mute"),
2984 "mute-affects-main-outs",
2985 _("Mute affects main outputs"),
2986 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2987 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2991 if (!ARDOUR::Profile->get_mixbus()) {
2992 add_option (_("Solo & mute"), new OptionEditorHeading (_("Send Routing")));
2993 add_option (_("Solo & mute"),
2995 "link-send-and-route-panner",
2996 _("Link panners of Aux and External Sends with main panner by default"),
2997 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2998 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
3002 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Preferences")));
3004 add_option (_("MIDI"),
3005 new SpinOption<float> (
3007 _("MIDI read-ahead time (seconds)"),
3008 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
3009 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
3014 add_option (_("MIDI"),
3015 new SpinOption<int32_t> (
3016 "initial-program-change",
3017 _("Initial program change"),
3018 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
3019 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
3023 add_option (_("MIDI"),
3025 "display-first-midi-bank-as-zero",
3026 _("Display first MIDI bank/program as 0"),
3027 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
3028 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
3031 add_option (_("MIDI"),
3033 "never-display-periodic-midi",
3034 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
3035 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
3036 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
3039 add_option (_("MIDI"),
3042 _("Sound MIDI notes as they are selected in the editor"),
3043 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
3044 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
3047 add_option (_("MIDI"),
3050 _("Send MIDI control feedback"),
3051 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
3052 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
3055 add_option (_("MIDI/Ports"), new OptionEditorHeading (_("MIDI Port Options")));
3057 add_option (_("MIDI/Ports"),
3059 "get-midi-input-follows-selection",
3060 _("MIDI input follows MIDI track selection"),
3061 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
3062 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
3065 add_option (_("MIDI/Ports"), new MidiPortOptions ());
3067 add_option (_("MIDI/Sync"), new OptionEditorHeading (_("MIDI Clock")));
3069 add_option (_("MIDI/Sync"),
3072 _("Send MIDI Clock"),
3073 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
3074 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
3077 add_option (_("MIDI/Sync"), new OptionEditorHeading (_("MIDI Time Code (MTC)")));
3079 add_option (_("MIDI/Sync"),
3082 _("Send MIDI Time Code"),
3083 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
3084 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
3087 add_option (_("MIDI/Sync"),
3088 new SpinOption<int> (
3089 "mtc-qf-speed-tolerance",
3090 _("Percentage either side of normal transport speed to transmit MTC"),
3091 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
3092 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
3096 add_option (_("MIDI/Sync"), new OptionEditorHeading (_("Midi Machine Control (MMC)")));
3098 add_option (_("MIDI/Sync"),
3101 _("Obey MIDI Machine Control commands"),
3102 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
3103 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
3106 add_option (_("MIDI/Sync"),
3109 _("Send MIDI Machine Control commands"),
3110 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
3111 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
3114 add_option (_("MIDI/Sync"),
3115 new SpinOption<uint8_t> (
3116 "mmc-receive-device-id",
3117 _("Inbound MMC device ID"),
3118 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
3119 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
3123 add_option (_("MIDI/Sync"),
3124 new SpinOption<uint8_t> (
3125 "mmc-send-device-id",
3126 _("Outbound MMC device ID"),
3127 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
3128 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
3132 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
3134 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
3135 "midi-audition-synth-uri",
3136 _("Midi Audition Synth (LV2)"),
3137 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
3138 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
3141 audition_synth->add(X_(""), _("None"));
3142 PluginInfoList all_plugs;
3143 PluginManager& manager (PluginManager::instance());
3145 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
3147 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
3148 if (manager.get_status (*i) == PluginManager::Hidden) continue;
3149 if (!(*i)->is_instrument()) continue;
3150 if ((*i)->type != ARDOUR::LV2) continue;
3151 if ((*i)->name.length() > 46) {
3152 audition_synth->add((*i)->unique_id, (*i)->name.substr (0, 44) + "...");
3154 audition_synth->add((*i)->unique_id, (*i)->name);
3159 add_option (_("MIDI"), audition_synth);
3161 /* Control Surfaces */
3163 add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
3165 /* VIDEO Timeline */
3166 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
3168 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3169 add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
3170 add_option (_("Plugins"),
3171 new RcActionButton (_("Scan for Plugins"),
3172 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3176 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
3178 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3179 bo = new BoolOption (
3180 "show-plugin-scan-window",
3181 _("Always Display Plugin Scan Progress"),
3182 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
3183 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
3185 add_option (_("Plugins"), bo);
3186 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3187 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
3190 bo = new BoolOption (
3191 "plugins-stop-with-transport",
3192 _("Silence plugins when the transport is stopped"),
3193 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
3194 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
3196 add_option (_("Plugins"), bo);
3197 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3198 _("<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."));
3200 bo = new BoolOption (
3201 "new-plugins-active",
3202 _("Make new plugins active"),
3203 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
3204 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
3206 add_option (_("Plugins"), bo);
3207 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3208 _("<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"));
3210 #if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
3211 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
3212 add_option (_("Plugins/VST"),
3213 new RcActionButton (_("Scan for Plugins"),
3214 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3216 #if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
3217 bo = new BoolOption (
3219 _("Enable Mac VST support (requires restart or re-scan)"),
3220 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
3221 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
3223 add_option (_("Plugins/VST"), bo);
3226 bo = new BoolOption (
3227 "discover-vst-on-start",
3228 _("Scan for [new] VST Plugins on Application Start"),
3229 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
3230 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
3232 add_option (_("Plugins/VST"), bo);
3233 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3234 _("<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"));
3236 #ifdef WINDOWS_VST_SUPPORT
3237 // currently verbose logging is only implemented for Windows VST.
3238 bo = new BoolOption (
3239 "verbose-plugin-scan",
3240 _("Verbose Plugin Scan"),
3241 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
3242 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
3244 add_option (_("Plugins/VST"), bo);
3245 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3246 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
3249 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
3251 add_option (_("Plugins/VST"),
3252 new RcActionButton (_("Clear"),
3253 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
3256 add_option (_("Plugins/VST"),
3257 new RcActionButton (_("Clear"),
3258 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
3259 _("VST Blacklist:")));
3262 #ifdef LXVST_SUPPORT
3263 add_option (_("Plugins/VST"),
3264 new RcActionButton (_("Edit"),
3265 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
3266 _("Linux VST Path:")));
3268 add_option (_("Plugins/VST"),
3269 new RcConfigDisplay (
3270 "plugin-path-lxvst",
3272 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
3276 #ifdef WINDOWS_VST_SUPPORT
3277 add_option (_("Plugins/VST"),
3278 new RcActionButton (_("Edit"),
3279 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
3280 _("Windows VST Path:")));
3281 add_option (_("Plugins"),
3282 new RcConfigDisplay (
3285 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
3289 #ifdef AUDIOUNIT_SUPPORT
3291 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
3292 add_option (_("Plugins/Audio Unit"),
3293 new RcActionButton (_("Scan for Plugins"),
3294 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3296 bo = new BoolOption (
3297 "discover-audio-units",
3298 _("Scan for [new] AudioUnit Plugins on Application Start"),
3299 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
3300 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
3302 add_option (_("Plugins/Audio Unit"), bo);
3303 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3304 _("<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."));
3306 add_option (_("Plugins/Audio Unit"),
3307 new RcActionButton (_("Clear"),
3308 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
3311 add_option (_("Plugins/Audio Unit"),
3312 new RcActionButton (_("Clear"),
3313 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
3314 _("AU Blacklist:")));
3317 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
3318 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
3319 add_option (_("Plugins"),
3321 "open-gui-after-adding-plugin",
3322 _("Automatically open the plugin GUI when adding a new plugin"),
3323 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
3324 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3327 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3328 add_option (_("Plugins"),
3330 "show-inline-display-by-default",
3331 _("Show Plugin Inline Display on Mixerstrip by default"),
3332 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3333 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3336 _plugin_prefer_inline = new BoolOption (
3337 "prefer-inline-over-gui",
3338 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3339 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3340 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3342 add_option (_("Plugins"), _plugin_prefer_inline);
3345 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3347 bo = new BoolOption (
3348 "ask-replace-instrument",
3349 _("Ask to replace existing instrument plugin"),
3350 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3351 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3353 add_option (_("Plugins"), bo);
3355 bo = new BoolOption (
3356 "ask-setup_instrument",
3357 _("Interactively configure instrument plugins on insert"),
3358 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3359 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3361 add_option (_("Plugins"), bo);
3362 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3363 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3368 #if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
3369 add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Graphics Acceleration")));
3372 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3373 BoolOption* bgc = new BoolOption (
3374 "cairo-image-surface",
3375 _("Disable Graphics Hardware Acceleration (requires restart)"),
3376 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3377 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3380 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3381 _("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));
3382 add_option (S_("Preferences|GUI"), bgc);
3385 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3386 BoolOption* bgo = new BoolOption (
3388 _("Possibly improve slow graphical performance (requires restart)"),
3389 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3390 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3393 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));
3394 add_option (S_("Preferences|GUI"), bgo);
3397 add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Graphical User Interface")));
3398 add_option (S_("Preferences|GUI"),
3400 "use-wm-visibility",
3401 _("Use Window Manager/Desktop visibility information"),
3402 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3403 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3406 add_option (S_("Preferences|GUI"),
3409 _("Graphically indicate mouse pointer hovering over various widgets"),
3410 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3411 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3414 add_option (S_("Preferences|GUI"),
3417 _("Show tooltips if mouse hovers over a control"),
3418 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3419 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3422 add_option (S_("Preferences|GUI"),
3424 "show-name-highlight",
3425 _("Use name highlight bars in region displays (requires a restart)"),
3426 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3427 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3430 add_option (S_("Preferences|GUI"),
3432 "super-rapid-clock-update",
3433 _("Update transport clock display at FPS instead of every 100ms"),
3434 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3435 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3440 /* font scaling does nothing with GDK/Quartz */
3441 add_option (S_("Preferences|GUI"), new FontScalingOptions ());
3444 /* Image cache size */
3446 Gtk::Adjustment *ics = manage (new Gtk::Adjustment(0, 1, 1024, 10)); /* 1 MB to 1GB in steps of 10MB */
3447 HSliderOption *sics = new HSliderOption("waveform-cache-size",
3448 _("Waveform image cache size (megabytes)"),
3450 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
3451 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size)
3453 sics->scale().set_digits (0);
3454 Gtkmm2ext::UI::instance()->set_tip
3455 (sics->tip_widget(),
3456 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
3457 add_option (S_("Preferences|GUI"), sics);
3459 if (!ARDOUR::Profile->get_mixbus()) {
3460 /* Lock GUI timeout */
3462 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
3463 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
3464 _("Lock timeout (seconds)"),
3466 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
3467 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds)
3469 slts->scale().set_digits (0);
3470 Gtkmm2ext::UI::instance()->set_tip
3471 (slts->tip_widget(),
3472 _("Lock GUI after this many idle seconds (zero to never lock)"));
3473 add_option (S_("Preferences|GUI"), slts);
3476 /* The names of these controls must be the same as those given in MixerStrip
3477 for the actual widgets being controlled.
3479 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3480 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3481 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3482 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3483 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3484 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3485 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3488 S_("Preferences|GUI"),
3489 new VisibilityOption (
3491 &_mixer_strip_visibility,
3492 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3493 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3497 add_option (S_("Preferences|GUI"),
3499 "default-narrow_ms",
3500 _("Use narrow strips in the mixer by default"),
3501 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3502 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3506 OptionEditorHeading* i18n_head = new OptionEditorHeading (_("Internationalization"));
3507 i18n_head->set_note (string_compose (_("These settings will only take effect after %1 is restarted (if available for your language preferences)."), PROGRAM_NAME));
3509 add_option (_("GUI/Translation"), i18n_head);
3511 bo = new BoolOption (
3512 "enable-translation",
3513 _("Use translations"),
3514 sigc::ptr_fun (ARDOUR::translations_are_enabled),
3515 sigc::ptr_fun (ARDOUR::set_translations_enabled)
3518 add_option (_("GUI/Translation"), bo);
3520 _l10n = new ComboOption<ARDOUR::LocaleMode> (
3523 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_locale_mode),
3524 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_locale_mode)
3527 _l10n->add (ARDOUR::SET_LC_ALL, _("Set complete locale"));
3528 _l10n->add (ARDOUR::SET_LC_MESSAGES, _("Enable only message translation"));
3529 _l10n->add (ARDOUR::SET_LC_MESSAGES_AND_LC_NUMERIC, _("Translate messages and format numeric format"));
3530 _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."));
3532 add_option (_("GUI/Translation"), _l10n);
3533 parameter_changed ("enable-translation");
3534 #endif // ENABLE_NLS
3536 add_option (_("GUI/Keyboard"), new OptionEditorHeading (_("Keyboard")));
3537 add_option (_("GUI/Keyboard"), new KeyboardOptions);
3539 add_option (_("GUI/Toolbar"), new OptionEditorHeading (_("Main Transport Items")));
3541 add_option (_("GUI/Toolbar"),
3543 "show-toolbar-selclock",
3544 _("Display Selection Clock in the Toolbar"),
3545 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
3546 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
3549 if (!ARDOUR::Profile->get_small_screen()) {
3550 add_option (_("GUI/Toolbar"),
3552 "show-secondary-clock",
3553 _("Display Secondary Clock in the Toolbar"),
3554 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
3555 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
3559 add_option (_("GUI/Toolbar"),
3561 "show-mini-timeline",
3562 _("Display Navigation Timeline in the Toolbar"),
3563 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
3564 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
3567 add_option (_("GUI/Toolbar"),
3569 "show-editor-meter",
3570 _("Display Master Level Meter in the Toolbar"),
3571 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
3572 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
3575 add_option (_("GUI/Toolbar"),
3576 new ColumVisibilityOption (
3577 "action-table-columns", _("Action Script Button Visibility"), 4,
3578 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3579 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3584 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
3586 ComboOption<float>* mht = new ComboOption<float> (
3588 _("Peak hold time"),
3589 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
3590 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
3593 mht->add (MeterHoldOff, _("off"));
3594 mht->add (MeterHoldShort, _("short"));
3595 mht->add (MeterHoldMedium, _("medium"));
3596 mht->add (MeterHoldLong, _("long"));
3598 add_option (S_("Preferences|Metering"), mht);
3600 ComboOption<float>* mfo = new ComboOption<float> (
3603 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
3604 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
3607 mfo->add (METER_FALLOFF_OFF, _("off"));
3608 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
3609 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
3610 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
3611 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
3612 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
3613 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
3615 add_option (S_("Preferences|Metering"), mfo);
3617 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
3618 "meter-line-up-level",
3619 _("Meter line-up level; 0dBu"),
3620 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
3621 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
3624 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3625 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3626 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3627 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3629 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."));
3631 add_option (S_("Preferences|Metering"), mlu);
3633 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
3634 "meter-line-up-din",
3635 _("IEC1/DIN Meter line-up level; 0dBu"),
3636 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
3637 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
3640 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3641 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3642 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3643 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3645 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
3647 add_option (S_("Preferences|Metering"), mld);
3649 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
3650 "meter-vu-standard",
3651 _("VU Meter standard"),
3652 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
3653 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
3656 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
3657 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
3658 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
3659 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
3661 add_option (S_("Preferences|Metering"), mvu);
3663 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
3664 HSliderOption *mpks = new HSliderOption("meter-peak",
3665 _("Peak threshold [dBFS]"),
3667 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
3668 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak)
3672 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3673 "meter-type-master",
3674 _("Default Meter Type for Master Bus"),
3675 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3676 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3678 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3679 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3680 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3681 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3682 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3683 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3684 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3685 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3687 add_option (S_("Preferences|Metering"), mtm);
3690 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3692 _("Default Meter Type for Busses"),
3693 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3694 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3696 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3697 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3698 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3699 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3700 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3701 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3702 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3703 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3705 add_option (S_("Preferences|Metering"), mtb);
3707 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3709 _("Default Meter Type for Tracks"),
3710 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3711 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3713 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3714 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3716 add_option (S_("Preferences|Metering"), mtt);
3719 Gtkmm2ext::UI::instance()->set_tip
3720 (mpks->tip_widget(),
3721 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
3723 add_option (S_("Preferences|Metering"), mpks);
3725 add_option (S_("Preferences|Metering"),
3728 _("LED meter style"),
3729 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3730 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3733 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Editor Meters")));
3735 add_option (S_("Preferences|Metering"),
3737 "show-track-meters",
3738 _("Show meters on tracks in the editor"),
3739 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3740 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3743 add_option (S_("Preferences|Metering"),
3745 "editor-stereo-only-meters",
3746 _("Show at most stereo meters in the track-header"),
3747 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3748 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3751 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
3753 add_option (S_("Preferences|Metering"),
3755 "save-export-analysis-image",
3756 _("Save loudness analysis as image file"),
3757 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
3758 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
3761 /* and now the theme manager */
3763 ThemeManager* tm = manage (new ThemeManager);
3764 add_option (_("Theme"), new OptionEditorHeading (_("Theme")));
3765 add_page (_("Theme"), *tm);
3767 add_option (_("Theme/Colors"), new ColorThemeManager);
3769 Widget::show_all ();
3771 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3772 parameter_changed ("send-ltc");
3773 parameter_changed ("sync-source");
3774 parameter_changed ("use-monitor-bus");
3775 parameter_changed ("open-gui-after-adding-plugin");
3777 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
3779 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
3780 (Gtk::StateType) here !!!
3782 Tabbable::set_state (*node, Stateful::loading_state_version);
3787 RCOptionEditor::parameter_changed (string const & p)
3789 OptionEditor::parameter_changed (p);
3791 if (p == "use-monitor-bus") {
3792 bool const s = Config->get_use_monitor_bus ();
3794 /* we can't use this if we don't have a monitor bus */
3795 Config->set_solo_control_is_listen_control (false);
3797 _solo_control_is_listen_control->set_sensitive (s);
3798 _listen_position->set_sensitive (s);
3799 } else if (p == "sync-source") {
3800 _sync_source->set_sensitive (true);
3802 _sync_source->set_sensitive (!_session->config.get_external_sync());
3804 switch(Config->get_sync_source()) {
3807 _sync_genlock->set_sensitive (true);
3808 _sync_framerate->set_sensitive (true);
3809 _sync_source_2997->set_sensitive (true);
3812 _sync_genlock->set_sensitive (false);
3813 _sync_framerate->set_sensitive (false);
3814 _sync_source_2997->set_sensitive (false);
3817 } else if (p == "send-ltc") {
3818 bool const s = Config->get_send_ltc ();
3819 _ltc_send_continuously->set_sensitive (s);
3820 _ltc_volume_slider->set_sensitive (s);
3821 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
3822 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3823 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
3826 } else if (p == "enable-translation") {
3827 _l10n->set_sensitive (ARDOUR::translations_are_enabled ());
3832 void RCOptionEditor::ltc_generator_volume_changed () {
3833 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
3836 void RCOptionEditor::plugin_scan_refresh () {
3837 PluginManager::instance().refresh();
3840 void RCOptionEditor::clear_vst_cache () {
3841 PluginManager::instance().clear_vst_cache();
3844 void RCOptionEditor::clear_vst_blacklist () {
3845 PluginManager::instance().clear_vst_blacklist();
3848 void RCOptionEditor::clear_au_cache () {
3849 PluginManager::instance().clear_au_cache();
3852 void RCOptionEditor::clear_au_blacklist () {
3853 PluginManager::instance().clear_au_blacklist();
3856 void RCOptionEditor::edit_lxvst_path () {
3857 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
3858 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3859 *current_toplevel(), _("Set Linux VST Search Path"),
3860 _rc_config->get_plugin_path_lxvst(),
3861 PluginManager::instance().get_default_lxvst_path()
3863 ResponseType r = (ResponseType) pd->run ();
3865 if (r == RESPONSE_ACCEPT) {
3866 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
3871 void RCOptionEditor::edit_vst_path () {
3872 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3873 *current_toplevel(), _("Set Windows VST Search Path"),
3874 _rc_config->get_plugin_path_vst(),
3875 PluginManager::instance().get_default_windows_vst_path()
3877 ResponseType r = (ResponseType) pd->run ();
3879 if (r == RESPONSE_ACCEPT) {
3880 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
3887 RCOptionEditor::populate_sync_options ()
3889 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3891 _sync_source->clear ();
3893 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3894 _sync_source->add (*i, sync_source_to_string (*i));
3897 if (sync_opts.empty()) {
3898 _sync_source->set_sensitive(false);
3900 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3901 _rc_config->set_sync_source(sync_opts.front());
3905 parameter_changed ("sync-source");
3909 RCOptionEditor::use_own_window (bool and_fill_it)
3911 bool new_window = !own_window ();
3913 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
3915 if (win && new_window) {
3916 win->set_name ("PreferencesWindow");
3917 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
3924 RCOptionEditor::get_state ()
3926 XMLNode* node = new XMLNode (X_("Preferences"));
3927 node->add_child_nocopy (Tabbable::get_state());