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 OptionEditorComponent
1161 : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1162 , _clip_level_slider (_clip_level_adjustment)
1163 , _label (_("Waveform Clip Level (dBFS):"))
1165 _label.set_name ("OptionsLabel");
1167 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ());
1169 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1171 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1174 void parameter_changed (string const & p)
1176 if (p == "waveform-clip-level") {
1177 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level());
1179 if (p == "show-waveform-clipping") {
1180 _clip_level_slider.set_sensitive (UIConfiguration::instance().get_show_waveform_clipping ());
1184 void set_state_from_config ()
1186 parameter_changed ("waveform-clip-level");
1187 parameter_changed ("show-waveform-clipping");
1190 void add_to_page (OptionEditorPage* p) {
1191 add_widgets_to_page (p, &_label, &_clip_level_slider);
1194 Gtk::Widget& tip_widget() {
1195 return _clip_level_slider;
1200 void clip_level_changed ()
1202 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1203 /* XXX: should be triggered from the parameter changed signal */
1204 ArdourWaveView::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1207 Adjustment _clip_level_adjustment;
1208 HScale _clip_level_slider;
1212 class BufferingOptions : public OptionEditorComponent
1215 BufferingOptions (RCConfiguration* c)
1217 , _label (_("Preset:"))
1218 , _playback ("playback-buffer-seconds", _("Playback (seconds of buffering)"),
1219 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_playback_buffer_seconds),
1220 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_playback_buffer_seconds),
1222 , _capture ("capture-buffer-seconds", _("Recording (seconds of buffering)"),
1223 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_capture_buffer_seconds),
1224 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_capture_buffer_seconds),
1227 // TODO use ComboOption
1228 vector<string> presets;
1230 /* these must match the order of the enums for BufferingPreset */
1231 presets.push_back (_("Small sessions (4-16 tracks)"));
1232 presets.push_back (_("Medium sessions (16-64 tracks)"));
1233 presets.push_back (_("Large sessions (64+ tracks)"));
1234 presets.push_back (_("Custom (set by sliders below)"));
1236 set_popdown_strings (_buffering_presets_combo, presets);
1237 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1239 _label.set_name ("OptionsLabel");
1240 _label.set_alignment (0, 0.5);
1244 add_to_page (OptionEditorPage* p)
1246 add_widgets_to_page (p, &_label, &_buffering_presets_combo);
1247 _playback.add_to_page (p);
1248 _capture.add_to_page (p);
1251 void parameter_changed (string const & p)
1253 if (p == "buffering-preset") {
1254 switch (_rc_config->get_buffering_preset()) {
1256 _playback.set_sensitive (false);
1257 _capture.set_sensitive (false);
1258 _buffering_presets_combo.set_active (0);
1261 _playback.set_sensitive (false);
1262 _capture.set_sensitive (false);
1263 _buffering_presets_combo.set_active (1);
1266 _playback.set_sensitive (false);
1267 _capture.set_sensitive (false);
1268 _buffering_presets_combo.set_active (2);
1271 _playback.set_sensitive (true);
1272 _capture.set_sensitive (true);
1273 _buffering_presets_combo.set_active (3);
1277 _playback.parameter_changed (p);
1278 _capture.parameter_changed (p);
1281 void set_state_from_config ()
1283 parameter_changed ("buffering-preset");
1284 _playback.set_state_from_config();
1285 _capture.set_state_from_config();
1288 Gtk::Widget& tip_widget() { return _buffering_presets_combo; }
1292 void preset_changed ()
1294 int index = _buffering_presets_combo.get_active_row_number ();
1300 _rc_config->set_buffering_preset (Small);
1303 _rc_config->set_buffering_preset (Medium);
1306 _rc_config->set_buffering_preset (Large);
1309 _rc_config->set_buffering_preset (Custom);
1312 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1317 RCConfiguration* _rc_config;
1319 HSliderOption _playback;
1320 HSliderOption _capture;
1321 ComboBoxText _buffering_presets_combo;
1324 class ControlSurfacesOptions : public OptionEditorMiniPage
1327 ControlSurfacesOptions ()
1328 : _ignore_view_change (0)
1330 _store = ListStore::create (_model);
1331 _view.set_model (_store);
1332 _view.append_column (_("Control Surface Protocol"), _model.name);
1333 _view.get_column(0)->set_resizable (true);
1334 _view.get_column(0)->set_expand (true);
1335 _view.append_column_editable (_("Enable"), _model.enabled);
1337 Gtk::HBox* edit_box = manage (new Gtk::HBox);
1338 edit_box->set_spacing(3);
1341 Label* label = manage (new Label);
1342 label->set_text (_("Edit the settings for selected protocol (it must be ENABLED first):"));
1343 edit_box->pack_start (*label, false, false);
1346 edit_button = manage (new Button(_("Show Protocol Settings")));
1347 edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
1348 edit_box->pack_start (*edit_button, true, true);
1349 edit_button->set_sensitive (false);
1350 edit_button->show ();
1352 int const n = table.property_n_rows();
1353 table.resize (n + 2, 3);
1354 table.attach (_view, 0, 3, n, n + 1);
1355 table.attach (*edit_box, 0, 3, n + 1, n + 2);
1357 ControlProtocolManager& m = ControlProtocolManager::instance ();
1358 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1359 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1361 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1362 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1363 _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
1366 void parameter_changed (std::string const &)
1371 void set_state_from_config ()
1375 ControlProtocolManager& m = ControlProtocolManager::instance ();
1376 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1378 if (!(*i)->mandatory) {
1379 TreeModel::Row r = *_store->append ();
1380 r[_model.name] = (*i)->name;
1381 r[_model.enabled] = 0 != (*i)->protocol;
1382 r[_model.protocol_info] = *i;
1389 void protocol_status_changed (ControlProtocolInfo* cpi) {
1391 TreeModel::Children rows = _store->children();
1393 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1394 string n = ((*x)[_model.name]);
1396 if ((*x)[_model.protocol_info] == cpi) {
1397 _ignore_view_change++;
1398 (*x)[_model.enabled] = 0 != cpi->protocol;
1399 _ignore_view_change--;
1400 selection_changed (); // update sensitivity
1406 void selection_changed ()
1408 //enable the Edit button when a row is selected for editing
1409 TreeModel::Row row = *(_view.get_selection()->get_selected());
1410 if (row && row[_model.enabled]) {
1411 ControlProtocolInfo* cpi = row[_model.protocol_info];
1412 edit_button->set_sensitive (cpi && cpi->protocol && cpi->protocol->has_editor ());
1414 edit_button->set_sensitive (false);
1418 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1420 TreeModel::Row r = *i;
1422 if (_ignore_view_change) {
1426 ControlProtocolInfo* cpi = r[_model.protocol_info];
1431 bool const was_enabled = (cpi->protocol != 0);
1432 bool const is_enabled = r[_model.enabled];
1435 if (was_enabled != is_enabled) {
1438 ControlProtocolManager::instance().activate (*cpi);
1440 ControlProtocolManager::instance().deactivate (*cpi);
1444 selection_changed ();
1447 void edit_btn_clicked ()
1450 ControlProtocolInfo* cpi;
1453 row = *(_view.get_selection()->get_selected());
1454 if (!row[_model.enabled]) {
1457 cpi = row[_model.protocol_info];
1458 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1461 Box* box = (Box*) cpi->protocol->get_gui ();
1465 if (box->get_parent()) {
1466 static_cast<ArdourWindow*>(box->get_parent())->present();
1469 WindowTitle title (Glib::get_application_name());
1470 title += row[_model.name];
1471 title += _("Configuration");
1472 /* once created, the window is managed by the surface itself (as ->get_parent())
1473 * Surface's tear_down_gui() is called on session close, when de-activating
1474 * or re-initializing a surface.
1475 * tear_down_gui() hides an deletes the Window if it exists.
1477 ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
1478 win->set_title (_("Control Protocol Settings"));
1484 void edit_clicked (GdkEventButton* ev)
1486 if (ev->type != GDK_2BUTTON_PRESS) {
1493 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1497 ControlSurfacesModelColumns ()
1501 add (protocol_info);
1504 TreeModelColumn<string> name;
1505 TreeModelColumn<bool> enabled;
1506 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1509 Glib::RefPtr<ListStore> _store;
1510 ControlSurfacesModelColumns _model;
1512 PBD::ScopedConnection protocol_status_connection;
1513 uint32_t _ignore_view_change;
1514 Gtk::Button* edit_button;
1517 class VideoTimelineOptions : public OptionEditorMiniPage
1520 VideoTimelineOptions (RCConfiguration* c)
1522 , _show_video_export_info_button (_("Show Video Export Info before export"))
1523 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1524 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1525 , _xjadeo_browse_button (_("Browse..."))
1528 int n = table.property_n_rows();
1530 t->attach (_show_video_export_info_button, 1, 4, n, n + 1);
1531 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1532 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1533 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1536 t->attach (_show_video_server_dialog_button, 1, 4, n, n + 1);
1537 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1538 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1539 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1542 t->attach (_video_advanced_setup_button, 1, 4, n, n + 1, FILL);
1543 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1544 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1545 _("<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."));
1548 Label* l = manage (new Label (_("Video Server URL:")));
1549 l->set_alignment (0, 0.5);
1550 t->attach (*l, 1, 2, n, n + 1, FILL);
1551 t->attach (_video_server_url_entry, 2, 4, n, n + 1, FILL);
1552 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1553 _("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"));
1556 l = manage (new Label (_("Video Folder:")));
1557 l->set_alignment (0, 0.5);
1558 t->attach (*l, 1, 2, n, n + 1, FILL);
1559 t->attach (_video_server_docroot_entry, 2, 4, n, n + 1);
1560 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1561 _("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."));
1564 l = manage (new Label (""));
1565 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1568 l = manage (new Label (string_compose ("<b>%1</b>", _("Video Monitor"))));
1569 l->set_use_markup (true);
1570 l->set_alignment (0, 0.5);
1571 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1574 l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"),
1577 #elif defined PLATFORM_WINDOWS
1583 l->set_alignment (0, 0.5);
1584 t->attach (*l, 1, 4, n, n + 1, FILL);
1587 t->attach (_custom_xjadeo_path, 2, 3, n, n + 1, EXPAND|FILL);
1588 Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart."));
1589 t->attach (_xjadeo_browse_button, 3, 4, n, n + 1, FILL);
1591 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1592 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1593 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1594 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1595 _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed));
1596 _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked));
1599 void server_url_changed ()
1601 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1604 void server_docroot_changed ()
1606 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1609 void show_video_export_info_toggled ()
1611 bool const x = _show_video_export_info_button.get_active ();
1612 _rc_config->set_show_video_export_info (x);
1615 void show_video_server_dialog_toggled ()
1617 bool const x = _show_video_server_dialog_button.get_active ();
1618 _rc_config->set_show_video_server_dialog (x);
1621 void video_advanced_setup_toggled ()
1623 bool const x = _video_advanced_setup_button.get_active ();
1624 _rc_config->set_video_advanced_setup(x);
1627 void custom_xjadeo_path_changed ()
1629 _rc_config->set_xjadeo_binary (_custom_xjadeo_path.get_text());
1632 void xjadeo_browse_clicked ()
1634 Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN);
1635 dialog.set_filename (_rc_config->get_xjadeo_binary());
1636 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1637 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1638 if (dialog.run () == Gtk::RESPONSE_OK) {
1639 const std::string& filename = dialog.get_filename();
1640 if (!filename.empty() && (
1642 Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) ||
1644 Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)
1646 _rc_config->set_xjadeo_binary (filename);
1651 void parameter_changed (string const & p)
1653 if (p == "video-server-url") {
1654 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1655 } else if (p == "video-server-docroot") {
1656 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1657 } else if (p == "show-video-export-info") {
1658 bool const x = _rc_config->get_show_video_export_info();
1659 _show_video_export_info_button.set_active (x);
1660 } else if (p == "show-video-server-dialog") {
1661 bool const x = _rc_config->get_show_video_server_dialog();
1662 _show_video_server_dialog_button.set_active (x);
1663 } else if (p == "video-advanced-setup") {
1664 bool const x = _rc_config->get_video_advanced_setup();
1665 _video_advanced_setup_button.set_active(x);
1666 _video_server_docroot_entry.set_sensitive(x);
1667 _video_server_url_entry.set_sensitive(x);
1668 } else if (p == "xjadeo-binary") {
1669 _custom_xjadeo_path.set_text (_rc_config->get_xjadeo_binary());
1673 void set_state_from_config ()
1675 parameter_changed ("video-server-url");
1676 parameter_changed ("video-server-docroot");
1677 parameter_changed ("video-monitor-setup-dialog");
1678 parameter_changed ("show-video-export-info");
1679 parameter_changed ("show-video-server-dialog");
1680 parameter_changed ("video-advanced-setup");
1681 parameter_changed ("xjadeo-binary");
1685 RCConfiguration* _rc_config;
1686 Entry _video_server_url_entry;
1687 Entry _video_server_docroot_entry;
1688 Entry _custom_xjadeo_path;
1689 CheckButton _show_video_export_info_button;
1690 CheckButton _show_video_server_dialog_button;
1691 CheckButton _video_advanced_setup_button;
1692 Button _xjadeo_browse_button;
1695 class ColumVisibilityOption : public Option
1698 ColumVisibilityOption (string id, string name, uint32_t n_col, sigc::slot<uint32_t> get, sigc::slot<bool, uint32_t> set)
1705 cb = (CheckButton**) malloc (sizeof (CheckButton*) * n_col);
1706 for (uint32_t i = 0; i < n_col; ++i) {
1707 CheckButton* col = manage (new CheckButton (string_compose (_("Column %1"), i + 1)));
1708 col->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ColumVisibilityOption::column_toggled), i));
1709 _hbox.pack_start (*col);
1712 parameter_changed (id);
1715 ~ColumVisibilityOption () {
1719 Gtk::Widget& tip_widget() { return _hbox; }
1721 void set_state_from_config ()
1723 uint32_t c = _get();
1724 for (uint32_t i = 0; i < _n_col; ++i) {
1725 bool en = (c & (1<<i)) ? true : false;
1726 if (cb[i]->get_active () != en) {
1727 cb[i]->set_active (en);
1732 void add_to_page (OptionEditorPage* p)
1734 _heading.add_to_page (p);
1735 add_widget_to_page (p, &_hbox);
1739 void column_toggled (int b) {
1740 uint32_t c = _get();
1742 if (cb[b]->get_active ()) {
1753 OptionEditorHeading _heading;
1757 sigc::slot<uint32_t> _get;
1758 sigc::slot<bool, uint32_t> _set;
1762 /** A class which allows control of visibility of some editor components usign
1763 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1764 * which has the correct members, but with null widget pointers. This
1765 * class allows the user to set visibility of the members, the details
1766 * of which are stored in a configuration variable which can be watched
1767 * by parts of the editor that actually contain the widgets whose visibility
1768 * is being controlled.
1771 class VisibilityOption : public Option
1774 /** @param name User-visible name for this group.
1775 * @param g `Dummy' VisibilityGroup (as described above).
1776 * @param get Method to get the value of the appropriate configuration variable.
1777 * @param set Method to set the value of the appropriate configuration variable.
1779 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1780 : Option (g->get_state_name(), name)
1782 , _visibility_group (g)
1786 /* Watch for changes made by the user to our members */
1787 _visibility_group->VisibilityChanged.connect_same_thread (
1788 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1792 void set_state_from_config ()
1794 /* Set our state from the current configuration */
1795 _visibility_group->set_state (_get ());
1798 void add_to_page (OptionEditorPage* p)
1800 _heading.add_to_page (p);
1801 add_widget_to_page (p, _visibility_group->list_view ());
1804 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1809 /* The user has changed something, so reflect this change
1810 in the RCConfiguration.
1812 _set (_visibility_group->get_state_value ());
1815 OptionEditorHeading _heading;
1816 VisibilityGroup* _visibility_group;
1817 sigc::slot<std::string> _get;
1818 sigc::slot<bool, std::string> _set;
1819 PBD::ScopedConnection _visibility_group_connection;
1823 class MidiPortOptions : public OptionEditorMiniPage, public sigc::trackable
1828 setup_midi_port_view (midi_output_view, false);
1829 setup_midi_port_view (midi_input_view, true);
1831 OptionEditorHeading* h = new OptionEditorHeading (_("MIDI Inputs"));
1832 h->add_to_page (this);
1834 Gtk::ScrolledWindow* scroller = manage (new Gtk::ScrolledWindow);
1835 scroller->add (midi_input_view);
1836 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1837 scroller->set_size_request (-1, 180);
1839 int n = table.property_n_rows();
1840 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1842 h = new OptionEditorHeading (_("MIDI Outputs"));
1843 h->add_to_page (this);
1845 scroller = manage (new Gtk::ScrolledWindow);
1846 scroller->add (midi_output_view);
1847 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1848 scroller->set_size_request (-1, 180);
1850 n = table.property_n_rows();
1851 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1853 midi_output_view.show ();
1854 midi_input_view.show ();
1856 table.signal_show().connect (sigc::mem_fun (*this, &MidiPortOptions::on_show));
1859 void parameter_changed (string const&) {}
1860 void set_state_from_config() {}
1865 AudioEngine::instance()->PortRegisteredOrUnregistered.connect (connections,
1866 invalidator (*this),
1867 boost::bind (&MidiPortOptions::refill, this),
1869 AudioEngine::instance()->MidiPortInfoChanged.connect (connections,
1870 invalidator (*this),
1871 boost::bind (&MidiPortOptions::refill, this),
1873 AudioEngine::instance()->MidiSelectionPortsChanged.connect (connections,
1874 invalidator (*this),
1875 boost::bind (&MidiPortOptions::refill, this),
1881 if (refill_midi_ports (true, midi_input_view)) {
1882 input_label.show ();
1884 input_label.hide ();
1886 if (refill_midi_ports (false, midi_output_view)) {
1887 output_label.show ();
1889 output_label.hide ();
1894 PBD::ScopedConnectionList connections;
1896 /* MIDI port management */
1897 struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord {
1899 MidiPortColumns () {
1908 Gtk::TreeModelColumn<std::string> pretty_name;
1909 Gtk::TreeModelColumn<bool> music_data;
1910 Gtk::TreeModelColumn<bool> control_data;
1911 Gtk::TreeModelColumn<bool> selection;
1912 Gtk::TreeModelColumn<std::string> name;
1913 Gtk::TreeModelColumn<std::string> filler;
1916 MidiPortColumns midi_port_columns;
1917 Gtk::TreeView midi_input_view;
1918 Gtk::TreeView midi_output_view;
1919 Gtk::Label input_label;
1920 Gtk::Label output_label;
1922 void setup_midi_port_view (Gtk::TreeView&, bool with_selection);
1923 bool refill_midi_ports (bool for_input, Gtk::TreeView&);
1924 void pretty_name_edit (std::string const & path, std::string const & new_text, Gtk::TreeView*);
1925 void midi_music_column_toggled (std::string const & path, Gtk::TreeView*);
1926 void midi_control_column_toggled (std::string const & path, Gtk::TreeView*);
1927 void midi_selection_column_toggled (std::string const & path, Gtk::TreeView*);
1931 MidiPortOptions::setup_midi_port_view (Gtk::TreeView& view, bool with_selection)
1933 int pretty_name_column;
1936 int selection_column;
1937 TreeViewColumn* col;
1940 pretty_name_column = view.append_column_editable (_("Name (click to edit)"), midi_port_columns.pretty_name) - 1;
1942 col = manage (new TreeViewColumn ("", midi_port_columns.music_data));
1943 col->set_alignment (ALIGN_CENTER);
1944 l = manage (new Label (_("Music Data")));
1945 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of music performance data."), PROGRAM_NAME));
1946 col->set_widget (*l);
1948 music_column = view.append_column (*col) - 1;
1950 col = manage (new TreeViewColumn ("", midi_port_columns.control_data));
1951 col->set_alignment (ALIGN_CENTER);
1952 l = manage (new Label (_("Control Data")));
1953 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of control data."), PROGRAM_NAME));
1954 col->set_widget (*l);
1956 control_column = view.append_column (*col) - 1;
1958 if (with_selection) {
1959 col = manage (new TreeViewColumn (_("Follow Selection"), midi_port_columns.selection));
1960 selection_column = view.append_column (*col) - 1;
1961 l = manage (new Label (_("Follow Selection")));
1962 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));
1963 col->set_widget (*l);
1967 /* filler column so that the last real column doesn't expand */
1968 view.append_column ("", midi_port_columns.filler);
1970 CellRendererText* pretty_name_cell = dynamic_cast<CellRendererText*> (view.get_column_cell_renderer (pretty_name_column));
1971 pretty_name_cell->property_editable() = true;
1972 pretty_name_cell->signal_edited().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::pretty_name_edit), &view));
1974 CellRendererToggle* toggle_cell;
1976 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (music_column));
1977 toggle_cell->property_activatable() = true;
1978 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_music_column_toggled), &view));
1980 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (control_column));
1981 toggle_cell->property_activatable() = true;
1982 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_control_column_toggled), &view));
1984 if (with_selection) {
1985 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (selection_column));
1986 toggle_cell->property_activatable() = true;
1987 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_selection_column_toggled), &view));
1990 view.get_selection()->set_mode (SELECTION_NONE);
1991 view.set_tooltip_column (4); /* port "real" name */
1992 view.get_column(0)->set_resizable (true);
1993 view.get_column(0)->set_expand (true);
1997 MidiPortOptions::refill_midi_ports (bool for_input, Gtk::TreeView& view)
1999 using namespace ARDOUR;
2001 std::vector<string> ports;
2003 AudioEngine::instance()->get_known_midi_ports (ports);
2005 if (ports.empty()) {
2010 Glib::RefPtr<ListStore> model = Gtk::ListStore::create (midi_port_columns);
2012 for (vector<string>::const_iterator s = ports.begin(); s != ports.end(); ++s) {
2014 if (AudioEngine::instance()->port_is_mine (*s)) {
2018 PortManager::MidiPortInformation mpi (AudioEngine::instance()->midi_port_information (*s));
2020 if (mpi.pretty_name.empty()) {
2021 /* vanished since get_known_midi_ports() */
2025 if (for_input != mpi.input) {
2029 TreeModel::Row row = *(model->append());
2031 row[midi_port_columns.pretty_name] = mpi.pretty_name;
2032 row[midi_port_columns.music_data] = mpi.properties & MidiPortMusic;
2033 row[midi_port_columns.control_data] = mpi.properties & MidiPortControl;
2034 row[midi_port_columns.selection] = mpi.properties & MidiPortSelection;
2035 row[midi_port_columns.name] = *s;
2038 view.set_model (model);
2044 MidiPortOptions::midi_music_column_toggled (string const & path, TreeView* view)
2046 TreeIter iter = view->get_model()->get_iter (path);
2052 bool new_value = ! bool ((*iter)[midi_port_columns.music_data]);
2054 /* don't reset model - wait for MidiPortInfoChanged signal */
2057 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2059 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2064 MidiPortOptions::midi_control_column_toggled (string const & path, TreeView* view)
2066 TreeIter iter = view->get_model()->get_iter (path);
2072 bool new_value = ! bool ((*iter)[midi_port_columns.control_data]);
2074 /* don't reset model - wait for MidiPortInfoChanged signal */
2077 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2079 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2084 MidiPortOptions::midi_selection_column_toggled (string const & path, TreeView* view)
2086 TreeIter iter = view->get_model()->get_iter (path);
2092 bool new_value = ! bool ((*iter)[midi_port_columns.selection]);
2094 /* don't reset model - wait for MidiSelectionPortsChanged signal */
2097 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2099 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2104 MidiPortOptions::pretty_name_edit (std::string const & path, string const & new_text, Gtk::TreeView* view)
2106 TreeIter iter = view->get_model()->get_iter (path);
2112 AudioEngine::instance()->set_midi_port_pretty_name ((*iter)[midi_port_columns.name], new_text);
2118 RCOptionEditor::RCOptionEditor ()
2119 : OptionEditorContainer (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
2120 , Tabbable (*this, _("Preferences")
2122 , false // detached by default (first start, no instant.xml)
2124 ) /* pack self-as-vbox into tabbable */
2125 , _rc_config (Config)
2126 , _mixer_strip_visibility ("mixer-element-visibility")
2128 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
2132 uint32_t hwcpus = hardware_concurrency ();
2136 add_option (_("General"), new OptionEditorHeading (_("DSP CPU Utilization")));
2138 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
2140 _("Signal processing uses"),
2141 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
2142 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
2145 procs->add (-1, _("all but one processor"));
2146 procs->add (0, _("all available processors"));
2148 for (uint32_t i = 1; i <= hwcpus; ++i) {
2149 procs->add (i, string_compose (P_("%1 processor", "%1 processors", i), i));
2152 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
2154 add_option (_("General"), procs);
2157 /* Image cache size */
2158 add_option (_("General"), new OptionEditorHeading (_("Memory Usage")));
2160 HSliderOption *sics = new HSliderOption ("waveform-cache-size",
2161 _("Waveform image cache size (megabytes)"),
2162 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
2163 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size),
2164 1, 1024, 10 /* 1 MB to 1GB in steps of 10MB */
2166 sics->scale().set_digits (0);
2167 Gtkmm2ext::UI::instance()->set_tip (
2169 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
2170 add_option (_("General"), sics);
2172 add_option (_("General"), new OptionEditorHeading (_("Engine")));
2174 add_option (_("General"),
2176 "try-autostart-engine",
2177 _("Try to auto-launch audio/midi engine"),
2178 sigc::mem_fun (*_rc_config, &RCConfiguration::get_try_autostart_engine),
2179 sigc::mem_fun (*_rc_config, &RCConfiguration::set_try_autostart_engine)
2182 add_option (_("General"), new OptionEditorHeading (_("Automation")));
2184 add_option (_("General"),
2185 new SpinOption<double> (
2186 "automation-thinning-factor",
2187 _("Thinning factor (larger value => less data)"),
2188 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
2189 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
2193 add_option (_("General"),
2194 new SpinOption<double> (
2195 "automation-interval-msecs",
2196 _("Automation sampling interval (milliseconds)"),
2197 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
2198 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
2202 add_option (_("General"), new OptionEditorHeading (_("Tempo")));
2204 bo = new BoolOption (
2205 "allow-non-quarter-pulse",
2206 _("Allow non quarter-note pulse"),
2207 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_allow_non_quarter_pulse),
2208 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_allow_non_quarter_pulse)
2210 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2211 string_compose (_("<b>When enabled</b> %1 will allow tempo to be expressed in divisions per minute\n"
2212 "<b>When disabled</b> %1 will only allow tempo to be expressed in quarter notes per minute"),
2214 add_option (_("General"), bo);
2216 if (!ARDOUR::Profile->get_mixbus()) {
2217 add_option (_("General"), new OptionEditorHeading (_("GUI Lock")));
2218 /* Lock GUI timeout */
2220 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2221 _("Lock timeout (seconds)"),
2222 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
2223 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds),
2226 slts->scale().set_digits (0);
2227 Gtkmm2ext::UI::instance()->set_tip (
2229 _("Lock GUI after this many idle seconds (zero to never lock)"));
2230 add_option (_("General"), slts);
2233 add_option (_("General/Session"), new OptionEditorHeading (S_("Options|Undo")));
2235 add_option (_("General/Session"), new UndoOptions (_rc_config));
2237 add_option (_("General/Session"),
2239 "verify-remove-last-capture",
2240 _("Verify removal of last capture"),
2241 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
2242 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
2245 add_option (_("General/Session"), new OptionEditorHeading (_("Session Management")));
2247 add_option (_("General/Session"),
2249 "periodic-safety-backups",
2250 _("Make periodic backups of the session file"),
2251 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
2252 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
2255 add_option (_("General/Session"),
2257 "only-copy-imported-files",
2258 _("Always copy imported files"),
2259 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
2260 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
2263 add_option (_("General/Session"), new DirectoryOption (
2264 X_("default-session-parent-dir"),
2265 _("Default folder for new sessions:"),
2266 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
2267 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
2270 add_option (_("General/Session"),
2271 new SpinOption<uint32_t> (
2272 "max-recent-sessions",
2273 _("Maximum number of recent sessions"),
2274 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
2275 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
2282 add_option (_("General/Translation"), new OptionEditorHeading (_("Internationalization")));
2284 bo = new BoolOption (
2285 "enable-translation",
2286 _("Use translations"),
2287 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2288 sigc::ptr_fun (ARDOUR::set_translations_enabled)
2291 bo->set_note (string_compose (_("These settings will only take effect after %1 is restarted (if available for your language preferences)."), PROGRAM_NAME));
2293 add_option (_("General/Translation"), bo);
2295 parameter_changed ("enable-translation");
2296 #endif // ENABLE_NLS
2301 add_option (_("Editor"), new OptionEditorHeading (_("General")));
2303 bo = new BoolOption (
2305 _("Prompt for new marker names"),
2306 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2307 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2309 add_option (_("Editor"), bo);
2310 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."
2311 "\n\nYou can always rename markers by right-clicking on them"));
2313 add_option (_("Editor"),
2315 "draggable-playhead",
2316 _("Allow dragging of playhead"),
2317 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2318 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2321 ComboOption<float>* dps = new ComboOption<float> (
2322 "draggable-playhead-speed",
2323 _("Playhead dragging speed (%)"),
2324 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead_speed),
2325 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead_speed)
2327 dps->add (0.05, _("5%"));
2328 dps->add (0.1, _("10%"));
2329 dps->add (0.25, _("25%"));
2330 dps->add (0.5, _("50%"));
2331 dps->add (1.0, _("100%"));
2332 add_option (_("Editor"), dps);
2334 ComboOption<float>* eet = new ComboOption<float> (
2335 "extra-ui-extents-time",
2336 _("Limit zooming & summary view to X minutes beyond session extents"),
2337 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_extra_ui_extents_time),
2338 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_extra_ui_extents_time)
2340 eet->add (1, _("1 minute"));
2341 eet->add (2, _("2 minutes"));
2342 eet->add (20, _("20 minutes"));
2343 eet->add (60, _("1 hour"));
2344 eet->add (60*2, _("2 hours"));
2345 eet->add (60*24, _("24 hours"));
2346 add_option (_("Editor"), eet);
2348 if (!Profile->get_mixbus()) {
2350 add_option (_("Editor"),
2352 "use-mouse-position-as-zoom-focus-on-scroll",
2353 _("Zoom to mouse position when zooming with scroll wheel"),
2354 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2355 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2359 add_option (_("Editor"),
2361 "use-time-rulers-to-zoom-with-vertical-drag",
2362 _("Zoom with vertical drag in rulers"),
2363 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag),
2364 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag)
2367 add_option (_("Editor"),
2369 "use-double-click-to-zoom-to-selection",
2370 _("Double click zooms to selection"),
2371 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection),
2372 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection)
2375 add_option (_("Editor"),
2377 "update-editor-during-summary-drag",
2378 _("Update editor window during drags of the summary"),
2379 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2380 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2383 add_option (_("Editor"),
2385 "autoscroll-editor",
2386 _("Auto-scroll editor window when dragging near its edges"),
2387 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2388 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2391 add_option (_("Editor"),
2392 new BoolComboOption (
2393 "show-region-gain-envelopes",
2394 _("Show gain envelopes in audio regions"),
2396 _("only in Draw and Internal Edit modes"),
2397 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2398 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2401 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2403 add_option (_("Editor"),
2405 "automation-follows-regions",
2406 _("Move relevant automation when audio regions are moved"),
2407 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2408 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2411 bo = new BoolOption (
2412 "new-automation-points-on-lane",
2413 _("Ignore Y-axis click position when adding new automation-points"),
2414 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_new_automation_points_on_lane),
2415 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_new_automation_points_on_lane)
2417 add_option (_("Editor"), bo);
2418 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2419 _("<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."));
2421 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2422 "default-fade-shape",
2423 _("Default fade shape"),
2424 sigc::mem_fun (*_rc_config,
2425 &RCConfiguration::get_default_fade_shape),
2426 sigc::mem_fun (*_rc_config,
2427 &RCConfiguration::set_default_fade_shape)
2430 fadeshape->add (FadeLinear,
2431 _("Linear (for highly correlated material)"));
2432 fadeshape->add (FadeConstantPower, _("Constant power"));
2433 fadeshape->add (FadeSymmetric, _("Symmetric"));
2434 fadeshape->add (FadeSlow, _("Slow"));
2435 fadeshape->add (FadeFast, _("Fast"));
2437 add_option (_("Editor"), fadeshape);
2439 ComboOption<RegionEquivalence> *eqv = new ComboOption<RegionEquivalence> (
2440 "region-equivalence",
2441 _("Regions in active edit groups are edited together"),
2442 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_equivalence),
2443 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_equivalence)
2446 eqv->add (Overlap, _("whenever they overlap in time"));
2447 eqv->add (Enclosed, _("if either encloses the other"));
2448 eqv->add (Exact, _("only if they have identical length, position and origin"));
2450 add_option (_("Editor"), eqv);
2452 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2454 _("Layering model"),
2455 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2456 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2459 lm->add (LaterHigher, _("later is higher"));
2460 lm->add (Manual, _("manual layering"));
2461 add_option (_("Editor"), lm);
2463 add_option (_("Editor"), new OptionEditorHeading (_("Split/Separate")));
2465 ComboOption<RangeSelectionAfterSplit> *rras = new ComboOption<RangeSelectionAfterSplit> (
2466 "range-selection-after-separate",
2467 _("After a Separate operation, in Range mode"),
2468 sigc::mem_fun (*_rc_config, &RCConfiguration::get_range_selection_after_split),
2469 sigc::mem_fun (*_rc_config, &RCConfiguration::set_range_selection_after_split));
2471 rras->add(ClearSel, _("Clear the Range Selection"));
2472 rras->add(PreserveSel, _("Preserve the Range Selection"));
2473 rras->add(ForceSel, _("Force-Select the regions under the range. (this might cause a tool change)"));
2474 add_option (_("Editor"), rras);
2476 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2477 "region-selection-after-split",
2478 _("After a Split operation, in Object mode"),
2479 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2480 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2482 // TODO: decide which of these modes are really useful
2483 rsas->add(None, _("Clear the Selected Regions"));
2484 rsas->add(NewlyCreatedLeft, _("Select only the newly-created regions BEFORE the split point"));
2485 rsas->add(NewlyCreatedRight, _("Select only the newly-created regions AFTER the split point"));
2486 rsas->add(NewlyCreatedBoth, _("Select the newly-created regions"));
2487 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2488 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2489 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2490 rsas->add(ExistingNewlyCreatedBoth, _("Preserve the existing selection, AND select all newly-created regions"));
2492 add_option (_("Editor"), rsas);
2494 add_option (_("Editor/Snap"), new OptionEditorHeading (_("General Snap options:")));
2496 add_option (_("Editor/Snap"),
2497 new SpinOption<uint32_t> (
2499 _("Snap Threshold (pixels)"),
2500 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_threshold),
2501 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_threshold),
2506 add_option (_("Editor/Snap"),
2508 "show-snapped-cursor",
2509 _("Show \"snapped cursor\""),
2510 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_snapped_cursor),
2511 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_snapped_cursor)
2514 add_option (_("Editor/Snap"),
2516 "rubberbanding-snaps-to-grid",
2517 _("Snap rubberband selection to grid"),
2518 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2519 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2522 add_option (_("Editor/Snap"),
2524 "grid-follows-internal",
2525 _("Grid switches to alternate selection for Internal Edit tools"),
2526 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_grid_follows_internal),
2527 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_grid_follows_internal)
2530 add_option (_("Editor/Snap"),
2532 "rulers-follow-grid",
2533 _("Rulers automatically change to follow the Grid mode selection"),
2534 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rulers_follow_grid),
2535 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rulers_follow_grid)
2538 add_option (_("Editor/Snap"), new OptionEditorHeading (_("When \"Snap\" is enabled, snap to:")));
2541 add_option (_("Editor/Snap"),
2545 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_marks),
2546 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_marks)
2549 add_option (_("Editor/Snap"),
2551 "snap-to-region-sync",
2552 _("Region Sync Points"),
2553 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_region_sync),
2554 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_region_sync)
2557 add_option (_("Editor/Snap"),
2559 "snap-to-region-start",
2561 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_region_start),
2562 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_region_start)
2565 add_option (_("Editor/Snap"),
2567 "snap-to-region-end",
2569 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_region_end),
2570 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_region_end)
2573 add_option (_("Editor/Snap"),
2577 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_grid),
2578 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_grid)
2581 add_option (_("Editor/Modifiers"), new OptionEditorHeading (_("Keyboard Modifiers")));
2582 add_option (_("Editor/Modifiers"), new KeyboardOptions);
2583 add_option (_("Editor/Modifiers"), new OptionEditorBlank ());
2585 /* MIXER -- SOLO AND MUTE */
2587 add_option (_("Mixer"), new OptionEditorHeading (_("Solo")));
2589 _solo_control_is_listen_control = new BoolOption (
2590 "solo-control-is-listen-control",
2591 _("Solo controls are Listen controls"),
2592 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2593 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2596 add_option (_("Mixer"), _solo_control_is_listen_control);
2598 add_option (_("Mixer"),
2601 _("Exclusive solo"),
2602 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2603 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2606 add_option (_("Mixer"),
2609 _("Show solo muting"),
2610 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2611 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2614 add_option (_("Mixer"),
2616 "solo-mute-override",
2617 _("Soloing overrides muting"),
2618 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2619 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2622 add_option (_("Mixer"),
2625 _("Solo-in-place mute cut (dB)"),
2626 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2627 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2630 _listen_position = new ComboOption<ListenPosition> (
2632 _("Listen Position"),
2633 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2634 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2637 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2638 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2640 add_option (_("Mixer"), _listen_position);
2642 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2644 _("PFL signals come from"),
2645 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2646 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2649 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2650 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2652 add_option (_("Mixer"), pp);
2654 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2656 _("AFL signals come from"),
2657 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2658 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2661 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2662 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2664 add_option (_("Mixer"), pa);
2666 add_option (_("Mixer"), new OptionEditorHeading (_("Default Track / Bus Muting Options")));
2668 add_option (_("Mixer"),
2670 "mute-affects-pre-fader",
2671 _("Mute affects pre-fader sends"),
2672 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2673 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2676 add_option (_("Mixer"),
2678 "mute-affects-post-fader",
2679 _("Mute affects post-fader sends"),
2680 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2681 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2684 add_option (_("Mixer"),
2686 "mute-affects-control-outs",
2687 _("Mute affects control outputs"),
2688 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2689 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2692 add_option (_("Mixer"),
2694 "mute-affects-main-outs",
2695 _("Mute affects main outputs"),
2696 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2697 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2701 if (!ARDOUR::Profile->get_mixbus()) {
2702 add_option (_("Mixer"), new OptionEditorHeading (_("Send Routing")));
2703 add_option (_("Mixer"),
2705 "link-send-and-route-panner",
2706 _("Link panners of Aux and External Sends with main panner by default"),
2707 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2708 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2714 add_option (_("Signal Flow"), new OptionEditorHeading (_("Monitoring")));
2716 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2718 _("Record monitoring handled by"),
2719 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2720 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2723 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2724 mm->add (HardwareMonitoring, _("via Audio Driver"));
2727 string prog (PROGRAM_NAME);
2728 boost::algorithm::to_lower (prog);
2729 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2730 mm->add (ExternalMonitoring, _("audio hardware"));
2732 add_option (_("Signal Flow"), mm);
2734 bo = new BoolOption (
2735 "tape-machine-mode",
2736 _("Tape machine mode"),
2737 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2738 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2740 add_option (_("Signal Flow"), bo);
2741 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2742 string_compose (_("<b>When enabled</b> %1 will not monitor a track's input if the transport is stopped."),
2745 if (!Profile->get_mixbus()) {
2747 add_option (_("Signal Flow"), new OptionEditorHeading (_("Track and Bus Connections")));
2749 bo = new BoolOption (
2750 "auto-connect-standard-busses",
2751 _("Auto-connect main output (master or monitor) bus to physical ports"),
2752 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2753 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2755 add_option (_("Signal Flow"), bo);
2756 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2757 _("<b>When enabled</b> the main output bus is auto-connected to the first N physical ports. "
2758 "If the session has a monitor-section, the monitor-bus output is conneced the the hardware playback ports, "
2759 "otherwise the master-bus output is directly used for playback."));
2761 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2762 "input-auto-connect",
2763 _("Connect track inputs"),
2764 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2765 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2768 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2769 iac->add (ManualConnect, _("manually"));
2771 add_option (_("Signal Flow"), iac);
2773 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2774 "output-auto-connect",
2775 _("Connect track and bus outputs"),
2776 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2777 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2780 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2781 oac->add (AutoConnectMaster, _("automatically to master bus"));
2782 oac->add (ManualConnect, _("manually"));
2784 add_option (_("Signal Flow"), oac);
2786 bo = new BoolOption (
2788 _("Use 'Strict-I/O' for new tracks or busses"),
2789 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2790 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2793 add_option (_("Signal Flow"), bo);
2794 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2795 _("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."));
2802 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2804 add_option (_("Audio"), new BufferingOptions (_rc_config));
2806 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2808 add_option (_("Audio"),
2810 "denormal-protection",
2811 _("Use DC bias to protect against denormals"),
2812 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2813 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2816 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2818 _("Processor handling"),
2819 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2820 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2824 dm->add (DenormalNone, _("no processor handling"));
2826 FPU* fpu = FPU::instance();
2828 if (fpu->has_flush_to_zero()) {
2830 dm->add (DenormalFTZ, _("use FlushToZero"));
2831 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2832 _rc_config->set_denormal_model(DenormalNone);
2835 if (fpu->has_denormals_are_zero()) {
2837 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2838 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2839 _rc_config->set_denormal_model(DenormalNone);
2842 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2844 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2845 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2846 _rc_config->set_denormal_model(DenormalNone);
2850 dm->set_sensitive(false);
2853 add_option (_("Audio"), dm);
2855 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2857 add_option (_("Audio"),
2859 "auto-analyse-audio",
2860 _("Enable automatic analysis of audio"),
2861 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2862 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2865 add_option (_("Audio"),
2867 "replicate-missing-region-channels",
2868 _("Replicate missing region channels"),
2869 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2870 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2875 add_option (_("MIDI"), new OptionEditorHeading (_("Buffering")));
2877 add_option (_("MIDI"),
2878 new SpinOption<float> (
2880 _("MIDI read-ahead time (seconds)"),
2881 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2882 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2887 add_option (_("MIDI"), new OptionEditorHeading (_("Session")));
2889 add_option (_("MIDI"),
2890 new SpinOption<int32_t> (
2891 "initial-program-change",
2892 _("Initial program change"),
2893 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2894 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2898 add_option (_("MIDI"), new OptionEditorHeading (_("Audition")));
2900 add_option (_("MIDI"),
2903 _("Sound MIDI notes as they are selected in the editor"),
2904 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2905 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2908 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2909 "midi-audition-synth-uri",
2910 _("MIDI Audition Synth (LV2)"),
2911 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2912 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2915 audition_synth->add(X_(""), _("None"));
2916 PluginInfoList all_plugs;
2917 PluginManager& manager (PluginManager::instance());
2919 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2921 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2922 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2923 if (!(*i)->is_instrument()) continue;
2924 if ((*i)->type != ARDOUR::LV2) continue;
2925 if ((*i)->name.length() > 46) {
2926 audition_synth->add((*i)->unique_id, (*i)->name.substr (0, 44) + "...");
2928 audition_synth->add((*i)->unique_id, (*i)->name);
2933 add_option (_("MIDI"), audition_synth);
2937 add_option (_("Metronome"), new OptionEditorHeading (_("Metronome")));
2938 add_option (_("Metronome"), new ClickOptions (_rc_config));
2939 add_option (_("Metronome"), new OptionEditorHeading (_("Options")));
2941 bo = new BoolOption (
2942 "click-record-only",
2943 _("Enable metronome only while recording"),
2944 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_record_only),
2945 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_record_only)
2948 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2949 string_compose (_("<b>When enabled</b> the metronome will remain silent if %1 is <b>not recording</b>."), PROGRAM_NAME));
2950 add_option (_("Metronome"), bo);
2951 add_option (_("Metronome"), new OptionEditorBlank ());
2956 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2958 ComboOption<float>* mht = new ComboOption<float> (
2960 _("Peak hold time"),
2961 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
2962 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
2965 mht->add (MeterHoldOff, _("off"));
2966 mht->add (MeterHoldShort, _("short"));
2967 mht->add (MeterHoldMedium, _("medium"));
2968 mht->add (MeterHoldLong, _("long"));
2970 add_option (S_("Preferences|Metering"), mht);
2972 ComboOption<float>* mfo = new ComboOption<float> (
2975 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2976 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2979 mfo->add (METER_FALLOFF_OFF, _("off"));
2980 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2981 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2982 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2983 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2984 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2985 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
2987 add_option (S_("Preferences|Metering"), mfo);
2989 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2990 "meter-line-up-level",
2991 _("Meter line-up level; 0dBu"),
2992 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
2993 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
2996 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2997 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2998 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2999 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3001 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."));
3003 add_option (S_("Preferences|Metering"), mlu);
3005 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
3006 "meter-line-up-din",
3007 _("IEC1/DIN Meter line-up level; 0dBu"),
3008 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
3009 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
3012 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3013 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3014 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3015 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3017 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
3019 add_option (S_("Preferences|Metering"), mld);
3021 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
3022 "meter-vu-standard",
3023 _("VU Meter standard"),
3024 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
3025 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
3028 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
3029 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
3030 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
3031 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
3033 add_option (S_("Preferences|Metering"), mvu);
3035 HSliderOption *mpks = new HSliderOption("meter-peak",
3036 _("Peak indicator threshold [dBFS]"),
3037 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
3038 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak),
3042 Gtkmm2ext::UI::instance()->set_tip (
3044 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
3046 add_option (S_("Preferences|Metering"), mpks);
3048 OptionEditorHeading* default_meter_head = new OptionEditorHeading (_("Default Meter Types"));
3049 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."));
3051 add_option (S_("Preferences|Metering"), default_meter_head);
3053 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3054 "meter-type-master",
3055 _("Default Meter Type for Master Bus"),
3056 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3057 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3059 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3060 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3061 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3062 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3063 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3064 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3065 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3066 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3068 add_option (S_("Preferences|Metering"), mtm);
3071 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3073 _("Default meter type for busses"),
3074 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3075 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3077 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3078 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3079 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3080 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3081 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3082 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3083 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3084 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3086 add_option (S_("Preferences|Metering"), mtb);
3088 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3090 _("Default meter type for tracks"),
3091 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3092 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3094 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3095 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3097 add_option (S_("Preferences|Metering"), mtt);
3099 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
3101 add_option (S_("Preferences|Metering"),
3103 "save-export-analysis-image",
3104 _("Save loudness analysis as image file"),
3105 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
3106 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
3109 /* TRANSPORT & Sync */
3111 add_option (_("Transport"), new OptionEditorHeading (_("General")));
3113 bo = new BoolOption (
3114 "stop-at-session-end",
3115 _("Stop at the end of the session"),
3116 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
3117 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
3119 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3120 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
3121 "when it reaches the current session end marker\n\n"
3122 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
3124 add_option (_("Transport"), bo);
3126 bo = new BoolOption (
3127 "latched-record-enable",
3128 _("Keep record-enable engaged on stop"),
3129 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
3130 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
3132 add_option (_("Transport"), bo);
3133 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3134 _("<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."));
3136 bo = new BoolOption (
3137 "disable-disarm-during-roll",
3138 _("Disable per-track record disarm while rolling"),
3139 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
3140 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
3142 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."));
3143 add_option (_("Transport"), bo);
3145 bo = new BoolOption (
3147 _("12dB gain reduction during fast-forward and fast-rewind"),
3148 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
3149 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
3151 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3152 _("<b>When enabled</b> this will reduce the unpleasant increase in perceived volume "
3153 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
3154 add_option (_("Transport"), bo);
3156 ComboOption<float>* psc = new ComboOption<float> (
3159 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
3160 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
3162 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
3163 (_("The amount of preroll to apply when <b>Play with Preroll</b> or <b>Record with Preroll</b>is initiated.\n\n"
3164 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
3165 psc->add (-4.0, _("4 Bars"));
3166 psc->add (-2.0, _("2 Bars"));
3167 psc->add (-1.0, _("1 Bar"));
3168 psc->add (0.0, _("0 (no pre-roll)"));
3169 psc->add (0.1, _("0.1 second"));
3170 psc->add (0.25, _("0.25 second"));
3171 psc->add (0.5, _("0.5 second"));
3172 psc->add (1.0, _("1.0 second"));
3173 psc->add (2.0, _("2.0 seconds"));
3174 add_option (_("Transport"), psc);
3177 add_option (_("Transport"), new OptionEditorHeading (_("Looping")));
3179 bo = new BoolOption (
3181 _("Play loop is a transport mode"),
3182 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
3183 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
3185 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3186 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
3187 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
3188 add_option (_("Transport"), bo);
3190 bo = new BoolOption (
3192 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
3193 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
3194 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
3196 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3197 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
3198 "preventing any need to do a transport locate at the end of the loop\n\n"
3199 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
3200 "which will often cause a small click or delay"), PROGRAM_NAME));
3201 add_option (_("Transport"), bo);
3203 add_option (_("Transport"), new OptionEditorHeading (_("Dropout (xrun) Handling")));
3204 bo = new BoolOption (
3205 "stop-recording-on-xrun",
3206 _("Stop recording when an xrun occurs"),
3207 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
3208 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
3210 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3211 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
3213 add_option (_("Transport"), bo);
3215 bo = new BoolOption (
3216 "create-xrun-marker",
3217 _("Create markers where xruns occur"),
3218 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
3219 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
3221 add_option (_("Transport"), bo);
3226 add_option (_("Sync"), new OptionEditorHeading (_("Transport Masters")));
3228 add_option (_("Sync"), new WidgetOption (X_("foo"), X_("Transport Masters"), _transport_masters_widget));
3230 _sync_framerate = new BoolOption (
3231 "timecode-sync-frame-rate",
3232 _("Match session video frame rate to external timecode"),
3233 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
3234 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
3236 Gtkmm2ext::UI::instance()->set_tip
3237 (_sync_framerate->tip_widget(),
3238 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
3239 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
3240 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
3241 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
3242 "timecode standard and the session standard."), PROGRAM_NAME));
3244 add_option (_("Sync"), _sync_framerate);
3246 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Generator")));
3248 add_option (_("Sync/LTC"),
3251 _("Enable LTC generator"),
3252 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
3253 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
3256 _ltc_send_continuously = new BoolOption (
3257 "ltc-send-continuously",
3258 _("Send LTC while stopped"),
3259 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
3260 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
3262 Gtkmm2ext::UI::instance()->set_tip
3263 (_ltc_send_continuously->tip_widget(),
3264 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
3265 add_option (_("Sync/LTC"), _ltc_send_continuously);
3267 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level [dBFS]"),
3268 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_output_volume),
3269 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_output_volume),
3273 Gtkmm2ext::UI::instance()->set_tip
3274 (_ltc_volume_slider->tip_widget(),
3275 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
3277 add_option (_("Sync/LTC"), _ltc_volume_slider);
3280 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Beat Clock (Mclk) Generator")));
3282 add_option (_("Sync/MIDI"),
3285 _("Enable Mclk generator"),
3286 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
3287 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
3290 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC) Generator")));
3292 add_option (_("Sync/MIDI"),
3295 _("Enable MTC Generator"),
3296 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
3297 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
3300 add_option (_("Sync/MIDI"),
3301 new SpinOption<int> (
3302 "mtc-qf-speed-tolerance",
3303 _("Percentage either side of normal transport speed to transmit MTC"),
3304 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
3305 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
3309 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Machine Control (MMC)")));
3311 add_option (_("Sync/MIDI"),
3314 _("Respond to MMC commands"),
3315 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
3316 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
3319 add_option (_("Sync/MIDI"),
3322 _("Send MMC commands"),
3323 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
3324 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
3327 add_option (_("Sync/MIDI"),
3328 new SpinOption<uint8_t> (
3329 "mmc-receive-device-id",
3330 _("Inbound MMC device ID"),
3331 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
3332 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
3336 add_option (_("Sync/MIDI"),
3337 new SpinOption<uint8_t> (
3338 "mmc-send-device-id",
3339 _("Outbound MMC device ID"),
3340 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
3341 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
3346 /* Control Surfaces */
3348 add_option (_("Control Surfaces"), new OptionEditorHeading (_("Control Surfaces")));
3349 add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
3352 add_option (_("MIDI Ports"), new OptionEditorHeading (_("MIDI Port Options")));
3354 add_option (_("MIDI Ports"),
3356 "midi-input-follows-selection",
3357 _("MIDI input follows MIDI track selection"),
3358 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
3359 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
3362 add_option (_("MIDI Ports"), new MidiPortOptions ());
3363 add_option (_("MIDI Ports"), new OptionEditorBlank ());
3367 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3368 add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
3369 add_option (_("Plugins"),
3370 new RcActionButton (_("Scan for Plugins"),
3371 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3375 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
3377 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3378 bo = new BoolOption (
3379 "show-plugin-scan-window",
3380 _("Always Display Plugin Scan Progress"),
3381 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
3382 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
3384 add_option (_("Plugins"), bo);
3385 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3386 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
3389 bo = new BoolOption (
3390 "plugins-stop-with-transport",
3391 _("Silence plugins when the transport is stopped"),
3392 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
3393 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
3395 add_option (_("Plugins"), bo);
3396 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3397 _("<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."));
3399 bo = new BoolOption (
3400 "new-plugins-active",
3401 _("Make new plugins active"),
3402 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
3403 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
3405 add_option (_("Plugins"), bo);
3406 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3407 _("<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"));
3409 ComboOption<uint32_t>* lna = new ComboOption<uint32_t> (
3410 "limit-n-automatables",
3411 _("Limit automatable parameters per plugin"),
3412 sigc::mem_fun (*_rc_config, &RCConfiguration::get_limit_n_automatables),
3413 sigc::mem_fun (*_rc_config, &RCConfiguration::set_limit_n_automatables)
3415 lna->add (0, _("Unlimited"));
3416 lna->add (64, _("64 parameters"));
3417 lna->add (128, _("128 parameters"));
3418 lna->add (256, _("256 parameters"));
3419 lna->add (512, _("512 parameters"));
3420 lna->add (999, _("999 parameters"));
3421 add_option (_("Plugins"), lna);
3422 Gtkmm2ext::UI::instance()->set_tip (lna->tip_widget(),
3423 _("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."));
3426 #if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
3427 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
3429 add_option (_("Plugins/VST"),
3430 new RcActionButton (_("Scan for Plugins"),
3431 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3434 #if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
3435 bo = new BoolOption (
3437 _("Enable Mac VST support (requires restart or re-scan)"),
3438 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
3439 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
3441 add_option (_("Plugins/VST"), bo);
3444 bo = new BoolOption (
3445 "discover-vst-on-start",
3446 _("Scan for [new] VST Plugins on Application Start"),
3447 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
3448 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
3450 add_option (_("Plugins/VST"), bo);
3451 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3452 _("<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"));
3454 #ifdef WINDOWS_VST_SUPPORT
3455 // currently verbose logging is only implemented for Windows VST.
3456 bo = new BoolOption (
3457 "verbose-plugin-scan",
3458 _("Verbose Plugin Scan"),
3459 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
3460 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
3462 add_option (_("Plugins/VST"), bo);
3463 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3464 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
3467 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
3469 add_option (_("Plugins/VST"),
3470 new RcActionButton (_("Clear"),
3471 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
3474 add_option (_("Plugins/VST"),
3475 new RcActionButton (_("Clear"),
3476 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
3477 _("VST Blacklist:")));
3480 #ifdef LXVST_SUPPORT
3481 add_option (_("Plugins/VST"),
3482 new RcActionButton (_("Edit"),
3483 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
3484 _("Linux VST Path:")));
3486 add_option (_("Plugins/VST"),
3487 new RcConfigDisplay (
3488 "plugin-path-lxvst",
3490 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
3494 #ifdef WINDOWS_VST_SUPPORT
3495 add_option (_("Plugins/VST"),
3496 new RcActionButton (_("Edit"),
3497 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
3498 _("Windows VST Path:")));
3499 add_option (_("Plugins/VST"),
3500 new RcConfigDisplay (
3503 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
3507 #ifdef AUDIOUNIT_SUPPORT
3509 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
3511 add_option (_("Plugins/Audio Unit"),
3512 new RcActionButton (_("Scan for Plugins"),
3513 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3516 bo = new BoolOption (
3517 "discover-audio-units",
3518 _("Scan for [new] AudioUnit Plugins on Application Start"),
3519 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
3520 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
3522 add_option (_("Plugins/Audio Unit"), bo);
3523 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3524 _("<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."));
3526 add_option (_("Plugins/Audio Unit"),
3527 new RcActionButton (_("Clear"),
3528 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
3531 add_option (_("Plugins/Audio Unit"),
3532 new RcActionButton (_("Clear"),
3533 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
3534 _("AU Blacklist:")));
3537 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
3538 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
3539 add_option (_("Plugins"),
3541 "open-gui-after-adding-plugin",
3542 _("Automatically open the plugin GUI when adding a new plugin"),
3543 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
3544 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3547 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3548 add_option (_("Plugins"),
3550 "show-inline-display-by-default",
3551 _("Show Plugin Inline Display on Mixerstrip by default"),
3552 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3553 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3556 _plugin_prefer_inline = new BoolOption (
3557 "prefer-inline-over-gui",
3558 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3559 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3560 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3562 add_option (_("Plugins"), _plugin_prefer_inline);
3565 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3567 bo = new BoolOption (
3568 "ask-replace-instrument",
3569 _("Ask to replace existing instrument plugin"),
3570 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3571 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3573 add_option (_("Plugins"), bo);
3575 bo = new BoolOption (
3576 "ask-setup_instrument",
3577 _("Interactively configure instrument plugins on insert"),
3578 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3579 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3581 add_option (_("Plugins"), bo);
3582 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3583 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3586 add_option (_("Plugins"), new OptionEditorBlank ());
3589 #if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
3590 add_option (_("Appearance"), new OptionEditorHeading (_("Graphics Acceleration")));
3593 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3594 BoolOption* bgc = new BoolOption (
3595 "cairo-image-surface",
3596 _("Disable Graphics Hardware Acceleration (requires restart)"),
3597 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3598 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3601 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3602 _("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));
3603 add_option (_("Appearance"), bgc);
3606 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3607 BoolOption* bgo = new BoolOption (
3609 _("Possibly improve slow graphical performance (requires restart)"),
3610 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3611 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3614 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));
3615 add_option (_("Appearance"), bgo);
3617 add_option (_("Appearance"), new OptionEditorHeading (_("Graphical User Interface")));
3619 add_option (_("Appearance"),
3622 _("Highlight widgets on mouseover"),
3623 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3624 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3627 add_option (_("Appearance"),
3630 _("Show tooltips if mouse hovers over a control"),
3631 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3632 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3635 bo = new BoolOption (
3636 "super-rapid-clock-update",
3637 _("Update clocks at TC Frame rate"),
3638 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3639 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3641 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3642 _("<b>When enabled</b> clock displays are updated every Timecode Frame (fps).\n\n"
3643 "<b>When disabled</b> clock displays are updated only every 100ms."
3645 add_option (_("Appearance"), bo);
3647 add_option (_("Appearance"),
3650 _("Blink Rec-Arm buttons"),
3651 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_rec_arm),
3652 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_rec_arm)
3655 add_option (_("Appearance"),
3657 "blink-alert-indicators",
3658 _("Blink Alert Indicators"),
3659 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_alert_indicators),
3660 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_alert_indicators)
3665 /* font scaling does nothing with GDK/Quartz */
3666 add_option (_("Appearance"), new FontScalingOptions ());
3668 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("General")));
3669 add_option (_("Appearance/Editor"),
3671 "show-name-highlight",
3672 _("Use name highlight bars in region displays (requires a restart)"),
3673 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3674 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3677 add_option (_("Appearance/Editor"),
3679 "color-regions-using-track-color",
3680 _("Region color follows track color"),
3681 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_color_regions_using_track_color),
3682 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_color_regions_using_track_color)
3685 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Waveforms")));
3687 if (!Profile->get_mixbus()) {
3688 add_option (_("Appearance/Editor"),
3691 _("Show waveforms in regions"),
3692 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
3693 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
3697 add_option (_("Appearance/Editor"),
3699 "show-waveforms-while-recording",
3700 _("Show waveforms while recording"),
3701 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
3702 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
3705 add_option (_("Appearance/Editor"),
3707 "show-waveform-clipping",
3708 _("Show waveform clipping"),
3709 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveform_clipping),
3710 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveform_clipping)
3713 add_option (_("Appearance/Editor"), new ClipLevelOptions ());
3715 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
3717 _("Waveform scale"),
3718 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
3719 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
3722 wfs->add (Linear, _("linear"));
3723 wfs->add (Logarithmic, _("logarithmic"));
3725 add_option (_("Appearance/Editor"), wfs);
3727 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
3729 _("Waveform shape"),
3730 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
3731 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
3734 wfsh->add (Traditional, _("traditional"));
3735 wfsh->add (Rectified, _("rectified"));
3737 add_option (_("Appearance/Editor"), wfsh);
3739 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Editor Meters")));
3741 add_option (_("Appearance/Editor"),
3743 "show-track-meters",
3744 _("Show meters in track headers"),
3745 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3746 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3749 add_option (_("Appearance/Editor"),
3751 "editor-stereo-only-meters",
3752 _("Limit track header meters to stereo"),
3753 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3754 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3757 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("MIDI Regions")));
3759 add_option (_("Appearance/Editor"),
3761 "display-first-midi-bank-as-zero",
3762 _("Display first MIDI bank/program as 0"),
3763 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
3764 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
3767 add_option (_("Appearance/Editor"),
3769 "never-display-periodic-midi",
3770 _("Don't display periodic (MTC, MMC) SysEx messages in MIDI Regions"),
3771 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
3772 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
3776 add_option (_("Appearance/Editor"),
3778 "use-note-bars-for-velocity",
3779 _("Show velocity horizontally inside notes"),
3780 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_note_bars_for_velocity),
3781 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_note_bars_for_velocity)
3784 add_option (_("Appearance/Editor"),
3786 "use-note-color-for-velocity",
3787 _("Use colors to show note velocity"),
3788 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_note_color_for_velocity),
3789 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_note_color_for_velocity)
3792 add_option (_("Appearance/Editor"), new OptionEditorBlank ());
3794 /* The names of these controls must be the same as those given in MixerStrip
3795 for the actual widgets being controlled.
3797 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3798 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3799 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3800 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3801 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3802 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3803 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3805 add_option (_("Appearance/Mixer"),
3806 new VisibilityOption (
3808 &_mixer_strip_visibility,
3809 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3810 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3814 add_option (_("Appearance/Mixer"),
3816 "default-narrow_ms",
3817 _("Use narrow strips in the mixer for new strips by default"),
3818 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3819 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3822 ComboOption<uint32_t>* mic = new ComboOption<uint32_t> (
3823 "max-inline-controls",
3824 _("Limit inline-mixer-strip controls per plugin"),
3825 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_max_inline_controls),
3826 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_max_inline_controls)
3828 mic->add (0, _("Unlimited"));
3829 mic->add (16, _("16 parameters"));
3830 mic->add (32, _("32 parameters"));
3831 mic->add (64, _("64 parameters"));
3832 mic->add (128, _("128 parameters"));
3833 add_option (_("Appearance/Mixer"), mic);
3835 add_option (_("Appearance/Mixer"), new OptionEditorBlank ());
3837 add_option (_("Appearance/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items")));
3839 add_option (_("Appearance/Toolbar"),
3841 "show-toolbar-recpunch",
3842 _("Display Record/Punch Options"),
3843 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_recpunch),
3844 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_recpunch)
3847 add_option (_("Appearance/Toolbar"),
3849 "show-toolbar-monitoring",
3850 _("Display Monitor Options"),
3851 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_monitoring),
3852 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_monitoring)
3855 add_option (_("Appearance/Toolbar"),
3857 "show-toolbar-selclock",
3858 _("Display Selection Clock"),
3859 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
3860 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
3863 if (!ARDOUR::Profile->get_small_screen()) {
3864 add_option (_("Appearance/Toolbar"),
3866 "show-secondary-clock",
3867 _("Display Secondary Clock"),
3868 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
3869 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
3873 add_option (_("Appearance/Toolbar"),
3875 "show-mini-timeline",
3876 _("Display Navigation Timeline"),
3877 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
3878 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
3881 add_option (_("Appearance/Toolbar"),
3883 "show-editor-meter",
3884 _("Display Master Level Meter"),
3885 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
3886 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
3889 add_option (_("Appearance/Toolbar"),
3890 new ColumVisibilityOption (
3891 "action-table-columns", _("Display Action-Buttons"), 4,
3892 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3893 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3896 add_option (_("Appearance/Toolbar"), new OptionEditorBlank ());
3899 /* and now the theme manager */
3901 add_option (_("Appearance/Theme"), new OptionEditorHeading (_("Theme")));
3903 add_option (_("Appearance/Theme"), new BoolOption (
3905 _("Draw \"flat\" buttons"),
3906 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_flat_buttons),
3907 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_flat_buttons)
3910 add_option (_("Appearance/Theme"), new BoolOption (
3912 _("Draw \"boxy\" buttons"),
3913 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_boxy_buttons),
3914 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_boxy_buttons)
3917 add_option (_("Appearance/Theme"), new BoolOption (
3919 _("LED meter style"),
3920 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3921 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3925 HSliderOption *gui_hs = new HSliderOption(
3926 "timeline-item-gradient-depth",
3927 _("Waveforms color gradient depth"),
3928 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_gradient_depth),
3929 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_gradient_depth),
3932 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3933 add_option (_("Appearance/Theme"), gui_hs);
3935 gui_hs = new HSliderOption(
3936 "timeline-item-gradient-depth",
3937 _("Timeline item gradient depth"),
3938 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_timeline_item_gradient_depth),
3939 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_timeline_item_gradient_depth),
3942 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3943 add_option (_("Appearance/Theme"), gui_hs);
3945 vector<string> icon_sets = ::get_icon_sets ();
3946 if (icon_sets.size() > 1) {
3947 ComboOption<std::string>* io = new ComboOption<std::string> (
3948 "icon-set", _("Icon Set"),
3949 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_icon_set),
3950 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_icon_set)
3952 for (vector<string>::const_iterator i = icon_sets.begin (); i != icon_sets.end (); ++i) {
3955 add_option (_("Appearance/Theme"), io);
3958 add_option (_("Appearance/Colors"), new OptionEditorHeading (_("Colors")));
3959 add_option (_("Appearance/Colors"), new ColorThemeManager);
3960 add_option (_("Appearance/Colors"), new OptionEditorBlank ());
3964 OptionEditorHeading* quirks_head = new OptionEditorHeading (_("Various Workarounds for Windowing Systems"));
3966 quirks_head->set_note (string_compose (_("Rules for closing, minimizing, maximizing, and stay-on-top can vary \
3967 with each version of your OS, and the preferences that you've set in your OS.\n\n\
3968 You can adjust the options, below, to change how %1's windows and dialogs behave.\n\n\
3969 These settings will only take effect after %1 is restarted.\n\
3972 add_option (_("Appearance/Quirks"), quirks_head);
3974 bo = new BoolOption (
3975 "use-wm-visibility",
3976 _("Use visibility information provided by your Window Manager/Desktop"),
3977 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3978 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3980 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3981 _("If you have trouble toggling between hidden Editor and Mixer windows, try changing this setting."));
3982 add_option (_("Appearance/Quirks"), bo);
3985 bo = new BoolOption (
3986 "all-floating-windows-are-dialogs",
3987 _("All floating windows are dialogs"),
3988 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_all_floating_windows_are_dialogs),
3989 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_all_floating_windows_are_dialogs)
3991 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3992 _("Mark all floating windows to be type \"Dialog\" rather than using \"Utility\" for some.\nThis may help with some window managers."));
3993 add_option (_("Appearance/Quirks"), bo);
3995 bo = new BoolOption (
3996 "transients-follow-front",
3997 _("Transient windows follow front window."),
3998 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_transients_follow_front),
3999 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_transients_follow_front)
4001 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
4002 _("Make transient windows follow the front window when toggling between the editor and mixer."));
4003 add_option (_("Appearance/Quirks"), bo);
4006 if (!Profile->get_mixbus()) {
4007 bo = new BoolOption (
4008 "floating-monitor-section",
4009 _("Float detached monitor-section window"),
4010 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_floating_monitor_section),
4011 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_floating_monitor_section)
4013 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
4014 _("When detaching the monitoring section, mark it as \"Utility\" window to stay in front."));
4015 add_option (_("Appearance/Quirks"), bo);
4018 add_option (_("Appearance/Quirks"), new OptionEditorBlank ());
4020 /* VIDEO Timeline */
4021 add_option (_("Video"), new OptionEditorHeading (_("Video Server")));
4022 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
4024 Widget::show_all ();
4026 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
4027 parameter_changed ("send-ltc");
4028 parameter_changed ("sync-source");
4029 parameter_changed ("use-monitor-bus");
4030 parameter_changed ("open-gui-after-adding-plugin");
4032 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
4034 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
4035 (Gtk::StateType) here !!!
4037 Tabbable::set_state (*node, Stateful::loading_state_version);
4040 set_current_page (_("General"));
4044 RCOptionEditor::set_session (Session *s)
4046 SessionHandlePtr::set_session (s);
4047 _transport_masters_widget.set_session (s);
4051 RCOptionEditor::parameter_changed (string const & p)
4053 OptionEditor::parameter_changed (p);
4055 if (p == "use-monitor-bus") {
4056 bool const s = Config->get_use_monitor_bus ();
4058 /* we can't use this if we don't have a monitor bus */
4059 Config->set_solo_control_is_listen_control (false);
4061 _solo_control_is_listen_control->set_sensitive (s);
4062 _listen_position->set_sensitive (s);
4063 } else if (p == "sync-source") {
4064 boost::shared_ptr<TransportMaster> tm (TransportMasterManager::instance().current());
4065 if (boost::dynamic_pointer_cast<TimecodeTransportMaster> (tm)) {
4066 _sync_framerate->set_sensitive (true);
4068 _sync_framerate->set_sensitive (false);
4070 } else if (p == "send-ltc") {
4071 bool const s = Config->get_send_ltc ();
4072 _ltc_send_continuously->set_sensitive (s);
4073 _ltc_volume_slider->set_sensitive (s);
4074 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
4075 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
4076 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
4081 void RCOptionEditor::plugin_scan_refresh () {
4082 PluginManager::instance().refresh();
4085 void RCOptionEditor::clear_vst_cache () {
4086 PluginManager::instance().clear_vst_cache();
4089 void RCOptionEditor::clear_vst_blacklist () {
4090 PluginManager::instance().clear_vst_blacklist();
4093 void RCOptionEditor::clear_au_cache () {
4094 PluginManager::instance().clear_au_cache();
4097 void RCOptionEditor::clear_au_blacklist () {
4098 PluginManager::instance().clear_au_blacklist();
4101 void RCOptionEditor::edit_lxvst_path () {
4102 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
4103 PathsDialog *pd = new PathsDialog (
4104 *current_toplevel(), _("Set Linux VST Search Path"),
4105 _rc_config->get_plugin_path_lxvst(),
4106 PluginManager::instance().get_default_lxvst_path()
4108 ResponseType r = (ResponseType) pd->run ();
4110 if (r == RESPONSE_ACCEPT) {
4111 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
4113 MessageDialog msg (_("Re-scan Plugins now?"),
4114 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
4115 msg.set_default_response (Gtk::RESPONSE_YES);
4116 if (msg.run() == Gtk::RESPONSE_YES) {
4118 plugin_scan_refresh ();
4124 void RCOptionEditor::edit_vst_path () {
4125 PathsDialog *pd = new PathsDialog (
4126 *current_toplevel(), _("Set Windows VST Search Path"),
4127 _rc_config->get_plugin_path_vst(),
4128 PluginManager::instance().get_default_windows_vst_path()
4130 ResponseType r = (ResponseType) pd->run ();
4132 if (r == RESPONSE_ACCEPT) {
4133 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
4134 MessageDialog msg (_("Re-scan Plugins now?"),
4135 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
4136 msg.set_default_response (Gtk::RESPONSE_YES);
4137 if (msg.run() == Gtk::RESPONSE_YES) {
4139 plugin_scan_refresh ();
4146 RCOptionEditor::use_own_window (bool and_fill_it)
4148 bool new_window = !own_window ();
4150 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
4152 if (win && new_window) {
4153 win->set_name ("PreferencesWindow");
4154 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
4156 win->set_resizable (false);
4163 RCOptionEditor::get_state ()
4165 XMLNode* node = new XMLNode (X_("Preferences"));
4166 node->add_child_nocopy (Tabbable::get_state());