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);
2228 add_option (_("General/Session"), new OptionEditorHeading (S_("Options|Undo")));
2230 add_option (_("General/Session"), new UndoOptions (_rc_config));
2232 add_option (_("General/Session"),
2234 "verify-remove-last-capture",
2235 _("Verify removal of last capture"),
2236 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
2237 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
2240 add_option (_("General/Session"), new OptionEditorHeading (_("Session Management")));
2242 add_option (_("General/Session"),
2244 "periodic-safety-backups",
2245 _("Make periodic backups of the session file"),
2246 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
2247 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
2250 add_option (_("General/Session"),
2252 "only-copy-imported-files",
2253 _("Always copy imported files"),
2254 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
2255 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
2258 add_option (_("General/Session"), new DirectoryOption (
2259 X_("default-session-parent-dir"),
2260 _("Default folder for new sessions:"),
2261 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
2262 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
2265 add_option (_("General/Session"),
2266 new SpinOption<uint32_t> (
2267 "max-recent-sessions",
2268 _("Maximum number of recent sessions"),
2269 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
2270 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
2277 add_option (_("General/Translation"), new OptionEditorHeading (_("Internationalization")));
2279 bo = new BoolOption (
2280 "enable-translation",
2281 _("Use translations"),
2282 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2283 sigc::ptr_fun (ARDOUR::set_translations_enabled)
2286 bo->set_note (string_compose (_("These settings will only take effect after %1 is restarted (if available for your language preferences)."), PROGRAM_NAME));
2288 add_option (_("General/Translation"), bo);
2290 parameter_changed ("enable-translation");
2291 #endif // ENABLE_NLS
2296 add_option (_("Editor"), new OptionEditorHeading (_("General")));
2298 bo = new BoolOption (
2300 _("Prompt for new marker names"),
2301 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2302 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2304 add_option (_("Editor"), bo);
2305 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."
2306 "\n\nYou can always rename markers by right-clicking on them"));
2308 add_option (_("Editor"),
2310 "draggable-playhead",
2311 _("Allow dragging of playhead"),
2312 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2313 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2316 ComboOption<float>* dps = new ComboOption<float> (
2317 "draggable-playhead-speed",
2318 _("Playhead dragging speed (%)"),
2319 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead_speed),
2320 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead_speed)
2322 dps->add (0.05, _("5%"));
2323 dps->add (0.1, _("10%"));
2324 dps->add (0.25, _("25%"));
2325 dps->add (0.5, _("50%"));
2326 dps->add (1.0, _("100%"));
2327 add_option (_("Editor"), dps);
2329 ComboOption<float>* eet = new ComboOption<float> (
2330 "extra-ui-extents-time",
2331 _("Limit zooming & summary view to X minutes beyond session extents"),
2332 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_extra_ui_extents_time),
2333 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_extra_ui_extents_time)
2335 eet->add (1, _("1 minute"));
2336 eet->add (2, _("2 minutes"));
2337 eet->add (20, _("20 minutes"));
2338 eet->add (60, _("1 hour"));
2339 eet->add (60*2, _("2 hours"));
2340 eet->add (60*24, _("24 hours"));
2341 add_option (_("Editor"), eet);
2343 if (!Profile->get_mixbus()) {
2345 add_option (_("Editor"),
2347 "use-mouse-position-as-zoom-focus-on-scroll",
2348 _("Zoom to mouse position when zooming with scroll wheel"),
2349 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2350 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2354 add_option (_("Editor"),
2356 "use-time-rulers-to-zoom-with-vertical-drag",
2357 _("Zoom with vertical drag in rulers"),
2358 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag),
2359 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag)
2362 add_option (_("Editor"),
2364 "use-double-click-to-zoom-to-selection",
2365 _("Double click zooms to selection"),
2366 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection),
2367 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection)
2370 add_option (_("Editor"),
2372 "update-editor-during-summary-drag",
2373 _("Update editor window during drags of the summary"),
2374 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2375 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2378 add_option (_("Editor"),
2380 "autoscroll-editor",
2381 _("Auto-scroll editor window when dragging near its edges"),
2382 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2383 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2386 add_option (_("Editor"),
2387 new BoolComboOption (
2388 "show-region-gain-envelopes",
2389 _("Show gain envelopes in audio regions"),
2391 _("only in Draw and Internal Edit modes"),
2392 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2393 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2396 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2398 add_option (_("Editor"),
2400 "automation-follows-regions",
2401 _("Move relevant automation when audio regions are moved"),
2402 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2403 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2406 bo = new BoolOption (
2407 "new-automation-points-on-lane",
2408 _("Ignore Y-axis click position when adding new automation-points"),
2409 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_new_automation_points_on_lane),
2410 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_new_automation_points_on_lane)
2412 add_option (_("Editor"), bo);
2413 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2414 _("<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."));
2416 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2417 "default-fade-shape",
2418 _("Default fade shape"),
2419 sigc::mem_fun (*_rc_config,
2420 &RCConfiguration::get_default_fade_shape),
2421 sigc::mem_fun (*_rc_config,
2422 &RCConfiguration::set_default_fade_shape)
2425 fadeshape->add (FadeLinear,
2426 _("Linear (for highly correlated material)"));
2427 fadeshape->add (FadeConstantPower, _("Constant power"));
2428 fadeshape->add (FadeSymmetric, _("Symmetric"));
2429 fadeshape->add (FadeSlow, _("Slow"));
2430 fadeshape->add (FadeFast, _("Fast"));
2432 add_option (_("Editor"), fadeshape);
2434 ComboOption<RegionEquivalence> *eqv = new ComboOption<RegionEquivalence> (
2435 "region-equivalency",
2436 _("Regions in active edit groups are edited together"),
2437 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_equivalence),
2438 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_equivalence)
2441 eqv->add (Overlap, _("whenever they overlap in time"));
2442 eqv->add (Enclosed, _("if either encloses the other"));
2443 eqv->add (Exact, _("only if they have identical length, position and origin"));
2444 eqv->add (LayerTime, _("only if they have identical length, position and layer"));
2446 add_option (_("Editor"), eqv);
2448 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2450 _("Layering model"),
2451 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2452 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2455 lm->add (LaterHigher, _("later is higher"));
2456 lm->add (Manual, _("manual layering"));
2457 add_option (_("Editor"), lm);
2459 add_option (_("Editor"), new OptionEditorHeading (_("Split/Separate")));
2461 ComboOption<RangeSelectionAfterSplit> *rras = new ComboOption<RangeSelectionAfterSplit> (
2462 "range-selection-after-separate",
2463 _("After a Separate operation, in Range mode"),
2464 sigc::mem_fun (*_rc_config, &RCConfiguration::get_range_selection_after_split),
2465 sigc::mem_fun (*_rc_config, &RCConfiguration::set_range_selection_after_split));
2467 rras->add(ClearSel, _("Clear the Range Selection"));
2468 rras->add(PreserveSel, _("Preserve the Range Selection"));
2469 rras->add(ForceSel, _("Force-Select the regions under the range. (this might cause a tool change)"));
2470 add_option (_("Editor"), rras);
2472 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2473 "region-selection-after-split",
2474 _("After a Split operation, in Object mode"),
2475 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2476 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2478 // TODO: decide which of these modes are really useful
2479 rsas->add(None, _("Clear the Selected Regions"));
2480 rsas->add(NewlyCreatedLeft, _("Select only the newly-created regions BEFORE the split point"));
2481 rsas->add(NewlyCreatedRight, _("Select only the newly-created regions AFTER the split point"));
2482 rsas->add(NewlyCreatedBoth, _("Select the newly-created regions"));
2483 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2484 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2485 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2486 rsas->add(ExistingNewlyCreatedBoth, _("Preserve the existing selection, AND select all newly-created regions"));
2488 add_option (_("Editor"), rsas);
2490 add_option (_("Editor/Snap"), new OptionEditorHeading (_("General Snap options:")));
2492 add_option (_("Editor/Snap"),
2493 new SpinOption<uint32_t> (
2495 _("Snap Threshold (pixels)"),
2496 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_threshold),
2497 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_threshold),
2502 add_option (_("Editor/Snap"),
2504 "show-snapped-cursor",
2505 _("Show \"snapped cursor\""),
2506 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_snapped_cursor),
2507 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_snapped_cursor)
2510 add_option (_("Editor/Snap"),
2512 "rubberbanding-snaps-to-grid",
2513 _("Snap rubberband selection to grid"),
2514 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2515 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2518 add_option (_("Editor/Snap"),
2520 "grid-follows-internal",
2521 _("Grid switches to alternate selection for Internal Edit tools"),
2522 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_grid_follows_internal),
2523 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_grid_follows_internal)
2526 add_option (_("Editor/Snap"),
2528 "rulers-follow-grid",
2529 _("Rulers automatically change to follow the Grid mode selection"),
2530 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rulers_follow_grid),
2531 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rulers_follow_grid)
2534 add_option (_("Editor/Snap"), new OptionEditorHeading (_("When \"Snap\" is enabled, snap to:")));
2537 add_option (_("Editor/Snap"),
2541 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_marks),
2542 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_marks)
2545 add_option (_("Editor/Snap"),
2547 "snap-to-region-sync",
2548 _("Region Sync Points"),
2549 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_region_sync),
2550 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_region_sync)
2553 add_option (_("Editor/Snap"),
2555 "snap-to-region-start",
2557 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_region_start),
2558 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_region_start)
2561 add_option (_("Editor/Snap"),
2563 "snap-to-region-end",
2565 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_region_end),
2566 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_region_end)
2569 add_option (_("Editor/Snap"),
2573 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_grid),
2574 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_grid)
2577 add_option (_("Editor/Modifiers"), new OptionEditorHeading (_("Keyboard Modifiers")));
2578 add_option (_("Editor/Modifiers"), new KeyboardOptions);
2579 add_option (_("Editor/Modifiers"), new OptionEditorBlank ());
2581 /* MIXER -- SOLO AND MUTE */
2583 add_option (_("Mixer"), new OptionEditorHeading (_("Solo")));
2585 _solo_control_is_listen_control = new BoolOption (
2586 "solo-control-is-listen-control",
2587 _("Solo controls are Listen controls"),
2588 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2589 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2592 add_option (_("Mixer"), _solo_control_is_listen_control);
2594 add_option (_("Mixer"),
2597 _("Exclusive solo"),
2598 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2599 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2602 add_option (_("Mixer"),
2605 _("Show solo muting"),
2606 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2607 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2610 add_option (_("Mixer"),
2612 "solo-mute-override",
2613 _("Soloing overrides muting"),
2614 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2615 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2618 add_option (_("Mixer"),
2621 _("Solo-in-place mute cut (dB)"),
2622 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2623 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2626 _listen_position = new ComboOption<ListenPosition> (
2628 _("Listen Position"),
2629 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2630 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2633 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2634 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2636 add_option (_("Mixer"), _listen_position);
2638 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2640 _("PFL signals come from"),
2641 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2642 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2645 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2646 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2648 add_option (_("Mixer"), pp);
2650 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2652 _("AFL signals come from"),
2653 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2654 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2657 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2658 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2660 add_option (_("Mixer"), pa);
2662 add_option (_("Mixer"), new OptionEditorHeading (_("Default Track / Bus Muting Options")));
2664 add_option (_("Mixer"),
2666 "mute-affects-pre-fader",
2667 _("Mute affects pre-fader sends"),
2668 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2669 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2672 add_option (_("Mixer"),
2674 "mute-affects-post-fader",
2675 _("Mute affects post-fader sends"),
2676 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2677 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2680 add_option (_("Mixer"),
2682 "mute-affects-control-outs",
2683 _("Mute affects control outputs"),
2684 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2685 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2688 add_option (_("Mixer"),
2690 "mute-affects-main-outs",
2691 _("Mute affects main outputs"),
2692 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2693 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2697 if (!ARDOUR::Profile->get_mixbus()) {
2698 add_option (_("Mixer"), new OptionEditorHeading (_("Send Routing")));
2699 add_option (_("Mixer"),
2701 "link-send-and-route-panner",
2702 _("Link panners of Aux and External Sends with main panner by default"),
2703 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2704 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2710 add_option (_("Signal Flow"), new OptionEditorHeading (_("Monitoring")));
2712 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2714 _("Record monitoring handled by"),
2715 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2716 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2719 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2720 mm->add (HardwareMonitoring, _("via Audio Driver"));
2723 string prog (PROGRAM_NAME);
2724 boost::algorithm::to_lower (prog);
2725 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2726 mm->add (ExternalMonitoring, _("audio hardware"));
2728 add_option (_("Signal Flow"), mm);
2730 bo = new BoolOption (
2731 "tape-machine-mode",
2732 _("Tape machine mode"),
2733 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2734 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2736 add_option (_("Signal Flow"), bo);
2737 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2738 string_compose (_("<b>When enabled</b> %1 will not monitor a track's input if the transport is stopped."),
2741 if (!Profile->get_mixbus()) {
2743 add_option (_("Signal Flow"), new OptionEditorHeading (_("Track and Bus Connections")));
2745 bo = new BoolOption (
2746 "auto-connect-standard-busses",
2747 _("Auto-connect main output (master or monitor) bus to physical ports"),
2748 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2749 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2751 add_option (_("Signal Flow"), bo);
2752 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2753 _("<b>When enabled</b> the main output bus is auto-connected to the first N physical ports. "
2754 "If the session has a monitor-section, the monitor-bus output is conneced the the hardware playback ports, "
2755 "otherwise the master-bus output is directly used for playback."));
2757 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2758 "input-auto-connect",
2759 _("Connect track inputs"),
2760 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2761 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2764 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2765 iac->add (ManualConnect, _("manually"));
2767 add_option (_("Signal Flow"), iac);
2769 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2770 "output-auto-connect",
2771 _("Connect track and bus outputs"),
2772 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2773 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2776 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2777 oac->add (AutoConnectMaster, _("automatically to master bus"));
2778 oac->add (ManualConnect, _("manually"));
2780 add_option (_("Signal Flow"), oac);
2782 bo = new BoolOption (
2784 _("Use 'Strict-I/O' for new tracks or busses"),
2785 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2786 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2789 add_option (_("Signal Flow"), bo);
2790 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2791 _("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."));
2798 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2800 add_option (_("Audio"), new BufferingOptions (_rc_config));
2802 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2804 add_option (_("Audio"),
2806 "denormal-protection",
2807 _("Use DC bias to protect against denormals"),
2808 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2809 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2812 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2814 _("Processor handling"),
2815 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2816 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2820 dm->add (DenormalNone, _("no processor handling"));
2822 FPU* fpu = FPU::instance();
2824 if (fpu->has_flush_to_zero()) {
2826 dm->add (DenormalFTZ, _("use FlushToZero"));
2827 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2828 _rc_config->set_denormal_model(DenormalNone);
2831 if (fpu->has_denormals_are_zero()) {
2833 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2834 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2835 _rc_config->set_denormal_model(DenormalNone);
2838 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2840 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2841 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2842 _rc_config->set_denormal_model(DenormalNone);
2846 dm->set_sensitive(false);
2849 add_option (_("Audio"), dm);
2851 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2853 add_option (_("Audio"),
2855 "auto-analyse-audio",
2856 _("Enable automatic analysis of audio"),
2857 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2858 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2861 add_option (_("Audio"),
2863 "replicate-missing-region-channels",
2864 _("Replicate missing region channels"),
2865 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2866 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2871 add_option (_("MIDI"), new OptionEditorHeading (_("Buffering")));
2873 add_option (_("MIDI"),
2874 new SpinOption<float> (
2876 _("MIDI read-ahead time (seconds)"),
2877 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2878 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2883 add_option (_("MIDI"), new OptionEditorHeading (_("Session")));
2885 add_option (_("MIDI"),
2886 new SpinOption<int32_t> (
2887 "initial-program-change",
2888 _("Initial program change"),
2889 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2890 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2894 add_option (_("MIDI"), new OptionEditorHeading (_("Audition")));
2896 add_option (_("MIDI"),
2899 _("Sound MIDI notes as they are selected in the editor"),
2900 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2901 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2906 add_option (_("Metronome"), new OptionEditorHeading (_("Metronome")));
2907 add_option (_("Metronome"), new ClickOptions (_rc_config));
2908 add_option (_("Metronome"), new OptionEditorHeading (_("Options")));
2910 bo = new BoolOption (
2911 "click-record-only",
2912 _("Enable metronome only while recording"),
2913 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_record_only),
2914 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_record_only)
2917 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2918 string_compose (_("<b>When enabled</b> the metronome will remain silent if %1 is <b>not recording</b>."), PROGRAM_NAME));
2919 add_option (_("Metronome"), bo);
2920 add_option (_("Metronome"), new OptionEditorBlank ());
2925 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2927 ComboOption<float>* mht = new ComboOption<float> (
2929 _("Peak hold time"),
2930 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
2931 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
2934 mht->add (MeterHoldOff, _("off"));
2935 mht->add (MeterHoldShort, _("short"));
2936 mht->add (MeterHoldMedium, _("medium"));
2937 mht->add (MeterHoldLong, _("long"));
2939 add_option (S_("Preferences|Metering"), mht);
2941 ComboOption<float>* mfo = new ComboOption<float> (
2944 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2945 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2948 mfo->add (METER_FALLOFF_OFF, _("off"));
2949 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2950 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2951 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2952 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2953 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2954 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
2956 add_option (S_("Preferences|Metering"), mfo);
2958 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2959 "meter-line-up-level",
2960 _("Meter line-up level; 0dBu"),
2961 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
2962 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
2965 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2966 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2967 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2968 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2970 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."));
2972 add_option (S_("Preferences|Metering"), mlu);
2974 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2975 "meter-line-up-din",
2976 _("IEC1/DIN Meter line-up level; 0dBu"),
2977 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
2978 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
2981 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2982 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2983 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2984 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2986 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2988 add_option (S_("Preferences|Metering"), mld);
2990 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2991 "meter-vu-standard",
2992 _("VU Meter standard"),
2993 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
2994 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
2997 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2998 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2999 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
3000 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
3002 add_option (S_("Preferences|Metering"), mvu);
3004 HSliderOption *mpks = new HSliderOption("meter-peak",
3005 _("Peak indicator threshold [dBFS]"),
3006 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
3007 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak),
3011 Gtkmm2ext::UI::instance()->set_tip (
3013 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
3015 add_option (S_("Preferences|Metering"), mpks);
3017 OptionEditorHeading* default_meter_head = new OptionEditorHeading (_("Default Meter Types"));
3018 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."));
3020 add_option (S_("Preferences|Metering"), default_meter_head);
3022 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3023 "meter-type-master",
3024 _("Default Meter Type for Master Bus"),
3025 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3026 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3028 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3029 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3030 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3031 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3032 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3033 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3034 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3035 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3037 add_option (S_("Preferences|Metering"), mtm);
3040 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3042 _("Default meter type for busses"),
3043 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3044 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3046 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3047 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3048 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3049 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3050 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3051 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3052 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3053 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3055 add_option (S_("Preferences|Metering"), mtb);
3057 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3059 _("Default meter type for tracks"),
3060 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3061 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3063 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3064 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3066 add_option (S_("Preferences|Metering"), mtt);
3068 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
3070 add_option (S_("Preferences|Metering"),
3072 "save-export-analysis-image",
3073 _("Save loudness analysis as image file"),
3074 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
3075 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
3078 /* TRANSPORT & Sync */
3080 add_option (_("Transport"), new OptionEditorHeading (_("General")));
3082 bo = new BoolOption (
3083 "stop-at-session-end",
3084 _("Stop at the end of the session"),
3085 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
3086 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
3088 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3089 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
3090 "when it reaches the current session end marker\n\n"
3091 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
3093 add_option (_("Transport"), bo);
3095 bo = new BoolOption (
3096 "latched-record-enable",
3097 _("Keep record-enable engaged on stop"),
3098 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
3099 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
3101 add_option (_("Transport"), bo);
3102 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3103 _("<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."));
3105 bo = new BoolOption (
3106 "disable-disarm-during-roll",
3107 _("Disable per-track record disarm while rolling"),
3108 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
3109 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
3111 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."));
3112 add_option (_("Transport"), bo);
3114 bo = new BoolOption (
3116 _("12dB gain reduction during fast-forward and fast-rewind"),
3117 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
3118 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
3120 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3121 _("<b>When enabled</b> this will reduce the unpleasant increase in perceived volume "
3122 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
3123 add_option (_("Transport"), bo);
3125 ComboOption<float>* psc = new ComboOption<float> (
3128 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
3129 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
3131 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
3132 (_("The amount of preroll to apply when <b>Play with Preroll</b> or <b>Record with Preroll</b>is initiated.\n\n"
3133 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
3134 psc->add (-4.0, _("4 Bars"));
3135 psc->add (-2.0, _("2 Bars"));
3136 psc->add (-1.0, _("1 Bar"));
3137 psc->add (0.0, _("0 (no pre-roll)"));
3138 psc->add (0.1, _("0.1 second"));
3139 psc->add (0.25, _("0.25 second"));
3140 psc->add (0.5, _("0.5 second"));
3141 psc->add (1.0, _("1.0 second"));
3142 psc->add (2.0, _("2.0 seconds"));
3143 add_option (_("Transport"), psc);
3146 add_option (_("Transport"), new OptionEditorHeading (_("Looping")));
3148 bo = new BoolOption (
3150 _("Play loop is a transport mode"),
3151 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
3152 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
3154 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3155 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
3156 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
3157 add_option (_("Transport"), bo);
3159 bo = new BoolOption (
3161 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
3162 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
3163 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
3165 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3166 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
3167 "preventing any need to do a transport locate at the end of the loop\n\n"
3168 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
3169 "which will often cause a small click or delay"), PROGRAM_NAME));
3170 add_option (_("Transport"), bo);
3172 add_option (_("Transport"), new OptionEditorHeading (_("Dropout (xrun) Handling")));
3173 bo = new BoolOption (
3174 "stop-recording-on-xrun",
3175 _("Stop recording when an xrun occurs"),
3176 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
3177 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
3179 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3180 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
3182 add_option (_("Transport"), bo);
3184 bo = new BoolOption (
3185 "create-xrun-marker",
3186 _("Create markers where xruns occur"),
3187 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
3188 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
3190 add_option (_("Transport"), bo);
3195 add_option (_("Sync"), new OptionEditorHeading (_("Transport Masters")));
3197 add_option (_("Sync"), new WidgetOption (X_("foo"), X_("Transport Masters"), _transport_masters_widget));
3199 _sync_framerate = new BoolOption (
3200 "timecode-sync-frame-rate",
3201 _("Match session video frame rate to external timecode"),
3202 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
3203 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
3205 Gtkmm2ext::UI::instance()->set_tip
3206 (_sync_framerate->tip_widget(),
3207 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
3208 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
3209 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
3210 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
3211 "timecode standard and the session standard."), PROGRAM_NAME));
3213 add_option (_("Sync"), _sync_framerate);
3215 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Generator")));
3217 add_option (_("Sync/LTC"),
3220 _("Enable LTC generator"),
3221 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
3222 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
3225 _ltc_send_continuously = new BoolOption (
3226 "ltc-send-continuously",
3227 _("Send LTC while stopped"),
3228 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
3229 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
3231 Gtkmm2ext::UI::instance()->set_tip
3232 (_ltc_send_continuously->tip_widget(),
3233 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
3234 add_option (_("Sync/LTC"), _ltc_send_continuously);
3236 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level [dBFS]"),
3237 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_output_volume),
3238 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_output_volume),
3242 Gtkmm2ext::UI::instance()->set_tip
3243 (_ltc_volume_slider->tip_widget(),
3244 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
3246 add_option (_("Sync/LTC"), _ltc_volume_slider);
3248 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Beat Clock (Mclk) Generator")));
3250 add_option (_("Sync/MIDI"),
3253 _("Enable Mclk generator"),
3254 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
3255 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
3258 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC) Generator")));
3260 add_option (_("Sync/MIDI"),
3263 _("Enable MTC Generator"),
3264 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
3265 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
3268 add_option (_("Sync/MIDI"),
3269 new SpinOption<int> (
3270 "mtc-qf-speed-tolerance",
3271 _("Percentage either side of normal transport speed to transmit MTC"),
3272 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
3273 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
3277 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Machine Control (MMC)")));
3279 add_option (_("Sync/MIDI"),
3282 _("Respond to MMC commands"),
3283 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
3284 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
3287 add_option (_("Sync/MIDI"),
3290 _("Send MMC commands"),
3291 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
3292 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
3295 add_option (_("Sync/MIDI"),
3296 new SpinOption<uint8_t> (
3297 "mmc-receive-device-id",
3298 _("Inbound MMC device ID"),
3299 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
3300 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
3304 add_option (_("Sync/MIDI"),
3305 new SpinOption<uint8_t> (
3306 "mmc-send-device-id",
3307 _("Outbound MMC device ID"),
3308 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
3309 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
3314 /* Control Surfaces */
3316 add_option (_("Control Surfaces"), new OptionEditorHeading (_("Control Surfaces")));
3317 add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
3320 add_option (_("MIDI Ports"), new OptionEditorHeading (_("MIDI Port Options")));
3322 add_option (_("MIDI Ports"),
3324 "midi-input-follows-selection",
3325 _("MIDI input follows MIDI track selection"),
3326 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
3327 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
3330 add_option (_("MIDI Ports"), new MidiPortOptions ());
3331 add_option (_("MIDI Ports"), new OptionEditorBlank ());
3335 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3336 add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
3337 add_option (_("Plugins"),
3338 new RcActionButton (_("Scan for Plugins"),
3339 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3343 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
3345 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3346 bo = new BoolOption (
3347 "show-plugin-scan-window",
3348 _("Always Display Plugin Scan Progress"),
3349 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
3350 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
3352 add_option (_("Plugins"), bo);
3353 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3354 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
3357 bo = new BoolOption (
3358 "plugins-stop-with-transport",
3359 _("Silence plugins when the transport is stopped"),
3360 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
3361 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
3363 add_option (_("Plugins"), bo);
3364 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3365 _("<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."));
3367 bo = new BoolOption (
3368 "new-plugins-active",
3369 _("Make new plugins active"),
3370 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
3371 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
3373 add_option (_("Plugins"), bo);
3374 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3375 _("<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"));
3377 ComboOption<uint32_t>* lna = new ComboOption<uint32_t> (
3378 "limit-n-automatables",
3379 _("Limit automatable parameters per plugin"),
3380 sigc::mem_fun (*_rc_config, &RCConfiguration::get_limit_n_automatables),
3381 sigc::mem_fun (*_rc_config, &RCConfiguration::set_limit_n_automatables)
3383 lna->add (0, _("Unlimited"));
3384 lna->add (64, _("64 parameters"));
3385 lna->add (128, _("128 parameters"));
3386 lna->add (256, _("256 parameters"));
3387 lna->add (512, _("512 parameters"));
3388 lna->add (999, _("999 parameters"));
3389 add_option (_("Plugins"), lna);
3390 Gtkmm2ext::UI::instance()->set_tip (lna->tip_widget(),
3391 _("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."));
3394 #if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
3395 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
3397 add_option (_("Plugins/VST"),
3398 new RcActionButton (_("Scan for Plugins"),
3399 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3402 #if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
3403 bo = new BoolOption (
3405 _("Enable Mac VST support (requires restart or re-scan)"),
3406 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
3407 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
3409 add_option (_("Plugins/VST"), bo);
3412 bo = new BoolOption (
3413 "discover-vst-on-start",
3414 _("Scan for [new] VST Plugins on Application Start"),
3415 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
3416 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
3418 add_option (_("Plugins/VST"), bo);
3419 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3420 _("<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"));
3422 #ifdef WINDOWS_VST_SUPPORT
3423 // currently verbose logging is only implemented for Windows VST.
3424 bo = new BoolOption (
3425 "verbose-plugin-scan",
3426 _("Verbose Plugin Scan"),
3427 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
3428 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
3430 add_option (_("Plugins/VST"), bo);
3431 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3432 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
3435 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
3437 add_option (_("Plugins/VST"),
3438 new RcActionButton (_("Clear"),
3439 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
3442 add_option (_("Plugins/VST"),
3443 new RcActionButton (_("Clear"),
3444 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
3445 _("VST Blacklist:")));
3448 #ifdef LXVST_SUPPORT
3449 add_option (_("Plugins/VST"),
3450 new RcActionButton (_("Edit"),
3451 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
3452 _("Linux VST Path:")));
3454 add_option (_("Plugins/VST"),
3455 new RcConfigDisplay (
3456 "plugin-path-lxvst",
3458 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
3462 #ifdef WINDOWS_VST_SUPPORT
3463 add_option (_("Plugins/VST"),
3464 new RcActionButton (_("Edit"),
3465 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
3466 _("Windows VST Path:")));
3467 add_option (_("Plugins/VST"),
3468 new RcConfigDisplay (
3471 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
3475 #ifdef AUDIOUNIT_SUPPORT
3477 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
3479 add_option (_("Plugins/Audio Unit"),
3480 new RcActionButton (_("Scan for Plugins"),
3481 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3484 bo = new BoolOption (
3485 "discover-audio-units",
3486 _("Scan for [new] AudioUnit Plugins on Application Start"),
3487 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
3488 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
3490 add_option (_("Plugins/Audio Unit"), bo);
3491 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3492 _("<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."));
3494 add_option (_("Plugins/Audio Unit"),
3495 new RcActionButton (_("Clear"),
3496 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
3499 add_option (_("Plugins/Audio Unit"),
3500 new RcActionButton (_("Clear"),
3501 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
3502 _("AU Blacklist:")));
3506 add_option (_("Plugins"), new OptionEditorHeading (_("LV1/LV2")));
3507 add_option (_("Plugins"),
3509 "conceal-lv1-if-lv2-exists",
3510 _("Conceal LADSPA (LV1) Plugins if matching LV2 exists"),
3511 sigc::mem_fun (*_rc_config, &RCConfiguration::get_conceal_lv1_if_lv2_exists),
3512 sigc::mem_fun (*_rc_config, &RCConfiguration::set_conceal_lv1_if_lv2_exists)
3516 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
3517 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
3518 add_option (_("Plugins"),
3520 "open-gui-after-adding-plugin",
3521 _("Automatically open the plugin GUI when adding a new plugin"),
3522 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
3523 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3526 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3527 add_option (_("Plugins"),
3529 "show-inline-display-by-default",
3530 _("Show Plugin Inline Display on Mixerstrip by default"),
3531 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3532 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3535 _plugin_prefer_inline = new BoolOption (
3536 "prefer-inline-over-gui",
3537 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3538 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3539 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3541 add_option (_("Plugins"), _plugin_prefer_inline);
3544 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3546 bo = new BoolOption (
3547 "ask-replace-instrument",
3548 _("Ask to replace existing instrument plugin"),
3549 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3550 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3552 add_option (_("Plugins"), bo);
3554 bo = new BoolOption (
3555 "ask-setup_instrument",
3556 _("Interactively configure instrument plugins on insert"),
3557 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3558 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3560 add_option (_("Plugins"), bo);
3561 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3562 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3565 add_option (_("Plugins"), new OptionEditorBlank ());
3568 #if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
3569 add_option (_("Appearance"), new OptionEditorHeading (_("Graphics Acceleration")));
3572 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3573 BoolOption* bgc = new BoolOption (
3574 "cairo-image-surface",
3575 _("Disable Graphics Hardware Acceleration (requires restart)"),
3576 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3577 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3580 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3581 _("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));
3582 add_option (_("Appearance"), bgc);
3585 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3586 BoolOption* bgo = new BoolOption (
3588 _("Possibly improve slow graphical performance (requires restart)"),
3589 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3590 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3593 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));
3594 add_option (_("Appearance"), bgo);
3596 add_option (_("Appearance"), new OptionEditorHeading (_("Graphical User Interface")));
3598 add_option (_("Appearance"),
3601 _("Highlight widgets on mouseover"),
3602 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3603 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3606 add_option (_("Appearance"),
3609 _("Show tooltips if mouse hovers over a control"),
3610 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3611 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3614 bo = new BoolOption (
3615 "super-rapid-clock-update",
3616 _("Update clocks at TC Frame rate"),
3617 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3618 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3620 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3621 _("<b>When enabled</b> clock displays are updated every Timecode Frame (fps).\n\n"
3622 "<b>When disabled</b> clock displays are updated only every 100ms."
3624 add_option (_("Appearance"), bo);
3626 add_option (_("Appearance"),
3629 _("Blink Rec-Arm buttons"),
3630 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_rec_arm),
3631 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_rec_arm)
3634 add_option (_("Appearance"),
3636 "blink-alert-indicators",
3637 _("Blink Alert Indicators"),
3638 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_alert_indicators),
3639 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_alert_indicators)
3644 /* font scaling does nothing with GDK/Quartz */
3645 add_option (_("Appearance"), new FontScalingOptions ());
3647 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("General")));
3648 add_option (_("Appearance/Editor"),
3650 "show-name-highlight",
3651 _("Use name highlight bars in region displays (requires a restart)"),
3652 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3653 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3656 add_option (_("Appearance/Editor"),
3658 "color-regions-using-track-color",
3659 _("Region color follows track color"),
3660 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_color_regions_using_track_color),
3661 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_color_regions_using_track_color)
3664 add_option (_("Appearance/Editor"),
3666 "show-region-names",
3667 _("Show Region Names"),
3668 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_name),
3669 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_name)
3672 #ifndef MIXBUS // hide this setting in Mixbus. Always on, 4px
3673 ComboOption<uint32_t>* gap = new ComboOption<uint32_t> (
3674 "vertical-region-gap",
3675 _("Add a visual gap below Audio Regions"),
3676 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_vertical_region_gap),
3677 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_vertical_region_gap)
3679 gap->add (0, _("None"));
3680 gap->add (2, _("Small"));
3681 gap->add (4, _("Large"));
3682 add_option (_("Appearance/Editor"), gap);
3685 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Waveforms")));
3687 if (!Profile->get_mixbus()) {
3688 add_option (_("Appearance/Editor"),
3691 _("Show waveforms in regions"),
3692 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
3693 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
3697 add_option (_("Appearance/Editor"),
3699 "show-waveforms-while-recording",
3700 _("Show waveforms while recording"),
3701 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
3702 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
3705 add_option (_("Appearance/Editor"),
3707 "show-waveform-clipping",
3708 _("Show waveform clipping"),
3709 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveform_clipping),
3710 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveform_clipping)
3713 add_option (_("Appearance/Editor"), new ClipLevelOptions ());
3715 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
3717 _("Waveform scale"),
3718 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
3719 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
3722 wfs->add (Linear, _("linear"));
3723 wfs->add (Logarithmic, _("logarithmic"));
3725 add_option (_("Appearance/Editor"), wfs);
3727 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
3729 _("Waveform shape"),
3730 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
3731 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
3734 wfsh->add (Traditional, _("traditional"));
3735 wfsh->add (Rectified, _("rectified"));
3737 add_option (_("Appearance/Editor"), wfsh);
3739 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Editor Meters")));
3741 add_option (_("Appearance/Editor"),
3743 "show-track-meters",
3744 _("Show meters in track headers"),
3745 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3746 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3749 add_option (_("Appearance/Editor"),
3751 "editor-stereo-only-meters",
3752 _("Limit track header meters to stereo"),
3753 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3754 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3757 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("MIDI Regions")));
3759 add_option (_("Appearance/Editor"),
3761 "display-first-midi-bank-as-zero",
3762 _("Display first MIDI bank/program as 0"),
3763 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
3764 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
3767 add_option (_("Appearance/Editor"),
3769 "never-display-periodic-midi",
3770 _("Don't display periodic (MTC, MMC) SysEx messages in MIDI Regions"),
3771 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
3772 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
3776 add_option (_("Appearance/Editor"),
3778 "use-note-bars-for-velocity",
3779 _("Show velocity horizontally inside notes"),
3780 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_note_bars_for_velocity),
3781 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_note_bars_for_velocity)
3784 add_option (_("Appearance/Editor"),
3786 "use-note-color-for-velocity",
3787 _("Use colors to show note velocity"),
3788 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_note_color_for_velocity),
3789 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_note_color_for_velocity)
3792 add_option (_("Appearance/Editor"), new OptionEditorBlank ());
3794 /* The names of these controls must be the same as those given in MixerStrip
3795 for the actual widgets being controlled.
3797 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3798 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3799 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3800 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3801 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3802 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3803 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3805 add_option (_("Appearance/Mixer"),
3806 new VisibilityOption (
3808 &_mixer_strip_visibility,
3809 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3810 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3814 add_option (_("Appearance/Mixer"),
3816 "default-narrow_ms",
3817 _("Use narrow strips in the mixer for new strips by default"),
3818 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3819 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3822 ComboOption<uint32_t>* mic = new ComboOption<uint32_t> (
3823 "max-inline-controls",
3824 _("Limit inline-mixer-strip controls per plugin"),
3825 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_max_inline_controls),
3826 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_max_inline_controls)
3828 mic->add (0, _("Unlimited"));
3829 mic->add (16, _("16 parameters"));
3830 mic->add (32, _("32 parameters"));
3831 mic->add (64, _("64 parameters"));
3832 mic->add (128, _("128 parameters"));
3833 add_option (_("Appearance/Mixer"), mic);
3835 add_option (_("Appearance/Mixer"), new OptionEditorBlank ());
3837 add_option (_("Appearance/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items")));
3839 add_option (_("Appearance/Toolbar"),
3841 "show-toolbar-recpunch",
3842 _("Display Record/Punch Options"),
3843 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_recpunch),
3844 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_recpunch)
3847 add_option (_("Appearance/Toolbar"),
3849 "show-toolbar-monitoring",
3850 _("Display Monitor Options"),
3851 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_monitoring),
3852 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_monitoring)
3855 add_option (_("Appearance/Toolbar"),
3857 "show-toolbar-selclock",
3858 _("Display Selection Clock"),
3859 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
3860 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
3863 if (!ARDOUR::Profile->get_small_screen()) {
3864 add_option (_("Appearance/Toolbar"),
3866 "show-secondary-clock",
3867 _("Display Secondary Clock"),
3868 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
3869 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
3873 add_option (_("Appearance/Toolbar"),
3875 "show-mini-timeline",
3876 _("Display Navigation Timeline"),
3877 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
3878 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
3881 add_option (_("Appearance/Toolbar"),
3883 "show-editor-meter",
3884 _("Display Master Level Meter"),
3885 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
3886 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
3889 add_option (_("Appearance/Toolbar"),
3890 new ColumVisibilityOption (
3891 "action-table-columns", _("Display Action-Buttons"), 4,
3892 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3893 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3896 add_option (_("Appearance/Toolbar"), new OptionEditorBlank ());
3899 /* and now the theme manager */
3901 add_option (_("Appearance/Theme"), new OptionEditorHeading (_("Theme")));
3903 add_option (_("Appearance/Theme"), new BoolOption (
3905 _("Draw \"flat\" buttons"),
3906 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_flat_buttons),
3907 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_flat_buttons)
3910 add_option (_("Appearance/Theme"), new BoolOption (
3912 _("Draw \"boxy\" buttons"),
3913 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_boxy_buttons),
3914 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_boxy_buttons)
3917 add_option (_("Appearance/Theme"), new BoolOption (
3919 _("LED meter style"),
3920 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3921 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3925 HSliderOption *gui_hs = new HSliderOption(
3926 "timeline-item-gradient-depth",
3927 _("Waveforms color gradient depth"),
3928 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_gradient_depth),
3929 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_gradient_depth),
3932 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3933 add_option (_("Appearance/Theme"), gui_hs);
3935 gui_hs = new HSliderOption(
3936 "timeline-item-gradient-depth",
3937 _("Timeline item gradient depth"),
3938 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_timeline_item_gradient_depth),
3939 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_timeline_item_gradient_depth),
3942 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3943 add_option (_("Appearance/Theme"), gui_hs);
3945 vector<string> icon_sets = ::get_icon_sets ();
3946 if (icon_sets.size() > 1) {
3947 ComboOption<std::string>* io = new ComboOption<std::string> (
3948 "icon-set", _("Icon Set"),
3949 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_icon_set),
3950 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_icon_set)
3952 for (vector<string>::const_iterator i = icon_sets.begin (); i != icon_sets.end (); ++i) {
3955 add_option (_("Appearance/Theme"), io);
3958 add_option (_("Appearance/Colors"), new OptionEditorHeading (_("Colors")));
3959 add_option (_("Appearance/Colors"), new ColorThemeManager);
3960 add_option (_("Appearance/Colors"), new OptionEditorBlank ());
3964 OptionEditorHeading* quirks_head = new OptionEditorHeading (_("Various Workarounds for Windowing Systems"));
3966 quirks_head->set_note (string_compose (_("Rules for closing, minimizing, maximizing, and stay-on-top can vary \
3967 with each version of your OS, and the preferences that you've set in your OS.\n\n\
3968 You can adjust the options, below, to change how %1's windows and dialogs behave.\n\n\
3969 These settings will only take effect after %1 is restarted.\n\
3972 add_option (_("Appearance/Quirks"), quirks_head);
3974 bo = new BoolOption (
3975 "use-wm-visibility",
3976 _("Use visibility information provided by your Window Manager/Desktop"),
3977 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3978 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3980 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3981 _("If you have trouble toggling between hidden Editor and Mixer windows, try changing this setting."));
3982 add_option (_("Appearance/Quirks"), bo);
3985 bo = new BoolOption (
3986 "all-floating-windows-are-dialogs",
3987 _("All floating windows are dialogs"),
3988 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_all_floating_windows_are_dialogs),
3989 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_all_floating_windows_are_dialogs)
3991 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3992 _("Mark all floating windows to be type \"Dialog\" rather than using \"Utility\" for some.\nThis may help with some window managers."));
3993 add_option (_("Appearance/Quirks"), bo);
3995 bo = new BoolOption (
3996 "transients-follow-front",
3997 _("Transient windows follow front window."),
3998 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_transients_follow_front),
3999 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_transients_follow_front)
4001 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
4002 _("Make transient windows follow the front window when toggling between the editor and mixer."));
4003 add_option (_("Appearance/Quirks"), bo);
4006 if (!Profile->get_mixbus()) {
4007 bo = new BoolOption (
4008 "floating-monitor-section",
4009 _("Float detached monitor-section window"),
4010 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_floating_monitor_section),
4011 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_floating_monitor_section)
4013 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
4014 _("When detaching the monitoring section, mark it as \"Utility\" window to stay in front."));
4015 add_option (_("Appearance/Quirks"), bo);
4018 add_option (_("Appearance/Quirks"), new OptionEditorBlank ());
4020 /* VIDEO Timeline */
4021 add_option (_("Video"), new OptionEditorHeading (_("Video Server")));
4022 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
4024 Widget::show_all ();
4026 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
4027 parameter_changed ("send-ltc");
4028 parameter_changed ("sync-source");
4029 parameter_changed ("open-gui-after-adding-plugin");
4031 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
4033 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
4034 (Gtk::StateType) here !!!
4036 Tabbable::set_state (*node, Stateful::loading_state_version);
4039 set_current_page (_("General"));
4043 RCOptionEditor::set_session (Session *s)
4045 SessionHandlePtr::set_session (s);
4046 _transport_masters_widget.set_session (s);
4050 RCOptionEditor::parameter_changed (string const & p)
4052 OptionEditor::parameter_changed (p);
4054 if (p == "use-monitor-bus") {
4055 bool const s = Config->get_use_monitor_bus ();
4057 /* we can't use this if we don't have a monitor bus */
4058 Config->set_solo_control_is_listen_control (false); // XXX
4060 _solo_control_is_listen_control->set_sensitive (s);
4061 _listen_position->set_sensitive (s);
4062 } else if (p == "sync-source") {
4063 boost::shared_ptr<TransportMaster> tm (TransportMasterManager::instance().current());
4064 if (boost::dynamic_pointer_cast<TimecodeTransportMaster> (tm)) {
4065 _sync_framerate->set_sensitive (true);
4067 _sync_framerate->set_sensitive (false);
4069 } else if (p == "send-ltc") {
4070 bool const s = Config->get_send_ltc ();
4071 _ltc_send_continuously->set_sensitive (s);
4072 _ltc_volume_slider->set_sensitive (s);
4073 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
4074 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
4075 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
4077 } else if (p == "conceal-lv1-if-lv2-exists") {
4078 PluginManager::instance().refresh (true);
4082 void RCOptionEditor::plugin_scan_refresh () {
4083 PluginManager::instance().refresh();
4086 void RCOptionEditor::clear_vst_cache () {
4087 PluginManager::instance().clear_vst_cache();
4090 void RCOptionEditor::clear_vst_blacklist () {
4091 PluginManager::instance().clear_vst_blacklist();
4094 void RCOptionEditor::clear_au_cache () {
4095 PluginManager::instance().clear_au_cache();
4098 void RCOptionEditor::clear_au_blacklist () {
4099 PluginManager::instance().clear_au_blacklist();
4102 void RCOptionEditor::edit_lxvst_path () {
4103 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
4104 PathsDialog *pd = new PathsDialog (
4105 *current_toplevel(), _("Set Linux VST Search Path"),
4106 _rc_config->get_plugin_path_lxvst(),
4107 PluginManager::instance().get_default_lxvst_path()
4109 ResponseType r = (ResponseType) pd->run ();
4111 if (r == RESPONSE_ACCEPT) {
4112 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
4114 MessageDialog msg (_("Re-scan Plugins now?"),
4115 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
4116 msg.set_default_response (Gtk::RESPONSE_YES);
4117 if (msg.run() == Gtk::RESPONSE_YES) {
4119 plugin_scan_refresh ();
4125 void RCOptionEditor::edit_vst_path () {
4126 PathsDialog *pd = new PathsDialog (
4127 *current_toplevel(), _("Set Windows VST Search Path"),
4128 _rc_config->get_plugin_path_vst(),
4129 PluginManager::instance().get_default_windows_vst_path()
4131 ResponseType r = (ResponseType) pd->run ();
4133 if (r == RESPONSE_ACCEPT) {
4134 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
4135 MessageDialog msg (_("Re-scan Plugins now?"),
4136 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
4137 msg.set_default_response (Gtk::RESPONSE_YES);
4138 if (msg.run() == Gtk::RESPONSE_YES) {
4140 plugin_scan_refresh ();
4147 RCOptionEditor::use_own_window (bool and_fill_it)
4149 bool new_window = !own_window ();
4151 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
4153 if (win && new_window) {
4154 win->set_name ("PreferencesWindow");
4155 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
4157 win->set_resizable (false);
4164 RCOptionEditor::get_state ()
4166 XMLNode* node = new XMLNode (X_("Preferences"));
4167 node->add_child_nocopy (Tabbable::get_state());