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/gtk_ui.h"
38 #include "gtkmm2ext/window_title.h"
44 #include "ardour/audio_backend.h"
45 #include "ardour/audioengine.h"
46 #include "ardour/control_protocol_manager.h"
47 #include "ardour/dB.h"
48 #include "ardour/port_manager.h"
49 #include "ardour/plugin_manager.h"
50 #include "ardour/profile.h"
51 #include "ardour/rc_configuration.h"
52 #include "ardour/transport_master_manager.h"
54 #include "control_protocol/control_protocol.h"
56 #include "waveview/wave_view.h"
58 #include "widgets/paths_dialog.h"
59 #include "widgets/tooltips.h"
61 #include "ardour_dialog.h"
62 #include "ardour_ui.h"
63 #include "ardour_window.h"
64 #include "color_theme_manager.h"
65 #include "gui_thread.h"
67 #include "meter_patterns.h"
68 #include "midi_tracer.h"
69 #include "rc_option_editor.h"
71 #include "transport_masters_dialog.h"
72 #include "ui_config.h"
77 using namespace Gtkmm2ext;
79 using namespace ARDOUR;
80 using namespace ARDOUR_UI_UTILS;
81 using namespace ArdourWidgets;
83 class ClickOptions : public OptionEditorMiniPage
86 ClickOptions (RCConfiguration* c)
88 , _click_browse_button (_("Browse..."))
89 , _click_emphasis_browse_button (_("Browse..."))
91 // TODO get rid of GTK -> use OptionEditor Widgets
96 l = manage (left_aligned_label (_("Emphasis on first beat")));
97 _use_emphasis_on_click_check_button.add (*l);
98 t->attach (_use_emphasis_on_click_check_button, 1, 3, row, row + 1, FILL);
99 _use_emphasis_on_click_check_button.signal_toggled().connect (
100 sigc::mem_fun (*this, &ClickOptions::use_emphasis_on_click_toggled));
103 l = manage (left_aligned_label (_("Use built-in default sounds")));
104 _use_default_click_check_button.add (*l);
105 t->attach (_use_default_click_check_button, 1, 3, row, row + 1, FILL);
106 _use_default_click_check_button.signal_toggled().connect (
107 sigc::mem_fun (*this, &ClickOptions::use_default_click_toggled));
110 l = manage (left_aligned_label (_("Audio file:")));
111 t->attach (*l, 1, 2, row, row + 1, FILL);
112 t->attach (_click_path_entry, 2, 3, row, row + 1, FILL);
113 _click_browse_button.signal_clicked ().connect (
114 sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
115 t->attach (_click_browse_button, 3, 4, row, row + 1, FILL);
118 l = manage (left_aligned_label (_("Emphasis audio file:")));
119 t->attach (*l, 1, 2, row, row + 1, FILL);
120 t->attach (_click_emphasis_path_entry, 2, 3, row, row + 1, FILL);
121 _click_emphasis_browse_button.signal_clicked ().connect (
122 sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
123 t->attach (_click_emphasis_browse_button, 3, 4, row, row + 1, FILL);
126 _click_fader = new FaderOption (
129 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
130 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
133 _click_fader->add_to_page (this);
134 _click_fader->set_state_from_config ();
136 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
137 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
139 if (_rc_config->get_click_sound ().empty() &&
140 _rc_config->get_click_emphasis_sound().empty()) {
141 _use_default_click_check_button.set_active (true);
142 _use_emphasis_on_click_check_button.set_active (_rc_config->get_use_click_emphasis ());
145 _use_default_click_check_button.set_active (false);
146 _use_emphasis_on_click_check_button.set_active (false);
150 void parameter_changed (string const & p)
152 if (p == "click-sound") {
153 _click_path_entry.set_text (_rc_config->get_click_sound());
154 } else if (p == "click-emphasis-sound") {
155 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
156 } else if (p == "use-click-emphasis") {
157 bool x = _rc_config->get_use_click_emphasis ();
158 _use_emphasis_on_click_check_button.set_active (x);
159 } else if (p == "click-gain") {
160 _click_fader->set_state_from_config ();
164 void set_state_from_config ()
166 parameter_changed ("click-sound");
167 parameter_changed ("click-emphasis-sound");
168 parameter_changed ("use-click-emphasis");
173 void click_browse_clicked ()
175 SoundFileChooser sfdb (_("Choose Click"));
180 if (sfdb.run () == RESPONSE_OK) {
181 click_chosen (sfdb.get_filename());
185 void click_chosen (string const & path)
187 _click_path_entry.set_text (path);
188 _rc_config->set_click_sound (path);
191 void click_changed ()
193 click_chosen (_click_path_entry.get_text ());
196 void click_emphasis_browse_clicked ()
198 SoundFileChooser sfdb (_("Choose Click Emphasis"));
203 if (sfdb.run () == RESPONSE_OK) {
204 click_emphasis_chosen (sfdb.get_filename());
208 void click_emphasis_chosen (string const & path)
210 _click_emphasis_path_entry.set_text (path);
211 _rc_config->set_click_emphasis_sound (path);
214 void click_emphasis_changed ()
216 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
219 void use_default_click_toggled ()
221 if (_use_default_click_check_button.get_active ()) {
222 _rc_config->set_click_sound ("");
223 _rc_config->set_click_emphasis_sound ("");
224 _click_path_entry.set_sensitive (false);
225 _click_emphasis_path_entry.set_sensitive (false);
226 _click_browse_button.set_sensitive (false);
227 _click_emphasis_browse_button.set_sensitive (false);
229 _click_path_entry.set_sensitive (true);
230 _click_emphasis_path_entry.set_sensitive (true);
231 _click_browse_button.set_sensitive (true);
232 _click_emphasis_browse_button.set_sensitive (true);
236 void use_emphasis_on_click_toggled ()
238 if (_use_emphasis_on_click_check_button.get_active ()) {
239 _rc_config->set_use_click_emphasis(true);
241 _rc_config->set_use_click_emphasis(false);
245 RCConfiguration* _rc_config;
246 CheckButton _use_default_click_check_button;
247 CheckButton _use_emphasis_on_click_check_button;
248 Entry _click_path_entry;
249 Entry _click_emphasis_path_entry;
250 Button _click_browse_button;
251 Button _click_emphasis_browse_button;
252 FaderOption* _click_fader;
255 class UndoOptions : public OptionEditorComponent
258 UndoOptions (RCConfiguration* c) :
260 _limit_undo_button (_("Limit undo history to")),
261 _save_undo_button (_("Save undo history of"))
263 // TODO get rid of GTK -> use OptionEditor SpinOption
264 _limit_undo_spin.set_range (0, 512);
265 _limit_undo_spin.set_increments (1, 10);
267 _save_undo_spin.set_range (0, 512);
268 _save_undo_spin.set_increments (1, 10);
270 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
271 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
272 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
273 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
276 void parameter_changed (string const & p)
278 if (p == "history-depth") {
279 int32_t const d = _rc_config->get_history_depth();
280 _limit_undo_button.set_active (d != 0);
281 _limit_undo_spin.set_sensitive (d != 0);
282 _limit_undo_spin.set_value (d);
283 } else if (p == "save-history") {
284 bool const x = _rc_config->get_save_history ();
285 _save_undo_button.set_active (x);
286 _save_undo_spin.set_sensitive (x);
287 } else if (p == "save-history-depth") {
288 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
292 void set_state_from_config ()
294 parameter_changed ("save-history");
295 parameter_changed ("history-depth");
296 parameter_changed ("save-history-depth");
299 void limit_undo_toggled ()
301 bool const x = _limit_undo_button.get_active ();
302 _limit_undo_spin.set_sensitive (x);
303 int32_t const n = x ? 16 : 0;
304 _limit_undo_spin.set_value (n);
305 _rc_config->set_history_depth (n);
308 void limit_undo_changed ()
310 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
313 void save_undo_toggled ()
315 bool const x = _save_undo_button.get_active ();
316 _rc_config->set_save_history (x);
319 void save_undo_changed ()
321 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
324 void add_to_page (OptionEditorPage* p)
326 int const n = p->table.property_n_rows();
327 Table* t = & p->table;
329 t->resize (n + 2, 3);
331 Label* l = manage (left_aligned_label (_("commands")));
332 HBox* box = manage (new HBox());
333 box->set_spacing (4);
334 box->pack_start (_limit_undo_spin, false, false);
335 box->pack_start (*l, true, true);
336 t->attach (_limit_undo_button, 1, 2, n, n +1, FILL);
337 t->attach (*box, 2, 3, n, n + 1, FILL | EXPAND);
339 l = manage (left_aligned_label (_("commands")));
340 box = manage (new HBox());
341 box->set_spacing (4);
342 box->pack_start (_save_undo_spin, false, false);
343 box->pack_start (*l, true, true);
344 t->attach (_save_undo_button, 1, 2, n + 1, n + 2, FILL);
345 t->attach (*box, 2, 3, n + 1, n + 2, FILL | EXPAND);
348 Gtk::Widget& tip_widget() {
349 return _limit_undo_button; // unused
353 RCConfiguration* _rc_config;
354 CheckButton _limit_undo_button;
355 SpinButton _limit_undo_spin;
356 CheckButton _save_undo_button;
357 SpinButton _save_undo_spin;
361 static const struct {
373 { "Key|Shift", GDK_SHIFT_MASK },
374 { "Command", GDK_MOD2_MASK },
375 { "Control", GDK_CONTROL_MASK },
376 { "Option", GDK_MOD1_MASK },
377 { "Command-Shift", GDK_MOD2_MASK|GDK_SHIFT_MASK },
378 { "Command-Option", GDK_MOD2_MASK|GDK_MOD1_MASK },
379 { "Command-Control", GDK_MOD2_MASK|GDK_CONTROL_MASK },
380 { "Command-Option-Control", GDK_MOD2_MASK|GDK_MOD1_MASK|GDK_CONTROL_MASK },
381 { "Option-Control", GDK_MOD1_MASK|GDK_CONTROL_MASK },
382 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
383 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
384 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_MOD2_MASK },
387 { "Key|Shift", GDK_SHIFT_MASK },
388 { "Control", GDK_CONTROL_MASK },
389 { "Alt", GDK_MOD1_MASK },
390 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
391 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
392 { "Control-Windows", GDK_CONTROL_MASK|GDK_MOD4_MASK },
393 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
394 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
395 { "Alt-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
396 { "Alt-Shift-Windows", GDK_MOD1_MASK|GDK_SHIFT_MASK|GDK_MOD4_MASK },
397 { "Mod2", GDK_MOD2_MASK },
398 { "Mod3", GDK_MOD3_MASK },
399 { "Windows", GDK_MOD4_MASK },
400 { "Mod5", GDK_MOD5_MASK },
406 class KeyboardOptions : public OptionEditorMiniPage
410 : _delete_button_adjustment (3, 1, 12)
411 , _delete_button_spin (_delete_button_adjustment)
412 , _edit_button_adjustment (3, 1, 5)
413 , _edit_button_spin (_edit_button_adjustment)
414 , _insert_note_button_adjustment (3, 1, 5)
415 , _insert_note_button_spin (_insert_note_button_adjustment)
417 // TODO get rid of GTK -> use OptionEditor Widgets
419 const std::string restart_msg = _("\nChanges to this setting will only persist after your project has been saved.");
420 /* internationalize and prepare for use with combos */
423 for (int i = 0; modifiers[i].name; ++i) {
424 dumb.push_back (S_(modifiers[i].name));
427 set_popdown_strings (_edit_modifier_combo, dumb);
428 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
429 Gtkmm2ext::UI::instance()->set_tip (_edit_modifier_combo,
430 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
437 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
438 l->set_name ("OptionsLabel");
442 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
443 strs.push_back (bf->first);
446 set_popdown_strings (_keyboard_layout_selector, strs);
447 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
448 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
450 t->attach (*l, col + 1, col + 2, row, row + 1, FILL, FILL);
451 t->attach (_keyboard_layout_selector, col + 2, col + 3, row, row + 1, FILL | EXPAND, FILL);
456 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Clicking:"))));
457 l->set_name ("OptionEditorHeading");
458 l->set_use_markup (true);
459 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
464 l = manage (left_aligned_label (_("Edit using:")));
465 l->set_name ("OptionsLabel");
467 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
468 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
470 l = manage (new Label (_("+ button")));
471 l->set_name ("OptionsLabel");
473 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
474 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, SHRINK , FILL);
476 _edit_button_spin.set_name ("OptionsEntry");
477 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
482 set_popdown_strings (_delete_modifier_combo, dumb);
483 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
484 Gtkmm2ext::UI::instance()->set_tip (_delete_modifier_combo,
485 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
487 l = manage (left_aligned_label (_("Delete using:")));
488 l->set_name ("OptionsLabel");
490 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
491 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
493 l = manage (new Label (_("+ button")));
494 l->set_name ("OptionsLabel");
496 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
497 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, SHRINK, FILL);
499 _delete_button_spin.set_name ("OptionsEntry");
500 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
505 set_popdown_strings (_insert_note_modifier_combo, dumb);
506 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
507 Gtkmm2ext::UI::instance()->set_tip (_insert_note_modifier_combo,
508 (string_compose (_("<b>Recommended Setting: %1 + button 1 (left mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
510 l = manage (left_aligned_label (_("Insert note using:")));
511 l->set_name ("OptionsLabel");
513 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
514 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
516 l = manage (new Label (_("+ button")));
517 l->set_name ("OptionsLabel");
519 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
520 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, SHRINK, FILL);
522 _insert_note_button_spin.set_name ("OptionsEntry");
523 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
527 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Beginning a Drag:"))));
528 l->set_name ("OptionEditorHeading");
529 l->set_use_markup (true);
530 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
536 set_popdown_strings (_copy_modifier_combo, dumb);
537 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
538 Gtkmm2ext::UI::instance()->set_tip (_copy_modifier_combo,
539 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
541 Keyboard::secondary_modifier_name (),
543 Keyboard::primary_modifier_name (),
547 l = manage (left_aligned_label (_("Copy items using:")));
548 l->set_name ("OptionsLabel");
550 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
551 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
556 /* constraint modifier */
557 set_popdown_strings (_constraint_modifier_combo, dumb);
558 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
559 Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo,
560 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
562 Keyboard::primary_modifier_name (),
564 Keyboard::tertiary_modifier_name (),
568 l = manage (left_aligned_label (_("Constrain drag using:")));
569 l->set_name ("OptionsLabel");
571 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
572 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
578 set_popdown_strings (_push_points_combo, dumb);
579 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
581 std::string mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
582 Gtkmm2ext::UI::instance()->set_tip (_push_points_combo,
583 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
585 l = manage (left_aligned_label (_("Push points using:")));
586 l->set_name ("OptionsLabel");
588 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
589 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
593 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Beginning a Trim:"))));
594 l->set_name ("OptionEditorHeading");
595 l->set_use_markup (true);
596 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
602 set_popdown_strings (_trim_contents_combo, dumb);
603 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
604 Gtkmm2ext::UI::instance()->set_tip (_trim_contents_combo,
605 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
607 l = manage (left_aligned_label (_("Trim contents using:")));
608 l->set_name ("OptionsLabel");
610 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
611 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
617 set_popdown_strings (_trim_anchored_combo, dumb);
618 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
620 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::tertiary_modifier_name ());
621 Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo,
622 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
624 l = manage (left_aligned_label (_("Anchored trim using:")));
625 l->set_name ("OptionsLabel");
627 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
629 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
634 /* jump trim disabled for now
635 set_popdown_strings (_trim_jump_combo, dumb);
636 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
638 l = manage (left_aligned_label (_("Jump after trim using:")));
639 l->set_name ("OptionsLabel");
641 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
643 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
649 /* note resize relative */
650 set_popdown_strings (_note_size_relative_combo, dumb);
651 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
652 Gtkmm2ext::UI::instance()->set_tip (_note_size_relative_combo,
653 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg))); // XXX 2ndary
655 l = manage (left_aligned_label (_("Resize notes relatively using:")));
656 l->set_name ("OptionsLabel");
658 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
660 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
664 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Dragging:"))));
665 l->set_name ("OptionEditorHeading");
666 l->set_use_markup (true);
667 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
673 set_popdown_strings (_snap_modifier_combo, dumb);
674 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
676 mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ());
678 mod_str = Keyboard::secondary_modifier_name();
680 Gtkmm2ext::UI::instance()->set_tip (_snap_modifier_combo,
681 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
683 l = manage (left_aligned_label (_("Ignore snap using:")));
684 l->set_name ("OptionsLabel");
686 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
687 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
693 set_popdown_strings (_snap_delta_combo, dumb);
694 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
696 mod_str = Keyboard::level4_modifier_name ();
698 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::level4_modifier_name ());
700 Gtkmm2ext::UI::instance()->set_tip (_snap_delta_combo,
701 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
703 l = manage (left_aligned_label (_("Snap relatively using:")));
704 l->set_name ("OptionsLabel");
706 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
707 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
711 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Trimming:"))));
712 l->set_name ("OptionEditorHeading");
713 l->set_use_markup (true);
714 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
720 set_popdown_strings (_trim_overlap_combo, dumb);
721 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
723 Gtkmm2ext::UI::instance()->set_tip (_trim_overlap_combo,
724 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
726 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
727 l->set_name ("OptionsLabel");
729 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
730 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
734 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Dragging Control Points:"))));
735 l->set_name ("OptionEditorHeading");
736 l->set_use_markup (true);
737 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
743 set_popdown_strings (_fine_adjust_combo, dumb);
744 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
746 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::secondary_modifier_name ()); // XXX just 2ndary ?!
747 Gtkmm2ext::UI::instance()->set_tip (_fine_adjust_combo,
748 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
750 l = manage (left_aligned_label (_("Fine adjust using:")));
751 l->set_name ("OptionsLabel");
753 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
754 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
756 OptionEditorHeading* h = new OptionEditorHeading (_("Reset"));
757 h->add_to_page (this);
759 RcActionButton* rb = new RcActionButton (_("Reset to recommended defaults"),
760 sigc::mem_fun (*this, &KeyboardOptions::reset_to_defaults));
761 rb->add_to_page (this);
763 set_state_from_config ();
766 void parameter_changed (string const &)
768 /* XXX: these aren't really config options... */
771 void set_state_from_config ()
773 _delete_button_adjustment.set_value (Keyboard::delete_button());
774 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
775 _edit_button_adjustment.set_value (Keyboard::edit_button());
777 for (int x = 0; modifiers[x].name; ++x) {
778 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
779 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
781 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
782 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
784 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
785 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
787 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
788 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
790 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
791 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
793 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
794 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
796 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
797 _push_points_combo.set_active_text (S_(modifiers[x].name));
799 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
800 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
802 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
803 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
806 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
807 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
810 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
811 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
813 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
814 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
816 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
817 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
819 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
820 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
825 void add_to_page (OptionEditorPage* p)
827 int const n = p->table.property_n_rows();
828 p->table.resize (n + 1, 3);
829 p->table.attach (box, 1, 3, n, n + 1, FILL | EXPAND, SHRINK, 0, 0);
834 void bindings_changed ()
836 string const txt = _keyboard_layout_selector.get_active_text();
838 /* XXX: config...? for all this keyboard stuff */
840 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
841 if (txt == i->first) {
842 if (Keyboard::load_keybindings (i->second)) {
843 Keyboard::save_keybindings ();
849 void edit_modifier_chosen ()
851 string const txt = _edit_modifier_combo.get_active_text();
853 for (int i = 0; modifiers[i].name; ++i) {
854 if (txt == S_(modifiers[i].name)) {
855 Keyboard::set_edit_modifier (modifiers[i].modifier);
861 void delete_modifier_chosen ()
863 string const txt = _delete_modifier_combo.get_active_text();
865 for (int i = 0; modifiers[i].name; ++i) {
866 if (txt == S_(modifiers[i].name)) {
867 Keyboard::set_delete_modifier (modifiers[i].modifier);
873 void copy_modifier_chosen ()
875 string const txt = _copy_modifier_combo.get_active_text();
877 for (int i = 0; modifiers[i].name; ++i) {
878 if (txt == S_(modifiers[i].name)) {
879 Keyboard::set_copy_modifier (modifiers[i].modifier);
885 void insert_note_modifier_chosen ()
887 string const txt = _insert_note_modifier_combo.get_active_text();
889 for (int i = 0; modifiers[i].name; ++i) {
890 if (txt == S_(modifiers[i].name)) {
891 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
897 void snap_modifier_chosen ()
899 string const txt = _snap_modifier_combo.get_active_text();
901 for (int i = 0; modifiers[i].name; ++i) {
902 if (txt == S_(modifiers[i].name)) {
903 Keyboard::set_snap_modifier (modifiers[i].modifier);
909 void snap_delta_modifier_chosen ()
911 string const txt = _snap_delta_combo.get_active_text();
913 for (int i = 0; modifiers[i].name; ++i) {
914 if (txt == S_(modifiers[i].name)) {
915 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
921 void constraint_modifier_chosen ()
923 string const txt = _constraint_modifier_combo.get_active_text();
925 for (int i = 0; modifiers[i].name; ++i) {
926 if (txt == S_(modifiers[i].name)) {
927 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
933 void trim_contents_modifier_chosen ()
935 string const txt = _trim_contents_combo.get_active_text();
937 for (int i = 0; modifiers[i].name; ++i) {
938 if (txt == S_(modifiers[i].name)) {
939 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
945 void trim_overlap_modifier_chosen ()
947 string const txt = _trim_overlap_combo.get_active_text();
949 for (int i = 0; modifiers[i].name; ++i) {
950 if (txt == S_(modifiers[i].name)) {
951 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
957 void trim_anchored_modifier_chosen ()
959 string const txt = _trim_anchored_combo.get_active_text();
961 for (int i = 0; modifiers[i].name; ++i) {
962 if (txt == S_(modifiers[i].name)) {
963 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
969 void fine_adjust_modifier_chosen ()
971 string const txt = _fine_adjust_combo.get_active_text();
973 for (int i = 0; modifiers[i].name; ++i) {
974 if (txt == S_(modifiers[i].name)) {
975 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
981 void push_points_modifier_chosen ()
983 string const txt = _push_points_combo.get_active_text();
985 for (int i = 0; modifiers[i].name; ++i) {
986 if (txt == S_(modifiers[i].name)) {
987 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
993 void note_size_relative_modifier_chosen ()
995 string const txt = _note_size_relative_combo.get_active_text();
997 for (int i = 0; modifiers[i].name; ++i) {
998 if (txt == S_(modifiers[i].name)) {
999 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
1005 void delete_button_changed ()
1007 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
1010 void edit_button_changed ()
1012 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
1015 void insert_note_button_changed ()
1017 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
1020 void reset_to_defaults ()
1023 Keyboard::set_edit_modifier (Keyboard::PrimaryModifier);
1024 Keyboard::set_edit_button (3);
1025 Keyboard::set_delete_modifier (Keyboard::TertiaryModifier);
1026 Keyboard::set_delete_button (3);
1027 Keyboard::set_insert_note_modifier (Keyboard::PrimaryModifier);
1028 Keyboard::set_insert_note_button (1);
1030 /* when beginning a drag */
1032 Keyboard::set_copy_modifier (Keyboard::SecondaryModifier);
1034 Keyboard::set_copy_modifier (Keyboard::PrimaryModifier);
1038 ArdourKeyboard::set_constraint_modifier (Keyboard::PrimaryModifier);
1040 ArdourKeyboard::set_constraint_modifier (Keyboard::TertiaryModifier);
1042 ArdourKeyboard::set_push_points_modifier (Keyboard::PrimaryModifier | Keyboard::Level4Modifier);
1044 /* when beginning a trim */
1045 ArdourKeyboard::set_trim_contents_modifier (Keyboard::PrimaryModifier);
1046 ArdourKeyboard::set_trim_anchored_modifier (Keyboard::PrimaryModifier | Keyboard::TertiaryModifier);
1047 ArdourKeyboard::set_note_size_relative_modifier (Keyboard::TertiaryModifier); // XXX better: 2ndary
1049 /* while dragging */
1051 Keyboard::set_snap_modifier (Keyboard::TertiaryModifier);
1053 Keyboard::set_snap_modifier (Keyboard::SecondaryModifier);
1056 Keyboard::set_snap_delta_modifier (Keyboard::Level4Modifier);
1058 Keyboard::set_snap_delta_modifier (Keyboard::SecondaryModifier | Keyboard::Level4Modifier);
1061 /* while trimming */
1062 ArdourKeyboard::set_trim_overlap_modifier (Keyboard::TertiaryModifier);
1064 /* while dragging ctrl points */
1065 ArdourKeyboard::set_fine_adjust_modifier (/*Keyboard::PrimaryModifier | */Keyboard::SecondaryModifier); // XXX
1067 set_state_from_config ();
1070 ComboBoxText _keyboard_layout_selector;
1071 ComboBoxText _edit_modifier_combo;
1072 ComboBoxText _delete_modifier_combo;
1073 ComboBoxText _copy_modifier_combo;
1074 ComboBoxText _insert_note_modifier_combo;
1075 ComboBoxText _snap_modifier_combo;
1076 ComboBoxText _snap_delta_combo;
1077 ComboBoxText _constraint_modifier_combo;
1078 ComboBoxText _trim_contents_combo;
1079 ComboBoxText _trim_overlap_combo;
1080 ComboBoxText _trim_anchored_combo;
1081 ComboBoxText _trim_jump_combo;
1082 ComboBoxText _fine_adjust_combo;
1083 ComboBoxText _push_points_combo;
1084 ComboBoxText _note_size_relative_combo;
1085 Adjustment _delete_button_adjustment;
1086 SpinButton _delete_button_spin;
1087 Adjustment _edit_button_adjustment;
1088 SpinButton _edit_button_spin;
1089 Adjustment _insert_note_button_adjustment;
1090 SpinButton _insert_note_button_spin;
1094 class FontScalingOptions : public HSliderOption
1097 FontScalingOptions ()
1098 : HSliderOption ("font-scale", _("GUI and Font scaling"),
1099 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_font_scale),
1100 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_font_scale),
1104 const std::string dflt = _("100%");
1105 const std::string empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
1107 _hscale.set_name("FontScaleSlider");
1108 _hscale.set_draw_value(false);
1109 _hscale.add_mark(50, Gtk::POS_TOP, empty);
1110 _hscale.add_mark(60, Gtk::POS_TOP, empty);
1111 _hscale.add_mark(70, Gtk::POS_TOP, empty);
1112 _hscale.add_mark(80, Gtk::POS_TOP, empty);
1113 _hscale.add_mark(90, Gtk::POS_TOP, empty);
1114 _hscale.add_mark(100, Gtk::POS_TOP, dflt);
1115 _hscale.add_mark(125, Gtk::POS_TOP, empty);
1116 _hscale.add_mark(150, Gtk::POS_TOP, empty);
1117 _hscale.add_mark(175, Gtk::POS_TOP, empty);
1118 _hscale.add_mark(200, Gtk::POS_TOP, empty);
1119 _hscale.add_mark(250, Gtk::POS_TOP, empty);
1121 set_note (_("Adjusting the scale requires an application restart to re-layout."));
1126 HSliderOption::changed ();
1127 /* XXX: should be triggered from the parameter changed signal */
1128 UIConfiguration::instance().reset_dpi ();
1132 class VstTimeOutSliderOption : public HSliderOption
1135 VstTimeOutSliderOption (RCConfiguration* c)
1136 : HSliderOption ("vst-scan-timeout", _("Scan Time Out"),
1137 sigc::mem_fun (*c, &RCConfiguration::get_vst_scan_timeout),
1138 sigc::mem_fun (*c, &RCConfiguration::set_vst_scan_timeout),
1141 _label.set_alignment (1.0, 0.5); // match buttons below
1142 _hscale.set_digits (0);
1143 _hscale.set_draw_value(false);
1144 _hscale.add_mark( 0, Gtk::POS_TOP, _("\u221e")); // infinity
1145 _hscale.add_mark( 300, Gtk::POS_TOP, _("30 sec"));
1146 _hscale.add_mark( 600, Gtk::POS_TOP, _("1 min"));
1147 _hscale.add_mark(1200, Gtk::POS_TOP, _("2 mins"));
1148 _hscale.add_mark(1800, Gtk::POS_TOP, _("3 mins"));
1149 _hscale.add_mark(2400, Gtk::POS_TOP, _("4 mins"));
1150 _hscale.add_mark(3000, Gtk::POS_TOP, _("5 mins"));
1152 Gtkmm2ext::UI::instance()->set_tip(_hscale,
1153 _("Specify the default timeout for plugin instantiation. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1157 class ClipLevelOptions : public HSliderOption
1161 : HSliderOption (X_("waveform-clip-level"),
1162 _("Waveform Clip Level (dBFS):"),
1163 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_clip_level),
1164 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_clip_level),
1165 -50.0, -0.5, 0.1, 1.0, /* units of dB */
1171 void parameter_changed (string const & p)
1173 if (p == "waveform-clip-level") {
1174 ArdourWaveView::WaveView::set_clip_level (UIConfiguration::instance().get_waveform_clip_level());
1176 if (p == "show-waveform-clipping") {
1177 _hscale.set_sensitive (UIConfiguration::instance().get_show_waveform_clipping ());
1181 void set_state_from_config ()
1183 parameter_changed ("waveform-clip-level");
1184 parameter_changed ("show-waveform-clipping");
1188 class BufferingOptions : public OptionEditorComponent
1191 BufferingOptions (RCConfiguration* c)
1193 , _label (_("Preset:"))
1194 , _playback ("playback-buffer-seconds", _("Playback (seconds of buffering)"),
1195 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_playback_buffer_seconds),
1196 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_playback_buffer_seconds),
1198 , _capture ("capture-buffer-seconds", _("Recording (seconds of buffering)"),
1199 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_capture_buffer_seconds),
1200 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_capture_buffer_seconds),
1203 // TODO use ComboOption
1204 vector<string> presets;
1206 /* these must match the order of the enums for BufferingPreset */
1207 presets.push_back (_("Small sessions (4-16 tracks)"));
1208 presets.push_back (_("Medium sessions (16-64 tracks)"));
1209 presets.push_back (_("Large sessions (64+ tracks)"));
1210 presets.push_back (_("Custom (set by sliders below)"));
1212 set_popdown_strings (_buffering_presets_combo, presets);
1213 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1215 _label.set_name ("OptionsLabel");
1216 _label.set_alignment (0, 0.5);
1220 add_to_page (OptionEditorPage* p)
1222 add_widgets_to_page (p, &_label, &_buffering_presets_combo);
1223 _playback.add_to_page (p);
1224 _capture.add_to_page (p);
1227 void parameter_changed (string const & p)
1229 if (p == "buffering-preset") {
1230 switch (_rc_config->get_buffering_preset()) {
1232 _playback.set_sensitive (false);
1233 _capture.set_sensitive (false);
1234 _buffering_presets_combo.set_active (0);
1237 _playback.set_sensitive (false);
1238 _capture.set_sensitive (false);
1239 _buffering_presets_combo.set_active (1);
1242 _playback.set_sensitive (false);
1243 _capture.set_sensitive (false);
1244 _buffering_presets_combo.set_active (2);
1247 _playback.set_sensitive (true);
1248 _capture.set_sensitive (true);
1249 _buffering_presets_combo.set_active (3);
1253 _playback.parameter_changed (p);
1254 _capture.parameter_changed (p);
1257 void set_state_from_config ()
1259 parameter_changed ("buffering-preset");
1260 _playback.set_state_from_config();
1261 _capture.set_state_from_config();
1264 Gtk::Widget& tip_widget() { return _buffering_presets_combo; }
1268 void preset_changed ()
1270 int index = _buffering_presets_combo.get_active_row_number ();
1276 _rc_config->set_buffering_preset (Small);
1279 _rc_config->set_buffering_preset (Medium);
1282 _rc_config->set_buffering_preset (Large);
1285 _rc_config->set_buffering_preset (Custom);
1288 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1293 RCConfiguration* _rc_config;
1295 HSliderOption _playback;
1296 HSliderOption _capture;
1297 ComboBoxText _buffering_presets_combo;
1300 class ControlSurfacesOptions : public OptionEditorMiniPage
1303 ControlSurfacesOptions ()
1304 : _ignore_view_change (0)
1306 _store = ListStore::create (_model);
1307 _view.set_model (_store);
1308 _view.append_column_editable (_("Enable"), _model.enabled);
1309 _view.append_column (_("Control Surface Protocol"), _model.name);
1310 _view.get_column(1)->set_resizable (true);
1311 _view.get_column(1)->set_expand (true);
1313 Gtk::HBox* edit_box = manage (new Gtk::HBox);
1314 edit_box->set_spacing(3);
1317 Label* label = manage (new Label);
1318 label->set_text (_("Edit the settings for selected protocol (it must be ENABLED first):"));
1319 edit_box->pack_start (*label, false, false);
1322 edit_button = manage (new Button(_("Show Protocol Settings")));
1323 edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
1324 edit_box->pack_start (*edit_button, true, true);
1325 edit_button->set_sensitive (false);
1326 edit_button->show ();
1328 int const n = table.property_n_rows();
1329 table.resize (n + 2, 3);
1330 table.attach (_view, 0, 3, n, n + 1);
1331 table.attach (*edit_box, 0, 3, n + 1, n + 2);
1333 ControlProtocolManager& m = ControlProtocolManager::instance ();
1334 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1335 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1337 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1338 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1339 _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
1342 void parameter_changed (std::string const &)
1347 void set_state_from_config ()
1351 ControlProtocolManager& m = ControlProtocolManager::instance ();
1352 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1354 if (!(*i)->mandatory) {
1355 TreeModel::Row r = *_store->append ();
1356 r[_model.name] = (*i)->name;
1357 r[_model.enabled] = 0 != (*i)->protocol;
1358 r[_model.protocol_info] = *i;
1365 void protocol_status_changed (ControlProtocolInfo* cpi) {
1367 TreeModel::Children rows = _store->children();
1369 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1370 string n = ((*x)[_model.name]);
1372 if ((*x)[_model.protocol_info] == cpi) {
1373 _ignore_view_change++;
1374 (*x)[_model.enabled] = 0 != cpi->protocol;
1375 _ignore_view_change--;
1376 selection_changed (); // update sensitivity
1382 void selection_changed ()
1384 //enable the Edit button when a row is selected for editing
1385 TreeModel::Row row = *(_view.get_selection()->get_selected());
1386 if (row && row[_model.enabled]) {
1387 ControlProtocolInfo* cpi = row[_model.protocol_info];
1388 edit_button->set_sensitive (cpi && cpi->protocol && cpi->protocol->has_editor ());
1390 edit_button->set_sensitive (false);
1394 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1396 TreeModel::Row r = *i;
1398 if (_ignore_view_change) {
1402 ControlProtocolInfo* cpi = r[_model.protocol_info];
1407 bool const was_enabled = (cpi->protocol != 0);
1408 bool const is_enabled = r[_model.enabled];
1411 if (was_enabled != is_enabled) {
1414 ControlProtocolManager::instance().activate (*cpi);
1416 ControlProtocolManager::instance().deactivate (*cpi);
1420 selection_changed ();
1423 void edit_btn_clicked ()
1426 ControlProtocolInfo* cpi;
1429 row = *(_view.get_selection()->get_selected());
1430 if (!row[_model.enabled]) {
1433 cpi = row[_model.protocol_info];
1434 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1437 Box* box = (Box*) cpi->protocol->get_gui ();
1441 if (box->get_parent()) {
1442 static_cast<ArdourWindow*>(box->get_parent())->present();
1445 WindowTitle title (Glib::get_application_name());
1446 title += row[_model.name];
1447 title += _("Configuration");
1448 /* once created, the window is managed by the surface itself (as ->get_parent())
1449 * Surface's tear_down_gui() is called on session close, when de-activating
1450 * or re-initializing a surface.
1451 * tear_down_gui() hides an deletes the Window if it exists.
1453 ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
1454 win->set_title (_("Control Protocol Settings"));
1460 void edit_clicked (GdkEventButton* ev)
1462 if (ev->type != GDK_2BUTTON_PRESS) {
1469 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1473 ControlSurfacesModelColumns ()
1477 add (protocol_info);
1480 TreeModelColumn<string> name;
1481 TreeModelColumn<bool> enabled;
1482 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1485 Glib::RefPtr<ListStore> _store;
1486 ControlSurfacesModelColumns _model;
1488 PBD::ScopedConnection protocol_status_connection;
1489 uint32_t _ignore_view_change;
1490 Gtk::Button* edit_button;
1493 class VideoTimelineOptions : public OptionEditorMiniPage
1496 VideoTimelineOptions (RCConfiguration* c)
1498 , _show_video_export_info_button (_("Show Video Export Info before export"))
1499 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1500 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1501 , _xjadeo_browse_button (_("Browse..."))
1504 int n = table.property_n_rows();
1506 t->attach (_show_video_export_info_button, 1, 4, n, n + 1);
1507 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1508 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1509 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1512 t->attach (_show_video_server_dialog_button, 1, 4, n, n + 1);
1513 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1514 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1515 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1518 t->attach (_video_advanced_setup_button, 1, 4, n, n + 1, FILL);
1519 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1520 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1521 _("<b>When enabled</b> you can specify a custom video-server URL and docroot. - Do not enable this option unless you know what you are doing."));
1524 Label* l = manage (new Label (_("Video Server URL:")));
1525 l->set_alignment (0, 0.5);
1526 t->attach (*l, 1, 2, n, n + 1, FILL);
1527 t->attach (_video_server_url_entry, 2, 4, n, n + 1, FILL);
1528 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1529 _("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"));
1532 l = manage (new Label (_("Video Folder:")));
1533 l->set_alignment (0, 0.5);
1534 t->attach (*l, 1, 2, n, n + 1, FILL);
1535 t->attach (_video_server_docroot_entry, 2, 4, n, n + 1);
1536 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1537 _("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 unavailable. It is used for the local video-monitor and file-browsing when opening/adding a video file."));
1540 l = manage (new Label (""));
1541 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1544 l = manage (new Label (string_compose ("<b>%1</b>", _("Video Monitor"))));
1545 l->set_use_markup (true);
1546 l->set_alignment (0, 0.5);
1547 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1550 l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"),
1553 #elif defined PLATFORM_WINDOWS
1559 l->set_alignment (0, 0.5);
1560 t->attach (*l, 1, 4, n, n + 1, FILL);
1563 t->attach (_custom_xjadeo_path, 2, 3, n, n + 1, EXPAND|FILL);
1564 Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart."));
1565 t->attach (_xjadeo_browse_button, 3, 4, n, n + 1, FILL);
1567 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1568 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1569 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1570 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1571 _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed));
1572 _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked));
1575 void server_url_changed ()
1577 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1580 void server_docroot_changed ()
1582 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1585 void show_video_export_info_toggled ()
1587 bool const x = _show_video_export_info_button.get_active ();
1588 _rc_config->set_show_video_export_info (x);
1591 void show_video_server_dialog_toggled ()
1593 bool const x = _show_video_server_dialog_button.get_active ();
1594 _rc_config->set_show_video_server_dialog (x);
1597 void video_advanced_setup_toggled ()
1599 bool const x = _video_advanced_setup_button.get_active ();
1600 _rc_config->set_video_advanced_setup(x);
1603 void custom_xjadeo_path_changed ()
1605 _rc_config->set_xjadeo_binary (_custom_xjadeo_path.get_text());
1608 void xjadeo_browse_clicked ()
1610 Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN);
1611 dialog.set_filename (_rc_config->get_xjadeo_binary());
1612 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1613 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1614 if (dialog.run () == Gtk::RESPONSE_OK) {
1615 const std::string& filename = dialog.get_filename();
1616 if (!filename.empty() && (
1618 Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) ||
1620 Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)
1622 _rc_config->set_xjadeo_binary (filename);
1627 void parameter_changed (string const & p)
1629 if (p == "video-server-url") {
1630 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1631 } else if (p == "video-server-docroot") {
1632 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1633 } else if (p == "show-video-export-info") {
1634 bool const x = _rc_config->get_show_video_export_info();
1635 _show_video_export_info_button.set_active (x);
1636 } else if (p == "show-video-server-dialog") {
1637 bool const x = _rc_config->get_show_video_server_dialog();
1638 _show_video_server_dialog_button.set_active (x);
1639 } else if (p == "video-advanced-setup") {
1640 bool const x = _rc_config->get_video_advanced_setup();
1641 _video_advanced_setup_button.set_active(x);
1642 _video_server_docroot_entry.set_sensitive(x);
1643 _video_server_url_entry.set_sensitive(x);
1644 } else if (p == "xjadeo-binary") {
1645 _custom_xjadeo_path.set_text (_rc_config->get_xjadeo_binary());
1649 void set_state_from_config ()
1651 parameter_changed ("video-server-url");
1652 parameter_changed ("video-server-docroot");
1653 parameter_changed ("video-monitor-setup-dialog");
1654 parameter_changed ("show-video-export-info");
1655 parameter_changed ("show-video-server-dialog");
1656 parameter_changed ("video-advanced-setup");
1657 parameter_changed ("xjadeo-binary");
1661 RCConfiguration* _rc_config;
1662 Entry _video_server_url_entry;
1663 Entry _video_server_docroot_entry;
1664 Entry _custom_xjadeo_path;
1665 CheckButton _show_video_export_info_button;
1666 CheckButton _show_video_server_dialog_button;
1667 CheckButton _video_advanced_setup_button;
1668 Button _xjadeo_browse_button;
1671 class ColumVisibilityOption : public Option
1674 ColumVisibilityOption (string id, string name, uint32_t n_col, sigc::slot<uint32_t> get, sigc::slot<bool, uint32_t> set)
1681 cb = (CheckButton**) malloc (sizeof (CheckButton*) * n_col);
1682 for (uint32_t i = 0; i < n_col; ++i) {
1683 CheckButton* col = manage (new CheckButton (string_compose (_("Column %1"), i + 1)));
1684 col->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ColumVisibilityOption::column_toggled), i));
1685 _hbox.pack_start (*col);
1688 parameter_changed (id);
1691 ~ColumVisibilityOption () {
1695 Gtk::Widget& tip_widget() { return _hbox; }
1697 void set_state_from_config ()
1699 uint32_t c = _get();
1700 for (uint32_t i = 0; i < _n_col; ++i) {
1701 bool en = (c & (1<<i)) ? true : false;
1702 if (cb[i]->get_active () != en) {
1703 cb[i]->set_active (en);
1708 void add_to_page (OptionEditorPage* p)
1710 _heading.add_to_page (p);
1711 add_widget_to_page (p, &_hbox);
1715 void column_toggled (int b) {
1716 uint32_t c = _get();
1718 if (cb[b]->get_active ()) {
1729 OptionEditorHeading _heading;
1733 sigc::slot<uint32_t> _get;
1734 sigc::slot<bool, uint32_t> _set;
1738 /** A class which allows control of visibility of some editor components usign
1739 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1740 * which has the correct members, but with null widget pointers. This
1741 * class allows the user to set visibility of the members, the details
1742 * of which are stored in a configuration variable which can be watched
1743 * by parts of the editor that actually contain the widgets whose visibility
1744 * is being controlled.
1747 class VisibilityOption : public Option
1750 /** @param name User-visible name for this group.
1751 * @param g `Dummy' VisibilityGroup (as described above).
1752 * @param get Method to get the value of the appropriate configuration variable.
1753 * @param set Method to set the value of the appropriate configuration variable.
1755 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1756 : Option (g->get_state_name(), name)
1758 , _visibility_group (g)
1762 /* Watch for changes made by the user to our members */
1763 _visibility_group->VisibilityChanged.connect_same_thread (
1764 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1768 void set_state_from_config ()
1770 /* Set our state from the current configuration */
1771 _visibility_group->set_state (_get ());
1774 void add_to_page (OptionEditorPage* p)
1776 _heading.add_to_page (p);
1777 add_widget_to_page (p, _visibility_group->list_view ());
1780 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1785 /* The user has changed something, so reflect this change
1786 in the RCConfiguration.
1788 _set (_visibility_group->get_state_value ());
1791 OptionEditorHeading _heading;
1792 VisibilityGroup* _visibility_group;
1793 sigc::slot<std::string> _get;
1794 sigc::slot<bool, std::string> _set;
1795 PBD::ScopedConnection _visibility_group_connection;
1799 class MidiPortOptions : public OptionEditorMiniPage, public sigc::trackable
1802 MidiPortOptions() : refill_id (-1) {
1804 setup_midi_port_view (midi_output_view, false);
1805 setup_midi_port_view (midi_input_view, true);
1807 OptionEditorHeading* h = new OptionEditorHeading (_("MIDI Inputs"));
1808 h->add_to_page (this);
1810 Gtk::ScrolledWindow* scroller = manage (new Gtk::ScrolledWindow);
1811 scroller->add (midi_input_view);
1812 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1813 scroller->set_size_request (-1, 180);
1815 int n = table.property_n_rows();
1816 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1818 h = new OptionEditorHeading (_("MIDI Outputs"));
1819 h->add_to_page (this);
1821 scroller = manage (new Gtk::ScrolledWindow);
1822 scroller->add (midi_output_view);
1823 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1824 scroller->set_size_request (-1, 180);
1826 n = table.property_n_rows();
1827 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1829 midi_output_view.show ();
1830 midi_input_view.show ();
1832 table.signal_map().connect (sigc::mem_fun (*this, &MidiPortOptions::on_map));
1833 table.signal_unmap().connect (sigc::mem_fun (*this, &MidiPortOptions::on_unmap));
1836 void parameter_changed (string const&) {}
1837 void set_state_from_config() {}
1843 AudioEngine::instance()->PortRegisteredOrUnregistered.connect (connections,
1844 invalidator (*this),
1845 boost::bind (&MidiPortOptions::refill, this),
1847 AudioEngine::instance()->MidiPortInfoChanged.connect (connections,
1848 invalidator (*this),
1849 boost::bind (&MidiPortOptions::refill, this),
1851 AudioEngine::instance()->MidiSelectionPortsChanged.connect (connections,
1852 invalidator (*this),
1853 boost::bind (&MidiPortOptions::refill, this),
1858 connections.drop_connections ();
1863 if (refill_midi_ports (true, midi_input_view)) {
1864 input_label.show ();
1866 input_label.hide ();
1868 if (refill_midi_ports (false, midi_output_view)) {
1869 output_label.show ();
1871 output_label.hide ();
1878 PBD::ScopedConnectionList connections;
1880 /* MIDI port management */
1881 struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord {
1883 MidiPortColumns () {
1893 Gtk::TreeModelColumn<std::string> pretty_name;
1894 Gtk::TreeModelColumn<bool> music_data;
1895 Gtk::TreeModelColumn<bool> control_data;
1896 Gtk::TreeModelColumn<bool> selection;
1897 Gtk::TreeModelColumn<std::string> fullname;
1898 Gtk::TreeModelColumn<std::string> shortname;
1899 Gtk::TreeModelColumn<std::string> filler;
1902 MidiPortColumns midi_port_columns;
1903 Gtk::TreeView midi_input_view;
1904 Gtk::TreeView midi_output_view;
1905 Gtk::Label input_label;
1906 Gtk::Label output_label;
1909 void setup_midi_port_view (Gtk::TreeView&, bool with_selection);
1910 bool refill_midi_ports (bool for_input, Gtk::TreeView&);
1911 void pretty_name_edit (std::string const & path, std::string const & new_text, Gtk::TreeView*);
1912 void midi_music_column_toggled (std::string const & path, Gtk::TreeView*);
1913 void midi_control_column_toggled (std::string const & path, Gtk::TreeView*);
1914 void midi_selection_column_toggled (std::string const & path, Gtk::TreeView*);
1918 MidiPortOptions::setup_midi_port_view (Gtk::TreeView& view, bool with_selection)
1920 int pretty_name_column;
1923 int selection_column;
1924 TreeViewColumn* col;
1927 pretty_name_column = view.append_column_editable (_("Name (click twice to edit)"), midi_port_columns.pretty_name) - 1;
1929 col = manage (new TreeViewColumn ("", midi_port_columns.music_data));
1930 col->set_alignment (ALIGN_CENTER);
1931 l = manage (new Label (_("Music Data")));
1932 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of music performance data."), PROGRAM_NAME));
1933 col->set_widget (*l);
1935 music_column = view.append_column (*col) - 1;
1937 col = manage (new TreeViewColumn ("", midi_port_columns.control_data));
1938 col->set_alignment (ALIGN_CENTER);
1939 l = manage (new Label (_("Control Data")));
1940 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of control data."), PROGRAM_NAME));
1941 col->set_widget (*l);
1943 control_column = view.append_column (*col) - 1;
1945 if (with_selection) {
1946 col = manage (new TreeViewColumn (_("Follow Selection"), midi_port_columns.selection));
1947 selection_column = view.append_column (*col) - 1;
1948 l = manage (new Label (_("Follow Selection")));
1949 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));
1950 col->set_widget (*l);
1954 /* filler column so that the last real column doesn't expand */
1955 view.append_column ("", midi_port_columns.filler);
1957 CellRendererText* pretty_name_cell = dynamic_cast<CellRendererText*> (view.get_column_cell_renderer (pretty_name_column));
1958 pretty_name_cell->property_editable() = true;
1959 pretty_name_cell->signal_edited().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::pretty_name_edit), &view));
1961 CellRendererToggle* toggle_cell;
1963 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (music_column));
1964 toggle_cell->property_activatable() = true;
1965 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_music_column_toggled), &view));
1967 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (control_column));
1968 toggle_cell->property_activatable() = true;
1969 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_control_column_toggled), &view));
1971 if (with_selection) {
1972 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (selection_column));
1973 toggle_cell->property_activatable() = true;
1974 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_selection_column_toggled), &view));
1977 view.get_selection()->set_mode (SELECTION_SINGLE);
1978 view.set_tooltip_column (5); /* port short name */
1979 view.get_column(0)->set_resizable (true);
1980 view.get_column(0)->set_expand (true);
1984 MidiPortOptions::refill_midi_ports (bool for_input, Gtk::TreeView& view)
1986 using namespace ARDOUR;
1988 std::vector<string> ports;
1990 AudioEngine::instance()->get_known_midi_ports (ports);
1992 if (ports.empty()) {
1997 Glib::RefPtr<ListStore> model = Gtk::ListStore::create (midi_port_columns);
1999 for (vector<string>::const_iterator s = ports.begin(); s != ports.end(); ++s) {
2001 if (AudioEngine::instance()->port_is_mine (*s)) {
2005 PortManager::MidiPortInformation mpi (AudioEngine::instance()->midi_port_information (*s));
2011 if (for_input != mpi.input) {
2015 TreeModel::Row row = *(model->append());
2017 row[midi_port_columns.pretty_name] = mpi.pretty_name;
2018 row[midi_port_columns.music_data] = mpi.properties & MidiPortMusic;
2019 row[midi_port_columns.control_data] = mpi.properties & MidiPortControl;
2020 row[midi_port_columns.selection] = mpi.properties & MidiPortSelection;
2021 row[midi_port_columns.fullname] = *s;
2022 row[midi_port_columns.shortname] = AudioEngine::instance()->short_port_name_from_port_name (*s);
2025 view.set_model (model);
2031 MidiPortOptions::midi_music_column_toggled (string const & path, TreeView* view)
2033 TreeIter iter = view->get_model()->get_iter (path);
2039 bool new_value = ! bool ((*iter)[midi_port_columns.music_data]);
2041 /* don't reset model - wait for MidiPortInfoChanged signal */
2044 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.fullname], MidiPortMusic);
2046 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.fullname], MidiPortMusic);
2051 MidiPortOptions::midi_control_column_toggled (string const & path, TreeView* view)
2053 TreeIter iter = view->get_model()->get_iter (path);
2059 bool new_value = ! bool ((*iter)[midi_port_columns.control_data]);
2061 /* don't reset model - wait for MidiPortInfoChanged signal */
2064 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.fullname], MidiPortControl);
2066 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.fullname], MidiPortControl);
2071 MidiPortOptions::midi_selection_column_toggled (string const & path, TreeView* view)
2073 TreeIter iter = view->get_model()->get_iter (path);
2079 bool new_value = ! bool ((*iter)[midi_port_columns.selection]);
2081 /* don't reset model - wait for MidiSelectionPortsChanged signal */
2084 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.fullname], MidiPortSelection);
2086 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.fullname], MidiPortSelection);
2091 MidiPortOptions::pretty_name_edit (std::string const & path, string const & new_text, Gtk::TreeView* view)
2093 TreeIter iter = view->get_model()->get_iter (path);
2099 AudioEngine::instance()->set_port_pretty_name ((*iter)[midi_port_columns.fullname], new_text);
2105 RCOptionEditor::RCOptionEditor ()
2106 : OptionEditorContainer (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
2107 , Tabbable (*this, _("Preferences")
2109 , false // detached by default (first start, no instant.xml)
2111 ) /* pack self-as-vbox into tabbable */
2112 , _rc_config (Config)
2113 , _mixer_strip_visibility ("mixer-element-visibility")
2115 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
2119 uint32_t hwcpus = hardware_concurrency ();
2123 add_option (_("General"), new OptionEditorHeading (_("DSP CPU Utilization")));
2125 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
2127 _("Signal processing uses"),
2128 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
2129 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
2132 procs->add (-1, _("all but one processor"));
2133 procs->add (0, _("all available processors"));
2135 for (uint32_t i = 1; i <= hwcpus; ++i) {
2136 procs->add (i, string_compose (P_("%1 processor", "%1 processors", i), i));
2139 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
2141 add_option (_("General"), procs);
2144 /* Image cache size */
2145 add_option (_("General"), new OptionEditorHeading (_("Memory Usage")));
2147 HSliderOption *sics = new HSliderOption ("waveform-cache-size",
2148 _("Waveform image cache size (megabytes)"),
2149 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
2150 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size),
2151 1, 1024, 10 /* 1 MB to 1GB in steps of 10MB */
2153 sics->scale().set_digits (0);
2154 Gtkmm2ext::UI::instance()->set_tip (
2156 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
2157 add_option (_("General"), sics);
2159 add_option (_("General"), new OptionEditorHeading (_("Engine")));
2161 add_option (_("General"),
2163 "try-autostart-engine",
2164 _("Try to auto-launch audio/midi engine"),
2165 sigc::mem_fun (*_rc_config, &RCConfiguration::get_try_autostart_engine),
2166 sigc::mem_fun (*_rc_config, &RCConfiguration::set_try_autostart_engine)
2169 add_option (_("General"), new OptionEditorHeading (_("Automation")));
2171 add_option (_("General"),
2172 new SpinOption<double> (
2173 "automation-thinning-factor",
2174 _("Thinning factor (larger value => less data)"),
2175 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
2176 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
2180 add_option (_("General"),
2181 new SpinOption<double> (
2182 "automation-interval-msecs",
2183 _("Automation sampling interval (milliseconds)"),
2184 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
2185 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
2189 add_option (_("General"), new OptionEditorHeading (_("Tempo")));
2191 bo = new BoolOption (
2192 "allow-non-quarter-pulse",
2193 _("Allow non quarter-note pulse"),
2194 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_allow_non_quarter_pulse),
2195 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_allow_non_quarter_pulse)
2197 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2198 string_compose (_("<b>When enabled</b> %1 will allow tempo to be expressed in divisions per minute\n"
2199 "<b>When disabled</b> %1 will only allow tempo to be expressed in quarter notes per minute"),
2201 add_option (_("General"), bo);
2203 if (!ARDOUR::Profile->get_mixbus()) {
2204 add_option (_("General"), new OptionEditorHeading (_("GUI Lock")));
2205 /* Lock GUI timeout */
2207 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2208 _("Lock timeout (seconds)"),
2209 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
2210 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds),
2213 slts->scale().set_digits (0);
2214 Gtkmm2ext::UI::instance()->set_tip (
2216 _("Lock GUI after this many idle seconds (zero to never lock)"));
2217 add_option (_("General"), slts);
2220 add_option (_("General/Session"), new OptionEditorHeading (S_("Options|Undo")));
2222 add_option (_("General/Session"), new UndoOptions (_rc_config));
2224 add_option (_("General/Session"),
2226 "verify-remove-last-capture",
2227 _("Verify removal of last capture"),
2228 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
2229 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
2232 add_option (_("General/Session"), new OptionEditorHeading (_("Session Management")));
2234 add_option (_("General/Session"),
2236 "periodic-safety-backups",
2237 _("Make periodic backups of the session file"),
2238 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
2239 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
2242 add_option (_("General/Session"),
2244 "only-copy-imported-files",
2245 _("Always copy imported files"),
2246 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
2247 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
2250 add_option (_("General/Session"), new DirectoryOption (
2251 X_("default-session-parent-dir"),
2252 _("Default folder for new sessions:"),
2253 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
2254 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
2257 add_option (_("General/Session"),
2258 new SpinOption<uint32_t> (
2259 "max-recent-sessions",
2260 _("Maximum number of recent sessions"),
2261 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
2262 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
2269 add_option (_("General/Translation"), new OptionEditorHeading (_("Internationalization")));
2271 bo = new BoolOption (
2272 "enable-translation",
2273 _("Use translations"),
2274 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2275 sigc::ptr_fun (ARDOUR::set_translations_enabled)
2278 bo->set_note (string_compose (_("These settings will only take effect after %1 is restarted (if available for your language preferences)."), PROGRAM_NAME));
2280 add_option (_("General/Translation"), bo);
2282 parameter_changed ("enable-translation");
2283 #endif // ENABLE_NLS
2288 add_option (_("Editor"), new OptionEditorHeading (_("General")));
2290 bo = new BoolOption (
2292 _("Prompt for new marker names"),
2293 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2294 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2296 add_option (_("Editor"), bo);
2297 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."
2298 "\n\nYou can always rename markers by right-clicking on them"));
2300 add_option (_("Editor"),
2302 "draggable-playhead",
2303 _("Allow dragging of playhead"),
2304 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2305 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2308 ComboOption<float>* dps = new ComboOption<float> (
2309 "draggable-playhead-speed",
2310 _("Playhead dragging speed (%)"),
2311 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead_speed),
2312 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead_speed)
2314 dps->add (0.05, _("5%"));
2315 dps->add (0.1, _("10%"));
2316 dps->add (0.25, _("25%"));
2317 dps->add (0.5, _("50%"));
2318 dps->add (1.0, _("100%"));
2319 add_option (_("Editor"), dps);
2321 ComboOption<float>* eet = new ComboOption<float> (
2322 "extra-ui-extents-time",
2323 _("Limit zooming & summary view to X minutes beyond session extents"),
2324 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_extra_ui_extents_time),
2325 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_extra_ui_extents_time)
2327 eet->add (1, _("1 minute"));
2328 eet->add (2, _("2 minutes"));
2329 eet->add (20, _("20 minutes"));
2330 eet->add (60, _("1 hour"));
2331 eet->add (60*2, _("2 hours"));
2332 eet->add (60*24, _("24 hours"));
2333 add_option (_("Editor"), eet);
2335 if (!Profile->get_mixbus()) {
2337 add_option (_("Editor"),
2339 "use-mouse-position-as-zoom-focus-on-scroll",
2340 _("Zoom to mouse position when zooming with scroll wheel"),
2341 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2342 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2346 add_option (_("Editor"),
2348 "use-time-rulers-to-zoom-with-vertical-drag",
2349 _("Zoom with vertical drag in rulers"),
2350 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag),
2351 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag)
2354 add_option (_("Editor"),
2356 "use-double-click-to-zoom-to-selection",
2357 _("Double click zooms to selection"),
2358 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection),
2359 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection)
2362 add_option (_("Editor"),
2364 "update-editor-during-summary-drag",
2365 _("Update editor window during drags of the summary"),
2366 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2367 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2370 add_option (_("Editor"),
2372 "autoscroll-editor",
2373 _("Auto-scroll editor window when dragging near its edges"),
2374 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2375 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2378 add_option (_("Editor"),
2379 new BoolComboOption (
2380 "show-region-gain-envelopes",
2381 _("Show gain envelopes in audio regions"),
2383 _("only in Draw and Internal Edit modes"),
2384 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2385 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2388 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2390 add_option (_("Editor"),
2392 "automation-follows-regions",
2393 _("Move relevant automation when audio regions are moved"),
2394 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2395 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2398 bo = new BoolOption (
2399 "new-automation-points-on-lane",
2400 _("Ignore Y-axis click position when adding new automation-points"),
2401 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_new_automation_points_on_lane),
2402 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_new_automation_points_on_lane)
2404 add_option (_("Editor"), bo);
2405 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2406 _("<b>When enabled</b> The new points drawn in any automation lane will be placed on the existing line, regardless of mouse y-axis position."));
2408 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2409 "default-fade-shape",
2410 _("Default fade shape"),
2411 sigc::mem_fun (*_rc_config,
2412 &RCConfiguration::get_default_fade_shape),
2413 sigc::mem_fun (*_rc_config,
2414 &RCConfiguration::set_default_fade_shape)
2417 fadeshape->add (FadeLinear,
2418 _("Linear (for highly correlated material)"));
2419 fadeshape->add (FadeConstantPower, _("Constant power"));
2420 fadeshape->add (FadeSymmetric, _("Symmetric"));
2421 fadeshape->add (FadeSlow, _("Slow"));
2422 fadeshape->add (FadeFast, _("Fast"));
2424 add_option (_("Editor"), fadeshape);
2426 ComboOption<RegionEquivalence> *eqv = new ComboOption<RegionEquivalence> (
2427 "region-equivalency",
2428 _("Regions in active edit groups are edited together"),
2429 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_equivalence),
2430 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_equivalence)
2433 eqv->add (Overlap, _("whenever they overlap in time"));
2434 eqv->add (Enclosed, _("if either encloses the other"));
2435 eqv->add (Exact, _("only if they have identical length, position and origin"));
2436 eqv->add (LayerTime, _("only if they have identical length, position and layer"));
2438 add_option (_("Editor"), eqv);
2440 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2442 _("Layering model"),
2443 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2444 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2447 lm->add (LaterHigher, _("later is higher"));
2448 lm->add (Manual, _("manual layering"));
2449 add_option (_("Editor"), lm);
2451 add_option (_("Editor"), new OptionEditorHeading (_("Split/Separate")));
2453 ComboOption<RangeSelectionAfterSplit> *rras = new ComboOption<RangeSelectionAfterSplit> (
2454 "range-selection-after-separate",
2455 _("After a Separate operation, in Range mode"),
2456 sigc::mem_fun (*_rc_config, &RCConfiguration::get_range_selection_after_split),
2457 sigc::mem_fun (*_rc_config, &RCConfiguration::set_range_selection_after_split));
2459 rras->add(ClearSel, _("Clear the Range Selection"));
2460 rras->add(PreserveSel, _("Preserve the Range Selection"));
2461 rras->add(ForceSel, _("Force-Select the regions under the range. (this might cause a tool change)"));
2462 add_option (_("Editor"), rras);
2464 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2465 "region-selection-after-split",
2466 _("After a Split operation, in Object mode"),
2467 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2468 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2470 // TODO: decide which of these modes are really useful
2471 rsas->add(None, _("Clear the Selected Regions"));
2472 rsas->add(NewlyCreatedLeft, _("Select only the newly-created regions BEFORE the split point"));
2473 rsas->add(NewlyCreatedRight, _("Select only the newly-created regions AFTER the split point"));
2474 rsas->add(NewlyCreatedBoth, _("Select the newly-created regions"));
2475 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2476 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2477 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2478 rsas->add(ExistingNewlyCreatedBoth, _("Preserve the existing selection, AND select all newly-created regions"));
2480 add_option (_("Editor"), rsas);
2482 add_option (_("Editor/Snap"), new OptionEditorHeading (_("General Snap options:")));
2484 add_option (_("Editor/Snap"),
2485 new SpinOption<uint32_t> (
2487 _("Snap Threshold (pixels)"),
2488 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_threshold),
2489 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_threshold),
2494 add_option (_("Editor/Snap"),
2496 "show-snapped-cursor",
2497 _("Show \"snapped cursor\""),
2498 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_snapped_cursor),
2499 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_snapped_cursor)
2502 add_option (_("Editor/Snap"),
2504 "rubberbanding-snaps-to-grid",
2505 _("Snap rubberband selection to grid"),
2506 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2507 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2510 add_option (_("Editor/Snap"),
2512 "grid-follows-internal",
2513 _("Grid switches to alternate selection for Internal Edit tools"),
2514 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_grid_follows_internal),
2515 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_grid_follows_internal)
2518 add_option (_("Editor/Snap"),
2520 "rulers-follow-grid",
2521 _("Rulers automatically change to follow the Grid mode selection"),
2522 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rulers_follow_grid),
2523 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rulers_follow_grid)
2526 add_option (_("Editor/Snap"), new OptionEditorHeading (_("When \"Snap\" is enabled, snap to:")));
2529 add_option (_("Editor/Snap"),
2533 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_marks),
2534 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_marks)
2537 add_option (_("Editor/Snap"),
2539 "snap-to-region-sync",
2540 _("Region Sync Points"),
2541 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_region_sync),
2542 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_region_sync)
2545 add_option (_("Editor/Snap"),
2547 "snap-to-region-start",
2549 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_region_start),
2550 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_region_start)
2553 add_option (_("Editor/Snap"),
2555 "snap-to-region-end",
2557 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_region_end),
2558 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_region_end)
2561 add_option (_("Editor/Snap"),
2565 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_grid),
2566 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_grid)
2569 add_option (_("Editor/Modifiers"), new OptionEditorHeading (_("Keyboard Modifiers")));
2570 add_option (_("Editor/Modifiers"), new KeyboardOptions);
2571 add_option (_("Editor/Modifiers"), new OptionEditorBlank ());
2573 /* MIXER -- SOLO AND MUTE */
2575 add_option (_("Mixer"), new OptionEditorHeading (_("Solo")));
2577 _solo_control_is_listen_control = new BoolOption (
2578 "solo-control-is-listen-control",
2579 _("Solo controls are Listen controls"),
2580 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2581 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2584 add_option (_("Mixer"), _solo_control_is_listen_control);
2586 add_option (_("Mixer"),
2589 _("Exclusive solo"),
2590 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2591 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2594 add_option (_("Mixer"),
2597 _("Show solo muting"),
2598 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2599 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2602 add_option (_("Mixer"),
2604 "solo-mute-override",
2605 _("Soloing overrides muting"),
2606 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2607 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2610 add_option (_("Mixer"),
2613 _("Solo-in-place mute cut (dB)"),
2614 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2615 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2618 _listen_position = new ComboOption<ListenPosition> (
2620 _("Listen Position"),
2621 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2622 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2625 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2626 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2628 add_option (_("Mixer"), _listen_position);
2630 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2632 _("PFL signals come from"),
2633 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2634 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2637 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2638 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2640 add_option (_("Mixer"), pp);
2642 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2644 _("AFL signals come from"),
2645 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2646 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2649 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2650 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2652 add_option (_("Mixer"), pa);
2654 add_option (_("Mixer"), new OptionEditorHeading (_("Default Track / Bus Muting Options")));
2656 add_option (_("Mixer"),
2658 "mute-affects-pre-fader",
2659 _("Mute affects pre-fader sends"),
2660 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2661 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2664 add_option (_("Mixer"),
2666 "mute-affects-post-fader",
2667 _("Mute affects post-fader sends"),
2668 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2669 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2672 add_option (_("Mixer"),
2674 "mute-affects-control-outs",
2675 _("Mute affects control outputs"),
2676 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2677 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2680 add_option (_("Mixer"),
2682 "mute-affects-main-outs",
2683 _("Mute affects main outputs"),
2684 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2685 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2689 if (!ARDOUR::Profile->get_mixbus()) {
2690 add_option (_("Mixer"), new OptionEditorHeading (_("Send Routing")));
2691 add_option (_("Mixer"),
2693 "link-send-and-route-panner",
2694 _("Link panners of Aux and External Sends with main panner by default"),
2695 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2696 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2702 add_option (_("Signal Flow"), new OptionEditorHeading (_("Monitoring")));
2704 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2706 _("Record monitoring handled by"),
2707 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2708 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2711 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2712 mm->add (HardwareMonitoring, _("via Audio Driver"));
2715 string prog (PROGRAM_NAME);
2716 boost::algorithm::to_lower (prog);
2717 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2718 mm->add (ExternalMonitoring, _("audio hardware"));
2720 add_option (_("Signal Flow"), mm);
2722 bo = new BoolOption (
2723 "tape-machine-mode",
2724 _("Tape machine mode"),
2725 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2726 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2728 add_option (_("Signal Flow"), bo);
2729 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2730 string_compose (_("<b>When enabled</b> %1 will not monitor a track's input if the transport is stopped."),
2733 if (!Profile->get_mixbus()) {
2735 add_option (_("Signal Flow"), new OptionEditorHeading (_("Track and Bus Connections")));
2737 bo = new BoolOption (
2738 "auto-connect-standard-busses",
2739 _("Auto-connect main output (master or monitor) bus to physical ports"),
2740 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2741 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2743 add_option (_("Signal Flow"), bo);
2744 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2745 _("<b>When enabled</b> the main output bus is auto-connected to the first N physical ports. "
2746 "If the session has a monitor-section, the monitor-bus output is conneced the the hardware playback ports, "
2747 "otherwise the master-bus output is directly used for playback."));
2749 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2750 "input-auto-connect",
2751 _("Connect track inputs"),
2752 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2753 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2756 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2757 iac->add (ManualConnect, _("manually"));
2759 add_option (_("Signal Flow"), iac);
2761 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2762 "output-auto-connect",
2763 _("Connect track and bus outputs"),
2764 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2765 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2768 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2769 oac->add (AutoConnectMaster, _("automatically to master bus"));
2770 oac->add (ManualConnect, _("manually"));
2772 add_option (_("Signal Flow"), oac);
2774 bo = new BoolOption (
2776 _("Use 'Strict-I/O' for new tracks or busses"),
2777 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2778 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2781 add_option (_("Signal Flow"), bo);
2782 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2783 _("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."));
2790 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2792 add_option (_("Audio"), new BufferingOptions (_rc_config));
2794 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2796 add_option (_("Audio"),
2798 "denormal-protection",
2799 _("Use DC bias to protect against denormals"),
2800 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2801 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2804 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2806 _("Processor handling"),
2807 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2808 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2812 dm->add (DenormalNone, _("no processor handling"));
2814 FPU* fpu = FPU::instance();
2816 if (fpu->has_flush_to_zero()) {
2818 dm->add (DenormalFTZ, _("use FlushToZero"));
2819 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2820 _rc_config->set_denormal_model(DenormalNone);
2823 if (fpu->has_denormals_are_zero()) {
2825 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2826 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2827 _rc_config->set_denormal_model(DenormalNone);
2830 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2832 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2833 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2834 _rc_config->set_denormal_model(DenormalNone);
2838 dm->set_sensitive(false);
2841 add_option (_("Audio"), dm);
2843 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2845 add_option (_("Audio"),
2847 "auto-analyse-audio",
2848 _("Enable automatic analysis of audio"),
2849 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2850 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2853 add_option (_("Audio"),
2855 "replicate-missing-region-channels",
2856 _("Replicate missing region channels"),
2857 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2858 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2863 add_option (_("MIDI"), new OptionEditorHeading (_("Buffering")));
2865 add_option (_("MIDI"),
2866 new SpinOption<float> (
2868 _("MIDI read-ahead time (seconds)"),
2869 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2870 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2875 add_option (_("MIDI"), new OptionEditorHeading (_("Session")));
2877 add_option (_("MIDI"),
2878 new SpinOption<int32_t> (
2879 "initial-program-change",
2880 _("Initial program change"),
2881 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2882 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2886 add_option (_("MIDI"), new OptionEditorHeading (_("Audition")));
2888 add_option (_("MIDI"),
2891 _("Sound MIDI notes as they are selected in the editor"),
2892 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2893 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2898 add_option (_("Metronome"), new OptionEditorHeading (_("Metronome")));
2899 add_option (_("Metronome"), new ClickOptions (_rc_config));
2900 add_option (_("Metronome"), new OptionEditorHeading (_("Options")));
2902 bo = new BoolOption (
2903 "click-record-only",
2904 _("Enable metronome only while recording"),
2905 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_record_only),
2906 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_record_only)
2909 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2910 string_compose (_("<b>When enabled</b> the metronome will remain silent if %1 is <b>not recording</b>."), PROGRAM_NAME));
2911 add_option (_("Metronome"), bo);
2912 add_option (_("Metronome"), new OptionEditorBlank ());
2917 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2919 ComboOption<float>* mht = new ComboOption<float> (
2921 _("Peak hold time"),
2922 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
2923 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
2926 mht->add (MeterHoldOff, _("off"));
2927 mht->add (MeterHoldShort, _("short"));
2928 mht->add (MeterHoldMedium, _("medium"));
2929 mht->add (MeterHoldLong, _("long"));
2931 add_option (S_("Preferences|Metering"), mht);
2933 ComboOption<float>* mfo = new ComboOption<float> (
2936 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2937 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2940 mfo->add (METER_FALLOFF_OFF, _("off"));
2941 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2942 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2943 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2944 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2945 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2946 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
2948 add_option (S_("Preferences|Metering"), mfo);
2950 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2951 "meter-line-up-level",
2952 _("Meter line-up level; 0dBu"),
2953 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
2954 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
2957 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2958 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2959 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2960 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2962 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."));
2964 add_option (S_("Preferences|Metering"), mlu);
2966 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2967 "meter-line-up-din",
2968 _("IEC1/DIN Meter line-up level; 0dBu"),
2969 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
2970 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
2973 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2974 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2975 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2976 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2978 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2980 add_option (S_("Preferences|Metering"), mld);
2982 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2983 "meter-vu-standard",
2984 _("VU Meter standard"),
2985 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
2986 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
2989 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2990 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2991 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2992 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2994 add_option (S_("Preferences|Metering"), mvu);
2996 HSliderOption *mpks = new HSliderOption("meter-peak",
2997 _("Peak indicator threshold [dBFS]"),
2998 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
2999 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak),
3003 Gtkmm2ext::UI::instance()->set_tip (
3005 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
3007 add_option (S_("Preferences|Metering"), mpks);
3009 OptionEditorHeading* default_meter_head = new OptionEditorHeading (_("Default Meter Types"));
3010 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."));
3012 add_option (S_("Preferences|Metering"), default_meter_head);
3014 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3015 "meter-type-master",
3016 _("Default Meter Type for Master Bus"),
3017 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3018 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3020 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3021 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3022 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3023 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3024 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3025 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3026 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3027 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3029 add_option (S_("Preferences|Metering"), mtm);
3032 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3034 _("Default meter type for busses"),
3035 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3036 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3038 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3039 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3040 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3041 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3042 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3043 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3044 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3045 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3047 add_option (S_("Preferences|Metering"), mtb);
3049 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3051 _("Default meter type for tracks"),
3052 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3053 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3055 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3056 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3058 add_option (S_("Preferences|Metering"), mtt);
3060 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
3062 add_option (S_("Preferences|Metering"),
3064 "save-export-analysis-image",
3065 _("Save loudness analysis as image file"),
3066 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
3067 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
3070 /* TRANSPORT & Sync */
3072 add_option (_("Transport"), new OptionEditorHeading (_("General")));
3074 bo = new BoolOption (
3075 "stop-at-session-end",
3076 _("Stop at the end of the session"),
3077 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
3078 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
3080 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3081 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
3082 "when it reaches the current session end marker\n\n"
3083 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
3085 add_option (_("Transport"), bo);
3087 bo = new BoolOption (
3088 "latched-record-enable",
3089 _("Keep record-enable engaged on stop"),
3090 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
3091 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
3093 add_option (_("Transport"), bo);
3094 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3095 _("<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."));
3097 bo = new BoolOption (
3098 "disable-disarm-during-roll",
3099 _("Disable per-track record disarm while rolling"),
3100 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
3101 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
3103 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."));
3104 add_option (_("Transport"), bo);
3106 bo = new BoolOption (
3108 _("12dB gain reduction during fast-forward and fast-rewind"),
3109 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
3110 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
3112 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3113 _("<b>When enabled</b> this will reduce the unpleasant increase in perceived volume "
3114 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
3115 add_option (_("Transport"), bo);
3117 ComboOption<float>* psc = new ComboOption<float> (
3120 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
3121 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
3123 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
3124 (_("The amount of preroll to apply when <b>Play with Preroll</b> or <b>Record with Preroll</b>is initiated.\n\n"
3125 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
3126 psc->add (-4.0, _("4 Bars"));
3127 psc->add (-2.0, _("2 Bars"));
3128 psc->add (-1.0, _("1 Bar"));
3129 psc->add (0.0, _("0 (no pre-roll)"));
3130 psc->add (0.1, _("0.1 second"));
3131 psc->add (0.25, _("0.25 second"));
3132 psc->add (0.5, _("0.5 second"));
3133 psc->add (1.0, _("1.0 second"));
3134 psc->add (2.0, _("2.0 seconds"));
3135 add_option (_("Transport"), psc);
3138 add_option (_("Transport"), new OptionEditorHeading (_("Looping")));
3140 bo = new BoolOption (
3142 _("Play loop is a transport mode"),
3143 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
3144 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
3146 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3147 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
3148 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
3149 add_option (_("Transport"), bo);
3151 bo = new BoolOption (
3153 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
3154 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
3155 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
3157 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3158 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
3159 "preventing any need to do a transport locate at the end of the loop\n\n"
3160 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
3161 "which will often cause a small click or delay"), PROGRAM_NAME));
3162 add_option (_("Transport"), bo);
3164 add_option (_("Transport"), new OptionEditorHeading (_("Dropout (xrun) Handling")));
3165 bo = new BoolOption (
3166 "stop-recording-on-xrun",
3167 _("Stop recording when an xrun occurs"),
3168 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
3169 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
3171 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3172 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
3174 add_option (_("Transport"), bo);
3176 bo = new BoolOption (
3177 "create-xrun-marker",
3178 _("Create markers where xruns occur"),
3179 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
3180 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
3182 add_option (_("Transport"), bo);
3187 add_option (_("Sync"), new OptionEditorHeading (_("Transport Masters")));
3189 add_option (_("Sync"), new WidgetOption (X_("foo"), X_("Transport Masters"), _transport_masters_widget));
3191 _sync_framerate = new BoolOption (
3192 "timecode-sync-frame-rate",
3193 _("Match session video frame rate to external timecode"),
3194 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
3195 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
3197 Gtkmm2ext::UI::instance()->set_tip
3198 (_sync_framerate->tip_widget(),
3199 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
3200 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
3201 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
3202 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
3203 "timecode standard and the session standard."), PROGRAM_NAME));
3205 add_option (_("Sync"), _sync_framerate);
3207 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Generator")));
3209 add_option (_("Sync/LTC"),
3212 _("Enable LTC generator"),
3213 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
3214 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
3217 _ltc_send_continuously = new BoolOption (
3218 "ltc-send-continuously",
3219 _("Send LTC while stopped"),
3220 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
3221 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
3223 Gtkmm2ext::UI::instance()->set_tip
3224 (_ltc_send_continuously->tip_widget(),
3225 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
3226 add_option (_("Sync/LTC"), _ltc_send_continuously);
3228 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level [dBFS]"),
3229 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_output_volume),
3230 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_output_volume),
3234 Gtkmm2ext::UI::instance()->set_tip
3235 (_ltc_volume_slider->tip_widget(),
3236 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
3238 add_option (_("Sync/LTC"), _ltc_volume_slider);
3240 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Beat Clock (Mclk) Generator")));
3242 add_option (_("Sync/MIDI"),
3245 _("Enable Mclk generator"),
3246 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
3247 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
3250 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC) Generator")));
3252 add_option (_("Sync/MIDI"),
3255 _("Enable MTC Generator"),
3256 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
3257 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
3260 add_option (_("Sync/MIDI"),
3261 new SpinOption<int> (
3262 "mtc-qf-speed-tolerance",
3263 _("Percentage either side of normal transport speed to transmit MTC"),
3264 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
3265 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
3269 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Machine Control (MMC)")));
3271 add_option (_("Sync/MIDI"),
3274 _("Respond to MMC commands"),
3275 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
3276 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
3279 add_option (_("Sync/MIDI"),
3282 _("Send MMC commands"),
3283 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
3284 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
3287 add_option (_("Sync/MIDI"),
3288 new SpinOption<uint8_t> (
3289 "mmc-receive-device-id",
3290 _("Inbound MMC device ID"),
3291 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
3292 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
3296 add_option (_("Sync/MIDI"),
3297 new SpinOption<uint8_t> (
3298 "mmc-send-device-id",
3299 _("Outbound MMC device ID"),
3300 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
3301 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
3306 /* Control Surfaces */
3308 add_option (_("Control Surfaces"), new OptionEditorHeading (_("Control Surfaces")));
3309 add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
3312 add_option (_("MIDI Ports"), new OptionEditorHeading (_("MIDI Port Options")));
3314 add_option (_("MIDI Ports"),
3316 "midi-input-follows-selection",
3317 _("MIDI input follows MIDI track selection"),
3318 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
3319 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
3322 add_option (_("MIDI Ports"), new MidiPortOptions ());
3323 add_option (_("MIDI Ports"), new OptionEditorBlank ());
3327 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3328 add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
3329 add_option (_("Plugins"),
3330 new RcActionButton (_("Scan for Plugins"),
3331 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3335 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
3337 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3338 bo = new BoolOption (
3339 "show-plugin-scan-window",
3340 _("Always Display Plugin Scan Progress"),
3341 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
3342 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
3344 add_option (_("Plugins"), bo);
3345 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3346 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
3349 bo = new BoolOption (
3350 "plugins-stop-with-transport",
3351 _("Silence plugins when the transport is stopped"),
3352 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
3353 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
3355 add_option (_("Plugins"), bo);
3356 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3357 _("<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."));
3359 bo = new BoolOption (
3360 "new-plugins-active",
3361 _("Make new plugins active"),
3362 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
3363 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
3365 add_option (_("Plugins"), bo);
3366 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3367 _("<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"));
3369 ComboOption<uint32_t>* lna = new ComboOption<uint32_t> (
3370 "limit-n-automatables",
3371 _("Limit automatable parameters per plugin"),
3372 sigc::mem_fun (*_rc_config, &RCConfiguration::get_limit_n_automatables),
3373 sigc::mem_fun (*_rc_config, &RCConfiguration::set_limit_n_automatables)
3375 lna->add (0, _("Unlimited"));
3376 lna->add (64, _("64 parameters"));
3377 lna->add (128, _("128 parameters"));
3378 lna->add (256, _("256 parameters"));
3379 lna->add (512, _("512 parameters"));
3380 lna->add (999, _("999 parameters"));
3381 add_option (_("Plugins"), lna);
3382 Gtkmm2ext::UI::instance()->set_tip (lna->tip_widget(),
3383 _("Some Plugins expose an unreasonable amount of control-inputs. This option limits the number of parameters that can are listed as automatable without restricting the number of total controls.\n\nThis reduces lag in the GUI and shortens excessively long drop-down lists for plugins with a large number of control ports.\n\nNote: This only affects newly added plugins and is applied to plugin on session-reload. Already automated parameters are retained."));
3386 #if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
3387 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
3389 add_option (_("Plugins/VST"),
3390 new RcActionButton (_("Scan for Plugins"),
3391 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3394 #if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
3395 bo = new BoolOption (
3397 _("Enable Mac VST support (requires restart or re-scan)"),
3398 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
3399 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
3401 add_option (_("Plugins/VST"), bo);
3404 bo = new BoolOption (
3405 "discover-vst-on-start",
3406 _("Scan for [new] VST Plugins on Application Start"),
3407 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
3408 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
3410 add_option (_("Plugins/VST"), bo);
3411 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3412 _("<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"));
3414 #ifdef WINDOWS_VST_SUPPORT
3415 // currently verbose logging is only implemented for Windows VST.
3416 bo = new BoolOption (
3417 "verbose-plugin-scan",
3418 _("Verbose Plugin Scan"),
3419 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
3420 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
3422 add_option (_("Plugins/VST"), bo);
3423 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3424 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
3427 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
3429 add_option (_("Plugins/VST"),
3430 new RcActionButton (_("Clear"),
3431 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
3434 add_option (_("Plugins/VST"),
3435 new RcActionButton (_("Clear"),
3436 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
3437 _("VST Blacklist:")));
3440 #ifdef LXVST_SUPPORT
3441 add_option (_("Plugins/VST"),
3442 new RcActionButton (_("Edit"),
3443 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
3444 _("Linux VST Path:")));
3446 add_option (_("Plugins/VST"),
3447 new RcConfigDisplay (
3448 "plugin-path-lxvst",
3450 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
3454 #ifdef WINDOWS_VST_SUPPORT
3455 add_option (_("Plugins/VST"),
3456 new RcActionButton (_("Edit"),
3457 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
3458 _("Windows VST Path:")));
3459 add_option (_("Plugins/VST"),
3460 new RcConfigDisplay (
3463 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
3467 #ifdef AUDIOUNIT_SUPPORT
3469 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
3471 add_option (_("Plugins/Audio Unit"),
3472 new RcActionButton (_("Scan for Plugins"),
3473 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3476 bo = new BoolOption (
3477 "discover-audio-units",
3478 _("Scan for [new] AudioUnit Plugins on Application Start"),
3479 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
3480 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
3482 add_option (_("Plugins/Audio Unit"), bo);
3483 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3484 _("<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."));
3486 add_option (_("Plugins/Audio Unit"),
3487 new RcActionButton (_("Clear"),
3488 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
3491 add_option (_("Plugins/Audio Unit"),
3492 new RcActionButton (_("Clear"),
3493 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
3494 _("AU Blacklist:")));
3498 add_option (_("Plugins"), new OptionEditorHeading (_("LV1/LV2")));
3499 add_option (_("Plugins"),
3501 "conceal-lv1-if-lv2-exists",
3502 _("Conceal LADSPA (LV1) Plugins if matching LV2 exists"),
3503 sigc::mem_fun (*_rc_config, &RCConfiguration::get_conceal_lv1_if_lv2_exists),
3504 sigc::mem_fun (*_rc_config, &RCConfiguration::set_conceal_lv1_if_lv2_exists)
3508 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
3509 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
3510 add_option (_("Plugins"),
3512 "open-gui-after-adding-plugin",
3513 _("Automatically open the plugin GUI when adding a new plugin"),
3514 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
3515 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3518 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3519 add_option (_("Plugins"),
3521 "show-inline-display-by-default",
3522 _("Show Plugin Inline Display on Mixerstrip by default"),
3523 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3524 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3527 _plugin_prefer_inline = new BoolOption (
3528 "prefer-inline-over-gui",
3529 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3530 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3531 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3533 add_option (_("Plugins"), _plugin_prefer_inline);
3536 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3538 bo = new BoolOption (
3539 "ask-replace-instrument",
3540 _("Ask to replace existing instrument plugin"),
3541 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3542 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3544 add_option (_("Plugins"), bo);
3546 bo = new BoolOption (
3547 "ask-setup_instrument",
3548 _("Interactively configure instrument plugins on insert"),
3549 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3550 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3552 add_option (_("Plugins"), bo);
3553 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3554 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3557 add_option (_("Plugins"), new OptionEditorBlank ());
3560 #if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
3561 add_option (_("Appearance"), new OptionEditorHeading (_("Graphics Acceleration")));
3564 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3565 BoolOption* bgc = new BoolOption (
3566 "cairo-image-surface",
3567 _("Disable Graphics Hardware Acceleration (requires restart)"),
3568 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3569 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3572 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3573 _("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));
3574 add_option (_("Appearance"), bgc);
3577 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3578 BoolOption* bgo = new BoolOption (
3580 _("Possibly improve slow graphical performance (requires restart)"),
3581 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3582 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3585 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));
3586 add_option (_("Appearance"), bgo);
3588 add_option (_("Appearance"), new OptionEditorHeading (_("Graphical User Interface")));
3590 add_option (_("Appearance"),
3593 _("Highlight widgets on mouseover"),
3594 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3595 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3598 add_option (_("Appearance"),
3601 _("Show tooltips if mouse hovers over a control"),
3602 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3603 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3606 bo = new BoolOption (
3607 "super-rapid-clock-update",
3608 _("Update clocks at TC Frame rate"),
3609 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3610 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3612 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3613 _("<b>When enabled</b> clock displays are updated every Timecode Frame (fps).\n\n"
3614 "<b>When disabled</b> clock displays are updated only every 100ms."
3616 add_option (_("Appearance"), bo);
3618 add_option (_("Appearance"),
3621 _("Blink Rec-Arm buttons"),
3622 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_rec_arm),
3623 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_rec_arm)
3626 add_option (_("Appearance"),
3628 "blink-alert-indicators",
3629 _("Blink Alert Indicators"),
3630 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_alert_indicators),
3631 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_alert_indicators)
3636 /* font scaling does nothing with GDK/Quartz */
3637 add_option (_("Appearance"), new FontScalingOptions ());
3639 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("General")));
3640 add_option (_("Appearance/Editor"),
3642 "show-name-highlight",
3643 _("Use name highlight bars in region displays (requires a restart)"),
3644 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3645 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3648 add_option (_("Appearance/Editor"),
3650 "color-regions-using-track-color",
3651 _("Region color follows track color"),
3652 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_color_regions_using_track_color),
3653 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_color_regions_using_track_color)
3656 add_option (_("Appearance/Editor"),
3658 "show-region-names",
3659 _("Show Region Names"),
3660 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_name),
3661 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_name)
3664 #ifndef MIXBUS // hide this setting in Mixbus. Always on, 4px
3665 ComboOption<uint32_t>* gap = new ComboOption<uint32_t> (
3666 "vertical-region-gap",
3667 _("Add a visual gap below Audio Regions"),
3668 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_vertical_region_gap),
3669 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_vertical_region_gap)
3671 gap->add (0, _("None"));
3672 gap->add (2, _("Small"));
3673 gap->add (4, _("Large"));
3674 add_option (_("Appearance/Editor"), gap);
3677 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Waveforms")));
3679 if (!Profile->get_mixbus()) {
3680 add_option (_("Appearance/Editor"),
3683 _("Show waveforms in regions"),
3684 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
3685 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
3689 add_option (_("Appearance/Editor"),
3691 "show-waveforms-while-recording",
3692 _("Show waveforms while recording"),
3693 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
3694 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
3697 add_option (_("Appearance/Editor"),
3699 "show-waveform-clipping",
3700 _("Show waveform clipping"),
3701 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveform_clipping),
3702 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveform_clipping)
3705 add_option (_("Appearance/Editor"), new ClipLevelOptions ());
3707 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
3709 _("Waveform scale"),
3710 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
3711 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
3714 wfs->add (Linear, _("linear"));
3715 wfs->add (Logarithmic, _("logarithmic"));
3717 add_option (_("Appearance/Editor"), wfs);
3719 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
3721 _("Waveform shape"),
3722 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
3723 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
3726 wfsh->add (Traditional, _("traditional"));
3727 wfsh->add (Rectified, _("rectified"));
3729 add_option (_("Appearance/Editor"), wfsh);
3731 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Editor Meters")));
3733 add_option (_("Appearance/Editor"),
3735 "show-track-meters",
3736 _("Show meters in track headers"),
3737 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3738 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3741 add_option (_("Appearance/Editor"),
3743 "editor-stereo-only-meters",
3744 _("Limit track header meters to stereo"),
3745 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3746 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3749 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("MIDI Regions")));
3751 add_option (_("Appearance/Editor"),
3753 "display-first-midi-bank-as-zero",
3754 _("Display first MIDI bank/program as 0"),
3755 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
3756 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
3759 add_option (_("Appearance/Editor"),
3761 "never-display-periodic-midi",
3762 _("Don't display periodic (MTC, MMC) SysEx messages in MIDI Regions"),
3763 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
3764 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
3768 add_option (_("Appearance/Editor"),
3770 "use-note-bars-for-velocity",
3771 _("Show velocity horizontally inside notes"),
3772 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_note_bars_for_velocity),
3773 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_note_bars_for_velocity)
3776 add_option (_("Appearance/Editor"),
3778 "use-note-color-for-velocity",
3779 _("Use colors to show note velocity"),
3780 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_note_color_for_velocity),
3781 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_note_color_for_velocity)
3784 add_option (_("Appearance/Editor"), new OptionEditorBlank ());
3786 /* The names of these controls must be the same as those given in MixerStrip
3787 for the actual widgets being controlled.
3789 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3790 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3791 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3792 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3793 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3794 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3795 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3797 add_option (_("Appearance/Mixer"),
3798 new VisibilityOption (
3800 &_mixer_strip_visibility,
3801 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3802 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3806 add_option (_("Appearance/Mixer"),
3808 "default-narrow_ms",
3809 _("Use narrow strips in the mixer for new strips by default"),
3810 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3811 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3814 ComboOption<uint32_t>* mic = new ComboOption<uint32_t> (
3815 "max-inline-controls",
3816 _("Limit inline-mixer-strip controls per plugin"),
3817 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_max_inline_controls),
3818 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_max_inline_controls)
3820 mic->add (0, _("Unlimited"));
3821 mic->add (16, _("16 parameters"));
3822 mic->add (32, _("32 parameters"));
3823 mic->add (64, _("64 parameters"));
3824 mic->add (128, _("128 parameters"));
3825 add_option (_("Appearance/Mixer"), mic);
3827 add_option (_("Appearance/Mixer"), new OptionEditorBlank ());
3829 add_option (_("Appearance/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items")));
3831 add_option (_("Appearance/Toolbar"),
3833 "show-toolbar-recpunch",
3834 _("Display Record/Punch Options"),
3835 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_recpunch),
3836 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_recpunch)
3839 add_option (_("Appearance/Toolbar"),
3841 "show-toolbar-monitoring",
3842 _("Display Monitor Options"),
3843 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_monitoring),
3844 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_monitoring)
3847 add_option (_("Appearance/Toolbar"),
3849 "show-toolbar-selclock",
3850 _("Display Selection Clock"),
3851 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
3852 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
3855 if (!ARDOUR::Profile->get_small_screen()) {
3856 add_option (_("Appearance/Toolbar"),
3858 "show-secondary-clock",
3859 _("Display Secondary Clock"),
3860 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
3861 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
3865 add_option (_("Appearance/Toolbar"),
3867 "show-mini-timeline",
3868 _("Display Navigation Timeline"),
3869 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
3870 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
3873 add_option (_("Appearance/Toolbar"),
3875 "show-editor-meter",
3876 _("Display Master Level Meter"),
3877 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
3878 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
3881 add_option (_("Appearance/Toolbar"),
3882 new ColumVisibilityOption (
3883 "action-table-columns", _("Display Action-Buttons"), 4,
3884 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3885 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3888 add_option (_("Appearance/Toolbar"), new OptionEditorBlank ());
3891 /* and now the theme manager */
3893 add_option (_("Appearance/Theme"), new OptionEditorHeading (_("Theme")));
3895 add_option (_("Appearance/Theme"), new BoolOption (
3897 _("Draw \"flat\" buttons"),
3898 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_flat_buttons),
3899 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_flat_buttons)
3902 add_option (_("Appearance/Theme"), new BoolOption (
3904 _("Draw \"boxy\" buttons"),
3905 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_boxy_buttons),
3906 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_boxy_buttons)
3909 add_option (_("Appearance/Theme"), new BoolOption (
3911 _("LED meter style"),
3912 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3913 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3917 HSliderOption *gui_hs = new HSliderOption(
3918 "timeline-item-gradient-depth",
3919 _("Waveforms color gradient depth"),
3920 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_gradient_depth),
3921 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_gradient_depth),
3924 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3925 add_option (_("Appearance/Theme"), gui_hs);
3927 gui_hs = new HSliderOption(
3928 "timeline-item-gradient-depth",
3929 _("Timeline item gradient depth"),
3930 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_timeline_item_gradient_depth),
3931 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_timeline_item_gradient_depth),
3934 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3935 add_option (_("Appearance/Theme"), gui_hs);
3937 vector<string> icon_sets = ::get_icon_sets ();
3938 if (icon_sets.size() > 1) {
3939 ComboOption<std::string>* io = new ComboOption<std::string> (
3940 "icon-set", _("Icon Set"),
3941 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_icon_set),
3942 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_icon_set)
3944 for (vector<string>::const_iterator i = icon_sets.begin (); i != icon_sets.end (); ++i) {
3947 add_option (_("Appearance/Theme"), io);
3950 add_option (_("Appearance/Colors"), new OptionEditorHeading (_("Colors")));
3951 add_option (_("Appearance/Colors"), new ColorThemeManager);
3952 add_option (_("Appearance/Colors"), new OptionEditorBlank ());
3956 OptionEditorHeading* quirks_head = new OptionEditorHeading (_("Various Workarounds for Windowing Systems"));
3958 quirks_head->set_note (string_compose (_("Rules for closing, minimizing, maximizing, and stay-on-top can vary \
3959 with each version of your OS, and the preferences that you've set in your OS.\n\n\
3960 You can adjust the options, below, to change how %1's windows and dialogs behave.\n\n\
3961 These settings will only take effect after %1 is restarted.\n\
3964 add_option (_("Appearance/Quirks"), quirks_head);
3966 bo = new BoolOption (
3967 "use-wm-visibility",
3968 _("Use visibility information provided by your Window Manager/Desktop"),
3969 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3970 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3972 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3973 _("If you have trouble toggling between hidden Editor and Mixer windows, try changing this setting."));
3974 add_option (_("Appearance/Quirks"), bo);
3977 bo = new BoolOption (
3978 "all-floating-windows-are-dialogs",
3979 _("All floating windows are dialogs"),
3980 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_all_floating_windows_are_dialogs),
3981 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_all_floating_windows_are_dialogs)
3983 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3984 _("Mark all floating windows to be type \"Dialog\" rather than using \"Utility\" for some.\nThis may help with some window managers."));
3985 add_option (_("Appearance/Quirks"), bo);
3987 bo = new BoolOption (
3988 "transients-follow-front",
3989 _("Transient windows follow front window."),
3990 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_transients_follow_front),
3991 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_transients_follow_front)
3993 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3994 _("Make transient windows follow the front window when toggling between the editor and mixer."));
3995 add_option (_("Appearance/Quirks"), bo);
3998 if (!Profile->get_mixbus()) {
3999 bo = new BoolOption (
4000 "floating-monitor-section",
4001 _("Float detached monitor-section window"),
4002 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_floating_monitor_section),
4003 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_floating_monitor_section)
4005 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
4006 _("When detaching the monitoring section, mark it as \"Utility\" window to stay in front."));
4007 add_option (_("Appearance/Quirks"), bo);
4010 add_option (_("Appearance/Quirks"), new OptionEditorBlank ());
4012 /* VIDEO Timeline */
4013 add_option (_("Video"), new OptionEditorHeading (_("Video Server")));
4014 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
4016 Widget::show_all ();
4018 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
4019 parameter_changed ("send-ltc");
4020 parameter_changed ("sync-source");
4021 parameter_changed ("open-gui-after-adding-plugin");
4023 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
4025 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
4026 (Gtk::StateType) here !!!
4028 Tabbable::set_state (*node, Stateful::loading_state_version);
4031 set_current_page (_("General"));
4035 RCOptionEditor::set_session (Session *s)
4037 SessionHandlePtr::set_session (s);
4038 _transport_masters_widget.set_session (s);
4042 RCOptionEditor::parameter_changed (string const & p)
4044 OptionEditor::parameter_changed (p);
4046 if (p == "use-monitor-bus") {
4047 bool const s = Config->get_use_monitor_bus ();
4049 /* we can't use this if we don't have a monitor bus */
4050 Config->set_solo_control_is_listen_control (false); // XXX
4052 _solo_control_is_listen_control->set_sensitive (s);
4053 _listen_position->set_sensitive (s);
4054 } else if (p == "sync-source") {
4055 boost::shared_ptr<TransportMaster> tm (TransportMasterManager::instance().current());
4056 if (boost::dynamic_pointer_cast<TimecodeTransportMaster> (tm)) {
4057 _sync_framerate->set_sensitive (true);
4059 _sync_framerate->set_sensitive (false);
4061 } else if (p == "send-ltc") {
4062 bool const s = Config->get_send_ltc ();
4063 _ltc_send_continuously->set_sensitive (s);
4064 _ltc_volume_slider->set_sensitive (s);
4065 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
4066 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
4067 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
4069 } else if (p == "conceal-lv1-if-lv2-exists") {
4070 PluginManager::instance().refresh (true);
4074 void RCOptionEditor::plugin_scan_refresh () {
4075 PluginManager::instance().refresh();
4078 void RCOptionEditor::clear_vst_cache () {
4079 PluginManager::instance().clear_vst_cache();
4082 void RCOptionEditor::clear_vst_blacklist () {
4083 PluginManager::instance().clear_vst_blacklist();
4086 void RCOptionEditor::clear_au_cache () {
4087 PluginManager::instance().clear_au_cache();
4090 void RCOptionEditor::clear_au_blacklist () {
4091 PluginManager::instance().clear_au_blacklist();
4094 void RCOptionEditor::edit_lxvst_path () {
4095 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
4096 PathsDialog *pd = new PathsDialog (
4097 *current_toplevel(), _("Set Linux VST Search Path"),
4098 _rc_config->get_plugin_path_lxvst(),
4099 PluginManager::instance().get_default_lxvst_path()
4101 ResponseType r = (ResponseType) pd->run ();
4103 if (r == RESPONSE_ACCEPT) {
4104 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
4106 MessageDialog msg (_("Re-scan Plugins now?"),
4107 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
4108 msg.set_default_response (Gtk::RESPONSE_YES);
4109 if (msg.run() == Gtk::RESPONSE_YES) {
4111 plugin_scan_refresh ();
4117 void RCOptionEditor::edit_vst_path () {
4118 PathsDialog *pd = new PathsDialog (
4119 *current_toplevel(), _("Set Windows VST Search Path"),
4120 _rc_config->get_plugin_path_vst(),
4121 PluginManager::instance().get_default_windows_vst_path()
4123 ResponseType r = (ResponseType) pd->run ();
4125 if (r == RESPONSE_ACCEPT) {
4126 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
4127 MessageDialog msg (_("Re-scan Plugins now?"),
4128 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
4129 msg.set_default_response (Gtk::RESPONSE_YES);
4130 if (msg.run() == Gtk::RESPONSE_YES) {
4132 plugin_scan_refresh ();
4139 RCOptionEditor::use_own_window (bool and_fill_it)
4141 bool new_window = !own_window ();
4143 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
4145 if (win && new_window) {
4146 win->set_name ("PreferencesWindow");
4147 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
4149 win->set_resizable (false);
4156 RCOptionEditor::get_state ()
4158 XMLNode* node = new XMLNode (X_("Preferences"));
4159 node->add_child_nocopy (Tabbable::get_state());