2 * Copyright (C) 2009-2012 Carl Hetherington <carl@carlh.net>
3 * Copyright (C) 2009-2015 David Robillard <d@drobilla.net>
4 * Copyright (C) 2009-2019 Paul Davis <paul@linuxaudiosystems.com>
5 * Copyright (C) 2012-2019 Robin Gareus <robin@gareus.org>
6 * Copyright (C) 2013-2016 Nick Mainsbridge <mainsbridge@gmail.com>
7 * Copyright (C) 2013-2018 Colin Fletcher <colin.m.fletcher@googlemail.com>
8 * Copyright (C) 2013 John Emmas <john@creativepost.co.uk>
9 * Copyright (C) 2014-2016 Tim Mayberry <mojofunk@gmail.com>
10 * Copyright (C) 2014-2019 Ben Loftis <ben@harrisonconsoles.com>
11 * Copyright (C) 2018 Len Ovens <len@ovenwerks.net>
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include "gtk2ardour-config.h"
32 #if !defined USE_CAIRO_IMAGE_SURFACE && !defined NDEBUG
33 #define OPTIONAL_CAIRO_IMAGE_SURFACE
36 #include <cairo/cairo.h>
38 #include <boost/algorithm/string.hpp>
40 #include <gtkmm/liststore.h>
41 #include <gtkmm/stock.h>
42 #include <gtkmm/scale.h>
44 #include "gtkmm2ext/utils.h"
45 #include "gtkmm2ext/gtk_ui.h"
46 #include "gtkmm2ext/window_title.h"
52 #include "ardour/audio_backend.h"
53 #include "ardour/audioengine.h"
54 #include "ardour/control_protocol_manager.h"
55 #include "ardour/dB.h"
56 #include "ardour/port_manager.h"
57 #include "ardour/plugin_manager.h"
58 #include "ardour/profile.h"
59 #include "ardour/rc_configuration.h"
60 #include "ardour/transport_master_manager.h"
62 #include "control_protocol/control_protocol.h"
64 #include "waveview/wave_view.h"
66 #include "widgets/paths_dialog.h"
67 #include "widgets/tooltips.h"
69 #include "ardour_dialog.h"
70 #include "ardour_ui.h"
71 #include "ardour_window.h"
72 #include "color_theme_manager.h"
73 #include "gui_thread.h"
75 #include "meter_patterns.h"
76 #include "midi_tracer.h"
77 #include "rc_option_editor.h"
79 #include "transport_masters_dialog.h"
80 #include "ui_config.h"
85 using namespace Gtkmm2ext;
87 using namespace ARDOUR;
88 using namespace ARDOUR_UI_UTILS;
89 using namespace ArdourWidgets;
91 class ClickOptions : public OptionEditorMiniPage
94 ClickOptions (RCConfiguration* c)
96 , _click_browse_button (_("Browse..."))
97 , _click_emphasis_browse_button (_("Browse..."))
99 // TODO get rid of GTK -> use OptionEditor Widgets
104 l = manage (left_aligned_label (_("Emphasis on first beat")));
105 _use_emphasis_on_click_check_button.add (*l);
106 t->attach (_use_emphasis_on_click_check_button, 1, 3, row, row + 1, FILL);
107 _use_emphasis_on_click_check_button.signal_toggled().connect (
108 sigc::mem_fun (*this, &ClickOptions::use_emphasis_on_click_toggled));
111 l = manage (left_aligned_label (_("Use built-in default sounds")));
112 _use_default_click_check_button.add (*l);
113 t->attach (_use_default_click_check_button, 1, 3, row, row + 1, FILL);
114 _use_default_click_check_button.signal_toggled().connect (
115 sigc::mem_fun (*this, &ClickOptions::use_default_click_toggled));
118 l = manage (left_aligned_label (_("Audio file:")));
119 t->attach (*l, 1, 2, row, row + 1, FILL);
120 t->attach (_click_path_entry, 2, 3, row, row + 1, FILL);
121 _click_browse_button.signal_clicked ().connect (
122 sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
123 t->attach (_click_browse_button, 3, 4, row, row + 1, FILL);
126 l = manage (left_aligned_label (_("Emphasis audio file:")));
127 t->attach (*l, 1, 2, row, row + 1, FILL);
128 t->attach (_click_emphasis_path_entry, 2, 3, row, row + 1, FILL);
129 _click_emphasis_browse_button.signal_clicked ().connect (
130 sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
131 t->attach (_click_emphasis_browse_button, 3, 4, row, row + 1, FILL);
134 _click_fader = new FaderOption (
137 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
138 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
141 _click_fader->add_to_page (this);
142 _click_fader->set_state_from_config ();
144 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
145 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
147 if (_rc_config->get_click_sound ().empty() &&
148 _rc_config->get_click_emphasis_sound().empty()) {
149 _use_default_click_check_button.set_active (true);
150 _use_emphasis_on_click_check_button.set_active (_rc_config->get_use_click_emphasis ());
153 _use_default_click_check_button.set_active (false);
154 _use_emphasis_on_click_check_button.set_active (false);
158 void parameter_changed (string const & p)
160 if (p == "click-sound") {
161 _click_path_entry.set_text (_rc_config->get_click_sound());
162 } else if (p == "click-emphasis-sound") {
163 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
164 } else if (p == "use-click-emphasis") {
165 bool x = _rc_config->get_use_click_emphasis ();
166 _use_emphasis_on_click_check_button.set_active (x);
167 } else if (p == "click-gain") {
168 _click_fader->set_state_from_config ();
172 void set_state_from_config ()
174 parameter_changed ("click-sound");
175 parameter_changed ("click-emphasis-sound");
176 parameter_changed ("use-click-emphasis");
181 void click_browse_clicked ()
183 SoundFileChooser sfdb (_("Choose Click"));
188 if (sfdb.run () == RESPONSE_OK) {
189 click_chosen (sfdb.get_filename());
193 void click_chosen (string const & path)
195 _click_path_entry.set_text (path);
196 _rc_config->set_click_sound (path);
199 void click_changed ()
201 click_chosen (_click_path_entry.get_text ());
204 void click_emphasis_browse_clicked ()
206 SoundFileChooser sfdb (_("Choose Click Emphasis"));
211 if (sfdb.run () == RESPONSE_OK) {
212 click_emphasis_chosen (sfdb.get_filename());
216 void click_emphasis_chosen (string const & path)
218 _click_emphasis_path_entry.set_text (path);
219 _rc_config->set_click_emphasis_sound (path);
222 void click_emphasis_changed ()
224 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
227 void use_default_click_toggled ()
229 if (_use_default_click_check_button.get_active ()) {
230 _rc_config->set_click_sound ("");
231 _rc_config->set_click_emphasis_sound ("");
232 _click_path_entry.set_sensitive (false);
233 _click_emphasis_path_entry.set_sensitive (false);
234 _click_browse_button.set_sensitive (false);
235 _click_emphasis_browse_button.set_sensitive (false);
237 _click_path_entry.set_sensitive (true);
238 _click_emphasis_path_entry.set_sensitive (true);
239 _click_browse_button.set_sensitive (true);
240 _click_emphasis_browse_button.set_sensitive (true);
244 void use_emphasis_on_click_toggled ()
246 if (_use_emphasis_on_click_check_button.get_active ()) {
247 _rc_config->set_use_click_emphasis(true);
249 _rc_config->set_use_click_emphasis(false);
253 RCConfiguration* _rc_config;
254 CheckButton _use_default_click_check_button;
255 CheckButton _use_emphasis_on_click_check_button;
256 Entry _click_path_entry;
257 Entry _click_emphasis_path_entry;
258 Button _click_browse_button;
259 Button _click_emphasis_browse_button;
260 FaderOption* _click_fader;
263 class UndoOptions : public OptionEditorComponent
266 UndoOptions (RCConfiguration* c) :
268 _limit_undo_button (_("Limit undo history to")),
269 _save_undo_button (_("Save undo history of"))
271 // TODO get rid of GTK -> use OptionEditor SpinOption
272 _limit_undo_spin.set_range (0, 512);
273 _limit_undo_spin.set_increments (1, 10);
275 _save_undo_spin.set_range (0, 512);
276 _save_undo_spin.set_increments (1, 10);
278 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
279 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
280 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
281 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
284 void parameter_changed (string const & p)
286 if (p == "history-depth") {
287 int32_t const d = _rc_config->get_history_depth();
288 _limit_undo_button.set_active (d != 0);
289 _limit_undo_spin.set_sensitive (d != 0);
290 _limit_undo_spin.set_value (d);
291 } else if (p == "save-history") {
292 bool const x = _rc_config->get_save_history ();
293 _save_undo_button.set_active (x);
294 _save_undo_spin.set_sensitive (x);
295 } else if (p == "save-history-depth") {
296 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
300 void set_state_from_config ()
302 parameter_changed ("save-history");
303 parameter_changed ("history-depth");
304 parameter_changed ("save-history-depth");
307 void limit_undo_toggled ()
309 bool const x = _limit_undo_button.get_active ();
310 _limit_undo_spin.set_sensitive (x);
311 int32_t const n = x ? 16 : 0;
312 _limit_undo_spin.set_value (n);
313 _rc_config->set_history_depth (n);
316 void limit_undo_changed ()
318 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
321 void save_undo_toggled ()
323 bool const x = _save_undo_button.get_active ();
324 _rc_config->set_save_history (x);
327 void save_undo_changed ()
329 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
332 void add_to_page (OptionEditorPage* p)
334 int const n = p->table.property_n_rows();
335 Table* t = & p->table;
337 t->resize (n + 2, 3);
339 Label* l = manage (left_aligned_label (_("commands")));
340 HBox* box = manage (new HBox());
341 box->set_spacing (4);
342 box->pack_start (_limit_undo_spin, false, false);
343 box->pack_start (*l, true, true);
344 t->attach (_limit_undo_button, 1, 2, n, n +1, FILL);
345 t->attach (*box, 2, 3, n, n + 1, FILL | EXPAND);
347 l = manage (left_aligned_label (_("commands")));
348 box = manage (new HBox());
349 box->set_spacing (4);
350 box->pack_start (_save_undo_spin, false, false);
351 box->pack_start (*l, true, true);
352 t->attach (_save_undo_button, 1, 2, n + 1, n + 2, FILL);
353 t->attach (*box, 2, 3, n + 1, n + 2, FILL | EXPAND);
356 Gtk::Widget& tip_widget() {
357 return _limit_undo_button; // unused
361 RCConfiguration* _rc_config;
362 CheckButton _limit_undo_button;
363 SpinButton _limit_undo_spin;
364 CheckButton _save_undo_button;
365 SpinButton _save_undo_spin;
369 static const struct {
381 { "Key|Shift", GDK_SHIFT_MASK },
382 { "Command", GDK_MOD2_MASK },
383 { "Control", GDK_CONTROL_MASK },
384 { "Option", GDK_MOD1_MASK },
385 { "Command-Shift", GDK_MOD2_MASK|GDK_SHIFT_MASK },
386 { "Command-Option", GDK_MOD2_MASK|GDK_MOD1_MASK },
387 { "Command-Control", GDK_MOD2_MASK|GDK_CONTROL_MASK },
388 { "Command-Option-Control", GDK_MOD2_MASK|GDK_MOD1_MASK|GDK_CONTROL_MASK },
389 { "Option-Control", GDK_MOD1_MASK|GDK_CONTROL_MASK },
390 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
391 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
392 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_MOD2_MASK },
395 { "Key|Shift", GDK_SHIFT_MASK },
396 { "Control", GDK_CONTROL_MASK },
397 { "Alt", GDK_MOD1_MASK },
398 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
399 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
400 { "Control-Windows", GDK_CONTROL_MASK|GDK_MOD4_MASK },
401 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
402 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
403 { "Alt-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
404 { "Alt-Shift-Windows", GDK_MOD1_MASK|GDK_SHIFT_MASK|GDK_MOD4_MASK },
405 { "Mod2", GDK_MOD2_MASK },
406 { "Mod3", GDK_MOD3_MASK },
407 { "Windows", GDK_MOD4_MASK },
408 { "Mod5", GDK_MOD5_MASK },
414 class KeyboardOptions : public OptionEditorMiniPage
418 : _delete_button_adjustment (3, 1, 12)
419 , _delete_button_spin (_delete_button_adjustment)
420 , _edit_button_adjustment (3, 1, 5)
421 , _edit_button_spin (_edit_button_adjustment)
422 , _insert_note_button_adjustment (3, 1, 5)
423 , _insert_note_button_spin (_insert_note_button_adjustment)
425 // TODO get rid of GTK -> use OptionEditor Widgets
427 const std::string restart_msg = _("\nChanges to this setting will only persist after your project has been saved.");
428 /* internationalize and prepare for use with combos */
431 for (int i = 0; modifiers[i].name; ++i) {
432 dumb.push_back (S_(modifiers[i].name));
435 set_popdown_strings (_edit_modifier_combo, dumb);
436 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
437 Gtkmm2ext::UI::instance()->set_tip (_edit_modifier_combo,
438 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
445 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
446 l->set_name ("OptionsLabel");
450 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
451 strs.push_back (bf->first);
454 set_popdown_strings (_keyboard_layout_selector, strs);
455 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
456 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
458 t->attach (*l, col + 1, col + 2, row, row + 1, FILL, FILL);
459 t->attach (_keyboard_layout_selector, col + 2, col + 3, row, row + 1, FILL | EXPAND, FILL);
464 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Clicking:"))));
465 l->set_name ("OptionEditorHeading");
466 l->set_use_markup (true);
467 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
472 l = manage (left_aligned_label (_("Edit using:")));
473 l->set_name ("OptionsLabel");
475 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
476 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
478 l = manage (new Label (_("+ button")));
479 l->set_name ("OptionsLabel");
481 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
482 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, SHRINK , FILL);
484 _edit_button_spin.set_name ("OptionsEntry");
485 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
490 set_popdown_strings (_delete_modifier_combo, dumb);
491 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
492 Gtkmm2ext::UI::instance()->set_tip (_delete_modifier_combo,
493 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
495 l = manage (left_aligned_label (_("Delete using:")));
496 l->set_name ("OptionsLabel");
498 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
499 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
501 l = manage (new Label (_("+ button")));
502 l->set_name ("OptionsLabel");
504 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
505 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, SHRINK, FILL);
507 _delete_button_spin.set_name ("OptionsEntry");
508 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
513 set_popdown_strings (_insert_note_modifier_combo, dumb);
514 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
515 Gtkmm2ext::UI::instance()->set_tip (_insert_note_modifier_combo,
516 (string_compose (_("<b>Recommended Setting: %1 + button 1 (left mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
518 l = manage (left_aligned_label (_("Insert note using:")));
519 l->set_name ("OptionsLabel");
521 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
522 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
524 l = manage (new Label (_("+ button")));
525 l->set_name ("OptionsLabel");
527 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
528 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, SHRINK, FILL);
530 _insert_note_button_spin.set_name ("OptionsEntry");
531 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
535 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Beginning a Drag:"))));
536 l->set_name ("OptionEditorHeading");
537 l->set_use_markup (true);
538 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
544 set_popdown_strings (_copy_modifier_combo, dumb);
545 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
546 Gtkmm2ext::UI::instance()->set_tip (_copy_modifier_combo,
547 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
549 Keyboard::secondary_modifier_name (),
551 Keyboard::primary_modifier_name (),
555 l = manage (left_aligned_label (_("Copy items using:")));
556 l->set_name ("OptionsLabel");
558 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
559 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
564 /* constraint modifier */
565 set_popdown_strings (_constraint_modifier_combo, dumb);
566 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
567 Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo,
568 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
570 Keyboard::primary_modifier_name (),
572 Keyboard::tertiary_modifier_name (),
576 l = manage (left_aligned_label (_("Constrain drag using:")));
577 l->set_name ("OptionsLabel");
579 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
580 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
586 set_popdown_strings (_push_points_combo, dumb);
587 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
589 std::string mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
590 Gtkmm2ext::UI::instance()->set_tip (_push_points_combo,
591 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
593 l = manage (left_aligned_label (_("Push points using:")));
594 l->set_name ("OptionsLabel");
596 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
597 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
601 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Beginning a Trim:"))));
602 l->set_name ("OptionEditorHeading");
603 l->set_use_markup (true);
604 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
610 set_popdown_strings (_trim_contents_combo, dumb);
611 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
612 Gtkmm2ext::UI::instance()->set_tip (_trim_contents_combo,
613 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
615 l = manage (left_aligned_label (_("Trim contents using:")));
616 l->set_name ("OptionsLabel");
618 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
619 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
625 set_popdown_strings (_trim_anchored_combo, dumb);
626 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
628 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::tertiary_modifier_name ());
629 Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo,
630 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
632 l = manage (left_aligned_label (_("Anchored trim using:")));
633 l->set_name ("OptionsLabel");
635 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
637 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
642 /* jump trim disabled for now
643 set_popdown_strings (_trim_jump_combo, dumb);
644 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
646 l = manage (left_aligned_label (_("Jump after trim using:")));
647 l->set_name ("OptionsLabel");
649 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
651 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
657 /* note resize relative */
658 set_popdown_strings (_note_size_relative_combo, dumb);
659 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
660 Gtkmm2ext::UI::instance()->set_tip (_note_size_relative_combo,
661 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg))); // XXX 2ndary
663 l = manage (left_aligned_label (_("Resize notes relatively using:")));
664 l->set_name ("OptionsLabel");
666 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
668 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
672 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Dragging:"))));
673 l->set_name ("OptionEditorHeading");
674 l->set_use_markup (true);
675 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
681 set_popdown_strings (_snap_modifier_combo, dumb);
682 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
684 mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ());
686 mod_str = Keyboard::secondary_modifier_name();
688 Gtkmm2ext::UI::instance()->set_tip (_snap_modifier_combo,
689 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
691 l = manage (left_aligned_label (_("Ignore snap using:")));
692 l->set_name ("OptionsLabel");
694 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
695 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
701 set_popdown_strings (_snap_delta_combo, dumb);
702 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
704 mod_str = Keyboard::level4_modifier_name ();
706 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::level4_modifier_name ());
708 Gtkmm2ext::UI::instance()->set_tip (_snap_delta_combo,
709 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
711 l = manage (left_aligned_label (_("Snap relatively using:")));
712 l->set_name ("OptionsLabel");
714 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
715 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
719 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Trimming:"))));
720 l->set_name ("OptionEditorHeading");
721 l->set_use_markup (true);
722 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
728 set_popdown_strings (_trim_overlap_combo, dumb);
729 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
731 Gtkmm2ext::UI::instance()->set_tip (_trim_overlap_combo,
732 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
734 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
735 l->set_name ("OptionsLabel");
737 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
738 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
742 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Dragging Control Points:"))));
743 l->set_name ("OptionEditorHeading");
744 l->set_use_markup (true);
745 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
751 set_popdown_strings (_fine_adjust_combo, dumb);
752 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
754 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::secondary_modifier_name ()); // XXX just 2ndary ?!
755 Gtkmm2ext::UI::instance()->set_tip (_fine_adjust_combo,
756 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
758 l = manage (left_aligned_label (_("Fine adjust using:")));
759 l->set_name ("OptionsLabel");
761 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
762 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
764 OptionEditorHeading* h = new OptionEditorHeading (_("Reset"));
765 h->add_to_page (this);
767 RcActionButton* rb = new RcActionButton (_("Reset to recommended defaults"),
768 sigc::mem_fun (*this, &KeyboardOptions::reset_to_defaults));
769 rb->add_to_page (this);
771 set_state_from_config ();
774 void parameter_changed (string const &)
776 /* XXX: these aren't really config options... */
779 void set_state_from_config ()
781 _delete_button_adjustment.set_value (Keyboard::delete_button());
782 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
783 _edit_button_adjustment.set_value (Keyboard::edit_button());
785 for (int x = 0; modifiers[x].name; ++x) {
786 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
787 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
789 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
790 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
792 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
793 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
795 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
796 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
798 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
799 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
801 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
802 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
804 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
805 _push_points_combo.set_active_text (S_(modifiers[x].name));
807 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
808 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
810 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
811 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
814 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
815 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
818 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
819 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
821 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
822 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
824 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
825 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
827 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
828 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
833 void add_to_page (OptionEditorPage* p)
835 int const n = p->table.property_n_rows();
836 p->table.resize (n + 1, 3);
837 p->table.attach (box, 1, 3, n, n + 1, FILL | EXPAND, SHRINK, 0, 0);
842 void bindings_changed ()
844 string const txt = _keyboard_layout_selector.get_active_text();
846 /* XXX: config...? for all this keyboard stuff */
848 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
849 if (txt == i->first) {
850 if (Keyboard::load_keybindings (i->second)) {
851 Keyboard::save_keybindings ();
857 void edit_modifier_chosen ()
859 string const txt = _edit_modifier_combo.get_active_text();
861 for (int i = 0; modifiers[i].name; ++i) {
862 if (txt == S_(modifiers[i].name)) {
863 Keyboard::set_edit_modifier (modifiers[i].modifier);
869 void delete_modifier_chosen ()
871 string const txt = _delete_modifier_combo.get_active_text();
873 for (int i = 0; modifiers[i].name; ++i) {
874 if (txt == S_(modifiers[i].name)) {
875 Keyboard::set_delete_modifier (modifiers[i].modifier);
881 void copy_modifier_chosen ()
883 string const txt = _copy_modifier_combo.get_active_text();
885 for (int i = 0; modifiers[i].name; ++i) {
886 if (txt == S_(modifiers[i].name)) {
887 Keyboard::set_copy_modifier (modifiers[i].modifier);
893 void insert_note_modifier_chosen ()
895 string const txt = _insert_note_modifier_combo.get_active_text();
897 for (int i = 0; modifiers[i].name; ++i) {
898 if (txt == S_(modifiers[i].name)) {
899 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
905 void snap_modifier_chosen ()
907 string const txt = _snap_modifier_combo.get_active_text();
909 for (int i = 0; modifiers[i].name; ++i) {
910 if (txt == S_(modifiers[i].name)) {
911 Keyboard::set_snap_modifier (modifiers[i].modifier);
917 void snap_delta_modifier_chosen ()
919 string const txt = _snap_delta_combo.get_active_text();
921 for (int i = 0; modifiers[i].name; ++i) {
922 if (txt == S_(modifiers[i].name)) {
923 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
929 void constraint_modifier_chosen ()
931 string const txt = _constraint_modifier_combo.get_active_text();
933 for (int i = 0; modifiers[i].name; ++i) {
934 if (txt == S_(modifiers[i].name)) {
935 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
941 void trim_contents_modifier_chosen ()
943 string const txt = _trim_contents_combo.get_active_text();
945 for (int i = 0; modifiers[i].name; ++i) {
946 if (txt == S_(modifiers[i].name)) {
947 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
953 void trim_overlap_modifier_chosen ()
955 string const txt = _trim_overlap_combo.get_active_text();
957 for (int i = 0; modifiers[i].name; ++i) {
958 if (txt == S_(modifiers[i].name)) {
959 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
965 void trim_anchored_modifier_chosen ()
967 string const txt = _trim_anchored_combo.get_active_text();
969 for (int i = 0; modifiers[i].name; ++i) {
970 if (txt == S_(modifiers[i].name)) {
971 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
977 void fine_adjust_modifier_chosen ()
979 string const txt = _fine_adjust_combo.get_active_text();
981 for (int i = 0; modifiers[i].name; ++i) {
982 if (txt == S_(modifiers[i].name)) {
983 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
989 void push_points_modifier_chosen ()
991 string const txt = _push_points_combo.get_active_text();
993 for (int i = 0; modifiers[i].name; ++i) {
994 if (txt == S_(modifiers[i].name)) {
995 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
1001 void note_size_relative_modifier_chosen ()
1003 string const txt = _note_size_relative_combo.get_active_text();
1005 for (int i = 0; modifiers[i].name; ++i) {
1006 if (txt == S_(modifiers[i].name)) {
1007 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
1013 void delete_button_changed ()
1015 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
1018 void edit_button_changed ()
1020 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
1023 void insert_note_button_changed ()
1025 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
1028 void reset_to_defaults ()
1031 Keyboard::set_edit_modifier (Keyboard::PrimaryModifier);
1032 Keyboard::set_edit_button (3);
1033 Keyboard::set_delete_modifier (Keyboard::TertiaryModifier);
1034 Keyboard::set_delete_button (3);
1035 Keyboard::set_insert_note_modifier (Keyboard::PrimaryModifier);
1036 Keyboard::set_insert_note_button (1);
1038 /* when beginning a drag */
1040 Keyboard::set_copy_modifier (Keyboard::SecondaryModifier);
1042 Keyboard::set_copy_modifier (Keyboard::PrimaryModifier);
1046 ArdourKeyboard::set_constraint_modifier (Keyboard::PrimaryModifier);
1048 ArdourKeyboard::set_constraint_modifier (Keyboard::TertiaryModifier);
1050 ArdourKeyboard::set_push_points_modifier (Keyboard::PrimaryModifier | Keyboard::Level4Modifier);
1052 /* when beginning a trim */
1053 ArdourKeyboard::set_trim_contents_modifier (Keyboard::PrimaryModifier);
1054 ArdourKeyboard::set_trim_anchored_modifier (Keyboard::PrimaryModifier | Keyboard::TertiaryModifier);
1055 ArdourKeyboard::set_note_size_relative_modifier (Keyboard::TertiaryModifier); // XXX better: 2ndary
1057 /* while dragging */
1059 Keyboard::set_snap_modifier (Keyboard::TertiaryModifier);
1061 Keyboard::set_snap_modifier (Keyboard::SecondaryModifier);
1064 Keyboard::set_snap_delta_modifier (Keyboard::Level4Modifier);
1066 Keyboard::set_snap_delta_modifier (Keyboard::SecondaryModifier | Keyboard::Level4Modifier);
1069 /* while trimming */
1070 ArdourKeyboard::set_trim_overlap_modifier (Keyboard::TertiaryModifier);
1072 /* while dragging ctrl points */
1073 ArdourKeyboard::set_fine_adjust_modifier (/*Keyboard::PrimaryModifier | */Keyboard::SecondaryModifier); // XXX
1075 set_state_from_config ();
1078 ComboBoxText _keyboard_layout_selector;
1079 ComboBoxText _edit_modifier_combo;
1080 ComboBoxText _delete_modifier_combo;
1081 ComboBoxText _copy_modifier_combo;
1082 ComboBoxText _insert_note_modifier_combo;
1083 ComboBoxText _snap_modifier_combo;
1084 ComboBoxText _snap_delta_combo;
1085 ComboBoxText _constraint_modifier_combo;
1086 ComboBoxText _trim_contents_combo;
1087 ComboBoxText _trim_overlap_combo;
1088 ComboBoxText _trim_anchored_combo;
1089 ComboBoxText _trim_jump_combo;
1090 ComboBoxText _fine_adjust_combo;
1091 ComboBoxText _push_points_combo;
1092 ComboBoxText _note_size_relative_combo;
1093 Adjustment _delete_button_adjustment;
1094 SpinButton _delete_button_spin;
1095 Adjustment _edit_button_adjustment;
1096 SpinButton _edit_button_spin;
1097 Adjustment _insert_note_button_adjustment;
1098 SpinButton _insert_note_button_spin;
1102 class FontScalingOptions : public HSliderOption
1105 FontScalingOptions ()
1106 : HSliderOption ("font-scale", _("GUI and Font scaling"),
1107 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_font_scale),
1108 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_font_scale),
1112 const std::string dflt = _("100%");
1113 const std::string empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
1115 _hscale.set_name("FontScaleSlider");
1116 _hscale.set_draw_value(false);
1117 _hscale.add_mark(50, Gtk::POS_TOP, empty);
1118 _hscale.add_mark(60, Gtk::POS_TOP, empty);
1119 _hscale.add_mark(70, Gtk::POS_TOP, empty);
1120 _hscale.add_mark(80, Gtk::POS_TOP, empty);
1121 _hscale.add_mark(90, Gtk::POS_TOP, empty);
1122 _hscale.add_mark(100, Gtk::POS_TOP, dflt);
1123 _hscale.add_mark(125, Gtk::POS_TOP, empty);
1124 _hscale.add_mark(150, Gtk::POS_TOP, empty);
1125 _hscale.add_mark(175, Gtk::POS_TOP, empty);
1126 _hscale.add_mark(200, Gtk::POS_TOP, empty);
1127 _hscale.add_mark(250, Gtk::POS_TOP, empty);
1129 set_note (_("Adjusting the scale requires an application restart to re-layout."));
1134 HSliderOption::changed ();
1135 /* XXX: should be triggered from the parameter changed signal */
1136 UIConfiguration::instance().reset_dpi ();
1140 class VstTimeOutSliderOption : public HSliderOption
1143 VstTimeOutSliderOption (RCConfiguration* c)
1144 : HSliderOption ("vst-scan-timeout", _("Scan Time Out"),
1145 sigc::mem_fun (*c, &RCConfiguration::get_vst_scan_timeout),
1146 sigc::mem_fun (*c, &RCConfiguration::set_vst_scan_timeout),
1149 _label.set_alignment (1.0, 0.5); // match buttons below
1150 _hscale.set_digits (0);
1151 _hscale.set_draw_value(false);
1152 _hscale.add_mark( 0, Gtk::POS_TOP, _("\u221e")); // infinity
1153 _hscale.add_mark( 300, Gtk::POS_TOP, _("30 sec"));
1154 _hscale.add_mark( 600, Gtk::POS_TOP, _("1 min"));
1155 _hscale.add_mark(1200, Gtk::POS_TOP, _("2 mins"));
1156 _hscale.add_mark(1800, Gtk::POS_TOP, _("3 mins"));
1157 _hscale.add_mark(2400, Gtk::POS_TOP, _("4 mins"));
1158 _hscale.add_mark(3000, Gtk::POS_TOP, _("5 mins"));
1160 Gtkmm2ext::UI::instance()->set_tip(_hscale,
1161 _("Specify the default timeout for plugin instantiation. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1165 class ClipLevelOptions : public HSliderOption
1169 : HSliderOption (X_("waveform-clip-level"),
1170 _("Waveform Clip Level (dBFS):"),
1171 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_clip_level),
1172 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_clip_level),
1173 -50.0, -0.5, 0.1, 1.0, /* units of dB */
1179 void parameter_changed (string const & p)
1181 if (p == "waveform-clip-level") {
1182 ArdourWaveView::WaveView::set_clip_level (UIConfiguration::instance().get_waveform_clip_level());
1184 if (p == "show-waveform-clipping") {
1185 _hscale.set_sensitive (UIConfiguration::instance().get_show_waveform_clipping ());
1189 void set_state_from_config ()
1191 parameter_changed ("waveform-clip-level");
1192 parameter_changed ("show-waveform-clipping");
1196 class BufferingOptions : public OptionEditorComponent
1199 BufferingOptions (RCConfiguration* c)
1201 , _label (_("Preset:"))
1202 , _playback ("playback-buffer-seconds", _("Playback (seconds of buffering)"),
1203 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_playback_buffer_seconds),
1204 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_playback_buffer_seconds),
1206 , _capture ("capture-buffer-seconds", _("Recording (seconds of buffering)"),
1207 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_capture_buffer_seconds),
1208 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_capture_buffer_seconds),
1211 // TODO use ComboOption
1212 vector<string> presets;
1214 /* these must match the order of the enums for BufferingPreset */
1215 presets.push_back (_("Small sessions (4-16 tracks)"));
1216 presets.push_back (_("Medium sessions (16-64 tracks)"));
1217 presets.push_back (_("Large sessions (64+ tracks)"));
1218 presets.push_back (_("Custom (set by sliders below)"));
1220 set_popdown_strings (_buffering_presets_combo, presets);
1221 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1223 _label.set_name ("OptionsLabel");
1224 _label.set_alignment (0, 0.5);
1228 add_to_page (OptionEditorPage* p)
1230 add_widgets_to_page (p, &_label, &_buffering_presets_combo);
1231 _playback.add_to_page (p);
1232 _capture.add_to_page (p);
1235 void parameter_changed (string const & p)
1237 if (p == "buffering-preset") {
1238 switch (_rc_config->get_buffering_preset()) {
1240 _playback.set_sensitive (false);
1241 _capture.set_sensitive (false);
1242 _buffering_presets_combo.set_active (0);
1245 _playback.set_sensitive (false);
1246 _capture.set_sensitive (false);
1247 _buffering_presets_combo.set_active (1);
1250 _playback.set_sensitive (false);
1251 _capture.set_sensitive (false);
1252 _buffering_presets_combo.set_active (2);
1255 _playback.set_sensitive (true);
1256 _capture.set_sensitive (true);
1257 _buffering_presets_combo.set_active (3);
1261 _playback.parameter_changed (p);
1262 _capture.parameter_changed (p);
1265 void set_state_from_config ()
1267 parameter_changed ("buffering-preset");
1268 _playback.set_state_from_config();
1269 _capture.set_state_from_config();
1272 Gtk::Widget& tip_widget() { return _buffering_presets_combo; }
1276 void preset_changed ()
1278 int index = _buffering_presets_combo.get_active_row_number ();
1284 _rc_config->set_buffering_preset (Small);
1287 _rc_config->set_buffering_preset (Medium);
1290 _rc_config->set_buffering_preset (Large);
1293 _rc_config->set_buffering_preset (Custom);
1296 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1301 RCConfiguration* _rc_config;
1303 HSliderOption _playback;
1304 HSliderOption _capture;
1305 ComboBoxText _buffering_presets_combo;
1308 class ControlSurfacesOptions : public OptionEditorMiniPage
1311 ControlSurfacesOptions ()
1312 : _ignore_view_change (0)
1314 _store = ListStore::create (_model);
1315 _view.set_model (_store);
1316 _view.append_column_editable (_("Enable"), _model.enabled);
1317 _view.append_column (_("Control Surface Protocol"), _model.name);
1318 _view.get_column(1)->set_resizable (true);
1319 _view.get_column(1)->set_expand (true);
1321 Gtk::HBox* edit_box = manage (new Gtk::HBox);
1322 edit_box->set_spacing(3);
1325 Label* label = manage (new Label);
1326 label->set_text (_("Edit the settings for selected protocol (it must be ENABLED first):"));
1327 edit_box->pack_start (*label, false, false);
1330 edit_button = manage (new Button(_("Show Protocol Settings")));
1331 edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
1332 edit_box->pack_start (*edit_button, true, true);
1333 edit_button->set_sensitive (false);
1334 edit_button->show ();
1336 int const n = table.property_n_rows();
1337 table.resize (n + 2, 3);
1338 table.attach (_view, 0, 3, n, n + 1);
1339 table.attach (*edit_box, 0, 3, n + 1, n + 2);
1341 ControlProtocolManager& m = ControlProtocolManager::instance ();
1342 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1343 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1345 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1346 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1347 _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
1350 void parameter_changed (std::string const &)
1355 void set_state_from_config ()
1359 ControlProtocolManager& m = ControlProtocolManager::instance ();
1360 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1362 if (!(*i)->mandatory) {
1363 TreeModel::Row r = *_store->append ();
1364 r[_model.name] = (*i)->name;
1365 r[_model.enabled] = 0 != (*i)->protocol;
1366 r[_model.protocol_info] = *i;
1373 void protocol_status_changed (ControlProtocolInfo* cpi) {
1375 TreeModel::Children rows = _store->children();
1377 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1378 string n = ((*x)[_model.name]);
1380 if ((*x)[_model.protocol_info] == cpi) {
1381 _ignore_view_change++;
1382 (*x)[_model.enabled] = 0 != cpi->protocol;
1383 _ignore_view_change--;
1384 selection_changed (); // update sensitivity
1390 void selection_changed ()
1392 //enable the Edit button when a row is selected for editing
1393 TreeModel::Row row = *(_view.get_selection()->get_selected());
1394 if (row && row[_model.enabled]) {
1395 ControlProtocolInfo* cpi = row[_model.protocol_info];
1396 edit_button->set_sensitive (cpi && cpi->protocol && cpi->protocol->has_editor ());
1398 edit_button->set_sensitive (false);
1402 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1404 TreeModel::Row r = *i;
1406 if (_ignore_view_change) {
1410 ControlProtocolInfo* cpi = r[_model.protocol_info];
1415 bool const was_enabled = (cpi->protocol != 0);
1416 bool const is_enabled = r[_model.enabled];
1419 if (was_enabled != is_enabled) {
1422 ControlProtocolManager::instance().activate (*cpi);
1424 ControlProtocolManager::instance().deactivate (*cpi);
1428 selection_changed ();
1431 void edit_btn_clicked ()
1434 ControlProtocolInfo* cpi;
1437 row = *(_view.get_selection()->get_selected());
1438 if (!row[_model.enabled]) {
1441 cpi = row[_model.protocol_info];
1442 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1445 Box* box = (Box*) cpi->protocol->get_gui ();
1449 if (box->get_parent()) {
1450 static_cast<ArdourWindow*>(box->get_parent())->present();
1453 WindowTitle title (Glib::get_application_name());
1454 title += row[_model.name];
1455 title += _("Configuration");
1456 /* once created, the window is managed by the surface itself (as ->get_parent())
1457 * Surface's tear_down_gui() is called on session close, when de-activating
1458 * or re-initializing a surface.
1459 * tear_down_gui() hides an deletes the Window if it exists.
1461 ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
1462 win->set_title (_("Control Protocol Settings"));
1468 void edit_clicked (GdkEventButton* ev)
1470 if (ev->type != GDK_2BUTTON_PRESS) {
1477 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1481 ControlSurfacesModelColumns ()
1485 add (protocol_info);
1488 TreeModelColumn<string> name;
1489 TreeModelColumn<bool> enabled;
1490 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1493 Glib::RefPtr<ListStore> _store;
1494 ControlSurfacesModelColumns _model;
1496 PBD::ScopedConnection protocol_status_connection;
1497 uint32_t _ignore_view_change;
1498 Gtk::Button* edit_button;
1501 class VideoTimelineOptions : public OptionEditorMiniPage
1504 VideoTimelineOptions (RCConfiguration* c)
1506 , _show_video_export_info_button (_("Show Video Export Info before export"))
1507 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1508 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1509 , _xjadeo_browse_button (_("Browse..."))
1512 int n = table.property_n_rows();
1514 t->attach (_show_video_export_info_button, 1, 4, n, n + 1);
1515 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1516 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1517 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1520 t->attach (_show_video_server_dialog_button, 1, 4, n, n + 1);
1521 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1522 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1523 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1526 t->attach (_video_advanced_setup_button, 1, 4, n, n + 1, FILL);
1527 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1528 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1529 _("<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."));
1532 Label* l = manage (new Label (_("Video Server URL:")));
1533 l->set_alignment (0, 0.5);
1534 t->attach (*l, 1, 2, n, n + 1, FILL);
1535 t->attach (_video_server_url_entry, 2, 4, n, n + 1, FILL);
1536 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1537 _("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"));
1540 l = manage (new Label (_("Video Folder:")));
1541 l->set_alignment (0, 0.5);
1542 t->attach (*l, 1, 2, n, n + 1, FILL);
1543 t->attach (_video_server_docroot_entry, 2, 4, n, n + 1);
1544 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1545 _("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."));
1548 l = manage (new Label (""));
1549 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1552 l = manage (new Label (string_compose ("<b>%1</b>", _("Video Monitor"))));
1553 l->set_use_markup (true);
1554 l->set_alignment (0, 0.5);
1555 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1558 l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"),
1561 #elif defined PLATFORM_WINDOWS
1567 l->set_alignment (0, 0.5);
1568 t->attach (*l, 1, 4, n, n + 1, FILL);
1571 t->attach (_custom_xjadeo_path, 2, 3, n, n + 1, EXPAND|FILL);
1572 Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart."));
1573 t->attach (_xjadeo_browse_button, 3, 4, n, n + 1, FILL);
1575 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1576 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1577 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1578 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1579 _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed));
1580 _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked));
1583 void server_url_changed ()
1585 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1588 void server_docroot_changed ()
1590 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1593 void show_video_export_info_toggled ()
1595 bool const x = _show_video_export_info_button.get_active ();
1596 _rc_config->set_show_video_export_info (x);
1599 void show_video_server_dialog_toggled ()
1601 bool const x = _show_video_server_dialog_button.get_active ();
1602 _rc_config->set_show_video_server_dialog (x);
1605 void video_advanced_setup_toggled ()
1607 bool const x = _video_advanced_setup_button.get_active ();
1608 _rc_config->set_video_advanced_setup(x);
1611 void custom_xjadeo_path_changed ()
1613 _rc_config->set_xjadeo_binary (_custom_xjadeo_path.get_text());
1616 void xjadeo_browse_clicked ()
1618 Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN);
1619 dialog.set_filename (_rc_config->get_xjadeo_binary());
1620 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1621 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1622 if (dialog.run () == Gtk::RESPONSE_OK) {
1623 const std::string& filename = dialog.get_filename();
1624 if (!filename.empty() && (
1626 Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) ||
1628 Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)
1630 _rc_config->set_xjadeo_binary (filename);
1635 void parameter_changed (string const & p)
1637 if (p == "video-server-url") {
1638 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1639 } else if (p == "video-server-docroot") {
1640 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1641 } else if (p == "show-video-export-info") {
1642 bool const x = _rc_config->get_show_video_export_info();
1643 _show_video_export_info_button.set_active (x);
1644 } else if (p == "show-video-server-dialog") {
1645 bool const x = _rc_config->get_show_video_server_dialog();
1646 _show_video_server_dialog_button.set_active (x);
1647 } else if (p == "video-advanced-setup") {
1648 bool const x = _rc_config->get_video_advanced_setup();
1649 _video_advanced_setup_button.set_active(x);
1650 _video_server_docroot_entry.set_sensitive(x);
1651 _video_server_url_entry.set_sensitive(x);
1652 } else if (p == "xjadeo-binary") {
1653 _custom_xjadeo_path.set_text (_rc_config->get_xjadeo_binary());
1657 void set_state_from_config ()
1659 parameter_changed ("video-server-url");
1660 parameter_changed ("video-server-docroot");
1661 parameter_changed ("video-monitor-setup-dialog");
1662 parameter_changed ("show-video-export-info");
1663 parameter_changed ("show-video-server-dialog");
1664 parameter_changed ("video-advanced-setup");
1665 parameter_changed ("xjadeo-binary");
1669 RCConfiguration* _rc_config;
1670 Entry _video_server_url_entry;
1671 Entry _video_server_docroot_entry;
1672 Entry _custom_xjadeo_path;
1673 CheckButton _show_video_export_info_button;
1674 CheckButton _show_video_server_dialog_button;
1675 CheckButton _video_advanced_setup_button;
1676 Button _xjadeo_browse_button;
1679 class ColumVisibilityOption : public Option
1682 ColumVisibilityOption (string id, string name, uint32_t n_col, sigc::slot<uint32_t> get, sigc::slot<bool, uint32_t> set)
1689 cb = (CheckButton**) malloc (sizeof (CheckButton*) * n_col);
1690 for (uint32_t i = 0; i < n_col; ++i) {
1691 CheckButton* col = manage (new CheckButton (string_compose (_("Column %1"), i + 1)));
1692 col->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ColumVisibilityOption::column_toggled), i));
1693 _hbox.pack_start (*col);
1696 parameter_changed (id);
1699 ~ColumVisibilityOption () {
1703 Gtk::Widget& tip_widget() { return _hbox; }
1705 void set_state_from_config ()
1707 uint32_t c = _get();
1708 for (uint32_t i = 0; i < _n_col; ++i) {
1709 bool en = (c & (1<<i)) ? true : false;
1710 if (cb[i]->get_active () != en) {
1711 cb[i]->set_active (en);
1716 void add_to_page (OptionEditorPage* p)
1718 _heading.add_to_page (p);
1719 add_widget_to_page (p, &_hbox);
1723 void column_toggled (int b) {
1724 uint32_t c = _get();
1726 if (cb[b]->get_active ()) {
1737 OptionEditorHeading _heading;
1741 sigc::slot<uint32_t> _get;
1742 sigc::slot<bool, uint32_t> _set;
1746 /** A class which allows control of visibility of some editor components usign
1747 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1748 * which has the correct members, but with null widget pointers. This
1749 * class allows the user to set visibility of the members, the details
1750 * of which are stored in a configuration variable which can be watched
1751 * by parts of the editor that actually contain the widgets whose visibility
1752 * is being controlled.
1755 class VisibilityOption : public Option
1758 /** @param name User-visible name for this group.
1759 * @param g `Dummy' VisibilityGroup (as described above).
1760 * @param get Method to get the value of the appropriate configuration variable.
1761 * @param set Method to set the value of the appropriate configuration variable.
1763 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1764 : Option (g->get_state_name(), name)
1766 , _visibility_group (g)
1770 /* Watch for changes made by the user to our members */
1771 _visibility_group->VisibilityChanged.connect_same_thread (
1772 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1776 void set_state_from_config ()
1778 /* Set our state from the current configuration */
1779 _visibility_group->set_state (_get ());
1782 void add_to_page (OptionEditorPage* p)
1784 _heading.add_to_page (p);
1785 add_widget_to_page (p, _visibility_group->list_view ());
1788 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1793 /* The user has changed something, so reflect this change
1794 in the RCConfiguration.
1796 _set (_visibility_group->get_state_value ());
1799 OptionEditorHeading _heading;
1800 VisibilityGroup* _visibility_group;
1801 sigc::slot<std::string> _get;
1802 sigc::slot<bool, std::string> _set;
1803 PBD::ScopedConnection _visibility_group_connection;
1807 class MidiPortOptions : public OptionEditorMiniPage, public sigc::trackable
1810 MidiPortOptions() : refill_id (-1) {
1812 setup_midi_port_view (midi_output_view, false);
1813 setup_midi_port_view (midi_input_view, true);
1815 OptionEditorHeading* h = new OptionEditorHeading (_("MIDI Inputs"));
1816 h->add_to_page (this);
1818 Gtk::ScrolledWindow* scroller = manage (new Gtk::ScrolledWindow);
1819 scroller->add (midi_input_view);
1820 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1821 scroller->set_size_request (-1, 180);
1823 int n = table.property_n_rows();
1824 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1826 h = new OptionEditorHeading (_("MIDI Outputs"));
1827 h->add_to_page (this);
1829 scroller = manage (new Gtk::ScrolledWindow);
1830 scroller->add (midi_output_view);
1831 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1832 scroller->set_size_request (-1, 180);
1834 n = table.property_n_rows();
1835 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1837 midi_output_view.show ();
1838 midi_input_view.show ();
1840 table.signal_map().connect (sigc::mem_fun (*this, &MidiPortOptions::on_map));
1841 table.signal_unmap().connect (sigc::mem_fun (*this, &MidiPortOptions::on_unmap));
1844 void parameter_changed (string const&) {}
1845 void set_state_from_config() {}
1851 AudioEngine::instance()->PortRegisteredOrUnregistered.connect (connections,
1852 invalidator (*this),
1853 boost::bind (&MidiPortOptions::refill, this),
1855 AudioEngine::instance()->MidiPortInfoChanged.connect (connections,
1856 invalidator (*this),
1857 boost::bind (&MidiPortOptions::refill, this),
1859 AudioEngine::instance()->MidiSelectionPortsChanged.connect (connections,
1860 invalidator (*this),
1861 boost::bind (&MidiPortOptions::refill, this),
1866 connections.drop_connections ();
1871 if (refill_midi_ports (true, midi_input_view)) {
1872 input_label.show ();
1874 input_label.hide ();
1876 if (refill_midi_ports (false, midi_output_view)) {
1877 output_label.show ();
1879 output_label.hide ();
1886 PBD::ScopedConnectionList connections;
1888 /* MIDI port management */
1889 struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord {
1891 MidiPortColumns () {
1901 Gtk::TreeModelColumn<std::string> pretty_name;
1902 Gtk::TreeModelColumn<bool> music_data;
1903 Gtk::TreeModelColumn<bool> control_data;
1904 Gtk::TreeModelColumn<bool> selection;
1905 Gtk::TreeModelColumn<std::string> fullname;
1906 Gtk::TreeModelColumn<std::string> shortname;
1907 Gtk::TreeModelColumn<std::string> filler;
1910 MidiPortColumns midi_port_columns;
1911 Gtk::TreeView midi_input_view;
1912 Gtk::TreeView midi_output_view;
1913 Gtk::Label input_label;
1914 Gtk::Label output_label;
1917 void setup_midi_port_view (Gtk::TreeView&, bool with_selection);
1918 bool refill_midi_ports (bool for_input, Gtk::TreeView&);
1919 void pretty_name_edit (std::string const & path, std::string const & new_text, Gtk::TreeView*);
1920 void midi_music_column_toggled (std::string const & path, Gtk::TreeView*);
1921 void midi_control_column_toggled (std::string const & path, Gtk::TreeView*);
1922 void midi_selection_column_toggled (std::string const & path, Gtk::TreeView*);
1926 MidiPortOptions::setup_midi_port_view (Gtk::TreeView& view, bool with_selection)
1928 int pretty_name_column;
1931 int selection_column;
1932 TreeViewColumn* col;
1935 pretty_name_column = view.append_column_editable (_("Name (click twice to edit)"), midi_port_columns.pretty_name) - 1;
1937 col = manage (new TreeViewColumn ("", midi_port_columns.music_data));
1938 col->set_alignment (ALIGN_CENTER);
1939 l = manage (new Label (_("Music Data")));
1940 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of music performance data."), PROGRAM_NAME));
1941 col->set_widget (*l);
1943 music_column = view.append_column (*col) - 1;
1945 col = manage (new TreeViewColumn ("", midi_port_columns.control_data));
1946 col->set_alignment (ALIGN_CENTER);
1947 l = manage (new Label (_("Control Data")));
1948 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of control data."), PROGRAM_NAME));
1949 col->set_widget (*l);
1951 control_column = view.append_column (*col) - 1;
1953 if (with_selection) {
1954 col = manage (new TreeViewColumn (_("Follow Selection"), midi_port_columns.selection));
1955 selection_column = view.append_column (*col) - 1;
1956 l = manage (new Label (_("Follow Selection")));
1957 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));
1958 col->set_widget (*l);
1962 /* filler column so that the last real column doesn't expand */
1963 view.append_column ("", midi_port_columns.filler);
1965 CellRendererText* pretty_name_cell = dynamic_cast<CellRendererText*> (view.get_column_cell_renderer (pretty_name_column));
1966 pretty_name_cell->property_editable() = true;
1967 pretty_name_cell->signal_edited().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::pretty_name_edit), &view));
1969 CellRendererToggle* toggle_cell;
1971 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (music_column));
1972 toggle_cell->property_activatable() = true;
1973 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_music_column_toggled), &view));
1975 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (control_column));
1976 toggle_cell->property_activatable() = true;
1977 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_control_column_toggled), &view));
1979 if (with_selection) {
1980 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (selection_column));
1981 toggle_cell->property_activatable() = true;
1982 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_selection_column_toggled), &view));
1985 view.get_selection()->set_mode (SELECTION_SINGLE);
1986 view.set_tooltip_column (5); /* port short name */
1987 view.get_column(0)->set_resizable (true);
1988 view.get_column(0)->set_expand (true);
1992 MidiPortOptions::refill_midi_ports (bool for_input, Gtk::TreeView& view)
1994 using namespace ARDOUR;
1996 std::vector<string> ports;
1998 AudioEngine::instance()->get_known_midi_ports (ports);
2000 if (ports.empty()) {
2005 Glib::RefPtr<ListStore> model = Gtk::ListStore::create (midi_port_columns);
2007 for (vector<string>::const_iterator s = ports.begin(); s != ports.end(); ++s) {
2009 if (AudioEngine::instance()->port_is_mine (*s)) {
2013 PortManager::MidiPortInformation mpi (AudioEngine::instance()->midi_port_information (*s));
2019 if (for_input != mpi.input) {
2023 TreeModel::Row row = *(model->append());
2025 row[midi_port_columns.pretty_name] = mpi.pretty_name;
2026 row[midi_port_columns.music_data] = mpi.properties & MidiPortMusic;
2027 row[midi_port_columns.control_data] = mpi.properties & MidiPortControl;
2028 row[midi_port_columns.selection] = mpi.properties & MidiPortSelection;
2029 row[midi_port_columns.fullname] = *s;
2030 row[midi_port_columns.shortname] = AudioEngine::instance()->short_port_name_from_port_name (*s);
2033 view.set_model (model);
2039 MidiPortOptions::midi_music_column_toggled (string const & path, TreeView* view)
2041 TreeIter iter = view->get_model()->get_iter (path);
2047 bool new_value = ! bool ((*iter)[midi_port_columns.music_data]);
2049 /* don't reset model - wait for MidiPortInfoChanged signal */
2052 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.fullname], MidiPortMusic);
2054 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.fullname], MidiPortMusic);
2059 MidiPortOptions::midi_control_column_toggled (string const & path, TreeView* view)
2061 TreeIter iter = view->get_model()->get_iter (path);
2067 bool new_value = ! bool ((*iter)[midi_port_columns.control_data]);
2069 /* don't reset model - wait for MidiPortInfoChanged signal */
2072 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.fullname], MidiPortControl);
2074 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.fullname], MidiPortControl);
2079 MidiPortOptions::midi_selection_column_toggled (string const & path, TreeView* view)
2081 TreeIter iter = view->get_model()->get_iter (path);
2087 bool new_value = ! bool ((*iter)[midi_port_columns.selection]);
2089 /* don't reset model - wait for MidiSelectionPortsChanged signal */
2092 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.fullname], MidiPortSelection);
2094 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.fullname], MidiPortSelection);
2099 MidiPortOptions::pretty_name_edit (std::string const & path, string const & new_text, Gtk::TreeView* view)
2101 TreeIter iter = view->get_model()->get_iter (path);
2107 AudioEngine::instance()->set_port_pretty_name ((*iter)[midi_port_columns.fullname], new_text);
2113 RCOptionEditor::RCOptionEditor ()
2114 : OptionEditorContainer (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
2115 , Tabbable (*this, _("Preferences")
2117 , false // detached by default (first start, no instant.xml)
2119 ) /* pack self-as-vbox into tabbable */
2120 , _rc_config (Config)
2121 , _mixer_strip_visibility ("mixer-element-visibility")
2123 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
2127 uint32_t hwcpus = hardware_concurrency ();
2131 add_option (_("General"), new OptionEditorHeading (_("DSP CPU Utilization")));
2133 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
2135 _("Signal processing uses"),
2136 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
2137 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
2140 procs->add (-1, _("all but one processor"));
2141 procs->add (0, _("all available processors"));
2143 for (uint32_t i = 1; i <= hwcpus; ++i) {
2144 procs->add (i, string_compose (P_("%1 processor", "%1 processors", i), i));
2147 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
2149 add_option (_("General"), procs);
2152 /* Image cache size */
2153 add_option (_("General"), new OptionEditorHeading (_("Memory Usage")));
2155 HSliderOption *sics = new HSliderOption ("waveform-cache-size",
2156 _("Waveform image cache size (megabytes)"),
2157 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
2158 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size),
2159 1, 1024, 10 /* 1 MB to 1GB in steps of 10MB */
2161 sics->scale().set_digits (0);
2162 Gtkmm2ext::UI::instance()->set_tip (
2164 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
2165 add_option (_("General"), sics);
2167 add_option (_("General"), new OptionEditorHeading (_("Engine")));
2169 add_option (_("General"),
2171 "try-autostart-engine",
2172 _("Try to auto-launch audio/midi engine"),
2173 sigc::mem_fun (*_rc_config, &RCConfiguration::get_try_autostart_engine),
2174 sigc::mem_fun (*_rc_config, &RCConfiguration::set_try_autostart_engine)
2177 add_option (_("General"), new OptionEditorHeading (_("Automation")));
2179 add_option (_("General"),
2180 new SpinOption<double> (
2181 "automation-thinning-factor",
2182 _("Thinning factor (larger value => less data)"),
2183 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
2184 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
2188 add_option (_("General"),
2189 new SpinOption<double> (
2190 "automation-interval-msecs",
2191 _("Automation sampling interval (milliseconds)"),
2192 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
2193 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
2197 add_option (_("General"), new OptionEditorHeading (_("Tempo")));
2199 bo = new BoolOption (
2200 "allow-non-quarter-pulse",
2201 _("Allow non quarter-note pulse"),
2202 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_allow_non_quarter_pulse),
2203 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_allow_non_quarter_pulse)
2205 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2206 string_compose (_("<b>When enabled</b> %1 will allow tempo to be expressed in divisions per minute\n"
2207 "<b>When disabled</b> %1 will only allow tempo to be expressed in quarter notes per minute"),
2209 add_option (_("General"), bo);
2211 if (!ARDOUR::Profile->get_mixbus()) {
2212 add_option (_("General"), new OptionEditorHeading (_("GUI Lock")));
2213 /* Lock GUI timeout */
2215 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2216 _("Lock timeout (seconds)"),
2217 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
2218 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds),
2221 slts->scale().set_digits (0);
2222 Gtkmm2ext::UI::instance()->set_tip (
2224 _("Lock GUI after this many idle seconds (zero to never lock)"));
2225 add_option (_("General"), slts);
2227 ComboOption<ScreenSaverMode>* scsvr = new ComboOption<ScreenSaverMode> (
2228 "screen-saver-mode",
2229 _("System Screensaver Mode"),
2230 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_screen_saver_mode),
2231 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_screen_saver_mode)
2234 scsvr->add (InhibitNever, _("Never Inhibit"));
2235 scsvr->add (InhibitWhileRecording, _("Inhibit while Recording"));
2236 scsvr->add (InhibitAlways, string_compose (_("Inhibit while %1 is running"), PROGRAM_NAME));
2238 add_option (_("General"), scsvr);
2243 add_option (_("General/Session"), new OptionEditorHeading (S_("Options|Undo")));
2245 add_option (_("General/Session"), new UndoOptions (_rc_config));
2247 add_option (_("General/Session"),
2249 "verify-remove-last-capture",
2250 _("Verify removal of last capture"),
2251 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
2252 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
2255 add_option (_("General/Session"), new OptionEditorHeading (_("Session Management")));
2257 add_option (_("General/Session"),
2259 "periodic-safety-backups",
2260 _("Make periodic backups of the session file"),
2261 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
2262 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
2265 add_option (_("General/Session"),
2267 "only-copy-imported-files",
2268 _("Always copy imported files"),
2269 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
2270 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
2273 add_option (_("General/Session"), new DirectoryOption (
2274 X_("default-session-parent-dir"),
2275 _("Default folder for new sessions:"),
2276 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
2277 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
2280 add_option (_("General/Session"),
2281 new SpinOption<uint32_t> (
2282 "max-recent-sessions",
2283 _("Maximum number of recent sessions"),
2284 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
2285 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
2292 add_option (_("General/Translation"), new OptionEditorHeading (_("Internationalization")));
2294 bo = new BoolOption (
2295 "enable-translation",
2296 _("Use translations"),
2297 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2298 sigc::ptr_fun (ARDOUR::set_translations_enabled)
2301 bo->set_note (string_compose (_("These settings will only take effect after %1 is restarted (if available for your language preferences)."), PROGRAM_NAME));
2303 add_option (_("General/Translation"), bo);
2305 parameter_changed ("enable-translation");
2306 #endif // ENABLE_NLS
2311 add_option (_("Editor"), new OptionEditorHeading (_("General")));
2313 bo = new BoolOption (
2315 _("Prompt for new marker names"),
2316 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2317 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2319 add_option (_("Editor"), bo);
2320 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."
2321 "\n\nYou can always rename markers by right-clicking on them"));
2323 add_option (_("Editor"),
2325 "draggable-playhead",
2326 _("Allow dragging of playhead"),
2327 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2328 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2331 ComboOption<float>* dps = new ComboOption<float> (
2332 "draggable-playhead-speed",
2333 _("Playhead dragging speed (%)"),
2334 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead_speed),
2335 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead_speed)
2337 dps->add (0.05, _("5%"));
2338 dps->add (0.1, _("10%"));
2339 dps->add (0.25, _("25%"));
2340 dps->add (0.5, _("50%"));
2341 dps->add (1.0, _("100%"));
2342 add_option (_("Editor"), dps);
2344 ComboOption<float>* eet = new ComboOption<float> (
2345 "extra-ui-extents-time",
2346 _("Limit zooming & summary view to X minutes beyond session extents"),
2347 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_extra_ui_extents_time),
2348 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_extra_ui_extents_time)
2350 eet->add (1, _("1 minute"));
2351 eet->add (2, _("2 minutes"));
2352 eet->add (20, _("20 minutes"));
2353 eet->add (60, _("1 hour"));
2354 eet->add (60*2, _("2 hours"));
2355 eet->add (60*24, _("24 hours"));
2356 add_option (_("Editor"), eet);
2358 if (!Profile->get_mixbus()) {
2360 add_option (_("Editor"),
2362 "use-mouse-position-as-zoom-focus-on-scroll",
2363 _("Zoom to mouse position when zooming with scroll wheel"),
2364 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2365 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2369 add_option (_("Editor"),
2371 "use-time-rulers-to-zoom-with-vertical-drag",
2372 _("Zoom with vertical drag in rulers"),
2373 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag),
2374 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag)
2377 add_option (_("Editor"),
2379 "use-double-click-to-zoom-to-selection",
2380 _("Double click zooms to selection"),
2381 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection),
2382 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection)
2385 add_option (_("Editor"),
2387 "update-editor-during-summary-drag",
2388 _("Update editor window during drags of the summary"),
2389 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2390 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2393 add_option (_("Editor"),
2395 "autoscroll-editor",
2396 _("Auto-scroll editor window when dragging near its edges"),
2397 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2398 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2401 add_option (_("Editor"),
2402 new BoolComboOption (
2403 "show-region-gain-envelopes",
2404 _("Show gain envelopes in audio regions"),
2406 _("only in Draw and Internal Edit modes"),
2407 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2408 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2411 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2413 add_option (_("Editor"),
2415 "automation-follows-regions",
2416 _("Move relevant automation when audio regions are moved"),
2417 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2418 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2421 bo = new BoolOption (
2422 "new-automation-points-on-lane",
2423 _("Ignore Y-axis click position when adding new automation-points"),
2424 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_new_automation_points_on_lane),
2425 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_new_automation_points_on_lane)
2427 add_option (_("Editor"), bo);
2428 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2429 _("<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."));
2431 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2432 "default-fade-shape",
2433 _("Default fade shape"),
2434 sigc::mem_fun (*_rc_config,
2435 &RCConfiguration::get_default_fade_shape),
2436 sigc::mem_fun (*_rc_config,
2437 &RCConfiguration::set_default_fade_shape)
2440 fadeshape->add (FadeLinear,
2441 _("Linear (for highly correlated material)"));
2442 fadeshape->add (FadeConstantPower, _("Constant power"));
2443 fadeshape->add (FadeSymmetric, _("Symmetric"));
2444 fadeshape->add (FadeSlow, _("Slow"));
2445 fadeshape->add (FadeFast, _("Fast"));
2447 add_option (_("Editor"), fadeshape);
2449 ComboOption<RegionEquivalence> *eqv = new ComboOption<RegionEquivalence> (
2450 "region-equivalency",
2451 _("Regions in active edit groups are edited together"),
2452 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_equivalence),
2453 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_equivalence)
2456 eqv->add (Overlap, _("whenever they overlap in time"));
2457 eqv->add (Enclosed, _("if either encloses the other"));
2458 eqv->add (Exact, _("only if they have identical length, position and origin"));
2459 eqv->add (LayerTime, _("only if they have identical length, position and layer"));
2461 add_option (_("Editor"), eqv);
2463 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2465 _("Layering model"),
2466 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2467 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2470 lm->add (LaterHigher, _("later is higher"));
2471 lm->add (Manual, _("manual layering"));
2472 add_option (_("Editor"), lm);
2474 add_option (_("Editor"), new OptionEditorHeading (_("Split/Separate")));
2476 ComboOption<RangeSelectionAfterSplit> *rras = new ComboOption<RangeSelectionAfterSplit> (
2477 "range-selection-after-separate",
2478 _("After a Separate operation, in Range mode"),
2479 sigc::mem_fun (*_rc_config, &RCConfiguration::get_range_selection_after_split),
2480 sigc::mem_fun (*_rc_config, &RCConfiguration::set_range_selection_after_split));
2482 rras->add(ClearSel, _("Clear the Range Selection"));
2483 rras->add(PreserveSel, _("Preserve the Range Selection"));
2484 rras->add(ForceSel, _("Force-Select the regions under the range. (this might cause a tool change)"));
2485 add_option (_("Editor"), rras);
2487 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2488 "region-selection-after-split",
2489 _("After a Split operation, in Object mode"),
2490 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2491 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2493 // TODO: decide which of these modes are really useful
2494 rsas->add(None, _("Clear the Selected Regions"));
2495 rsas->add(NewlyCreatedLeft, _("Select only the newly-created regions BEFORE the split point"));
2496 rsas->add(NewlyCreatedRight, _("Select only the newly-created regions AFTER the split point"));
2497 rsas->add(NewlyCreatedBoth, _("Select the newly-created regions"));
2498 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2499 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2500 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2501 rsas->add(ExistingNewlyCreatedBoth, _("Preserve the existing selection, AND select all newly-created regions"));
2503 add_option (_("Editor"), rsas);
2505 add_option (_("Editor/Snap"), new OptionEditorHeading (_("General Snap options:")));
2507 add_option (_("Editor/Snap"),
2508 new SpinOption<uint32_t> (
2510 _("Snap Threshold (pixels)"),
2511 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_threshold),
2512 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_threshold),
2517 add_option (_("Editor/Snap"),
2519 "show-snapped-cursor",
2520 _("Show \"snapped cursor\""),
2521 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_snapped_cursor),
2522 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_snapped_cursor)
2525 add_option (_("Editor/Snap"),
2527 "rubberbanding-snaps-to-grid",
2528 _("Snap rubberband selection to grid"),
2529 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2530 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2533 add_option (_("Editor/Snap"),
2535 "grid-follows-internal",
2536 _("Grid switches to alternate selection for Internal Edit tools"),
2537 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_grid_follows_internal),
2538 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_grid_follows_internal)
2541 add_option (_("Editor/Snap"),
2543 "rulers-follow-grid",
2544 _("Rulers automatically change to follow the Grid mode selection"),
2545 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rulers_follow_grid),
2546 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rulers_follow_grid)
2549 add_option (_("Editor/Snap"), new OptionEditorHeading (_("When \"Snap\" is enabled, snap to:")));
2552 add_option (_("Editor/Snap"),
2556 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_marks),
2557 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_marks)
2560 add_option (_("Editor/Snap"),
2562 "snap-to-region-sync",
2563 _("Region Sync Points"),
2564 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_region_sync),
2565 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_region_sync)
2568 add_option (_("Editor/Snap"),
2570 "snap-to-region-start",
2572 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_region_start),
2573 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_region_start)
2576 add_option (_("Editor/Snap"),
2578 "snap-to-region-end",
2580 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_region_end),
2581 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_region_end)
2584 add_option (_("Editor/Snap"),
2588 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_grid),
2589 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_grid)
2592 add_option (_("Editor/Modifiers"), new OptionEditorHeading (_("Keyboard Modifiers")));
2593 add_option (_("Editor/Modifiers"), new KeyboardOptions);
2594 add_option (_("Editor/Modifiers"), new OptionEditorBlank ());
2596 /* MIXER -- SOLO AND MUTE */
2598 add_option (_("Mixer"), new OptionEditorHeading (_("Solo")));
2600 _solo_control_is_listen_control = new BoolOption (
2601 "solo-control-is-listen-control",
2602 _("Solo controls are Listen controls"),
2603 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2604 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2607 add_option (_("Mixer"), _solo_control_is_listen_control);
2609 add_option (_("Mixer"),
2612 _("Exclusive solo"),
2613 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2614 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2617 add_option (_("Mixer"),
2620 _("Show solo muting"),
2621 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2622 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2625 add_option (_("Mixer"),
2627 "solo-mute-override",
2628 _("Soloing overrides muting"),
2629 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2630 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2633 add_option (_("Mixer"),
2636 _("Solo-in-place mute cut (dB)"),
2637 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2638 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2641 _listen_position = new ComboOption<ListenPosition> (
2643 _("Listen Position"),
2644 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2645 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2648 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2649 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2651 add_option (_("Mixer"), _listen_position);
2653 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2655 _("PFL signals come from"),
2656 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2657 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2660 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2661 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2663 add_option (_("Mixer"), pp);
2665 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2667 _("AFL signals come from"),
2668 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2669 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2672 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2673 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2675 add_option (_("Mixer"), pa);
2677 add_option (_("Mixer"), new OptionEditorHeading (_("Default Track / Bus Muting Options")));
2679 add_option (_("Mixer"),
2681 "mute-affects-pre-fader",
2682 _("Mute affects pre-fader sends"),
2683 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2684 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2687 add_option (_("Mixer"),
2689 "mute-affects-post-fader",
2690 _("Mute affects post-fader sends"),
2691 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2692 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2695 add_option (_("Mixer"),
2697 "mute-affects-control-outs",
2698 _("Mute affects control outputs"),
2699 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2700 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2703 add_option (_("Mixer"),
2705 "mute-affects-main-outs",
2706 _("Mute affects main outputs"),
2707 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2708 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2712 if (!ARDOUR::Profile->get_mixbus()) {
2713 add_option (_("Mixer"), new OptionEditorHeading (_("Send Routing")));
2714 add_option (_("Mixer"),
2716 "link-send-and-route-panner",
2717 _("Link panners of Aux and External Sends with main panner by default"),
2718 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2719 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2725 add_option (_("Signal Flow"), new OptionEditorHeading (_("Monitoring")));
2727 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2729 _("Record monitoring handled by"),
2730 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2731 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2734 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2735 mm->add (HardwareMonitoring, _("via Audio Driver"));
2738 string prog (PROGRAM_NAME);
2739 boost::algorithm::to_lower (prog);
2740 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2741 mm->add (ExternalMonitoring, _("audio hardware"));
2743 add_option (_("Signal Flow"), mm);
2745 bo = new BoolOption (
2746 "tape-machine-mode",
2747 _("Tape machine mode"),
2748 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2749 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2751 add_option (_("Signal Flow"), bo);
2752 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2753 string_compose (_("<b>When enabled</b> %1 will not monitor a track's input if the transport is stopped."),
2756 if (!Profile->get_mixbus()) {
2758 add_option (_("Signal Flow"), new OptionEditorHeading (_("Track and Bus Connections")));
2760 bo = new BoolOption (
2761 "auto-connect-standard-busses",
2762 _("Auto-connect main output (master or monitor) bus to physical ports"),
2763 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2764 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2766 add_option (_("Signal Flow"), bo);
2767 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2768 _("<b>When enabled</b> the main output bus is auto-connected to the first N physical ports. "
2769 "If the session has a monitor-section, the monitor-bus output is conneced the the hardware playback ports, "
2770 "otherwise the master-bus output is directly used for playback."));
2772 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2773 "input-auto-connect",
2774 _("Connect track inputs"),
2775 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2776 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2779 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2780 iac->add (ManualConnect, _("manually"));
2782 add_option (_("Signal Flow"), iac);
2784 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2785 "output-auto-connect",
2786 _("Connect track and bus outputs"),
2787 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2788 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2791 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2792 oac->add (AutoConnectMaster, _("automatically to master bus"));
2793 oac->add (ManualConnect, _("manually"));
2795 add_option (_("Signal Flow"), oac);
2797 bo = new BoolOption (
2799 _("Use 'Strict-I/O' for new tracks or busses"),
2800 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2801 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2804 add_option (_("Signal Flow"), bo);
2805 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2806 _("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."));
2813 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2815 add_option (_("Audio"), new BufferingOptions (_rc_config));
2817 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2819 add_option (_("Audio"),
2821 "denormal-protection",
2822 _("Use DC bias to protect against denormals"),
2823 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2824 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2827 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2829 _("Processor handling"),
2830 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2831 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2835 dm->add (DenormalNone, _("no processor handling"));
2837 FPU* fpu = FPU::instance();
2839 if (fpu->has_flush_to_zero()) {
2841 dm->add (DenormalFTZ, _("use FlushToZero"));
2842 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2843 _rc_config->set_denormal_model(DenormalNone);
2846 if (fpu->has_denormals_are_zero()) {
2848 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2849 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2850 _rc_config->set_denormal_model(DenormalNone);
2853 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2855 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2856 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2857 _rc_config->set_denormal_model(DenormalNone);
2861 dm->set_sensitive(false);
2864 add_option (_("Audio"), dm);
2866 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2868 add_option (_("Audio"),
2870 "auto-analyse-audio",
2871 _("Enable automatic analysis of audio"),
2872 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2873 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2876 add_option (_("Audio"),
2878 "replicate-missing-region-channels",
2879 _("Replicate missing region channels"),
2880 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2881 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2886 add_option (_("MIDI"), new OptionEditorHeading (_("Buffering")));
2888 add_option (_("MIDI"),
2889 new SpinOption<float> (
2891 _("MIDI read-ahead time (seconds)"),
2892 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2893 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2898 add_option (_("MIDI"), new OptionEditorHeading (_("Session")));
2900 add_option (_("MIDI"),
2901 new SpinOption<int32_t> (
2902 "initial-program-change",
2903 _("Initial program change"),
2904 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2905 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2909 add_option (_("MIDI"), new OptionEditorHeading (_("Audition")));
2911 add_option (_("MIDI"),
2914 _("Sound MIDI notes as they are selected in the editor"),
2915 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2916 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2921 add_option (_("Metronome"), new OptionEditorHeading (_("Metronome")));
2922 add_option (_("Metronome"), new ClickOptions (_rc_config));
2923 add_option (_("Metronome"), new OptionEditorHeading (_("Options")));
2925 bo = new BoolOption (
2926 "click-record-only",
2927 _("Enable metronome only while recording"),
2928 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_record_only),
2929 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_record_only)
2932 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2933 string_compose (_("<b>When enabled</b> the metronome will remain silent if %1 is <b>not recording</b>."), PROGRAM_NAME));
2934 add_option (_("Metronome"), bo);
2935 add_option (_("Metronome"), new OptionEditorBlank ());
2940 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2942 ComboOption<float>* mht = new ComboOption<float> (
2944 _("Peak hold time"),
2945 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
2946 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
2949 mht->add (MeterHoldOff, _("off"));
2950 mht->add (MeterHoldShort, _("short"));
2951 mht->add (MeterHoldMedium, _("medium"));
2952 mht->add (MeterHoldLong, _("long"));
2954 add_option (S_("Preferences|Metering"), mht);
2956 ComboOption<float>* mfo = new ComboOption<float> (
2959 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2960 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2963 mfo->add (METER_FALLOFF_OFF, _("off"));
2964 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2965 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2966 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2967 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2968 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2969 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
2971 add_option (S_("Preferences|Metering"), mfo);
2973 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2974 "meter-line-up-level",
2975 _("Meter line-up level; 0dBu"),
2976 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
2977 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
2980 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2981 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2982 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2983 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2985 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."));
2987 add_option (S_("Preferences|Metering"), mlu);
2989 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2990 "meter-line-up-din",
2991 _("IEC1/DIN Meter line-up level; 0dBu"),
2992 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
2993 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
2996 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2997 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2998 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2999 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3001 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
3003 add_option (S_("Preferences|Metering"), mld);
3005 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
3006 "meter-vu-standard",
3007 _("VU Meter standard"),
3008 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
3009 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
3012 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
3013 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
3014 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
3015 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
3017 add_option (S_("Preferences|Metering"), mvu);
3019 HSliderOption *mpks = new HSliderOption("meter-peak",
3020 _("Peak indicator threshold [dBFS]"),
3021 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
3022 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak),
3026 Gtkmm2ext::UI::instance()->set_tip (
3028 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
3030 add_option (S_("Preferences|Metering"), mpks);
3032 OptionEditorHeading* default_meter_head = new OptionEditorHeading (_("Default Meter Types"));
3033 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."));
3035 add_option (S_("Preferences|Metering"), default_meter_head);
3037 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3038 "meter-type-master",
3039 _("Default Meter Type for Master Bus"),
3040 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3041 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3043 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3044 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3045 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3046 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3047 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3048 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3049 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3050 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3052 add_option (S_("Preferences|Metering"), mtm);
3055 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3057 _("Default meter type for busses"),
3058 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3059 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3061 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3062 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3063 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3064 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3065 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3066 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3067 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3068 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3070 add_option (S_("Preferences|Metering"), mtb);
3072 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3074 _("Default meter type for tracks"),
3075 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3076 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3078 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3079 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3081 add_option (S_("Preferences|Metering"), mtt);
3083 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
3085 add_option (S_("Preferences|Metering"),
3087 "save-export-analysis-image",
3088 _("Save loudness analysis as image file after export"),
3089 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
3090 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
3093 add_option (S_("Preferences|Metering"),
3095 "save-export-mixer-screenshot",
3096 _("Save Mixer screenshot after export"),
3097 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_mixer_screenshot),
3098 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_mixer_screenshot)
3101 /* TRANSPORT & Sync */
3103 add_option (_("Transport"), new OptionEditorHeading (_("General")));
3105 bo = new BoolOption (
3106 "stop-at-session-end",
3107 _("Stop at the end of the session"),
3108 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
3109 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
3111 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3112 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
3113 "when it reaches the current session end marker\n\n"
3114 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
3116 add_option (_("Transport"), bo);
3118 bo = new BoolOption (
3119 "latched-record-enable",
3120 _("Keep record-enable engaged on stop"),
3121 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
3122 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
3124 add_option (_("Transport"), bo);
3125 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3126 _("<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."));
3128 bo = new BoolOption (
3129 "disable-disarm-during-roll",
3130 _("Disable per-track record disarm while rolling"),
3131 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
3132 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
3134 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."));
3135 add_option (_("Transport"), bo);
3137 bo = new BoolOption (
3139 _("12dB gain reduction during fast-forward and fast-rewind"),
3140 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
3141 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
3143 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3144 _("<b>When enabled</b> this will reduce the unpleasant increase in perceived volume "
3145 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
3146 add_option (_("Transport"), bo);
3148 ComboOption<float>* psc = new ComboOption<float> (
3151 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
3152 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
3154 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
3155 (_("The amount of preroll to apply when <b>Play with Preroll</b> or <b>Record with Preroll</b>is initiated.\n\n"
3156 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
3157 psc->add (-4.0, _("4 Bars"));
3158 psc->add (-2.0, _("2 Bars"));
3159 psc->add (-1.0, _("1 Bar"));
3160 psc->add (0.0, _("0 (no pre-roll)"));
3161 psc->add (0.1, _("0.1 second"));
3162 psc->add (0.25, _("0.25 second"));
3163 psc->add (0.5, _("0.5 second"));
3164 psc->add (1.0, _("1.0 second"));
3165 psc->add (2.0, _("2.0 seconds"));
3166 add_option (_("Transport"), psc);
3169 add_option (_("Transport"), new OptionEditorHeading (_("Looping")));
3171 bo = new BoolOption (
3173 _("Play loop is a transport mode"),
3174 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
3175 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
3177 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3178 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
3179 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
3180 add_option (_("Transport"), bo);
3182 bo = new BoolOption (
3184 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
3185 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
3186 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
3188 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3189 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
3190 "preventing any need to do a transport locate at the end of the loop\n\n"
3191 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
3192 "which will often cause a small click or delay"), PROGRAM_NAME));
3193 add_option (_("Transport"), bo);
3195 add_option (_("Transport"), new OptionEditorHeading (_("Dropout (xrun) Handling")));
3196 bo = new BoolOption (
3197 "stop-recording-on-xrun",
3198 _("Stop recording when an xrun occurs"),
3199 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
3200 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
3202 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3203 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
3205 add_option (_("Transport"), bo);
3207 bo = new BoolOption (
3208 "create-xrun-marker",
3209 _("Create markers where xruns occur"),
3210 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
3211 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
3213 add_option (_("Transport"), bo);
3218 add_option (_("Sync"), new OptionEditorHeading (_("Transport Masters")));
3220 add_option (_("Sync"), new WidgetOption (X_("foo"), X_("Transport Masters"), _transport_masters_widget));
3222 _sync_framerate = new BoolOption (
3223 "timecode-sync-frame-rate",
3224 _("Match session video frame rate to external timecode"),
3225 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
3226 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
3228 Gtkmm2ext::UI::instance()->set_tip
3229 (_sync_framerate->tip_widget(),
3230 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
3231 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
3232 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
3233 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
3234 "timecode standard and the session standard."), PROGRAM_NAME));
3236 add_option (_("Sync"), _sync_framerate);
3238 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Generator")));
3240 add_option (_("Sync/LTC"),
3243 _("Enable LTC generator"),
3244 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
3245 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
3248 _ltc_send_continuously = new BoolOption (
3249 "ltc-send-continuously",
3250 _("Send LTC while stopped"),
3251 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
3252 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
3254 Gtkmm2ext::UI::instance()->set_tip
3255 (_ltc_send_continuously->tip_widget(),
3256 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
3257 add_option (_("Sync/LTC"), _ltc_send_continuously);
3259 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level [dBFS]"),
3260 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_output_volume),
3261 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_output_volume),
3265 Gtkmm2ext::UI::instance()->set_tip
3266 (_ltc_volume_slider->tip_widget(),
3267 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
3269 add_option (_("Sync/LTC"), _ltc_volume_slider);
3271 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Beat Clock (Mclk) Generator")));
3273 add_option (_("Sync/MIDI"),
3276 _("Enable Mclk generator"),
3277 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
3278 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
3281 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC) Generator")));
3283 add_option (_("Sync/MIDI"),
3286 _("Enable MTC Generator"),
3287 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
3288 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
3291 add_option (_("Sync/MIDI"),
3292 new SpinOption<int> (
3293 "mtc-qf-speed-tolerance",
3294 _("Percentage either side of normal transport speed to transmit MTC"),
3295 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
3296 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
3300 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Machine Control (MMC)")));
3302 add_option (_("Sync/MIDI"),
3305 _("Respond to MMC commands"),
3306 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
3307 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
3310 add_option (_("Sync/MIDI"),
3313 _("Send MMC commands"),
3314 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
3315 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
3318 add_option (_("Sync/MIDI"),
3319 new SpinOption<uint8_t> (
3320 "mmc-receive-device-id",
3321 _("Inbound MMC device ID"),
3322 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
3323 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
3327 add_option (_("Sync/MIDI"),
3328 new SpinOption<uint8_t> (
3329 "mmc-send-device-id",
3330 _("Outbound MMC device ID"),
3331 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
3332 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
3337 /* Control Surfaces */
3339 add_option (_("Control Surfaces"), new OptionEditorHeading (_("Control Surfaces")));
3340 add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
3343 add_option (_("MIDI Ports"), new OptionEditorHeading (_("MIDI Port Options")));
3345 add_option (_("MIDI Ports"),
3347 "midi-input-follows-selection",
3348 _("MIDI input follows MIDI track selection"),
3349 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
3350 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
3353 add_option (_("MIDI Ports"), new MidiPortOptions ());
3354 add_option (_("MIDI Ports"), new OptionEditorBlank ());
3358 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3359 add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
3360 add_option (_("Plugins"),
3361 new RcActionButton (_("Scan for Plugins"),
3362 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3366 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
3368 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3369 bo = new BoolOption (
3370 "show-plugin-scan-window",
3371 _("Always Display Plugin Scan Progress"),
3372 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
3373 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
3375 add_option (_("Plugins"), bo);
3376 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3377 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
3380 bo = new BoolOption (
3381 "plugins-stop-with-transport",
3382 _("Silence plugins when the transport is stopped"),
3383 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
3384 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
3386 add_option (_("Plugins"), bo);
3387 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3388 _("<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."));
3390 bo = new BoolOption (
3391 "new-plugins-active",
3392 _("Make new plugins active"),
3393 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
3394 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
3396 add_option (_("Plugins"), bo);
3397 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3398 _("<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"));
3400 ComboOption<uint32_t>* lna = new ComboOption<uint32_t> (
3401 "limit-n-automatables",
3402 _("Limit automatable parameters per plugin"),
3403 sigc::mem_fun (*_rc_config, &RCConfiguration::get_limit_n_automatables),
3404 sigc::mem_fun (*_rc_config, &RCConfiguration::set_limit_n_automatables)
3406 lna->add (0, _("Unlimited"));
3407 lna->add (64, _("64 parameters"));
3408 lna->add (128, _("128 parameters"));
3409 lna->add (256, _("256 parameters"));
3410 lna->add (512, _("512 parameters"));
3411 lna->add (999, _("999 parameters"));
3412 add_option (_("Plugins"), lna);
3413 Gtkmm2ext::UI::instance()->set_tip (lna->tip_widget(),
3414 _("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."));
3417 #if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
3418 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
3420 add_option (_("Plugins/VST"),
3421 new RcActionButton (_("Scan for Plugins"),
3422 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3425 #if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
3426 bo = new BoolOption (
3428 _("Enable Mac VST support (requires restart or re-scan)"),
3429 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
3430 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
3432 add_option (_("Plugins/VST"), bo);
3435 bo = new BoolOption (
3436 "discover-vst-on-start",
3437 _("Scan for [new] VST Plugins on Application Start"),
3438 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
3439 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
3441 add_option (_("Plugins/VST"), bo);
3442 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3443 _("<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"));
3445 #ifdef WINDOWS_VST_SUPPORT
3446 // currently verbose logging is only implemented for Windows VST.
3447 bo = new BoolOption (
3448 "verbose-plugin-scan",
3449 _("Verbose Plugin Scan"),
3450 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
3451 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
3453 add_option (_("Plugins/VST"), bo);
3454 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3455 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
3458 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
3460 add_option (_("Plugins/VST"),
3461 new RcActionButton (_("Clear"),
3462 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
3465 add_option (_("Plugins/VST"),
3466 new RcActionButton (_("Clear"),
3467 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
3468 _("VST Blacklist:")));
3471 #ifdef LXVST_SUPPORT
3472 add_option (_("Plugins/VST"),
3473 new RcActionButton (_("Edit"),
3474 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
3475 _("Linux VST Path:")));
3477 add_option (_("Plugins/VST"),
3478 new RcConfigDisplay (
3479 "plugin-path-lxvst",
3481 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
3485 #ifdef WINDOWS_VST_SUPPORT
3486 add_option (_("Plugins/VST"),
3487 new RcActionButton (_("Edit"),
3488 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
3489 _("Windows VST Path:")));
3490 add_option (_("Plugins/VST"),
3491 new RcConfigDisplay (
3494 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
3498 #ifdef AUDIOUNIT_SUPPORT
3500 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
3502 add_option (_("Plugins/Audio Unit"),
3503 new RcActionButton (_("Scan for Plugins"),
3504 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3507 bo = new BoolOption (
3508 "discover-audio-units",
3509 _("Scan for [new] AudioUnit Plugins on Application Start"),
3510 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
3511 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
3513 add_option (_("Plugins/Audio Unit"), bo);
3514 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3515 _("<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."));
3517 add_option (_("Plugins/Audio Unit"),
3518 new RcActionButton (_("Clear"),
3519 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
3522 add_option (_("Plugins/Audio Unit"),
3523 new RcActionButton (_("Clear"),
3524 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
3525 _("AU Blacklist:")));
3529 add_option (_("Plugins"), new OptionEditorHeading (_("LV1/LV2")));
3530 add_option (_("Plugins"),
3532 "conceal-lv1-if-lv2-exists",
3533 _("Conceal LADSPA (LV1) Plugins if matching LV2 exists"),
3534 sigc::mem_fun (*_rc_config, &RCConfiguration::get_conceal_lv1_if_lv2_exists),
3535 sigc::mem_fun (*_rc_config, &RCConfiguration::set_conceal_lv1_if_lv2_exists)
3539 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
3540 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
3541 add_option (_("Plugins"),
3543 "open-gui-after-adding-plugin",
3544 _("Automatically open the plugin GUI when adding a new plugin"),
3545 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
3546 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3549 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3550 add_option (_("Plugins"),
3552 "show-inline-display-by-default",
3553 _("Show Plugin Inline Display on Mixerstrip by default"),
3554 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3555 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3558 _plugin_prefer_inline = new BoolOption (
3559 "prefer-inline-over-gui",
3560 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3561 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3562 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3564 add_option (_("Plugins"), _plugin_prefer_inline);
3567 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3569 bo = new BoolOption (
3570 "ask-replace-instrument",
3571 _("Ask to replace existing instrument plugin"),
3572 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3573 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3575 add_option (_("Plugins"), bo);
3577 bo = new BoolOption (
3578 "ask-setup_instrument",
3579 _("Interactively configure instrument plugins on insert"),
3580 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3581 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3583 add_option (_("Plugins"), bo);
3584 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3585 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3588 add_option (_("Plugins"), new OptionEditorBlank ());
3591 #if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
3592 add_option (_("Appearance"), new OptionEditorHeading (_("Graphics Acceleration")));
3595 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3596 BoolOption* bgc = new BoolOption (
3597 "cairo-image-surface",
3598 _("Disable Graphics Hardware Acceleration (requires restart)"),
3599 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3600 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3603 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3604 _("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));
3605 add_option (_("Appearance"), bgc);
3608 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3609 BoolOption* bgo = new BoolOption (
3611 _("Possibly improve slow graphical performance (requires restart)"),
3612 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3613 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3616 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));
3617 add_option (_("Appearance"), bgo);
3619 add_option (_("Appearance"), new OptionEditorHeading (_("Graphical User Interface")));
3621 add_option (_("Appearance"),
3624 _("Highlight widgets on mouseover"),
3625 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3626 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3629 add_option (_("Appearance"),
3632 _("Show tooltips if mouse hovers over a control"),
3633 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3634 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3637 bo = new BoolOption (
3638 "super-rapid-clock-update",
3639 _("Update clocks at TC Frame rate"),
3640 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3641 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3643 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3644 _("<b>When enabled</b> clock displays are updated every Timecode Frame (fps).\n\n"
3645 "<b>When disabled</b> clock displays are updated only every 100ms."
3647 add_option (_("Appearance"), bo);
3649 add_option (_("Appearance"),
3652 _("Blink Rec-Arm buttons"),
3653 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_rec_arm),
3654 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_rec_arm)
3657 add_option (_("Appearance"),
3659 "blink-alert-indicators",
3660 _("Blink Alert Indicators"),
3661 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_alert_indicators),
3662 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_alert_indicators)
3667 /* font scaling does nothing with GDK/Quartz */
3668 add_option (_("Appearance"), new FontScalingOptions ());
3670 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("General")));
3671 add_option (_("Appearance/Editor"),
3673 "show-name-highlight",
3674 _("Use name highlight bars in region displays (requires a restart)"),
3675 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3676 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3679 add_option (_("Appearance/Editor"),
3681 "color-regions-using-track-color",
3682 _("Region color follows track color"),
3683 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_color_regions_using_track_color),
3684 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_color_regions_using_track_color)
3687 add_option (_("Appearance/Editor"),
3689 "show-region-names",
3690 _("Show Region Names"),
3691 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_name),
3692 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_name)
3695 #ifndef MIXBUS // hide this setting in Mixbus. Always on, 4px
3696 ComboOption<uint32_t>* gap = new ComboOption<uint32_t> (
3697 "vertical-region-gap",
3698 _("Add a visual gap below Audio Regions"),
3699 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_vertical_region_gap),
3700 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_vertical_region_gap)
3702 gap->add (0, _("None"));
3703 gap->add (2, _("Small"));
3704 gap->add (4, _("Large"));
3705 add_option (_("Appearance/Editor"), gap);
3708 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Waveforms")));
3710 if (!Profile->get_mixbus()) {
3711 add_option (_("Appearance/Editor"),
3714 _("Show waveforms in regions"),
3715 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
3716 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
3720 add_option (_("Appearance/Editor"),
3722 "show-waveforms-while-recording",
3723 _("Show waveforms while recording"),
3724 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
3725 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
3728 add_option (_("Appearance/Editor"),
3730 "show-waveform-clipping",
3731 _("Show waveform clipping"),
3732 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveform_clipping),
3733 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveform_clipping)
3736 add_option (_("Appearance/Editor"), new ClipLevelOptions ());
3738 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
3740 _("Waveform scale"),
3741 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
3742 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
3745 wfs->add (Linear, _("linear"));
3746 wfs->add (Logarithmic, _("logarithmic"));
3748 add_option (_("Appearance/Editor"), wfs);
3750 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
3752 _("Waveform shape"),
3753 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
3754 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
3757 wfsh->add (Traditional, _("traditional"));
3758 wfsh->add (Rectified, _("rectified"));
3760 add_option (_("Appearance/Editor"), wfsh);
3762 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Editor Meters")));
3764 add_option (_("Appearance/Editor"),
3766 "show-track-meters",
3767 _("Show meters in track headers"),
3768 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3769 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3772 add_option (_("Appearance/Editor"),
3774 "editor-stereo-only-meters",
3775 _("Limit track header meters to stereo"),
3776 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3777 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3780 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("MIDI Regions")));
3782 add_option (_("Appearance/Editor"),
3784 "display-first-midi-bank-as-zero",
3785 _("Display first MIDI bank/program as 0"),
3786 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
3787 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
3790 add_option (_("Appearance/Editor"),
3792 "never-display-periodic-midi",
3793 _("Don't display periodic (MTC, MMC) SysEx messages in MIDI Regions"),
3794 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
3795 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
3799 add_option (_("Appearance/Editor"),
3801 "use-note-bars-for-velocity",
3802 _("Show velocity horizontally inside notes"),
3803 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_note_bars_for_velocity),
3804 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_note_bars_for_velocity)
3807 add_option (_("Appearance/Editor"),
3809 "use-note-color-for-velocity",
3810 _("Use colors to show note velocity"),
3811 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_note_color_for_velocity),
3812 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_note_color_for_velocity)
3815 add_option (_("Appearance/Editor"), new OptionEditorBlank ());
3817 /* The names of these controls must be the same as those given in MixerStrip
3818 for the actual widgets being controlled.
3820 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3821 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3822 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3823 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3824 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3825 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3826 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3828 add_option (_("Appearance/Mixer"),
3829 new VisibilityOption (
3831 &_mixer_strip_visibility,
3832 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3833 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3837 add_option (_("Appearance/Mixer"),
3839 "default-narrow_ms",
3840 _("Use narrow strips in the mixer for new strips by default"),
3841 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3842 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3845 ComboOption<uint32_t>* mic = new ComboOption<uint32_t> (
3846 "max-inline-controls",
3847 _("Limit inline-mixer-strip controls per plugin"),
3848 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_max_inline_controls),
3849 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_max_inline_controls)
3851 mic->add (0, _("Unlimited"));
3852 mic->add (16, _("16 parameters"));
3853 mic->add (32, _("32 parameters"));
3854 mic->add (64, _("64 parameters"));
3855 mic->add (128, _("128 parameters"));
3856 add_option (_("Appearance/Mixer"), mic);
3858 add_option (_("Appearance/Mixer"), new OptionEditorBlank ());
3860 add_option (_("Appearance/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items")));
3862 add_option (_("Appearance/Toolbar"),
3864 "show-toolbar-recpunch",
3865 _("Display Record/Punch Options"),
3866 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_recpunch),
3867 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_recpunch)
3870 add_option (_("Appearance/Toolbar"),
3872 "show-toolbar-monitoring",
3873 _("Display Monitor Options"),
3874 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_monitoring),
3875 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_monitoring)
3878 add_option (_("Appearance/Toolbar"),
3880 "show-toolbar-selclock",
3881 _("Display Selection Clock"),
3882 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
3883 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
3886 if (!ARDOUR::Profile->get_small_screen()) {
3887 add_option (_("Appearance/Toolbar"),
3889 "show-secondary-clock",
3890 _("Display Secondary Clock"),
3891 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
3892 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
3896 add_option (_("Appearance/Toolbar"),
3898 "show-mini-timeline",
3899 _("Display Navigation Timeline"),
3900 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
3901 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
3904 add_option (_("Appearance/Toolbar"),
3906 "show-editor-meter",
3907 _("Display Master Level Meter"),
3908 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
3909 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
3912 add_option (_("Appearance/Toolbar"),
3913 new ColumVisibilityOption (
3914 "action-table-columns", _("Display Action-Buttons"), 4,
3915 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3916 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3919 add_option (_("Appearance/Toolbar"), new OptionEditorBlank ());
3922 /* and now the theme manager */
3924 add_option (_("Appearance/Theme"), new OptionEditorHeading (_("Theme")));
3926 add_option (_("Appearance/Theme"), new BoolOption (
3928 _("Draw \"flat\" buttons"),
3929 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_flat_buttons),
3930 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_flat_buttons)
3933 add_option (_("Appearance/Theme"), new BoolOption (
3935 _("Draw \"boxy\" buttons"),
3936 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_boxy_buttons),
3937 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_boxy_buttons)
3940 add_option (_("Appearance/Theme"), new BoolOption (
3942 _("LED meter style"),
3943 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3944 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3948 HSliderOption *gui_hs = new HSliderOption(
3949 "timeline-item-gradient-depth",
3950 _("Waveforms color gradient depth"),
3951 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_gradient_depth),
3952 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_gradient_depth),
3955 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3956 add_option (_("Appearance/Theme"), gui_hs);
3958 gui_hs = new HSliderOption(
3959 "timeline-item-gradient-depth",
3960 _("Timeline item gradient depth"),
3961 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_timeline_item_gradient_depth),
3962 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_timeline_item_gradient_depth),
3965 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3966 add_option (_("Appearance/Theme"), gui_hs);
3968 vector<string> icon_sets = ::get_icon_sets ();
3969 if (icon_sets.size() > 1) {
3970 ComboOption<std::string>* io = new ComboOption<std::string> (
3971 "icon-set", _("Icon Set"),
3972 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_icon_set),
3973 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_icon_set)
3975 for (vector<string>::const_iterator i = icon_sets.begin (); i != icon_sets.end (); ++i) {
3978 add_option (_("Appearance/Theme"), io);
3981 add_option (_("Appearance/Colors"), new OptionEditorHeading (_("Colors")));
3982 add_option (_("Appearance/Colors"), new ColorThemeManager);
3983 add_option (_("Appearance/Colors"), new OptionEditorBlank ());
3987 OptionEditorHeading* quirks_head = new OptionEditorHeading (_("Various Workarounds for Windowing Systems"));
3989 quirks_head->set_note (string_compose (_("Rules for closing, minimizing, maximizing, and stay-on-top can vary \
3990 with each version of your OS, and the preferences that you've set in your OS.\n\n\
3991 You can adjust the options, below, to change how %1's windows and dialogs behave.\n\n\
3992 These settings will only take effect after %1 is restarted.\n\
3995 add_option (_("Appearance/Quirks"), quirks_head);
3997 bo = new BoolOption (
3998 "use-wm-visibility",
3999 _("Use visibility information provided by your Window Manager/Desktop"),
4000 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
4001 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
4003 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
4004 _("If you have trouble toggling between hidden Editor and Mixer windows, try changing this setting."));
4005 add_option (_("Appearance/Quirks"), bo);
4008 bo = new BoolOption (
4009 "all-floating-windows-are-dialogs",
4010 _("All floating windows are dialogs"),
4011 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_all_floating_windows_are_dialogs),
4012 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_all_floating_windows_are_dialogs)
4014 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
4015 _("Mark all floating windows to be type \"Dialog\" rather than using \"Utility\" for some.\nThis may help with some window managers."));
4016 add_option (_("Appearance/Quirks"), bo);
4018 bo = new BoolOption (
4019 "transients-follow-front",
4020 _("Transient windows follow front window."),
4021 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_transients_follow_front),
4022 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_transients_follow_front)
4024 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
4025 _("Make transient windows follow the front window when toggling between the editor and mixer."));
4026 add_option (_("Appearance/Quirks"), bo);
4029 if (!Profile->get_mixbus()) {
4030 bo = new BoolOption (
4031 "floating-monitor-section",
4032 _("Float detached monitor-section window"),
4033 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_floating_monitor_section),
4034 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_floating_monitor_section)
4036 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
4037 _("When detaching the monitoring section, mark it as \"Utility\" window to stay in front."));
4038 add_option (_("Appearance/Quirks"), bo);
4041 add_option (_("Appearance/Quirks"), new OptionEditorBlank ());
4043 /* VIDEO Timeline */
4044 add_option (_("Video"), new OptionEditorHeading (_("Video Server")));
4045 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
4047 Widget::show_all ();
4049 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
4050 parameter_changed ("send-ltc");
4051 parameter_changed ("sync-source");
4052 parameter_changed ("open-gui-after-adding-plugin");
4054 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
4056 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
4057 (Gtk::StateType) here !!!
4059 Tabbable::set_state (*node, Stateful::loading_state_version);
4062 set_current_page (_("General"));
4066 RCOptionEditor::set_session (Session *s)
4068 SessionHandlePtr::set_session (s);
4069 _transport_masters_widget.set_session (s);
4073 RCOptionEditor::parameter_changed (string const & p)
4075 OptionEditor::parameter_changed (p);
4077 if (p == "use-monitor-bus") {
4078 bool const s = Config->get_use_monitor_bus ();
4080 /* we can't use this if we don't have a monitor bus */
4081 Config->set_solo_control_is_listen_control (false); // XXX
4083 _solo_control_is_listen_control->set_sensitive (s);
4084 _listen_position->set_sensitive (s);
4085 } else if (p == "sync-source") {
4086 boost::shared_ptr<TransportMaster> tm (TransportMasterManager::instance().current());
4087 if (boost::dynamic_pointer_cast<TimecodeTransportMaster> (tm)) {
4088 _sync_framerate->set_sensitive (true);
4090 _sync_framerate->set_sensitive (false);
4092 } else if (p == "send-ltc") {
4093 bool const s = Config->get_send_ltc ();
4094 _ltc_send_continuously->set_sensitive (s);
4095 _ltc_volume_slider->set_sensitive (s);
4096 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
4097 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
4098 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
4100 } else if (p == "conceal-lv1-if-lv2-exists") {
4101 PluginManager::instance().refresh (true);
4105 void RCOptionEditor::plugin_scan_refresh () {
4106 PluginManager::instance().refresh();
4109 void RCOptionEditor::clear_vst_cache () {
4110 PluginManager::instance().clear_vst_cache();
4113 void RCOptionEditor::clear_vst_blacklist () {
4114 PluginManager::instance().clear_vst_blacklist();
4117 void RCOptionEditor::clear_au_cache () {
4118 PluginManager::instance().clear_au_cache();
4121 void RCOptionEditor::clear_au_blacklist () {
4122 PluginManager::instance().clear_au_blacklist();
4125 void RCOptionEditor::edit_lxvst_path () {
4126 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
4127 PathsDialog *pd = new PathsDialog (
4128 *current_toplevel(), _("Set Linux VST Search Path"),
4129 _rc_config->get_plugin_path_lxvst(),
4130 PluginManager::instance().get_default_lxvst_path()
4132 ResponseType r = (ResponseType) pd->run ();
4134 if (r == RESPONSE_ACCEPT) {
4135 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
4137 MessageDialog msg (_("Re-scan Plugins now?"),
4138 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
4139 msg.set_default_response (Gtk::RESPONSE_YES);
4140 if (msg.run() == Gtk::RESPONSE_YES) {
4142 plugin_scan_refresh ();
4148 void RCOptionEditor::edit_vst_path () {
4149 PathsDialog *pd = new PathsDialog (
4150 *current_toplevel(), _("Set Windows VST Search Path"),
4151 _rc_config->get_plugin_path_vst(),
4152 PluginManager::instance().get_default_windows_vst_path()
4154 ResponseType r = (ResponseType) pd->run ();
4156 if (r == RESPONSE_ACCEPT) {
4157 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
4158 MessageDialog msg (_("Re-scan Plugins now?"),
4159 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
4160 msg.set_default_response (Gtk::RESPONSE_YES);
4161 if (msg.run() == Gtk::RESPONSE_YES) {
4163 plugin_scan_refresh ();
4170 RCOptionEditor::use_own_window (bool and_fill_it)
4172 bool new_window = !own_window ();
4174 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
4176 if (win && new_window) {
4177 win->set_name ("PreferencesWindow");
4178 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
4180 win->set_resizable (false);
4187 RCOptionEditor::get_state ()
4189 XMLNode* node = new XMLNode (X_("Preferences"));
4190 node->add_child_nocopy (Tabbable::get_state());