2 Copyright (C) 2001-2011 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "gtk2ardour-config.h"
24 #if !defined USE_CAIRO_IMAGE_SURFACE && !defined NDEBUG
25 #define OPTIONAL_CAIRO_IMAGE_SURFACE
28 #include <cairo/cairo.h>
30 #include <boost/algorithm/string.hpp>
32 #include <gtkmm/liststore.h>
33 #include <gtkmm/stock.h>
34 #include <gtkmm/scale.h>
36 #include <gtkmm2ext/utils.h>
37 #include <gtkmm2ext/slider_controller.h>
38 #include <gtkmm2ext/gtk_ui.h>
39 #include <gtkmm2ext/paths_dialog.h>
40 #include <gtkmm2ext/window_title.h>
46 #include "ardour/audio_backend.h"
47 #include "ardour/audioengine.h"
48 #include "ardour/profile.h"
49 #include "ardour/dB.h"
50 #include "ardour/rc_configuration.h"
51 #include "ardour/control_protocol_manager.h"
52 #include "ardour/port_manager.h"
53 #include "ardour/plugin_manager.h"
54 #include "control_protocol/control_protocol.h"
56 #include "canvas/wave_view.h"
58 #include "ardour_dialog.h"
59 #include "ardour_ui.h"
60 #include "ardour_window.h"
61 #include "color_theme_manager.h"
62 #include "gui_thread.h"
64 #include "meter_patterns.h"
65 #include "midi_tracer.h"
66 #include "rc_option_editor.h"
69 #include "ui_config.h"
74 using namespace Gtkmm2ext;
76 using namespace ARDOUR;
77 using namespace ARDOUR_UI_UTILS;
79 class ClickOptions : public OptionEditorMiniPage
82 ClickOptions (RCConfiguration* c)
84 , _click_browse_button (_("Browse..."))
85 , _click_emphasis_browse_button (_("Browse..."))
87 // TODO get rid of GTK -> use OptionEditor Widgets
92 l = manage (left_aligned_label (_("Emphasis on first beat")));
93 _use_emphasis_on_click_check_button.add (*l);
94 t->attach (_use_emphasis_on_click_check_button, 1, 3, row, row + 1, FILL);
95 _use_emphasis_on_click_check_button.signal_toggled().connect (
96 sigc::mem_fun (*this, &ClickOptions::use_emphasis_on_click_toggled));
99 l = manage (left_aligned_label (_("Use built-in default sounds")));
100 _use_default_click_check_button.add (*l);
101 t->attach (_use_default_click_check_button, 1, 3, row, row + 1, FILL);
102 _use_default_click_check_button.signal_toggled().connect (
103 sigc::mem_fun (*this, &ClickOptions::use_default_click_toggled));
106 l = manage (left_aligned_label (_("Audio file:")));
107 t->attach (*l, 1, 2, row, row + 1, FILL);
108 t->attach (_click_path_entry, 2, 3, row, row + 1, FILL);
109 _click_browse_button.signal_clicked ().connect (
110 sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
111 t->attach (_click_browse_button, 3, 4, row, row + 1, FILL);
114 l = manage (left_aligned_label (_("Emphasis audio file:")));
115 t->attach (*l, 1, 2, row, row + 1, FILL);
116 t->attach (_click_emphasis_path_entry, 2, 3, row, row + 1, FILL);
117 _click_emphasis_browse_button.signal_clicked ().connect (
118 sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
119 t->attach (_click_emphasis_browse_button, 3, 4, row, row + 1, FILL);
122 _click_fader = new FaderOption (
125 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
126 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
129 _click_fader->add_to_page (this);
130 _click_fader->set_state_from_config ();
132 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
133 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
135 if (_rc_config->get_click_sound ().empty() &&
136 _rc_config->get_click_emphasis_sound().empty()) {
137 _use_default_click_check_button.set_active (true);
138 _use_emphasis_on_click_check_button.set_active (true);
141 _use_default_click_check_button.set_active (false);
142 _use_emphasis_on_click_check_button.set_active (false);
146 void parameter_changed (string const & p)
148 if (p == "click-sound") {
149 _click_path_entry.set_text (_rc_config->get_click_sound());
150 } else if (p == "click-emphasis-sound") {
151 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
152 } else if (p == "use-click-emphasis") {
153 bool x = _rc_config->get_use_click_emphasis ();
154 _use_emphasis_on_click_check_button.set_active (x);
155 } else if (p == "click-gain") {
156 _click_fader->set_state_from_config ();
160 void set_state_from_config ()
162 parameter_changed ("click-sound");
163 parameter_changed ("click-emphasis-sound");
164 parameter_changed ("use-click-emphasis");
169 void click_browse_clicked ()
171 SoundFileChooser sfdb (_("Choose Click"));
176 if (sfdb.run () == RESPONSE_OK) {
177 click_chosen (sfdb.get_filename());
181 void click_chosen (string const & path)
183 _click_path_entry.set_text (path);
184 _rc_config->set_click_sound (path);
187 void click_changed ()
189 click_chosen (_click_path_entry.get_text ());
192 void click_emphasis_browse_clicked ()
194 SoundFileChooser sfdb (_("Choose Click Emphasis"));
199 if (sfdb.run () == RESPONSE_OK) {
200 click_emphasis_chosen (sfdb.get_filename());
204 void click_emphasis_chosen (string const & path)
206 _click_emphasis_path_entry.set_text (path);
207 _rc_config->set_click_emphasis_sound (path);
210 void click_emphasis_changed ()
212 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
215 void use_default_click_toggled ()
217 if (_use_default_click_check_button.get_active ()) {
218 _rc_config->set_click_sound ("");
219 _rc_config->set_click_emphasis_sound ("");
220 _click_path_entry.set_sensitive (false);
221 _click_emphasis_path_entry.set_sensitive (false);
222 _click_browse_button.set_sensitive (false);
223 _click_emphasis_browse_button.set_sensitive (false);
225 _click_path_entry.set_sensitive (true);
226 _click_emphasis_path_entry.set_sensitive (true);
227 _click_browse_button.set_sensitive (true);
228 _click_emphasis_browse_button.set_sensitive (true);
232 void use_emphasis_on_click_toggled ()
234 if (_use_emphasis_on_click_check_button.get_active ()) {
235 _rc_config->set_use_click_emphasis(true);
237 _rc_config->set_use_click_emphasis(false);
241 RCConfiguration* _rc_config;
242 CheckButton _use_default_click_check_button;
243 CheckButton _use_emphasis_on_click_check_button;
244 Entry _click_path_entry;
245 Entry _click_emphasis_path_entry;
246 Button _click_browse_button;
247 Button _click_emphasis_browse_button;
248 FaderOption* _click_fader;
251 class UndoOptions : public OptionEditorComponent
254 UndoOptions (RCConfiguration* c) :
256 _limit_undo_button (_("Limit undo history to")),
257 _save_undo_button (_("Save undo history of"))
259 // TODO get rid of GTK -> use OptionEditor SpinOption
260 _limit_undo_spin.set_range (0, 512);
261 _limit_undo_spin.set_increments (1, 10);
263 _save_undo_spin.set_range (0, 512);
264 _save_undo_spin.set_increments (1, 10);
266 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
267 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
268 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
269 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
272 void parameter_changed (string const & p)
274 if (p == "history-depth") {
275 int32_t const d = _rc_config->get_history_depth();
276 _limit_undo_button.set_active (d != 0);
277 _limit_undo_spin.set_sensitive (d != 0);
278 _limit_undo_spin.set_value (d);
279 } else if (p == "save-history") {
280 bool const x = _rc_config->get_save_history ();
281 _save_undo_button.set_active (x);
282 _save_undo_spin.set_sensitive (x);
283 } else if (p == "save-history-depth") {
284 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
288 void set_state_from_config ()
290 parameter_changed ("save-history");
291 parameter_changed ("history-depth");
292 parameter_changed ("save-history-depth");
295 void limit_undo_toggled ()
297 bool const x = _limit_undo_button.get_active ();
298 _limit_undo_spin.set_sensitive (x);
299 int32_t const n = x ? 16 : 0;
300 _limit_undo_spin.set_value (n);
301 _rc_config->set_history_depth (n);
304 void limit_undo_changed ()
306 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
309 void save_undo_toggled ()
311 bool const x = _save_undo_button.get_active ();
312 _rc_config->set_save_history (x);
315 void save_undo_changed ()
317 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
320 void add_to_page (OptionEditorPage* p)
322 int const n = p->table.property_n_rows();
323 Table* t = & p->table;
325 t->resize (n + 2, 3);
327 Label* l = manage (left_aligned_label (_("commands")));
328 HBox* box = manage (new HBox());
329 box->set_spacing (4);
330 box->pack_start (_limit_undo_spin, false, false);
331 box->pack_start (*l, true, true);
332 t->attach (_limit_undo_button, 1, 2, n, n +1, FILL);
333 t->attach (*box, 2, 3, n, n + 1, FILL | EXPAND);
335 l = manage (left_aligned_label (_("commands")));
336 box = manage (new HBox());
337 box->set_spacing (4);
338 box->pack_start (_save_undo_spin, false, false);
339 box->pack_start (*l, true, true);
340 t->attach (_save_undo_button, 1, 2, n + 1, n + 2, FILL);
341 t->attach (*box, 2, 3, n + 1, n + 2, FILL | EXPAND);
344 Gtk::Widget& tip_widget() {
345 return _limit_undo_button; // unused
349 RCConfiguration* _rc_config;
350 CheckButton _limit_undo_button;
351 SpinButton _limit_undo_spin;
352 CheckButton _save_undo_button;
353 SpinButton _save_undo_spin;
357 static const struct {
369 { "Key|Shift", GDK_SHIFT_MASK },
370 { "Command", GDK_MOD2_MASK },
371 { "Control", GDK_CONTROL_MASK },
372 { "Option", GDK_MOD1_MASK },
373 { "Command-Shift", GDK_MOD2_MASK|GDK_SHIFT_MASK },
374 { "Command-Option", GDK_MOD2_MASK|GDK_MOD1_MASK },
375 { "Command-Control", GDK_MOD2_MASK|GDK_CONTROL_MASK },
376 { "Command-Option-Control", GDK_MOD2_MASK|GDK_MOD1_MASK|GDK_CONTROL_MASK },
377 { "Option-Control", GDK_MOD1_MASK|GDK_CONTROL_MASK },
378 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
379 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
380 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_MOD2_MASK },
383 { "Key|Shift", GDK_SHIFT_MASK },
384 { "Control", GDK_CONTROL_MASK },
385 { "Alt", GDK_MOD1_MASK },
386 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
387 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
388 { "Control-Windows", GDK_CONTROL_MASK|GDK_MOD4_MASK },
389 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
390 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
391 { "Alt-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
392 { "Alt-Shift-Windows", GDK_MOD1_MASK|GDK_SHIFT_MASK|GDK_MOD4_MASK },
393 { "Mod2", GDK_MOD2_MASK },
394 { "Mod3", GDK_MOD3_MASK },
395 { "Windows", GDK_MOD4_MASK },
396 { "Mod5", GDK_MOD5_MASK },
402 class KeyboardOptions : public OptionEditorMiniPage
406 : _delete_button_adjustment (3, 1, 12)
407 , _delete_button_spin (_delete_button_adjustment)
408 , _edit_button_adjustment (3, 1, 5)
409 , _edit_button_spin (_edit_button_adjustment)
410 , _insert_note_button_adjustment (3, 1, 5)
411 , _insert_note_button_spin (_insert_note_button_adjustment)
413 // TODO get rid of GTK -> use OptionEditor Widgets
415 const std::string restart_msg = _("\nChanges to this setting will only persist after your project has been saved.");
416 /* internationalize and prepare for use with combos */
419 for (int i = 0; modifiers[i].name; ++i) {
420 dumb.push_back (S_(modifiers[i].name));
423 set_popdown_strings (_edit_modifier_combo, dumb);
424 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
425 Gtkmm2ext::UI::instance()->set_tip (_edit_modifier_combo,
426 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
433 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
434 l->set_name ("OptionsLabel");
438 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
439 strs.push_back (bf->first);
442 set_popdown_strings (_keyboard_layout_selector, strs);
443 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
444 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
446 t->attach (*l, col + 1, col + 2, row, row + 1, FILL, FILL);
447 t->attach (_keyboard_layout_selector, col + 2, col + 3, row, row + 1, FILL | EXPAND, FILL);
452 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Clicking:"))));
453 l->set_name ("OptionEditorHeading");
454 l->set_use_markup (true);
455 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
460 l = manage (left_aligned_label (_("Edit using:")));
461 l->set_name ("OptionsLabel");
463 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
464 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
466 l = manage (new Label (_("+ button")));
467 l->set_name ("OptionsLabel");
469 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
470 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, SHRINK , FILL);
472 _edit_button_spin.set_name ("OptionsEntry");
473 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
478 set_popdown_strings (_delete_modifier_combo, dumb);
479 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
480 Gtkmm2ext::UI::instance()->set_tip (_delete_modifier_combo,
481 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
483 l = manage (left_aligned_label (_("Delete using:")));
484 l->set_name ("OptionsLabel");
486 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
487 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
489 l = manage (new Label (_("+ button")));
490 l->set_name ("OptionsLabel");
492 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
493 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, SHRINK, FILL);
495 _delete_button_spin.set_name ("OptionsEntry");
496 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
501 set_popdown_strings (_insert_note_modifier_combo, dumb);
502 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
503 Gtkmm2ext::UI::instance()->set_tip (_insert_note_modifier_combo,
504 (string_compose (_("<b>Recommended Setting: %1 + button 1 (left mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
506 l = manage (left_aligned_label (_("Insert note using:")));
507 l->set_name ("OptionsLabel");
509 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
510 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
512 l = manage (new Label (_("+ button")));
513 l->set_name ("OptionsLabel");
515 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
516 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, SHRINK, FILL);
518 _insert_note_button_spin.set_name ("OptionsEntry");
519 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
523 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Beginning a Drag:"))));
524 l->set_name ("OptionEditorHeading");
525 l->set_use_markup (true);
526 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
532 set_popdown_strings (_copy_modifier_combo, dumb);
533 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
534 Gtkmm2ext::UI::instance()->set_tip (_copy_modifier_combo,
535 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
537 Keyboard::secondary_modifier_name (),
539 Keyboard::primary_modifier_name (),
543 l = manage (left_aligned_label (_("Copy items using:")));
544 l->set_name ("OptionsLabel");
546 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
547 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
552 /* constraint modifier */
553 set_popdown_strings (_constraint_modifier_combo, dumb);
554 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
555 Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo,
556 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
558 Keyboard::primary_modifier_name (),
560 Keyboard::tertiary_modifier_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, 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 std::string 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)));
581 l = manage (left_aligned_label (_("Push points using:")));
582 l->set_name ("OptionsLabel");
584 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
585 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
589 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Beginning a Trim:"))));
590 l->set_name ("OptionEditorHeading");
591 l->set_use_markup (true);
592 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
598 set_popdown_strings (_trim_contents_combo, dumb);
599 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
600 Gtkmm2ext::UI::instance()->set_tip (_trim_contents_combo,
601 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
603 l = manage (left_aligned_label (_("Trim contents using:")));
604 l->set_name ("OptionsLabel");
606 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
607 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
613 set_popdown_strings (_trim_anchored_combo, dumb);
614 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
616 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::tertiary_modifier_name ());
617 Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo,
618 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
620 l = manage (left_aligned_label (_("Anchored trim using:")));
621 l->set_name ("OptionsLabel");
623 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
625 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
630 /* jump trim disabled for now
631 set_popdown_strings (_trim_jump_combo, dumb);
632 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
634 l = manage (left_aligned_label (_("Jump after trim using:")));
635 l->set_name ("OptionsLabel");
637 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
639 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
645 /* note resize relative */
646 set_popdown_strings (_note_size_relative_combo, dumb);
647 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
648 Gtkmm2ext::UI::instance()->set_tip (_note_size_relative_combo,
649 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg))); // XXX 2ndary
651 l = manage (left_aligned_label (_("Resize notes relatively using:")));
652 l->set_name ("OptionsLabel");
654 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
656 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
660 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Dragging:"))));
661 l->set_name ("OptionEditorHeading");
662 l->set_use_markup (true);
663 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
669 set_popdown_strings (_snap_modifier_combo, dumb);
670 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
672 mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ());
674 mod_str = Keyboard::secondary_modifier_name();
676 Gtkmm2ext::UI::instance()->set_tip (_snap_modifier_combo,
677 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
679 l = manage (left_aligned_label (_("Ignore snap using:")));
680 l->set_name ("OptionsLabel");
682 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
683 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
689 set_popdown_strings (_snap_delta_combo, dumb);
690 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
692 mod_str = Keyboard::level4_modifier_name ();
694 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::level4_modifier_name ());
696 Gtkmm2ext::UI::instance()->set_tip (_snap_delta_combo,
697 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
699 l = manage (left_aligned_label (_("Snap relatively using:")));
700 l->set_name ("OptionsLabel");
702 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
703 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
707 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Trimming:"))));
708 l->set_name ("OptionEditorHeading");
709 l->set_use_markup (true);
710 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
716 set_popdown_strings (_trim_overlap_combo, dumb);
717 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
719 Gtkmm2ext::UI::instance()->set_tip (_trim_overlap_combo,
720 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
722 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
723 l->set_name ("OptionsLabel");
725 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
726 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
730 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Dragging Control Points:"))));
731 l->set_name ("OptionEditorHeading");
732 l->set_use_markup (true);
733 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
739 set_popdown_strings (_fine_adjust_combo, dumb);
740 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
742 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::secondary_modifier_name ()); // XXX just 2ndary ?!
743 Gtkmm2ext::UI::instance()->set_tip (_fine_adjust_combo,
744 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
746 l = manage (left_aligned_label (_("Fine adjust using:")));
747 l->set_name ("OptionsLabel");
749 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
750 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
752 OptionEditorHeading* h = new OptionEditorHeading (_("Reset"));
753 h->add_to_page (this);
755 RcActionButton* rb = new RcActionButton (_("Reset to recommended defaults"),
756 sigc::mem_fun (*this, &KeyboardOptions::reset_to_defaults));
757 rb->add_to_page (this);
759 set_state_from_config ();
762 void parameter_changed (string const &)
764 /* XXX: these aren't really config options... */
767 void set_state_from_config ()
769 _delete_button_adjustment.set_value (Keyboard::delete_button());
770 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
771 _edit_button_adjustment.set_value (Keyboard::edit_button());
773 for (int x = 0; modifiers[x].name; ++x) {
774 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
775 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
777 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
778 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
780 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
781 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
783 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
784 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
786 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
787 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
789 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
790 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
792 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
793 _push_points_combo.set_active_text (S_(modifiers[x].name));
795 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
796 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
798 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
799 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
802 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
803 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
806 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
807 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
809 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
810 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
812 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
813 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
815 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
816 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
821 void add_to_page (OptionEditorPage* p)
823 int const n = p->table.property_n_rows();
824 p->table.resize (n + 1, 3);
825 p->table.attach (box, 1, 3, n, n + 1, FILL | EXPAND, SHRINK, 0, 0);
830 void bindings_changed ()
832 string const txt = _keyboard_layout_selector.get_active_text();
834 /* XXX: config...? for all this keyboard stuff */
836 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
837 if (txt == i->first) {
838 if (Keyboard::load_keybindings (i->second)) {
839 Keyboard::save_keybindings ();
845 void edit_modifier_chosen ()
847 string const txt = _edit_modifier_combo.get_active_text();
849 for (int i = 0; modifiers[i].name; ++i) {
850 if (txt == S_(modifiers[i].name)) {
851 Keyboard::set_edit_modifier (modifiers[i].modifier);
857 void delete_modifier_chosen ()
859 string const txt = _delete_modifier_combo.get_active_text();
861 for (int i = 0; modifiers[i].name; ++i) {
862 if (txt == S_(modifiers[i].name)) {
863 Keyboard::set_delete_modifier (modifiers[i].modifier);
869 void copy_modifier_chosen ()
871 string const txt = _copy_modifier_combo.get_active_text();
873 for (int i = 0; modifiers[i].name; ++i) {
874 if (txt == S_(modifiers[i].name)) {
875 Keyboard::set_copy_modifier (modifiers[i].modifier);
881 void insert_note_modifier_chosen ()
883 string const txt = _insert_note_modifier_combo.get_active_text();
885 for (int i = 0; modifiers[i].name; ++i) {
886 if (txt == S_(modifiers[i].name)) {
887 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
893 void snap_modifier_chosen ()
895 string const txt = _snap_modifier_combo.get_active_text();
897 for (int i = 0; modifiers[i].name; ++i) {
898 if (txt == S_(modifiers[i].name)) {
899 Keyboard::set_snap_modifier (modifiers[i].modifier);
905 void snap_delta_modifier_chosen ()
907 string const txt = _snap_delta_combo.get_active_text();
909 for (int i = 0; modifiers[i].name; ++i) {
910 if (txt == S_(modifiers[i].name)) {
911 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
917 void constraint_modifier_chosen ()
919 string const txt = _constraint_modifier_combo.get_active_text();
921 for (int i = 0; modifiers[i].name; ++i) {
922 if (txt == S_(modifiers[i].name)) {
923 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
929 void trim_contents_modifier_chosen ()
931 string const txt = _trim_contents_combo.get_active_text();
933 for (int i = 0; modifiers[i].name; ++i) {
934 if (txt == S_(modifiers[i].name)) {
935 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
941 void trim_overlap_modifier_chosen ()
943 string const txt = _trim_overlap_combo.get_active_text();
945 for (int i = 0; modifiers[i].name; ++i) {
946 if (txt == S_(modifiers[i].name)) {
947 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
953 void trim_anchored_modifier_chosen ()
955 string const txt = _trim_anchored_combo.get_active_text();
957 for (int i = 0; modifiers[i].name; ++i) {
958 if (txt == S_(modifiers[i].name)) {
959 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
965 void fine_adjust_modifier_chosen ()
967 string const txt = _fine_adjust_combo.get_active_text();
969 for (int i = 0; modifiers[i].name; ++i) {
970 if (txt == S_(modifiers[i].name)) {
971 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
977 void push_points_modifier_chosen ()
979 string const txt = _push_points_combo.get_active_text();
981 for (int i = 0; modifiers[i].name; ++i) {
982 if (txt == S_(modifiers[i].name)) {
983 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
989 void note_size_relative_modifier_chosen ()
991 string const txt = _note_size_relative_combo.get_active_text();
993 for (int i = 0; modifiers[i].name; ++i) {
994 if (txt == S_(modifiers[i].name)) {
995 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
1001 void delete_button_changed ()
1003 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
1006 void edit_button_changed ()
1008 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
1011 void insert_note_button_changed ()
1013 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
1016 void reset_to_defaults ()
1019 Keyboard::set_edit_modifier (Keyboard::PrimaryModifier);
1020 Keyboard::set_edit_button (3);
1021 Keyboard::set_delete_modifier (Keyboard::TertiaryModifier);
1022 Keyboard::set_delete_button (3);
1023 Keyboard::set_insert_note_modifier (Keyboard::PrimaryModifier);
1024 Keyboard::set_insert_note_button (1);
1026 /* when beginning a drag */
1028 Keyboard::set_copy_modifier (Keyboard::SecondaryModifier);
1030 Keyboard::set_copy_modifier (Keyboard::PrimaryModifier);
1034 ArdourKeyboard::set_constraint_modifier (Keyboard::PrimaryModifier);
1036 ArdourKeyboard::set_constraint_modifier (Keyboard::TertiaryModifier);
1038 ArdourKeyboard::set_push_points_modifier (Keyboard::PrimaryModifier | Keyboard::Level4Modifier);
1040 /* when beginning a trim */
1041 ArdourKeyboard::set_trim_contents_modifier (Keyboard::PrimaryModifier);
1042 ArdourKeyboard::set_trim_anchored_modifier (Keyboard::PrimaryModifier | Keyboard::TertiaryModifier);
1043 ArdourKeyboard::set_note_size_relative_modifier (Keyboard::TertiaryModifier); // XXX better: 2ndary
1045 /* while dragging */
1047 Keyboard::set_snap_modifier (Keyboard::TertiaryModifier);
1049 Keyboard::set_snap_modifier (Keyboard::SecondaryModifier);
1052 Keyboard::set_snap_delta_modifier (Keyboard::Level4Modifier);
1054 Keyboard::set_snap_delta_modifier (Keyboard::SecondaryModifier | Keyboard::Level4Modifier);
1057 /* while trimming */
1058 ArdourKeyboard::set_trim_overlap_modifier (Keyboard::TertiaryModifier);
1060 /* while dragging ctrl points */
1061 ArdourKeyboard::set_fine_adjust_modifier (/*Keyboard::PrimaryModifier | */Keyboard::SecondaryModifier); // XXX
1063 set_state_from_config ();
1066 ComboBoxText _keyboard_layout_selector;
1067 ComboBoxText _edit_modifier_combo;
1068 ComboBoxText _delete_modifier_combo;
1069 ComboBoxText _copy_modifier_combo;
1070 ComboBoxText _insert_note_modifier_combo;
1071 ComboBoxText _snap_modifier_combo;
1072 ComboBoxText _snap_delta_combo;
1073 ComboBoxText _constraint_modifier_combo;
1074 ComboBoxText _trim_contents_combo;
1075 ComboBoxText _trim_overlap_combo;
1076 ComboBoxText _trim_anchored_combo;
1077 ComboBoxText _trim_jump_combo;
1078 ComboBoxText _fine_adjust_combo;
1079 ComboBoxText _push_points_combo;
1080 ComboBoxText _note_size_relative_combo;
1081 Adjustment _delete_button_adjustment;
1082 SpinButton _delete_button_spin;
1083 Adjustment _edit_button_adjustment;
1084 SpinButton _edit_button_spin;
1085 Adjustment _insert_note_button_adjustment;
1086 SpinButton _insert_note_button_spin;
1090 class FontScalingOptions : public HSliderOption
1093 FontScalingOptions ()
1094 : HSliderOption ("font-scale", _("GUI and Font scaling"),
1095 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_font_scale),
1096 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_font_scale),
1100 const std::string dflt = _("100%");
1101 const std::string empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
1103 _hscale.set_name("FontScaleSlider");
1104 _hscale.set_draw_value(false);
1105 _hscale.add_mark(50, Gtk::POS_TOP, empty);
1106 _hscale.add_mark(60, Gtk::POS_TOP, empty);
1107 _hscale.add_mark(70, Gtk::POS_TOP, empty);
1108 _hscale.add_mark(80, Gtk::POS_TOP, empty);
1109 _hscale.add_mark(90, Gtk::POS_TOP, empty);
1110 _hscale.add_mark(100, Gtk::POS_TOP, dflt);
1111 _hscale.add_mark(125, Gtk::POS_TOP, empty);
1112 _hscale.add_mark(150, Gtk::POS_TOP, empty);
1113 _hscale.add_mark(175, Gtk::POS_TOP, empty);
1114 _hscale.add_mark(200, Gtk::POS_TOP, empty);
1115 _hscale.add_mark(250, Gtk::POS_TOP, empty);
1117 set_note (_("Adjusting the scale requires an application restart to re-layout."));
1122 HSliderOption::changed ();
1123 /* XXX: should be triggered from the parameter changed signal */
1124 UIConfiguration::instance().reset_dpi ();
1128 class VstTimeOutSliderOption : public HSliderOption
1131 VstTimeOutSliderOption (RCConfiguration* c)
1132 : HSliderOption ("vst-scan-timeout", _("Scan Time Out"),
1133 sigc::mem_fun (*c, &RCConfiguration::get_vst_scan_timeout),
1134 sigc::mem_fun (*c, &RCConfiguration::set_vst_scan_timeout),
1137 _label.set_alignment (1.0, 0.5); // match buttons below
1138 _hscale.set_digits (0);
1139 _hscale.set_draw_value(false);
1140 _hscale.add_mark( 0, Gtk::POS_TOP, _("\u221e")); // infinity
1141 _hscale.add_mark( 300, Gtk::POS_TOP, _("30 sec"));
1142 _hscale.add_mark( 600, Gtk::POS_TOP, _("1 min"));
1143 _hscale.add_mark(1200, Gtk::POS_TOP, _("2 mins"));
1144 _hscale.add_mark(1800, Gtk::POS_TOP, _("3 mins"));
1145 _hscale.add_mark(2400, Gtk::POS_TOP, _("4 mins"));
1146 _hscale.add_mark(3000, Gtk::POS_TOP, _("5 mins"));
1148 Gtkmm2ext::UI::instance()->set_tip(_hscale,
1149 _("Specify the default timeout for plugin instantiation. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1153 class ClipLevelOptions : public OptionEditorComponent
1157 : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1158 , _clip_level_slider (_clip_level_adjustment)
1159 , _label (_("Waveform Clip Level (dBFS):"))
1161 _label.set_name ("OptionsLabel");
1163 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ());
1165 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1167 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1170 void parameter_changed (string const & p)
1172 if (p == "waveform-clip-level") {
1173 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level());
1175 if (p == "show-waveform-clipping") {
1176 _clip_level_slider.set_sensitive (UIConfiguration::instance().get_show_waveform_clipping ());
1180 void set_state_from_config ()
1182 parameter_changed ("waveform-clip-level");
1183 parameter_changed ("show-waveform-clipping");
1186 void add_to_page (OptionEditorPage* p) {
1187 add_widgets_to_page (p, &_label, &_clip_level_slider);
1190 Gtk::Widget& tip_widget() {
1191 return _clip_level_slider;
1196 void clip_level_changed ()
1198 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1199 /* XXX: should be triggered from the parameter changed signal */
1200 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1203 Adjustment _clip_level_adjustment;
1204 HScale _clip_level_slider;
1208 class BufferingOptions : public OptionEditorComponent
1211 BufferingOptions (RCConfiguration* c)
1213 , _label (_("Preset:"))
1214 , _playback ("playback-buffer-seconds", _("Playback (seconds of buffering)"),
1215 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_playback_buffer_seconds),
1216 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_playback_buffer_seconds),
1218 , _capture ("capture-buffer-seconds", _("Recording (seconds of buffering)"),
1219 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_capture_buffer_seconds),
1220 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_capture_buffer_seconds),
1223 // TODO use ComboOption
1224 vector<string> presets;
1226 /* these must match the order of the enums for BufferingPreset */
1227 presets.push_back (_("Small sessions (4-16 tracks)"));
1228 presets.push_back (_("Medium sessions (16-64 tracks)"));
1229 presets.push_back (_("Large sessions (64+ tracks)"));
1230 presets.push_back (_("Custom (set by sliders below)"));
1232 set_popdown_strings (_buffering_presets_combo, presets);
1233 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1235 _label.set_name ("OptionsLabel");
1236 _label.set_alignment (0, 0.5);
1240 add_to_page (OptionEditorPage* p)
1242 add_widgets_to_page (p, &_label, &_buffering_presets_combo);
1243 _playback.add_to_page (p);
1244 _capture.add_to_page (p);
1247 void parameter_changed (string const & p)
1249 if (p == "buffering-preset") {
1250 switch (_rc_config->get_buffering_preset()) {
1252 _playback.set_sensitive (false);
1253 _capture.set_sensitive (false);
1254 _buffering_presets_combo.set_active (0);
1257 _playback.set_sensitive (false);
1258 _capture.set_sensitive (false);
1259 _buffering_presets_combo.set_active (1);
1262 _playback.set_sensitive (false);
1263 _capture.set_sensitive (false);
1264 _buffering_presets_combo.set_active (2);
1267 _playback.set_sensitive (true);
1268 _capture.set_sensitive (true);
1269 _buffering_presets_combo.set_active (3);
1273 _playback.parameter_changed (p);
1274 _capture.parameter_changed (p);
1277 void set_state_from_config ()
1279 parameter_changed ("buffering-preset");
1280 _playback.set_state_from_config();
1281 _capture.set_state_from_config();
1284 Gtk::Widget& tip_widget() { return _buffering_presets_combo; }
1288 void preset_changed ()
1290 int index = _buffering_presets_combo.get_active_row_number ();
1296 _rc_config->set_buffering_preset (Small);
1299 _rc_config->set_buffering_preset (Medium);
1302 _rc_config->set_buffering_preset (Large);
1305 _rc_config->set_buffering_preset (Custom);
1308 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1313 RCConfiguration* _rc_config;
1315 HSliderOption _playback;
1316 HSliderOption _capture;
1317 ComboBoxText _buffering_presets_combo;
1320 class ControlSurfacesOptions : public OptionEditorMiniPage
1323 ControlSurfacesOptions ()
1324 : _ignore_view_change (0)
1326 _store = ListStore::create (_model);
1327 _view.set_model (_store);
1328 _view.append_column (_("Control Surface Protocol"), _model.name);
1329 _view.get_column(0)->set_resizable (true);
1330 _view.get_column(0)->set_expand (true);
1331 _view.append_column_editable (_("Enable"), _model.enabled);
1333 Gtk::HBox* edit_box = manage (new Gtk::HBox);
1334 edit_box->set_spacing(3);
1337 Label* label = manage (new Label);
1338 label->set_text (_("Edit the settings for selected protocol (it must be ENABLED first):"));
1339 edit_box->pack_start (*label, false, false);
1342 edit_button = manage (new Button(_("Show Protocol Settings")));
1343 edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
1344 edit_box->pack_start (*edit_button, true, true);
1345 edit_button->set_sensitive (false);
1346 edit_button->show ();
1348 int const n = table.property_n_rows();
1349 table.resize (n + 2, 3);
1350 table.attach (_view, 0, 3, n, n + 1);
1351 table.attach (*edit_box, 0, 3, n + 1, n + 2);
1353 ControlProtocolManager& m = ControlProtocolManager::instance ();
1354 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1355 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1357 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1358 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1359 _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
1362 void parameter_changed (std::string const &)
1367 void set_state_from_config ()
1371 ControlProtocolManager& m = ControlProtocolManager::instance ();
1372 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1374 if (!(*i)->mandatory) {
1375 TreeModel::Row r = *_store->append ();
1376 r[_model.name] = (*i)->name;
1377 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1378 r[_model.protocol_info] = *i;
1385 void protocol_status_changed (ControlProtocolInfo* cpi) {
1387 TreeModel::Children rows = _store->children();
1389 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1390 string n = ((*x)[_model.name]);
1392 if ((*x)[_model.protocol_info] == cpi) {
1393 _ignore_view_change++;
1394 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1395 _ignore_view_change--;
1401 void selection_changed ()
1403 //enable the Edit button when a row is selected for editing
1404 TreeModel::Row row = *(_view.get_selection()->get_selected());
1405 if (row && row[_model.enabled])
1406 edit_button->set_sensitive (true);
1408 edit_button->set_sensitive (false);
1411 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1413 TreeModel::Row r = *i;
1415 if (_ignore_view_change) {
1419 ControlProtocolInfo* cpi = r[_model.protocol_info];
1424 bool const was_enabled = (cpi->protocol != 0);
1425 bool const is_enabled = r[_model.enabled];
1428 if (was_enabled != is_enabled) {
1431 ControlProtocolManager::instance().activate (*cpi);
1433 ControlProtocolManager::instance().deactivate (*cpi);
1437 selection_changed ();
1440 void edit_btn_clicked ()
1443 ControlProtocolInfo* cpi;
1446 row = *(_view.get_selection()->get_selected());
1447 if (!row[_model.enabled]) {
1450 cpi = row[_model.protocol_info];
1451 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1454 Box* box = (Box*) cpi->protocol->get_gui ();
1458 if (box->get_parent()) {
1459 static_cast<ArdourWindow*>(box->get_parent())->present();
1462 WindowTitle title (Glib::get_application_name());
1463 title += row[_model.name];
1464 title += _("Configuration");
1465 /* once created, the window is managed by the surface itself (as ->get_parent())
1466 * Surface's tear_down_gui() is called on session close, when de-activating
1467 * or re-initializing a surface.
1468 * tear_down_gui() hides an deletes the Window if it exists.
1470 ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
1471 win->set_title (_("Control Protocol Settings"));
1477 void edit_clicked (GdkEventButton* ev)
1479 if (ev->type != GDK_2BUTTON_PRESS) {
1486 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1490 ControlSurfacesModelColumns ()
1494 add (protocol_info);
1497 TreeModelColumn<string> name;
1498 TreeModelColumn<bool> enabled;
1499 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1502 Glib::RefPtr<ListStore> _store;
1503 ControlSurfacesModelColumns _model;
1505 PBD::ScopedConnection protocol_status_connection;
1506 uint32_t _ignore_view_change;
1507 Gtk::Button* edit_button;
1510 class VideoTimelineOptions : public OptionEditorMiniPage
1513 VideoTimelineOptions (RCConfiguration* c)
1515 , _show_video_export_info_button (_("Show Video Export Info before export"))
1516 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1517 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1518 , _xjadeo_browse_button (_("Browse..."))
1521 int n = table.property_n_rows();
1523 t->attach (_show_video_export_info_button, 1, 4, n, n + 1);
1524 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1525 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1526 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1529 t->attach (_show_video_server_dialog_button, 1, 4, n, n + 1);
1530 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1531 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1532 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1535 t->attach (_video_advanced_setup_button, 1, 4, n, n + 1, FILL);
1536 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1537 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1538 _("<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."));
1541 Label* l = manage (new Label (_("Video Server URL:")));
1542 l->set_alignment (0, 0.5);
1543 t->attach (*l, 1, 2, n, n + 1, FILL);
1544 t->attach (_video_server_url_entry, 2, 4, n, n + 1, FILL);
1545 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1546 _("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"));
1549 l = manage (new Label (_("Video Folder:")));
1550 l->set_alignment (0, 0.5);
1551 t->attach (*l, 1, 2, n, n + 1, FILL);
1552 t->attach (_video_server_docroot_entry, 2, 4, n, n + 1);
1553 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1554 _("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."));
1557 l = manage (new Label (""));
1558 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1561 l = manage (new Label (string_compose ("<b>%1</b>", _("Video Monitor"))));
1562 l->set_use_markup (true);
1563 l->set_alignment (0, 0.5);
1564 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1567 l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"),
1570 #elif defined PLATFORM_WINDOWS
1576 l->set_alignment (0, 0.5);
1577 t->attach (*l, 1, 4, n, n + 1, FILL);
1580 t->attach (_custom_xjadeo_path, 2, 3, n, n + 1, EXPAND|FILL);
1581 Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart."));
1582 t->attach (_xjadeo_browse_button, 3, 4, n, n + 1, FILL);
1584 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1585 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1586 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1587 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1588 _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed));
1589 _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked));
1591 // xjadeo-path is a UIConfig parameter
1592 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &VideoTimelineOptions::parameter_changed));
1595 void server_url_changed ()
1597 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1600 void server_docroot_changed ()
1602 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1605 void show_video_export_info_toggled ()
1607 bool const x = _show_video_export_info_button.get_active ();
1608 _rc_config->set_show_video_export_info (x);
1611 void show_video_server_dialog_toggled ()
1613 bool const x = _show_video_server_dialog_button.get_active ();
1614 _rc_config->set_show_video_server_dialog (x);
1617 void video_advanced_setup_toggled ()
1619 bool const x = _video_advanced_setup_button.get_active ();
1620 _rc_config->set_video_advanced_setup(x);
1623 void custom_xjadeo_path_changed ()
1625 UIConfiguration::instance().set_xjadeo_binary (_custom_xjadeo_path.get_text());
1628 void xjadeo_browse_clicked ()
1630 Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN);
1631 dialog.set_filename (UIConfiguration::instance().get_xjadeo_binary());
1632 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1633 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1634 if (dialog.run () == Gtk::RESPONSE_OK) {
1635 const std::string& filename = dialog.get_filename();
1636 if (!filename.empty() && (
1638 Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) ||
1640 Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)
1642 UIConfiguration::instance().set_xjadeo_binary (filename);
1647 void parameter_changed (string const & p)
1649 if (p == "video-server-url") {
1650 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1651 } else if (p == "video-server-docroot") {
1652 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1653 } else if (p == "show-video-export-info") {
1654 bool const x = _rc_config->get_show_video_export_info();
1655 _show_video_export_info_button.set_active (x);
1656 } else if (p == "show-video-server-dialog") {
1657 bool const x = _rc_config->get_show_video_server_dialog();
1658 _show_video_server_dialog_button.set_active (x);
1659 } else if (p == "video-advanced-setup") {
1660 bool const x = _rc_config->get_video_advanced_setup();
1661 _video_advanced_setup_button.set_active(x);
1662 _video_server_docroot_entry.set_sensitive(x);
1663 _video_server_url_entry.set_sensitive(x);
1664 } else if (p == "xjadeo-binary") {
1665 _custom_xjadeo_path.set_text (UIConfiguration::instance().get_xjadeo_binary());
1669 void set_state_from_config ()
1671 parameter_changed ("video-server-url");
1672 parameter_changed ("video-server-docroot");
1673 parameter_changed ("video-monitor-setup-dialog");
1674 parameter_changed ("show-video-export-info");
1675 parameter_changed ("show-video-server-dialog");
1676 parameter_changed ("video-advanced-setup");
1677 parameter_changed ("xjadeo-binary");
1681 RCConfiguration* _rc_config;
1682 Entry _video_server_url_entry;
1683 Entry _video_server_docroot_entry;
1684 Entry _custom_xjadeo_path;
1685 CheckButton _show_video_export_info_button;
1686 CheckButton _show_video_server_dialog_button;
1687 CheckButton _video_advanced_setup_button;
1688 Button _xjadeo_browse_button;
1691 class ColumVisibilityOption : public Option
1694 ColumVisibilityOption (string id, string name, uint32_t n_col, sigc::slot<uint32_t> get, sigc::slot<bool, uint32_t> set)
1701 cb = (CheckButton**) malloc (sizeof (CheckButton*) * n_col);
1702 for (uint32_t i = 0; i < n_col; ++i) {
1703 CheckButton* col = manage (new CheckButton (string_compose (_("Column %1"), i + 1)));
1704 col->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ColumVisibilityOption::column_toggled), i));
1705 _hbox.pack_start (*col);
1708 parameter_changed (id);
1711 ~ColumVisibilityOption () {
1715 Gtk::Widget& tip_widget() { return _hbox; }
1717 void set_state_from_config ()
1719 uint32_t c = _get();
1720 for (uint32_t i = 0; i < _n_col; ++i) {
1721 bool en = (c & (1<<i)) ? true : false;
1722 if (cb[i]->get_active () != en) {
1723 cb[i]->set_active (en);
1728 void add_to_page (OptionEditorPage* p)
1730 _heading.add_to_page (p);
1731 add_widget_to_page (p, &_hbox);
1735 void column_toggled (int b) {
1736 uint32_t c = _get();
1738 if (cb[b]->get_active ()) {
1749 OptionEditorHeading _heading;
1753 sigc::slot<uint32_t> _get;
1754 sigc::slot<bool, uint32_t> _set;
1758 /** A class which allows control of visibility of some editor components usign
1759 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1760 * which has the correct members, but with null widget pointers. This
1761 * class allows the user to set visibility of the members, the details
1762 * of which are stored in a configuration variable which can be watched
1763 * by parts of the editor that actually contain the widgets whose visibility
1764 * is being controlled.
1767 class VisibilityOption : public Option
1770 /** @param name User-visible name for this group.
1771 * @param g `Dummy' VisibilityGroup (as described above).
1772 * @param get Method to get the value of the appropriate configuration variable.
1773 * @param set Method to set the value of the appropriate configuration variable.
1775 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1776 : Option (g->get_state_name(), name)
1778 , _visibility_group (g)
1782 /* Watch for changes made by the user to our members */
1783 _visibility_group->VisibilityChanged.connect_same_thread (
1784 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1788 void set_state_from_config ()
1790 /* Set our state from the current configuration */
1791 _visibility_group->set_state (_get ());
1794 void add_to_page (OptionEditorPage* p)
1796 _heading.add_to_page (p);
1797 add_widget_to_page (p, _visibility_group->list_view ());
1800 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1805 /* The user has changed something, so reflect this change
1806 in the RCConfiguration.
1808 _set (_visibility_group->get_state_value ());
1811 OptionEditorHeading _heading;
1812 VisibilityGroup* _visibility_group;
1813 sigc::slot<std::string> _get;
1814 sigc::slot<bool, std::string> _set;
1815 PBD::ScopedConnection _visibility_group_connection;
1819 class MidiPortOptions : public OptionEditorMiniPage, public sigc::trackable
1824 setup_midi_port_view (midi_output_view, false);
1825 setup_midi_port_view (midi_input_view, true);
1827 OptionEditorHeading* h = new OptionEditorHeading (_("MIDI Inputs"));
1828 h->add_to_page (this);
1830 Gtk::ScrolledWindow* scroller = manage (new Gtk::ScrolledWindow);
1831 scroller->add (midi_input_view);
1832 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1833 scroller->set_size_request (-1, 180);
1835 int n = table.property_n_rows();
1836 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1838 h = new OptionEditorHeading (_("MIDI Outputs"));
1839 h->add_to_page (this);
1841 scroller = manage (new Gtk::ScrolledWindow);
1842 scroller->add (midi_output_view);
1843 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1844 scroller->set_size_request (-1, 180);
1846 n = table.property_n_rows();
1847 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1849 midi_output_view.show ();
1850 midi_input_view.show ();
1852 table.signal_show().connect (sigc::mem_fun (*this, &MidiPortOptions::on_show));
1855 void parameter_changed (string const&) {}
1856 void set_state_from_config() {}
1861 AudioEngine::instance()->PortRegisteredOrUnregistered.connect (connections,
1862 invalidator (*this),
1863 boost::bind (&MidiPortOptions::refill, this),
1865 AudioEngine::instance()->MidiPortInfoChanged.connect (connections,
1866 invalidator (*this),
1867 boost::bind (&MidiPortOptions::refill, this),
1869 AudioEngine::instance()->MidiSelectionPortsChanged.connect (connections,
1870 invalidator (*this),
1871 boost::bind (&MidiPortOptions::refill, this),
1877 if (refill_midi_ports (true, midi_input_view)) {
1878 input_label.show ();
1880 input_label.hide ();
1882 if (refill_midi_ports (false, midi_output_view)) {
1883 output_label.show ();
1885 output_label.hide ();
1890 PBD::ScopedConnectionList connections;
1892 /* MIDI port management */
1893 struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord {
1895 MidiPortColumns () {
1904 Gtk::TreeModelColumn<std::string> pretty_name;
1905 Gtk::TreeModelColumn<bool> music_data;
1906 Gtk::TreeModelColumn<bool> control_data;
1907 Gtk::TreeModelColumn<bool> selection;
1908 Gtk::TreeModelColumn<std::string> name;
1909 Gtk::TreeModelColumn<std::string> filler;
1912 MidiPortColumns midi_port_columns;
1913 Gtk::TreeView midi_input_view;
1914 Gtk::TreeView midi_output_view;
1915 Gtk::Label input_label;
1916 Gtk::Label output_label;
1918 void setup_midi_port_view (Gtk::TreeView&, bool with_selection);
1919 bool refill_midi_ports (bool for_input, Gtk::TreeView&);
1920 void pretty_name_edit (std::string const & path, std::string const & new_text, Gtk::TreeView*);
1921 void midi_music_column_toggled (std::string const & path, Gtk::TreeView*);
1922 void midi_control_column_toggled (std::string const & path, Gtk::TreeView*);
1923 void midi_selection_column_toggled (std::string const & path, Gtk::TreeView*);
1927 MidiPortOptions::setup_midi_port_view (Gtk::TreeView& view, bool with_selection)
1929 int pretty_name_column;
1932 int selection_column;
1933 TreeViewColumn* col;
1936 pretty_name_column = view.append_column_editable (_("Name (click to edit)"), midi_port_columns.pretty_name) - 1;
1938 col = manage (new TreeViewColumn ("", midi_port_columns.music_data));
1939 col->set_alignment (ALIGN_CENTER);
1940 l = manage (new Label (_("Music Data")));
1941 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of music performance data."), PROGRAM_NAME));
1942 col->set_widget (*l);
1944 music_column = view.append_column (*col) - 1;
1946 col = manage (new TreeViewColumn ("", midi_port_columns.control_data));
1947 col->set_alignment (ALIGN_CENTER);
1948 l = manage (new Label (_("Control Data")));
1949 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of control data."), PROGRAM_NAME));
1950 col->set_widget (*l);
1952 control_column = view.append_column (*col) - 1;
1954 if (with_selection) {
1955 col = manage (new TreeViewColumn (_("Follow Selection"), midi_port_columns.selection));
1956 selection_column = view.append_column (*col) - 1;
1957 l = manage (new Label (_("Follow Selection")));
1958 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));
1959 col->set_widget (*l);
1963 /* filler column so that the last real column doesn't expand */
1964 view.append_column ("", midi_port_columns.filler);
1966 CellRendererText* pretty_name_cell = dynamic_cast<CellRendererText*> (view.get_column_cell_renderer (pretty_name_column));
1967 pretty_name_cell->property_editable() = true;
1968 pretty_name_cell->signal_edited().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::pretty_name_edit), &view));
1970 CellRendererToggle* toggle_cell;
1972 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (music_column));
1973 toggle_cell->property_activatable() = true;
1974 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_music_column_toggled), &view));
1976 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (control_column));
1977 toggle_cell->property_activatable() = true;
1978 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_control_column_toggled), &view));
1980 if (with_selection) {
1981 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (selection_column));
1982 toggle_cell->property_activatable() = true;
1983 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_selection_column_toggled), &view));
1986 view.get_selection()->set_mode (SELECTION_NONE);
1987 view.set_tooltip_column (4); /* port "real" name */
1988 view.get_column(0)->set_resizable (true);
1989 view.get_column(0)->set_expand (true);
1993 MidiPortOptions::refill_midi_ports (bool for_input, Gtk::TreeView& view)
1995 using namespace ARDOUR;
1997 std::vector<string> ports;
1999 AudioEngine::instance()->get_known_midi_ports (ports);
2001 if (ports.empty()) {
2006 Glib::RefPtr<ListStore> model = Gtk::ListStore::create (midi_port_columns);
2008 for (vector<string>::const_iterator s = ports.begin(); s != ports.end(); ++s) {
2010 if (AudioEngine::instance()->port_is_mine (*s)) {
2014 PortManager::MidiPortInformation mpi (AudioEngine::instance()->midi_port_information (*s));
2016 if (mpi.pretty_name.empty()) {
2017 /* vanished since get_known_midi_ports() */
2021 if (for_input != mpi.input) {
2025 TreeModel::Row row = *(model->append());
2027 row[midi_port_columns.pretty_name] = mpi.pretty_name;
2028 row[midi_port_columns.music_data] = mpi.properties & MidiPortMusic;
2029 row[midi_port_columns.control_data] = mpi.properties & MidiPortControl;
2030 row[midi_port_columns.selection] = mpi.properties & MidiPortSelection;
2031 row[midi_port_columns.name] = *s;
2034 view.set_model (model);
2040 MidiPortOptions::midi_music_column_toggled (string const & path, TreeView* view)
2042 TreeIter iter = view->get_model()->get_iter (path);
2048 bool new_value = ! bool ((*iter)[midi_port_columns.music_data]);
2050 /* don't reset model - wait for MidiPortInfoChanged signal */
2053 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2055 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2060 MidiPortOptions::midi_control_column_toggled (string const & path, TreeView* view)
2062 TreeIter iter = view->get_model()->get_iter (path);
2068 bool new_value = ! bool ((*iter)[midi_port_columns.control_data]);
2070 /* don't reset model - wait for MidiPortInfoChanged signal */
2073 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2075 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2080 MidiPortOptions::midi_selection_column_toggled (string const & path, TreeView* view)
2082 TreeIter iter = view->get_model()->get_iter (path);
2088 bool new_value = ! bool ((*iter)[midi_port_columns.selection]);
2090 /* don't reset model - wait for MidiSelectionPortsChanged signal */
2093 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2095 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2100 MidiPortOptions::pretty_name_edit (std::string const & path, string const & new_text, Gtk::TreeView* view)
2102 TreeIter iter = view->get_model()->get_iter (path);
2108 boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
2110 ARDOUR::PortEngine::PortHandle ph = backend->get_port_by_name ((*iter)[midi_port_columns.name]);
2112 backend->set_port_property (ph, "http://jackaudio.org/metadata/pretty-name", new_text, "");
2113 (*iter)[midi_port_columns.pretty_name] = new_text;
2121 RCOptionEditor::RCOptionEditor ()
2122 : OptionEditorContainer (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
2123 , Tabbable (*this, _("Preferences")
2125 , false // detached by default (first start, no instant.xml)
2127 ) /* pack self-as-vbox into tabbable */
2128 , _rc_config (Config)
2129 , _mixer_strip_visibility ("mixer-element-visibility")
2131 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
2135 uint32_t hwcpus = hardware_concurrency ();
2137 BoolComboOption* bco;
2140 add_option (_("General"), new OptionEditorHeading (_("DSP CPU Utilization")));
2142 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
2144 _("Signal processing uses"),
2145 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
2146 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
2149 procs->add (-1, _("all but one processor"));
2150 procs->add (0, _("all available processors"));
2152 for (uint32_t i = 1; i <= hwcpus; ++i) {
2153 procs->add (i, string_compose (P_("%1 processor", "%1 processors", i), i));
2156 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
2158 add_option (_("General"), procs);
2161 /* Image cache size */
2162 add_option (_("General"), new OptionEditorHeading (_("Memory Usage")));
2164 HSliderOption *sics = new HSliderOption ("waveform-cache-size",
2165 _("Waveform image cache size (megabytes)"),
2166 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
2167 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size),
2168 1, 1024, 10 /* 1 MB to 1GB in steps of 10MB */
2170 sics->scale().set_digits (0);
2171 Gtkmm2ext::UI::instance()->set_tip (
2173 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
2174 add_option (_("General"), sics);
2176 add_option (_("General"), new OptionEditorHeading (_("Engine")));
2178 add_option (_("General"),
2180 "try-autostart-engine",
2181 _("Try to auto-launch audio/midi engine"),
2182 sigc::mem_fun (*_rc_config, &RCConfiguration::get_try_autostart_engine),
2183 sigc::mem_fun (*_rc_config, &RCConfiguration::set_try_autostart_engine)
2186 add_option (_("General"), new OptionEditorHeading (_("Automation")));
2188 add_option (_("General"),
2189 new SpinOption<double> (
2190 "automation-thinning-factor",
2191 _("Thinning factor (larger value => less data)"),
2192 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
2193 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
2197 add_option (_("General"),
2198 new SpinOption<double> (
2199 "automation-interval-msecs",
2200 _("Automation sampling interval (milliseconds)"),
2201 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
2202 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
2206 add_option (_("General"), new OptionEditorHeading (_("Tempo")));
2208 bo = new BoolOption (
2209 "allow-non-quarter-pulse",
2210 _("Allow non quarter-note pulse"),
2211 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_allow_non_quarter_pulse),
2212 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_allow_non_quarter_pulse)
2214 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2215 string_compose (_("<b>When enabled</b> %1 will allow tempo to be expressed in divisions per minute\n"
2216 "<b>When disabled</b> %1 will only allow tempo to be expressed in quarter notes per minute"),
2218 add_option (_("General"), bo);
2220 if (!ARDOUR::Profile->get_mixbus()) {
2221 add_option (_("General"), new OptionEditorHeading (_("GUI Lock")));
2222 /* Lock GUI timeout */
2224 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2225 _("Lock timeout (seconds)"),
2226 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
2227 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds),
2230 slts->scale().set_digits (0);
2231 Gtkmm2ext::UI::instance()->set_tip (
2233 _("Lock GUI after this many idle seconds (zero to never lock)"));
2234 add_option (_("General"), slts);
2237 add_option (_("General/Session"), new OptionEditorHeading (S_("Options|Undo")));
2239 add_option (_("General/Session"), new UndoOptions (_rc_config));
2241 add_option (_("General/Session"),
2243 "verify-remove-last-capture",
2244 _("Verify removal of last capture"),
2245 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
2246 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
2249 add_option (_("General/Session"), new OptionEditorHeading (_("Session Management")));
2251 add_option (_("General/Session"),
2253 "periodic-safety-backups",
2254 _("Make periodic backups of the session file"),
2255 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
2256 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
2259 add_option (_("General/Session"),
2261 "only-copy-imported-files",
2262 _("Always copy imported files"),
2263 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
2264 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
2267 add_option (_("General/Session"), new DirectoryOption (
2268 X_("default-session-parent-dir"),
2269 _("Default folder for new sessions:"),
2270 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
2271 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
2274 add_option (_("General/Session"),
2275 new SpinOption<uint32_t> (
2276 "max-recent-sessions",
2277 _("Maximum number of recent sessions"),
2278 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
2279 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
2286 add_option (_("General/Translation"), new OptionEditorHeading (_("Internationalization")));
2288 bo = new BoolOption (
2289 "enable-translation",
2290 _("Use translations"),
2291 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2292 sigc::ptr_fun (ARDOUR::set_translations_enabled)
2295 bo->set_note (string_compose (_("These settings will only take effect after %1 is restarted (if available for your language preferences)."), PROGRAM_NAME));
2297 add_option (_("General/Translation"), bo);
2299 _l10n = new ComboOption<ARDOUR::LocaleMode> (
2302 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_locale_mode),
2303 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_locale_mode)
2306 _l10n->add (ARDOUR::SET_LC_ALL, _("Set complete locale"));
2307 _l10n->add (ARDOUR::SET_LC_MESSAGES, _("Enable only message translation"));
2308 _l10n->add (ARDOUR::SET_LC_MESSAGES_AND_LC_NUMERIC, _("Translate messages and format numeric format"));
2309 _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."));
2311 add_option (_("General/Translation"), _l10n);
2312 parameter_changed ("enable-translation");
2313 #endif // ENABLE_NLS
2318 add_option (_("Editor"), new OptionEditorHeading (_("General")));
2320 add_option (_("Editor"),
2322 "rubberbanding-snaps-to-grid",
2323 _("Snap rubberband to grid"),
2324 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2325 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2328 bo = new BoolOption (
2330 _("Prompt for new marker names"),
2331 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2332 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2334 add_option (_("Editor"), bo);
2335 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."
2336 "\n\nYou can always rename markers by right-clicking on them"));
2338 add_option (_("Editor"),
2340 "draggable-playhead",
2341 _("Allow dragging of playhead"),
2342 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2343 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2346 if (!Profile->get_mixbus()) {
2348 add_option (_("Editor"),
2350 "use-mouse-position-as-zoom-focus-on-scroll",
2351 _("Zoom to mouse position when zooming with scroll wheel"),
2352 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2353 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2357 add_option (_("Editor"),
2359 "use-time-rulers-to-zoom-with-vertical-drag",
2360 _("Zoom with vertical drag in rulers"),
2361 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag),
2362 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag)
2365 add_option (_("Editor"),
2367 "use-double-click-to-zoom-to-selection",
2368 _("Double click zooms to selection"),
2369 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection),
2370 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection)
2373 add_option (_("Editor"),
2375 "update-editor-during-summary-drag",
2376 _("Update editor window during drags of the summary"),
2377 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2378 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2381 add_option (_("Editor"),
2383 "autoscroll-editor",
2384 _("Auto-scroll editor window when dragging near its edges"),
2385 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2386 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2389 add_option (_("Editor"),
2390 new BoolComboOption (
2391 "show-region-gain-envelopes",
2392 _("Show gain envelopes in audio regions"),
2394 _("only in Draw and Internal Edit modes"),
2395 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2396 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2399 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2401 add_option (_("Editor"),
2403 "automation-follows-regions",
2404 _("Move relevant automation when audio regions are moved"),
2405 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2406 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2409 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2410 "default-fade-shape",
2411 _("Default fade shape"),
2412 sigc::mem_fun (*_rc_config,
2413 &RCConfiguration::get_default_fade_shape),
2414 sigc::mem_fun (*_rc_config,
2415 &RCConfiguration::set_default_fade_shape)
2418 fadeshape->add (FadeLinear,
2419 _("Linear (for highly correlated material)"));
2420 fadeshape->add (FadeConstantPower, _("Constant power"));
2421 fadeshape->add (FadeSymmetric, _("Symmetric"));
2422 fadeshape->add (FadeSlow, _("Slow"));
2423 fadeshape->add (FadeFast, _("Fast"));
2425 add_option (_("Editor"), fadeshape);
2427 bco = new BoolComboOption (
2428 "use-overlap-equivalency",
2429 _("Regions in edit groups are edited together"),
2430 _("whenever they overlap in time"),
2431 _("only if they have identical length and position"),
2432 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2433 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2436 add_option (_("Editor"), bco);
2438 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2440 _("Layering model"),
2441 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2442 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2445 lm->add (LaterHigher, _("later is higher"));
2446 lm->add (Manual, _("manual layering"));
2447 add_option (_("Editor"), lm);
2449 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2450 "region-selection-after-split",
2451 _("After splitting selected regions, select"),
2452 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2453 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2455 // TODO: decide which of these modes are really useful
2456 rsas->add(None, _("no regions"));
2457 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2458 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2459 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2460 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2461 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2462 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2463 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2465 add_option (_("Editor"), rsas);
2467 add_option (_("Editor/Modifiers"), new OptionEditorHeading (_("Keyboard Modifiers")));
2468 add_option (_("Editor/Modifiers"), new KeyboardOptions);
2469 add_option (_("Editor/Modifiers"), new OptionEditorBlank ());
2471 /* MIXER -- SOLO AND MUTE */
2473 add_option (_("Mixer"), new OptionEditorHeading (_("Solo")));
2475 _solo_control_is_listen_control = new BoolOption (
2476 "solo-control-is-listen-control",
2477 _("Solo controls are Listen controls"),
2478 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2479 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2482 add_option (_("Mixer"), _solo_control_is_listen_control);
2484 add_option (_("Mixer"),
2487 _("Exclusive solo"),
2488 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2489 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2492 add_option (_("Mixer"),
2495 _("Show solo muting"),
2496 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2497 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2500 add_option (_("Mixer"),
2502 "solo-mute-override",
2503 _("Soloing overrides muting"),
2504 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2505 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2508 add_option (_("Mixer"),
2511 _("Solo-in-place mute cut (dB)"),
2512 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2513 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2516 _listen_position = new ComboOption<ListenPosition> (
2518 _("Listen Position"),
2519 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2520 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2523 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2524 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2526 add_option (_("Mixer"), _listen_position);
2528 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2530 _("PFL signals come from"),
2531 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2532 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2535 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2536 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2538 add_option (_("Mixer"), pp);
2540 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2542 _("AFL signals come from"),
2543 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2544 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2547 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2548 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2550 add_option (_("Mixer"), pa);
2552 add_option (_("Mixer"), new OptionEditorHeading (_("Default Track / Bus Muting Options")));
2554 add_option (_("Mixer"),
2556 "mute-affects-pre-fader",
2557 _("Mute affects pre-fader sends"),
2558 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2559 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2562 add_option (_("Mixer"),
2564 "mute-affects-post-fader",
2565 _("Mute affects post-fader sends"),
2566 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2567 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2570 add_option (_("Mixer"),
2572 "mute-affects-control-outs",
2573 _("Mute affects control outputs"),
2574 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2575 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2578 add_option (_("Mixer"),
2580 "mute-affects-main-outs",
2581 _("Mute affects main outputs"),
2582 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2583 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2587 if (!ARDOUR::Profile->get_mixbus()) {
2588 add_option (_("Mixer"), new OptionEditorHeading (_("Send Routing")));
2589 add_option (_("Mixer"),
2591 "link-send-and-route-panner",
2592 _("Link panners of Aux and External Sends with main panner by default"),
2593 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2594 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2600 add_option (_("Signal Flow"), new OptionEditorHeading (_("Monitoring")));
2602 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2604 _("Record monitoring handled by"),
2605 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2606 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2609 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2610 mm->add (HardwareMonitoring, _("via Audio Driver"));
2613 string prog (PROGRAM_NAME);
2614 boost::algorithm::to_lower (prog);
2615 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2616 mm->add (ExternalMonitoring, _("audio hardware"));
2618 add_option (_("Signal Flow"), mm);
2620 bo = new BoolOption (
2621 "tape-machine-mode",
2622 _("Tape machine mode"),
2623 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2624 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2626 add_option (_("Signal Flow"), bo);
2627 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2628 string_compose (_("<b>When enabled</b> %1 will not monitor a track's input if the transport is stopped."),
2631 if (!Profile->get_mixbus()) {
2633 add_option (_("Signal Flow"), new OptionEditorHeading (_("Track and Bus Connections")));
2635 add_option (_("Signal Flow"),
2637 "auto-connect-standard-busses",
2638 _("Auto-connect master/monitor busses"),
2639 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2640 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2643 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2644 "input-auto-connect",
2645 _("Connect track inputs"),
2646 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2647 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2650 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2651 iac->add (ManualConnect, _("manually"));
2653 add_option (_("Signal Flow"), iac);
2655 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2656 "output-auto-connect",
2657 _("Connect track and bus outputs"),
2658 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2659 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2662 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2663 oac->add (AutoConnectMaster, _("automatically to master bus"));
2664 oac->add (ManualConnect, _("manually"));
2666 add_option (_("Signal Flow"), oac);
2668 bo = new BoolOption (
2670 _("Use 'Strict-I/O' for new tracks or busses"),
2671 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2672 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2675 add_option (_("Signal Flow"), bo);
2676 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2677 _("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."));
2684 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2686 add_option (_("Audio"), new BufferingOptions (_rc_config));
2688 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2690 add_option (_("Audio"),
2692 "denormal-protection",
2693 _("Use DC bias to protect against denormals"),
2694 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2695 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2698 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2700 _("Processor handling"),
2701 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2702 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2706 dm->add (DenormalNone, _("no processor handling"));
2708 FPU* fpu = FPU::instance();
2710 if (fpu->has_flush_to_zero()) {
2712 dm->add (DenormalFTZ, _("use FlushToZero"));
2713 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2714 _rc_config->set_denormal_model(DenormalNone);
2717 if (fpu->has_denormals_are_zero()) {
2719 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2720 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2721 _rc_config->set_denormal_model(DenormalNone);
2724 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2726 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2727 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2728 _rc_config->set_denormal_model(DenormalNone);
2732 dm->set_sensitive(false);
2735 add_option (_("Audio"), dm);
2737 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2739 add_option (_("Audio"),
2741 "auto-analyse-audio",
2742 _("Enable automatic analysis of audio"),
2743 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2744 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2747 add_option (_("Audio"),
2749 "replicate-missing-region-channels",
2750 _("Replicate missing region channels"),
2751 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2752 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2757 add_option (_("MIDI"), new OptionEditorHeading (_("Buffering")));
2759 add_option (_("MIDI"),
2760 new SpinOption<float> (
2762 _("MIDI read-ahead time (seconds)"),
2763 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2764 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2769 add_option (_("MIDI"), new OptionEditorHeading (_("Session")));
2771 add_option (_("MIDI"),
2772 new SpinOption<int32_t> (
2773 "initial-program-change",
2774 _("Initial program change"),
2775 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2776 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2780 add_option (_("MIDI"), new OptionEditorHeading (_("Audition")));
2782 add_option (_("MIDI"),
2785 _("Sound MIDI notes as they are selected in the editor"),
2786 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2787 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2790 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2791 "midi-audition-synth-uri",
2792 _("MIDI Audition Synth (LV2)"),
2793 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2794 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2797 audition_synth->add(X_(""), _("None"));
2798 PluginInfoList all_plugs;
2799 PluginManager& manager (PluginManager::instance());
2801 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2803 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2804 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2805 if (!(*i)->is_instrument()) continue;
2806 if ((*i)->type != ARDOUR::LV2) continue;
2807 if ((*i)->name.length() > 46) {
2808 audition_synth->add((*i)->unique_id, (*i)->name.substr (0, 44) + "...");
2810 audition_synth->add((*i)->unique_id, (*i)->name);
2815 add_option (_("MIDI"), audition_synth);
2819 add_option (_("Metronome"), new OptionEditorHeading (_("Metronome")));
2820 add_option (_("Metronome"), new ClickOptions (_rc_config));
2821 add_option (_("Metronome"), new OptionEditorHeading (_("Options")));
2823 bo = new BoolOption (
2824 "click-record-only",
2825 _("Enable metronome only while recording"),
2826 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_record_only),
2827 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_record_only)
2830 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2831 string_compose (_("<b>When enabled</b> the metronome will remain silent if %1 is <b>not recording</b>."), PROGRAM_NAME));
2832 add_option (_("Metronome"), bo);
2833 add_option (_("Metronome"), new OptionEditorBlank ());
2838 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2840 ComboOption<float>* mht = new ComboOption<float> (
2842 _("Peak hold time"),
2843 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
2844 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
2847 mht->add (MeterHoldOff, _("off"));
2848 mht->add (MeterHoldShort, _("short"));
2849 mht->add (MeterHoldMedium, _("medium"));
2850 mht->add (MeterHoldLong, _("long"));
2852 add_option (S_("Preferences|Metering"), mht);
2854 ComboOption<float>* mfo = new ComboOption<float> (
2857 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2858 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2861 mfo->add (METER_FALLOFF_OFF, _("off"));
2862 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2863 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2864 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2865 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2866 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2867 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
2869 add_option (S_("Preferences|Metering"), mfo);
2871 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2872 "meter-line-up-level",
2873 _("Meter line-up level; 0dBu"),
2874 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
2875 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
2878 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2879 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2880 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2881 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2883 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."));
2885 add_option (S_("Preferences|Metering"), mlu);
2887 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2888 "meter-line-up-din",
2889 _("IEC1/DIN Meter line-up level; 0dBu"),
2890 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
2891 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
2894 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2895 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2896 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2897 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2899 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2901 add_option (S_("Preferences|Metering"), mld);
2903 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2904 "meter-vu-standard",
2905 _("VU Meter standard"),
2906 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
2907 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
2910 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2911 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2912 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2913 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2915 add_option (S_("Preferences|Metering"), mvu);
2917 HSliderOption *mpks = new HSliderOption("meter-peak",
2918 _("Peak indicator threshold [dBFS]"),
2919 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
2920 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak),
2924 Gtkmm2ext::UI::instance()->set_tip (
2926 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
2928 add_option (S_("Preferences|Metering"), mpks);
2930 OptionEditorHeading* default_meter_head = new OptionEditorHeading (_("Default Meter Types"));
2931 default_meter_head->set_note (_("These settings apply to newly created tracks and busses. For the Master bus, this will be when a new session is created."));
2933 add_option (S_("Preferences|Metering"), default_meter_head);
2935 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
2936 "meter-type-master",
2937 _("Default Meter Type for Master Bus"),
2938 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
2939 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
2941 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2942 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2943 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2944 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2945 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2946 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2947 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2948 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
2950 add_option (S_("Preferences|Metering"), mtm);
2953 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
2955 _("Default meter type for busses"),
2956 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
2957 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
2959 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2960 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2961 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2962 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2963 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2964 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2965 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2966 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
2968 add_option (S_("Preferences|Metering"), mtb);
2970 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
2972 _("Default meter type for tracks"),
2973 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
2974 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
2976 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2977 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
2979 add_option (S_("Preferences|Metering"), mtt);
2981 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
2983 add_option (S_("Preferences|Metering"),
2985 "save-export-analysis-image",
2986 _("Save loudness analysis as image file"),
2987 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
2988 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
2991 /* TRANSPORT & Sync */
2993 add_option (_("Transport"), new OptionEditorHeading (_("General")));
2995 bo = new BoolOption (
2996 "stop-at-session-end",
2997 _("Stop at the end of the session"),
2998 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
2999 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
3001 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3002 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
3003 "when it reaches the current session end marker\n\n"
3004 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
3006 add_option (_("Transport"), bo);
3008 bo = new BoolOption (
3009 "latched-record-enable",
3010 _("Keep record-enable engaged on stop"),
3011 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
3012 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
3014 add_option (_("Transport"), bo);
3015 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3016 _("<b>When enabled</b> master record will remain engaged when the transport transitions to stop.\n<b>When disabled</b> master record will be disabled when the transport transitions to stop."));
3018 bo = new BoolOption (
3019 "disable-disarm-during-roll",
3020 _("Disable per-track record disarm while rolling"),
3021 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
3022 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
3024 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(), _("<b>When enabled</b> this will prevent you from accidentally stopping specific tracks recording during a take."));
3025 add_option (_("Transport"), bo);
3027 bo = new BoolOption (
3029 _("12dB gain reduction during fast-forward and fast-rewind"),
3030 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
3031 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
3033 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3034 _("<b>When enabled</b> rhis will reduce the unpleasant increase in perceived volume "
3035 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
3036 add_option (_("Transport"), bo);
3038 ComboOption<float>* psc = new ComboOption<float> (
3041 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
3042 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
3044 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
3045 (_("The amount of preroll to apply when <b>Play with Preroll</b> or <b>Record with Preroll</b>is initiated.\n\n"
3046 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
3047 psc->add (-4.0, _("4 Bars"));
3048 psc->add (-2.0, _("2 Bars"));
3049 psc->add (-1.0, _("1 Bar"));
3050 psc->add (0.0, _("0 (no pre-roll)"));
3051 psc->add (0.1, _("0.1 second"));
3052 psc->add (0.25, _("0.25 second"));
3053 psc->add (0.5, _("0.5 second"));
3054 psc->add (1.0, _("1.0 second"));
3055 psc->add (2.0, _("2.0 seconds"));
3056 add_option (_("Transport"), psc);
3059 add_option (_("Transport"), new OptionEditorHeading (_("Looping")));
3061 bo = new BoolOption (
3063 _("Play loop is a transport mode"),
3064 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
3065 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
3067 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3068 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
3069 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
3070 add_option (_("Transport"), bo);
3072 bo = new BoolOption (
3074 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
3075 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
3076 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
3078 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3079 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
3080 "preventing any need to do a transport locate at the end of the loop\n\n"
3081 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
3082 "which will often cause a small click or delay"), PROGRAM_NAME));
3083 add_option (_("Transport"), bo);
3085 add_option (_("Transport"), new OptionEditorHeading (_("Dropout (xrun) Handling")));
3086 bo = new BoolOption (
3087 "stop-recording-on-xrun",
3088 _("Stop recording when an xrun occurs"),
3089 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
3090 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
3092 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3093 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
3095 add_option (_("Transport"), bo);
3097 bo = new BoolOption (
3098 "create-xrun-marker",
3099 _("Create markers where xruns occur"),
3100 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
3101 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
3103 add_option (_("Transport"), bo);
3108 add_option (_("Sync"), new OptionEditorHeading (_("External Syncronization")));
3110 _sync_source = new ComboOption<SyncSource> (
3112 _("External timecode source"),
3113 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
3114 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
3117 add_option (_("Sync"), _sync_source);
3119 _sync_framerate = new BoolOption (
3120 "timecode-sync-frame-rate",
3121 _("Match session video frame rate to external timecode"),
3122 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
3123 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
3125 Gtkmm2ext::UI::instance()->set_tip
3126 (_sync_framerate->tip_widget(),
3127 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
3128 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
3129 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
3130 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
3131 "timecode standard and the session standard."), PROGRAM_NAME));
3133 add_option (_("Sync"), _sync_framerate);
3135 _sync_genlock = new BoolOption (
3136 "timecode-source-is-synced",
3137 _("Sync-lock timecode to clock (disable drift compensation)"),
3138 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
3139 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
3141 Gtkmm2ext::UI::instance()->set_tip
3142 (_sync_genlock->tip_widget(),
3143 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
3144 "Sync Lock indicates that the selected external timecode source shares clock-sync "
3145 "(Black & Burst, Wordclock, etc) with the audio interface. "
3146 "This option disables drift compensation. The transport speed is fixed at 1.0. "
3147 "Vari-speed LTC will be ignored and cause drift."
3149 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
3150 "timecode sources shares clock sync."
3154 add_option (_("Sync"), _sync_genlock);
3156 _sync_source_2997 = new BoolOption (
3157 "timecode-source-2997",
3158 _("Lock to 29.9700 fps instead of 30000/1001"),
3159 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
3160 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
3162 Gtkmm2ext::UI::instance()->set_tip
3163 (_sync_source_2997->tip_widget(),
3164 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
3165 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
3166 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
3167 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
3168 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
3169 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
3172 add_option (_("Sync"), _sync_source_2997);
3174 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Reader")));
3176 _ltc_port = new ComboStringOption (
3178 _("LTC incoming port"),
3179 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
3180 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
3183 vector<string> physical_inputs;
3184 physical_inputs.push_back (_("None"));
3185 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
3186 _ltc_port->set_popdown_strings (physical_inputs);
3188 populate_sync_options ();
3189 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
3191 add_option (_("Sync/LTC"), _ltc_port);
3193 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Generator")));
3195 add_option (_("Sync/LTC"),
3198 _("Enable LTC generator"),
3199 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
3200 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
3203 _ltc_send_continuously = new BoolOption (
3204 "ltc-send-continuously",
3205 _("Send LTC while stopped"),
3206 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
3207 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
3209 Gtkmm2ext::UI::instance()->set_tip
3210 (_ltc_send_continuously->tip_widget(),
3211 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
3212 add_option (_("Sync/LTC"), _ltc_send_continuously);
3214 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level [dBFS]"),
3215 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_output_volume),
3216 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_output_volume),
3220 Gtkmm2ext::UI::instance()->set_tip
3221 (_ltc_volume_slider->tip_widget(),
3222 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
3224 add_option (_("Sync/LTC"), _ltc_volume_slider);
3227 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Beat Clock (Mclk) Generator")));
3229 add_option (_("Sync/MIDI"),
3232 _("Enable Mclk generator"),
3233 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
3234 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
3237 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC) Generator")));
3239 add_option (_("Sync/MIDI"),
3242 _("Enable MTC Generator"),
3243 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
3244 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
3247 add_option (_("Sync/MIDI"),
3248 new SpinOption<int> (
3249 "mtc-qf-speed-tolerance",
3250 _("Percentage either side of normal transport speed to transmit MTC"),
3251 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
3252 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
3256 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Machine Control (MMC)")));
3258 add_option (_("Sync/MIDI"),
3261 _("Respond to MMC commands"),
3262 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
3263 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
3266 add_option (_("Sync/MIDI"),
3269 _("Send MMC commands"),
3270 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
3271 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
3274 add_option (_("Sync/MIDI"),
3275 new SpinOption<uint8_t> (
3276 "mmc-receive-device-id",
3277 _("Inbound MMC device ID"),
3278 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
3279 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
3283 add_option (_("Sync/MIDI"),
3284 new SpinOption<uint8_t> (
3285 "mmc-send-device-id",
3286 _("Outbound MMC device ID"),
3287 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
3288 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
3293 /* Control Surfaces */
3295 add_option (_("Control Surfaces"), new OptionEditorHeading (_("Control Surfaces")));
3296 add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
3299 add_option (_("MIDI Ports"), new OptionEditorHeading (_("MIDI Port Options")));
3301 add_option (_("MIDI Ports"),
3303 "get-midi-input-follows-selection",
3304 _("MIDI input follows MIDI track selection"),
3305 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
3306 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
3309 add_option (_("MIDI Ports"), new MidiPortOptions ());
3310 add_option (_("MIDI Ports"), new OptionEditorBlank ());
3314 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3315 add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
3316 add_option (_("Plugins"),
3317 new RcActionButton (_("Scan for Plugins"),
3318 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3322 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
3324 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3325 bo = new BoolOption (
3326 "show-plugin-scan-window",
3327 _("Always Display Plugin Scan Progress"),
3328 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
3329 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
3331 add_option (_("Plugins"), bo);
3332 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3333 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
3336 bo = new BoolOption (
3337 "plugins-stop-with-transport",
3338 _("Silence plugins when the transport is stopped"),
3339 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
3340 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
3342 add_option (_("Plugins"), bo);
3343 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3344 _("<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."));
3346 bo = new BoolOption (
3347 "new-plugins-active",
3348 _("Make new plugins active"),
3349 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
3350 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
3352 add_option (_("Plugins"), bo);
3353 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3354 _("<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"));
3356 #if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
3357 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
3359 add_option (_("Plugins/VST"),
3360 new RcActionButton (_("Scan for Plugins"),
3361 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3364 #if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
3365 bo = new BoolOption (
3367 _("Enable Mac VST support (requires restart or re-scan)"),
3368 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
3369 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
3371 add_option (_("Plugins/VST"), bo);
3374 bo = new BoolOption (
3375 "discover-vst-on-start",
3376 _("Scan for [new] VST Plugins on Application Start"),
3377 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
3378 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
3380 add_option (_("Plugins/VST"), bo);
3381 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3382 _("<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"));
3384 #ifdef WINDOWS_VST_SUPPORT
3385 // currently verbose logging is only implemented for Windows VST.
3386 bo = new BoolOption (
3387 "verbose-plugin-scan",
3388 _("Verbose Plugin Scan"),
3389 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
3390 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
3392 add_option (_("Plugins/VST"), bo);
3393 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3394 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
3397 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
3399 add_option (_("Plugins/VST"),
3400 new RcActionButton (_("Clear"),
3401 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
3404 add_option (_("Plugins/VST"),
3405 new RcActionButton (_("Clear"),
3406 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
3407 _("VST Blacklist:")));
3410 #ifdef LXVST_SUPPORT
3411 add_option (_("Plugins/VST"),
3412 new RcActionButton (_("Edit"),
3413 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
3414 _("Linux VST Path:")));
3416 add_option (_("Plugins/VST"),
3417 new RcConfigDisplay (
3418 "plugin-path-lxvst",
3420 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
3424 #ifdef WINDOWS_VST_SUPPORT
3425 add_option (_("Plugins/VST"),
3426 new RcActionButton (_("Edit"),
3427 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
3428 _("Windows VST Path:")));
3429 add_option (_("Plugins/VST"),
3430 new RcConfigDisplay (
3433 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
3437 #ifdef AUDIOUNIT_SUPPORT
3439 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
3441 add_option (_("Plugins/Audio Unit"),
3442 new RcActionButton (_("Scan for Plugins"),
3443 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3446 bo = new BoolOption (
3447 "discover-audio-units",
3448 _("Scan for [new] AudioUnit Plugins on Application Start"),
3449 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
3450 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
3452 add_option (_("Plugins/Audio Unit"), bo);
3453 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3454 _("<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."));
3456 add_option (_("Plugins/Audio Unit"),
3457 new RcActionButton (_("Clear"),
3458 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
3461 add_option (_("Plugins/Audio Unit"),
3462 new RcActionButton (_("Clear"),
3463 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
3464 _("AU Blacklist:")));
3467 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
3468 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
3469 add_option (_("Plugins"),
3471 "open-gui-after-adding-plugin",
3472 _("Automatically open the plugin GUI when adding a new plugin"),
3473 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
3474 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3477 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3478 add_option (_("Plugins"),
3480 "show-inline-display-by-default",
3481 _("Show Plugin Inline Display on Mixerstrip by default"),
3482 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3483 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3486 _plugin_prefer_inline = new BoolOption (
3487 "prefer-inline-over-gui",
3488 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3489 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3490 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3492 add_option (_("Plugins"), _plugin_prefer_inline);
3495 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3497 bo = new BoolOption (
3498 "ask-replace-instrument",
3499 _("Ask to replace existing instrument plugin"),
3500 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3501 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3503 add_option (_("Plugins"), bo);
3505 bo = new BoolOption (
3506 "ask-setup_instrument",
3507 _("Interactively configure instrument plugins on insert"),
3508 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3509 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3511 add_option (_("Plugins"), bo);
3512 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3513 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3516 add_option (_("Plugins"), new OptionEditorBlank ());
3519 #if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
3520 add_option (_("Appearance"), new OptionEditorHeading (_("Graphics Acceleration")));
3523 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3524 BoolOption* bgc = new BoolOption (
3525 "cairo-image-surface",
3526 _("Disable Graphics Hardware Acceleration (requires restart)"),
3527 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3528 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3531 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3532 _("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));
3533 add_option (_("Appearance"), bgc);
3536 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3537 BoolOption* bgo = new BoolOption (
3539 _("Possibly improve slow graphical performance (requires restart)"),
3540 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3541 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3544 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));
3545 add_option (_("Appearance"), bgo);
3547 add_option (_("Appearance"), new OptionEditorHeading (_("Graphical User Interface")));
3549 add_option (_("Appearance"),
3552 _("Highlight widgets on mouseover"),
3553 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3554 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3557 add_option (_("Appearance"),
3560 _("Show tooltips if mouse hovers over a control"),
3561 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3562 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3565 bo = new BoolOption (
3566 "super-rapid-clock-update",
3567 _("Update clocks at TC Frame rate"),
3568 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3569 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3571 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3572 _("<b>When enabled</b> clock displays are updated every Timecode Frame (fps).\n\n"
3573 "<b>When disabled</b> clock displays are updated only every 100ms."
3575 add_option (_("Appearance"), bo);
3577 add_option (_("Appearance"),
3580 _("Blink Rec-Arm buttons"),
3581 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_rec_arm),
3582 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_rec_arm)
3585 add_option (_("Appearance"),
3587 "blink-alert-indicators",
3588 _("Blink Alert Indicators"),
3589 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_alert_indicators),
3590 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_alert_indicators)
3595 /* font scaling does nothing with GDK/Quartz */
3596 add_option (_("Appearance"), new FontScalingOptions ());
3598 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("General")));
3599 add_option (_("Appearance/Editor"),
3601 "show-name-highlight",
3602 _("Use name highlight bars in region displays (requires a restart)"),
3603 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3604 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3607 add_option (_("Appearance/Editor"),
3609 "color-regions-using-track-color",
3610 _("Region color follows track color"),
3611 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_color_regions_using_track_color),
3612 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_color_regions_using_track_color)
3615 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Waveforms")));
3617 if (!Profile->get_mixbus()) {
3618 add_option (_("Appearance/Editor"),
3621 _("Show waveforms in regions"),
3622 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
3623 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
3627 add_option (_("Appearance/Editor"),
3629 "show-waveforms-while-recording",
3630 _("Show waveforms while recording"),
3631 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
3632 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
3635 add_option (_("Appearance/Editor"),
3637 "show-waveform-clipping",
3638 _("Show waveform clipping"),
3639 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveform_clipping),
3640 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveform_clipping)
3643 add_option (_("Appearance/Editor"), new ClipLevelOptions ());
3645 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
3647 _("Waveform scale"),
3648 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
3649 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
3652 wfs->add (Linear, _("linear"));
3653 wfs->add (Logarithmic, _("logarithmic"));
3655 add_option (_("Appearance/Editor"), wfs);
3657 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
3659 _("Waveform shape"),
3660 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
3661 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
3664 wfsh->add (Traditional, _("traditional"));
3665 wfsh->add (Rectified, _("rectified"));
3667 add_option (_("Appearance/Editor"), wfsh);
3669 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Editor Meters")));
3671 add_option (_("Appearance/Editor"),
3673 "show-track-meters",
3674 _("Show meters in track headers"),
3675 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3676 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3679 add_option (_("Appearance/Editor"),
3681 "editor-stereo-only-meters",
3682 _("Limit track header meters to stereo"),
3683 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3684 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3687 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("MIDI Regions")));
3689 add_option (_("Appearance/Editor"),
3691 "display-first-midi-bank-as-zero",
3692 _("Display first MIDI bank/program as 0"),
3693 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
3694 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
3697 add_option (_("Appearance/Editor"),
3699 "never-display-periodic-midi",
3700 _("Don't display periodic (MTC, MMC) SysEx messages in MIDI Regions"),
3701 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
3702 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
3705 add_option (_("Appearance/Editor"), new OptionEditorBlank ());
3707 /* The names of these controls must be the same as those given in MixerStrip
3708 for the actual widgets being controlled.
3710 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3711 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3712 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3713 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3714 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3715 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3716 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3718 add_option (_("Appearance/Mixer"),
3719 new VisibilityOption (
3721 &_mixer_strip_visibility,
3722 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3723 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3727 add_option (_("Appearance/Mixer"),
3729 "default-narrow_ms",
3730 _("Use narrow strips in the mixer for new strips by default"),
3731 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3732 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3735 add_option (_("Appearance/Mixer"), new OptionEditorBlank ());
3737 add_option (_("Appearance/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items")));
3739 add_option (_("Appearance/Toolbar"),
3741 "show-toolbar-recpunch",
3742 _("Display Record/Punch Options"),
3743 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_recpunch),
3744 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_recpunch)
3747 add_option (_("Appearance/Toolbar"),
3749 "show-toolbar-monitoring",
3750 _("Display Monitor Options"),
3751 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_monitoring),
3752 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_monitoring)
3755 add_option (_("Appearance/Toolbar"),
3757 "show-toolbar-selclock",
3758 _("Display Selection Clock"),
3759 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
3760 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
3763 if (!ARDOUR::Profile->get_small_screen()) {
3764 add_option (_("Appearance/Toolbar"),
3766 "show-secondary-clock",
3767 _("Display Secondary Clock"),
3768 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
3769 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
3773 add_option (_("Appearance/Toolbar"),
3775 "show-mini-timeline",
3776 _("Display Navigation Timeline"),
3777 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
3778 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
3781 add_option (_("Appearance/Toolbar"),
3783 "show-editor-meter",
3784 _("Display Master Level Meter"),
3785 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
3786 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
3789 add_option (_("Appearance/Toolbar"),
3790 new ColumVisibilityOption (
3791 "action-table-columns", _("Lua Action Script Button Visibility"), 4,
3792 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3793 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3796 add_option (_("Appearance/Toolbar"), new OptionEditorBlank ());
3799 /* and now the theme manager */
3801 add_option (_("Appearance/Theme"), new OptionEditorHeading (_("Theme")));
3803 add_option (_("Appearance/Theme"), new BoolOption (
3805 _("Draw \"flat\" buttons"),
3806 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_flat_buttons),
3807 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_flat_buttons)
3810 add_option (_("Appearance/Theme"), new BoolOption (
3812 _("LED meter style"),
3813 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3814 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3818 HSliderOption *gui_hs = new HSliderOption(
3819 "timeline-item-gradient-depth",
3820 _("Waveforms color gradient depth"),
3821 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_gradient_depth),
3822 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_gradient_depth),
3825 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3826 add_option (_("Appearance/Theme"), gui_hs);
3828 gui_hs = new HSliderOption(
3829 "timeline-item-gradient-depth",
3830 _("Timeline item gradient depth"),
3831 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_timeline_item_gradient_depth),
3832 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_timeline_item_gradient_depth),
3835 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3836 add_option (_("Appearance/Theme"), gui_hs);
3838 vector<string> icon_sets = ::get_icon_sets ();
3839 if (icon_sets.size() > 1) {
3840 ComboOption<std::string>* io = new ComboOption<std::string> (
3841 "icon-set", _("Icon Set"),
3842 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_icon_set),
3843 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_icon_set)
3845 for (vector<string>::const_iterator i = icon_sets.begin (); i != icon_sets.end (); ++i) {
3848 add_option (_("Appearance/Theme"), io);
3851 add_option (_("Appearance/Colors"), new OptionEditorHeading (_("Colors")));
3852 add_option (_("Appearance/Colors"), new ColorThemeManager);
3853 add_option (_("Appearance/Colors"), new OptionEditorBlank ());
3857 OptionEditorHeading* quirks_head = new OptionEditorHeading (_("Various Workarounds for Windowing Systems"));
3859 quirks_head->set_note (string_compose (_("Rules for closing, minimizing, maximizing, and stay-on-top can vary\
3860 with each version of your OS, and the preferences that you've set in your OS.\n\n\
3861 You can adjust the options, below, to change how %1's windows and dialogs behave.\n\n\
3862 These settings will only take effect after %1 is restarted.\n\
3865 add_option (_("Appearance/Quirks"), quirks_head);
3867 bo = new BoolOption (
3868 "use-wm-visibility",
3869 _("Use visibility information provided by your Window Manager/Desktop"),
3870 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3871 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3873 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3874 _("If you have trouble toggling between hidden Editor and Mixer windows, try changing this setting."));
3875 add_option (_("Appearance/Quirks"), bo);
3878 bo = new BoolOption (
3879 "all-floating-windows-are-dialogs",
3880 _("All floating windows are dialogs"),
3881 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_all_floating_windows_are_dialogs),
3882 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_all_floating_windows_are_dialogs)
3884 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3885 _("Mark all floating windows to be type \"Dialog\" rather than using \"Utility\" for some.\nThis may help with some window managers."));
3886 add_option (_("Appearance/Quirks"), bo);
3888 bo = new BoolOption (
3889 "transients-follow-front",
3890 _("Transient windows follow front window."),
3891 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_transients_follow_front),
3892 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_transients_follow_front)
3894 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3895 _("Make transient windows follow the front window when toggling between the editor and mixer."));
3896 add_option (_("Appearance/Quirks"), bo);
3899 if (!Profile->get_mixbus()) {
3900 bo = new BoolOption (
3901 "floating-monitor-section",
3902 _("Float detached monitor-section window"),
3903 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_floating_monitor_section),
3904 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_floating_monitor_section)
3906 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3907 _("When detaching the monitoring section, mark it as \"Utility\" window to stay in front."));
3908 add_option (_("Appearance/Quirks"), bo);
3911 add_option (_("Appearance/Quirks"), new OptionEditorBlank ());
3913 /* VIDEO Timeline */
3914 add_option (_("Video"), new OptionEditorHeading (_("Video Server")));
3915 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
3917 Widget::show_all ();
3919 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3920 parameter_changed ("send-ltc");
3921 parameter_changed ("sync-source");
3922 parameter_changed ("use-monitor-bus");
3923 parameter_changed ("open-gui-after-adding-plugin");
3925 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
3927 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
3928 (Gtk::StateType) here !!!
3930 Tabbable::set_state (*node, Stateful::loading_state_version);
3933 set_current_page (_("General"));
3937 RCOptionEditor::parameter_changed (string const & p)
3939 OptionEditor::parameter_changed (p);
3941 if (p == "use-monitor-bus") {
3942 bool const s = Config->get_use_monitor_bus ();
3944 /* we can't use this if we don't have a monitor bus */
3945 Config->set_solo_control_is_listen_control (false);
3947 _solo_control_is_listen_control->set_sensitive (s);
3948 _listen_position->set_sensitive (s);
3949 } else if (p == "sync-source") {
3950 _sync_source->set_sensitive (true);
3952 _sync_source->set_sensitive (!_session->config.get_external_sync());
3954 switch(Config->get_sync_source()) {
3957 _sync_genlock->set_sensitive (true);
3958 _sync_framerate->set_sensitive (true);
3959 _sync_source_2997->set_sensitive (true);
3962 _sync_genlock->set_sensitive (false);
3963 _sync_framerate->set_sensitive (false);
3964 _sync_source_2997->set_sensitive (false);
3967 } else if (p == "send-ltc") {
3968 bool const s = Config->get_send_ltc ();
3969 _ltc_send_continuously->set_sensitive (s);
3970 _ltc_volume_slider->set_sensitive (s);
3971 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
3972 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3973 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
3976 } else if (p == "enable-translation") {
3977 _l10n->set_sensitive (ARDOUR::translations_are_enabled ());
3982 void RCOptionEditor::plugin_scan_refresh () {
3983 PluginManager::instance().refresh();
3986 void RCOptionEditor::clear_vst_cache () {
3987 PluginManager::instance().clear_vst_cache();
3990 void RCOptionEditor::clear_vst_blacklist () {
3991 PluginManager::instance().clear_vst_blacklist();
3994 void RCOptionEditor::clear_au_cache () {
3995 PluginManager::instance().clear_au_cache();
3998 void RCOptionEditor::clear_au_blacklist () {
3999 PluginManager::instance().clear_au_blacklist();
4002 void RCOptionEditor::edit_lxvst_path () {
4003 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
4004 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
4005 *current_toplevel(), _("Set Linux VST Search Path"),
4006 _rc_config->get_plugin_path_lxvst(),
4007 PluginManager::instance().get_default_lxvst_path()
4009 ResponseType r = (ResponseType) pd->run ();
4011 if (r == RESPONSE_ACCEPT) {
4012 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
4014 MessageDialog msg (_("Re-scan Plugins now?"),
4015 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
4016 msg.set_default_response (Gtk::RESPONSE_YES);
4017 if (msg.run() == Gtk::RESPONSE_YES) {
4019 plugin_scan_refresh ();
4025 void RCOptionEditor::edit_vst_path () {
4026 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
4027 *current_toplevel(), _("Set Windows VST Search Path"),
4028 _rc_config->get_plugin_path_vst(),
4029 PluginManager::instance().get_default_windows_vst_path()
4031 ResponseType r = (ResponseType) pd->run ();
4033 if (r == RESPONSE_ACCEPT) {
4034 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
4035 MessageDialog msg (_("Re-scan Plugins now?"),
4036 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
4037 msg.set_default_response (Gtk::RESPONSE_YES);
4038 if (msg.run() == Gtk::RESPONSE_YES) {
4040 plugin_scan_refresh ();
4048 RCOptionEditor::populate_sync_options ()
4050 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
4052 _sync_source->clear ();
4054 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
4055 _sync_source->add (*i, sync_source_to_string (*i));
4058 if (sync_opts.empty()) {
4059 _sync_source->set_sensitive(false);
4061 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
4062 _rc_config->set_sync_source(sync_opts.front());
4066 parameter_changed ("sync-source");
4070 RCOptionEditor::use_own_window (bool and_fill_it)
4072 bool new_window = !own_window ();
4074 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
4076 if (win && new_window) {
4077 win->set_name ("PreferencesWindow");
4078 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
4080 win->set_resizable (false);
4087 RCOptionEditor::get_state ()
4089 XMLNode* node = new XMLNode (X_("Preferences"));
4090 node->add_child_nocopy (Tabbable::get_state());