2 Copyright (C) 2001-2011 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "gtk2ardour-config.h"
24 #if !defined USE_CAIRO_IMAGE_SURFACE && !defined NDEBUG
25 #define OPTIONAL_CAIRO_IMAGE_SURFACE
28 #include <cairo/cairo.h>
30 #include <boost/algorithm/string.hpp>
32 #include <gtkmm/liststore.h>
33 #include <gtkmm/stock.h>
34 #include <gtkmm/scale.h>
36 #include "gtkmm2ext/utils.h"
37 #include "gtkmm2ext/gtk_ui.h"
38 #include "gtkmm2ext/window_title.h"
44 #include "ardour/audio_backend.h"
45 #include "ardour/audioengine.h"
46 #include "ardour/profile.h"
47 #include "ardour/dB.h"
48 #include "ardour/rc_configuration.h"
49 #include "ardour/control_protocol_manager.h"
50 #include "ardour/port_manager.h"
51 #include "ardour/plugin_manager.h"
52 #include "control_protocol/control_protocol.h"
54 #include "waveview/wave_view.h"
56 #include "widgets/paths_dialog.h"
57 #include "widgets/tooltips.h"
59 #include "ardour_dialog.h"
60 #include "ardour_ui.h"
61 #include "ardour_window.h"
62 #include "color_theme_manager.h"
63 #include "gui_thread.h"
65 #include "meter_patterns.h"
66 #include "midi_tracer.h"
67 #include "rc_option_editor.h"
69 #include "ui_config.h"
74 using namespace Gtkmm2ext;
76 using namespace ARDOUR;
77 using namespace ARDOUR_UI_UTILS;
78 using namespace ArdourWidgets;
80 class ClickOptions : public OptionEditorMiniPage
83 ClickOptions (RCConfiguration* c)
85 , _click_browse_button (_("Browse..."))
86 , _click_emphasis_browse_button (_("Browse..."))
88 // TODO get rid of GTK -> use OptionEditor Widgets
93 l = manage (left_aligned_label (_("Emphasis on first beat")));
94 _use_emphasis_on_click_check_button.add (*l);
95 t->attach (_use_emphasis_on_click_check_button, 1, 3, row, row + 1, FILL);
96 _use_emphasis_on_click_check_button.signal_toggled().connect (
97 sigc::mem_fun (*this, &ClickOptions::use_emphasis_on_click_toggled));
100 l = manage (left_aligned_label (_("Use built-in default sounds")));
101 _use_default_click_check_button.add (*l);
102 t->attach (_use_default_click_check_button, 1, 3, row, row + 1, FILL);
103 _use_default_click_check_button.signal_toggled().connect (
104 sigc::mem_fun (*this, &ClickOptions::use_default_click_toggled));
107 l = manage (left_aligned_label (_("Audio file:")));
108 t->attach (*l, 1, 2, row, row + 1, FILL);
109 t->attach (_click_path_entry, 2, 3, row, row + 1, FILL);
110 _click_browse_button.signal_clicked ().connect (
111 sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
112 t->attach (_click_browse_button, 3, 4, row, row + 1, FILL);
115 l = manage (left_aligned_label (_("Emphasis audio file:")));
116 t->attach (*l, 1, 2, row, row + 1, FILL);
117 t->attach (_click_emphasis_path_entry, 2, 3, row, row + 1, FILL);
118 _click_emphasis_browse_button.signal_clicked ().connect (
119 sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
120 t->attach (_click_emphasis_browse_button, 3, 4, row, row + 1, FILL);
123 _click_fader = new FaderOption (
126 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
127 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
130 _click_fader->add_to_page (this);
131 _click_fader->set_state_from_config ();
133 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
134 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
136 if (_rc_config->get_click_sound ().empty() &&
137 _rc_config->get_click_emphasis_sound().empty()) {
138 _use_default_click_check_button.set_active (true);
139 _use_emphasis_on_click_check_button.set_active (true);
142 _use_default_click_check_button.set_active (false);
143 _use_emphasis_on_click_check_button.set_active (false);
147 void parameter_changed (string const & p)
149 if (p == "click-sound") {
150 _click_path_entry.set_text (_rc_config->get_click_sound());
151 } else if (p == "click-emphasis-sound") {
152 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
153 } else if (p == "use-click-emphasis") {
154 bool x = _rc_config->get_use_click_emphasis ();
155 _use_emphasis_on_click_check_button.set_active (x);
156 } else if (p == "click-gain") {
157 _click_fader->set_state_from_config ();
161 void set_state_from_config ()
163 parameter_changed ("click-sound");
164 parameter_changed ("click-emphasis-sound");
165 parameter_changed ("use-click-emphasis");
170 void click_browse_clicked ()
172 SoundFileChooser sfdb (_("Choose Click"));
177 if (sfdb.run () == RESPONSE_OK) {
178 click_chosen (sfdb.get_filename());
182 void click_chosen (string const & path)
184 _click_path_entry.set_text (path);
185 _rc_config->set_click_sound (path);
188 void click_changed ()
190 click_chosen (_click_path_entry.get_text ());
193 void click_emphasis_browse_clicked ()
195 SoundFileChooser sfdb (_("Choose Click Emphasis"));
200 if (sfdb.run () == RESPONSE_OK) {
201 click_emphasis_chosen (sfdb.get_filename());
205 void click_emphasis_chosen (string const & path)
207 _click_emphasis_path_entry.set_text (path);
208 _rc_config->set_click_emphasis_sound (path);
211 void click_emphasis_changed ()
213 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
216 void use_default_click_toggled ()
218 if (_use_default_click_check_button.get_active ()) {
219 _rc_config->set_click_sound ("");
220 _rc_config->set_click_emphasis_sound ("");
221 _click_path_entry.set_sensitive (false);
222 _click_emphasis_path_entry.set_sensitive (false);
223 _click_browse_button.set_sensitive (false);
224 _click_emphasis_browse_button.set_sensitive (false);
226 _click_path_entry.set_sensitive (true);
227 _click_emphasis_path_entry.set_sensitive (true);
228 _click_browse_button.set_sensitive (true);
229 _click_emphasis_browse_button.set_sensitive (true);
233 void use_emphasis_on_click_toggled ()
235 if (_use_emphasis_on_click_check_button.get_active ()) {
236 _rc_config->set_use_click_emphasis(true);
238 _rc_config->set_use_click_emphasis(false);
242 RCConfiguration* _rc_config;
243 CheckButton _use_default_click_check_button;
244 CheckButton _use_emphasis_on_click_check_button;
245 Entry _click_path_entry;
246 Entry _click_emphasis_path_entry;
247 Button _click_browse_button;
248 Button _click_emphasis_browse_button;
249 FaderOption* _click_fader;
252 class UndoOptions : public OptionEditorComponent
255 UndoOptions (RCConfiguration* c) :
257 _limit_undo_button (_("Limit undo history to")),
258 _save_undo_button (_("Save undo history of"))
260 // TODO get rid of GTK -> use OptionEditor SpinOption
261 _limit_undo_spin.set_range (0, 512);
262 _limit_undo_spin.set_increments (1, 10);
264 _save_undo_spin.set_range (0, 512);
265 _save_undo_spin.set_increments (1, 10);
267 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
268 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
269 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
270 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
273 void parameter_changed (string const & p)
275 if (p == "history-depth") {
276 int32_t const d = _rc_config->get_history_depth();
277 _limit_undo_button.set_active (d != 0);
278 _limit_undo_spin.set_sensitive (d != 0);
279 _limit_undo_spin.set_value (d);
280 } else if (p == "save-history") {
281 bool const x = _rc_config->get_save_history ();
282 _save_undo_button.set_active (x);
283 _save_undo_spin.set_sensitive (x);
284 } else if (p == "save-history-depth") {
285 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
289 void set_state_from_config ()
291 parameter_changed ("save-history");
292 parameter_changed ("history-depth");
293 parameter_changed ("save-history-depth");
296 void limit_undo_toggled ()
298 bool const x = _limit_undo_button.get_active ();
299 _limit_undo_spin.set_sensitive (x);
300 int32_t const n = x ? 16 : 0;
301 _limit_undo_spin.set_value (n);
302 _rc_config->set_history_depth (n);
305 void limit_undo_changed ()
307 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
310 void save_undo_toggled ()
312 bool const x = _save_undo_button.get_active ();
313 _rc_config->set_save_history (x);
316 void save_undo_changed ()
318 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
321 void add_to_page (OptionEditorPage* p)
323 int const n = p->table.property_n_rows();
324 Table* t = & p->table;
326 t->resize (n + 2, 3);
328 Label* l = manage (left_aligned_label (_("commands")));
329 HBox* box = manage (new HBox());
330 box->set_spacing (4);
331 box->pack_start (_limit_undo_spin, false, false);
332 box->pack_start (*l, true, true);
333 t->attach (_limit_undo_button, 1, 2, n, n +1, FILL);
334 t->attach (*box, 2, 3, n, n + 1, FILL | EXPAND);
336 l = manage (left_aligned_label (_("commands")));
337 box = manage (new HBox());
338 box->set_spacing (4);
339 box->pack_start (_save_undo_spin, false, false);
340 box->pack_start (*l, true, true);
341 t->attach (_save_undo_button, 1, 2, n + 1, n + 2, FILL);
342 t->attach (*box, 2, 3, n + 1, n + 2, FILL | EXPAND);
345 Gtk::Widget& tip_widget() {
346 return _limit_undo_button; // unused
350 RCConfiguration* _rc_config;
351 CheckButton _limit_undo_button;
352 SpinButton _limit_undo_spin;
353 CheckButton _save_undo_button;
354 SpinButton _save_undo_spin;
358 static const struct {
370 { "Key|Shift", GDK_SHIFT_MASK },
371 { "Command", GDK_MOD2_MASK },
372 { "Control", GDK_CONTROL_MASK },
373 { "Option", GDK_MOD1_MASK },
374 { "Command-Shift", GDK_MOD2_MASK|GDK_SHIFT_MASK },
375 { "Command-Option", GDK_MOD2_MASK|GDK_MOD1_MASK },
376 { "Command-Control", GDK_MOD2_MASK|GDK_CONTROL_MASK },
377 { "Command-Option-Control", GDK_MOD2_MASK|GDK_MOD1_MASK|GDK_CONTROL_MASK },
378 { "Option-Control", GDK_MOD1_MASK|GDK_CONTROL_MASK },
379 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
380 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
381 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_MOD2_MASK },
384 { "Key|Shift", GDK_SHIFT_MASK },
385 { "Control", GDK_CONTROL_MASK },
386 { "Alt", GDK_MOD1_MASK },
387 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
388 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
389 { "Control-Windows", GDK_CONTROL_MASK|GDK_MOD4_MASK },
390 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
391 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
392 { "Alt-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
393 { "Alt-Shift-Windows", GDK_MOD1_MASK|GDK_SHIFT_MASK|GDK_MOD4_MASK },
394 { "Mod2", GDK_MOD2_MASK },
395 { "Mod3", GDK_MOD3_MASK },
396 { "Windows", GDK_MOD4_MASK },
397 { "Mod5", GDK_MOD5_MASK },
403 class KeyboardOptions : public OptionEditorMiniPage
407 : _delete_button_adjustment (3, 1, 12)
408 , _delete_button_spin (_delete_button_adjustment)
409 , _edit_button_adjustment (3, 1, 5)
410 , _edit_button_spin (_edit_button_adjustment)
411 , _insert_note_button_adjustment (3, 1, 5)
412 , _insert_note_button_spin (_insert_note_button_adjustment)
414 // TODO get rid of GTK -> use OptionEditor Widgets
416 const std::string restart_msg = _("\nChanges to this setting will only persist after your project has been saved.");
417 /* internationalize and prepare for use with combos */
420 for (int i = 0; modifiers[i].name; ++i) {
421 dumb.push_back (S_(modifiers[i].name));
424 set_popdown_strings (_edit_modifier_combo, dumb);
425 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
426 Gtkmm2ext::UI::instance()->set_tip (_edit_modifier_combo,
427 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
434 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
435 l->set_name ("OptionsLabel");
439 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
440 strs.push_back (bf->first);
443 set_popdown_strings (_keyboard_layout_selector, strs);
444 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
445 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
447 t->attach (*l, col + 1, col + 2, row, row + 1, FILL, FILL);
448 t->attach (_keyboard_layout_selector, col + 2, col + 3, row, row + 1, FILL | EXPAND, FILL);
453 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Clicking:"))));
454 l->set_name ("OptionEditorHeading");
455 l->set_use_markup (true);
456 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
461 l = manage (left_aligned_label (_("Edit using:")));
462 l->set_name ("OptionsLabel");
464 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
465 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
467 l = manage (new Label (_("+ button")));
468 l->set_name ("OptionsLabel");
470 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
471 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, SHRINK , FILL);
473 _edit_button_spin.set_name ("OptionsEntry");
474 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
479 set_popdown_strings (_delete_modifier_combo, dumb);
480 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
481 Gtkmm2ext::UI::instance()->set_tip (_delete_modifier_combo,
482 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
484 l = manage (left_aligned_label (_("Delete using:")));
485 l->set_name ("OptionsLabel");
487 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
488 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
490 l = manage (new Label (_("+ button")));
491 l->set_name ("OptionsLabel");
493 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
494 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, SHRINK, FILL);
496 _delete_button_spin.set_name ("OptionsEntry");
497 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
502 set_popdown_strings (_insert_note_modifier_combo, dumb);
503 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
504 Gtkmm2ext::UI::instance()->set_tip (_insert_note_modifier_combo,
505 (string_compose (_("<b>Recommended Setting: %1 + button 1 (left mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
507 l = manage (left_aligned_label (_("Insert note using:")));
508 l->set_name ("OptionsLabel");
510 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
511 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
513 l = manage (new Label (_("+ button")));
514 l->set_name ("OptionsLabel");
516 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
517 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, SHRINK, FILL);
519 _insert_note_button_spin.set_name ("OptionsEntry");
520 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
524 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Beginning a Drag:"))));
525 l->set_name ("OptionEditorHeading");
526 l->set_use_markup (true);
527 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
533 set_popdown_strings (_copy_modifier_combo, dumb);
534 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
535 Gtkmm2ext::UI::instance()->set_tip (_copy_modifier_combo,
536 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
538 Keyboard::secondary_modifier_name (),
540 Keyboard::primary_modifier_name (),
544 l = manage (left_aligned_label (_("Copy items using:")));
545 l->set_name ("OptionsLabel");
547 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
548 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
553 /* constraint modifier */
554 set_popdown_strings (_constraint_modifier_combo, dumb);
555 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
556 Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo,
557 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
559 Keyboard::primary_modifier_name (),
561 Keyboard::tertiary_modifier_name (),
565 l = manage (left_aligned_label (_("Constrain drag using:")));
566 l->set_name ("OptionsLabel");
568 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
569 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
575 set_popdown_strings (_push_points_combo, dumb);
576 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
578 std::string mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
579 Gtkmm2ext::UI::instance()->set_tip (_push_points_combo,
580 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
582 l = manage (left_aligned_label (_("Push points using:")));
583 l->set_name ("OptionsLabel");
585 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
586 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
590 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Beginning a Trim:"))));
591 l->set_name ("OptionEditorHeading");
592 l->set_use_markup (true);
593 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
599 set_popdown_strings (_trim_contents_combo, dumb);
600 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
601 Gtkmm2ext::UI::instance()->set_tip (_trim_contents_combo,
602 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
604 l = manage (left_aligned_label (_("Trim contents using:")));
605 l->set_name ("OptionsLabel");
607 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
608 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
614 set_popdown_strings (_trim_anchored_combo, dumb);
615 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
617 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::tertiary_modifier_name ());
618 Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo,
619 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
621 l = manage (left_aligned_label (_("Anchored trim using:")));
622 l->set_name ("OptionsLabel");
624 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
626 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
631 /* jump trim disabled for now
632 set_popdown_strings (_trim_jump_combo, dumb);
633 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
635 l = manage (left_aligned_label (_("Jump after trim using:")));
636 l->set_name ("OptionsLabel");
638 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
640 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
646 /* note resize relative */
647 set_popdown_strings (_note_size_relative_combo, dumb);
648 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
649 Gtkmm2ext::UI::instance()->set_tip (_note_size_relative_combo,
650 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg))); // XXX 2ndary
652 l = manage (left_aligned_label (_("Resize notes relatively using:")));
653 l->set_name ("OptionsLabel");
655 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
657 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
661 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Dragging:"))));
662 l->set_name ("OptionEditorHeading");
663 l->set_use_markup (true);
664 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
670 set_popdown_strings (_snap_modifier_combo, dumb);
671 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
673 mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ());
675 mod_str = Keyboard::secondary_modifier_name();
677 Gtkmm2ext::UI::instance()->set_tip (_snap_modifier_combo,
678 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
680 l = manage (left_aligned_label (_("Ignore snap using:")));
681 l->set_name ("OptionsLabel");
683 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
684 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
690 set_popdown_strings (_snap_delta_combo, dumb);
691 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
693 mod_str = Keyboard::level4_modifier_name ();
695 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::level4_modifier_name ());
697 Gtkmm2ext::UI::instance()->set_tip (_snap_delta_combo,
698 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
700 l = manage (left_aligned_label (_("Snap relatively using:")));
701 l->set_name ("OptionsLabel");
703 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
704 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
708 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Trimming:"))));
709 l->set_name ("OptionEditorHeading");
710 l->set_use_markup (true);
711 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
717 set_popdown_strings (_trim_overlap_combo, dumb);
718 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
720 Gtkmm2ext::UI::instance()->set_tip (_trim_overlap_combo,
721 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
723 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
724 l->set_name ("OptionsLabel");
726 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
727 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
731 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Dragging Control Points:"))));
732 l->set_name ("OptionEditorHeading");
733 l->set_use_markup (true);
734 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
740 set_popdown_strings (_fine_adjust_combo, dumb);
741 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
743 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::secondary_modifier_name ()); // XXX just 2ndary ?!
744 Gtkmm2ext::UI::instance()->set_tip (_fine_adjust_combo,
745 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
747 l = manage (left_aligned_label (_("Fine adjust using:")));
748 l->set_name ("OptionsLabel");
750 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
751 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
753 OptionEditorHeading* h = new OptionEditorHeading (_("Reset"));
754 h->add_to_page (this);
756 RcActionButton* rb = new RcActionButton (_("Reset to recommended defaults"),
757 sigc::mem_fun (*this, &KeyboardOptions::reset_to_defaults));
758 rb->add_to_page (this);
760 set_state_from_config ();
763 void parameter_changed (string const &)
765 /* XXX: these aren't really config options... */
768 void set_state_from_config ()
770 _delete_button_adjustment.set_value (Keyboard::delete_button());
771 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
772 _edit_button_adjustment.set_value (Keyboard::edit_button());
774 for (int x = 0; modifiers[x].name; ++x) {
775 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
776 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
778 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
779 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
781 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
782 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
784 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
785 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
787 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
788 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
790 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
791 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
793 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
794 _push_points_combo.set_active_text (S_(modifiers[x].name));
796 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
797 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
799 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
800 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
803 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
804 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
807 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
808 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
810 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
811 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
813 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
814 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
816 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
817 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
822 void add_to_page (OptionEditorPage* p)
824 int const n = p->table.property_n_rows();
825 p->table.resize (n + 1, 3);
826 p->table.attach (box, 1, 3, n, n + 1, FILL | EXPAND, SHRINK, 0, 0);
831 void bindings_changed ()
833 string const txt = _keyboard_layout_selector.get_active_text();
835 /* XXX: config...? for all this keyboard stuff */
837 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
838 if (txt == i->first) {
839 if (Keyboard::load_keybindings (i->second)) {
840 Keyboard::save_keybindings ();
846 void edit_modifier_chosen ()
848 string const txt = _edit_modifier_combo.get_active_text();
850 for (int i = 0; modifiers[i].name; ++i) {
851 if (txt == S_(modifiers[i].name)) {
852 Keyboard::set_edit_modifier (modifiers[i].modifier);
858 void delete_modifier_chosen ()
860 string const txt = _delete_modifier_combo.get_active_text();
862 for (int i = 0; modifiers[i].name; ++i) {
863 if (txt == S_(modifiers[i].name)) {
864 Keyboard::set_delete_modifier (modifiers[i].modifier);
870 void copy_modifier_chosen ()
872 string const txt = _copy_modifier_combo.get_active_text();
874 for (int i = 0; modifiers[i].name; ++i) {
875 if (txt == S_(modifiers[i].name)) {
876 Keyboard::set_copy_modifier (modifiers[i].modifier);
882 void insert_note_modifier_chosen ()
884 string const txt = _insert_note_modifier_combo.get_active_text();
886 for (int i = 0; modifiers[i].name; ++i) {
887 if (txt == S_(modifiers[i].name)) {
888 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
894 void snap_modifier_chosen ()
896 string const txt = _snap_modifier_combo.get_active_text();
898 for (int i = 0; modifiers[i].name; ++i) {
899 if (txt == S_(modifiers[i].name)) {
900 Keyboard::set_snap_modifier (modifiers[i].modifier);
906 void snap_delta_modifier_chosen ()
908 string const txt = _snap_delta_combo.get_active_text();
910 for (int i = 0; modifiers[i].name; ++i) {
911 if (txt == S_(modifiers[i].name)) {
912 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
918 void constraint_modifier_chosen ()
920 string const txt = _constraint_modifier_combo.get_active_text();
922 for (int i = 0; modifiers[i].name; ++i) {
923 if (txt == S_(modifiers[i].name)) {
924 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
930 void trim_contents_modifier_chosen ()
932 string const txt = _trim_contents_combo.get_active_text();
934 for (int i = 0; modifiers[i].name; ++i) {
935 if (txt == S_(modifiers[i].name)) {
936 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
942 void trim_overlap_modifier_chosen ()
944 string const txt = _trim_overlap_combo.get_active_text();
946 for (int i = 0; modifiers[i].name; ++i) {
947 if (txt == S_(modifiers[i].name)) {
948 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
954 void trim_anchored_modifier_chosen ()
956 string const txt = _trim_anchored_combo.get_active_text();
958 for (int i = 0; modifiers[i].name; ++i) {
959 if (txt == S_(modifiers[i].name)) {
960 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
966 void fine_adjust_modifier_chosen ()
968 string const txt = _fine_adjust_combo.get_active_text();
970 for (int i = 0; modifiers[i].name; ++i) {
971 if (txt == S_(modifiers[i].name)) {
972 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
978 void push_points_modifier_chosen ()
980 string const txt = _push_points_combo.get_active_text();
982 for (int i = 0; modifiers[i].name; ++i) {
983 if (txt == S_(modifiers[i].name)) {
984 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
990 void note_size_relative_modifier_chosen ()
992 string const txt = _note_size_relative_combo.get_active_text();
994 for (int i = 0; modifiers[i].name; ++i) {
995 if (txt == S_(modifiers[i].name)) {
996 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
1002 void delete_button_changed ()
1004 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
1007 void edit_button_changed ()
1009 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
1012 void insert_note_button_changed ()
1014 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
1017 void reset_to_defaults ()
1020 Keyboard::set_edit_modifier (Keyboard::PrimaryModifier);
1021 Keyboard::set_edit_button (3);
1022 Keyboard::set_delete_modifier (Keyboard::TertiaryModifier);
1023 Keyboard::set_delete_button (3);
1024 Keyboard::set_insert_note_modifier (Keyboard::PrimaryModifier);
1025 Keyboard::set_insert_note_button (1);
1027 /* when beginning a drag */
1029 Keyboard::set_copy_modifier (Keyboard::SecondaryModifier);
1031 Keyboard::set_copy_modifier (Keyboard::PrimaryModifier);
1035 ArdourKeyboard::set_constraint_modifier (Keyboard::PrimaryModifier);
1037 ArdourKeyboard::set_constraint_modifier (Keyboard::TertiaryModifier);
1039 ArdourKeyboard::set_push_points_modifier (Keyboard::PrimaryModifier | Keyboard::Level4Modifier);
1041 /* when beginning a trim */
1042 ArdourKeyboard::set_trim_contents_modifier (Keyboard::PrimaryModifier);
1043 ArdourKeyboard::set_trim_anchored_modifier (Keyboard::PrimaryModifier | Keyboard::TertiaryModifier);
1044 ArdourKeyboard::set_note_size_relative_modifier (Keyboard::TertiaryModifier); // XXX better: 2ndary
1046 /* while dragging */
1048 Keyboard::set_snap_modifier (Keyboard::TertiaryModifier);
1050 Keyboard::set_snap_modifier (Keyboard::SecondaryModifier);
1053 Keyboard::set_snap_delta_modifier (Keyboard::Level4Modifier);
1055 Keyboard::set_snap_delta_modifier (Keyboard::SecondaryModifier | Keyboard::Level4Modifier);
1058 /* while trimming */
1059 ArdourKeyboard::set_trim_overlap_modifier (Keyboard::TertiaryModifier);
1061 /* while dragging ctrl points */
1062 ArdourKeyboard::set_fine_adjust_modifier (/*Keyboard::PrimaryModifier | */Keyboard::SecondaryModifier); // XXX
1064 set_state_from_config ();
1067 ComboBoxText _keyboard_layout_selector;
1068 ComboBoxText _edit_modifier_combo;
1069 ComboBoxText _delete_modifier_combo;
1070 ComboBoxText _copy_modifier_combo;
1071 ComboBoxText _insert_note_modifier_combo;
1072 ComboBoxText _snap_modifier_combo;
1073 ComboBoxText _snap_delta_combo;
1074 ComboBoxText _constraint_modifier_combo;
1075 ComboBoxText _trim_contents_combo;
1076 ComboBoxText _trim_overlap_combo;
1077 ComboBoxText _trim_anchored_combo;
1078 ComboBoxText _trim_jump_combo;
1079 ComboBoxText _fine_adjust_combo;
1080 ComboBoxText _push_points_combo;
1081 ComboBoxText _note_size_relative_combo;
1082 Adjustment _delete_button_adjustment;
1083 SpinButton _delete_button_spin;
1084 Adjustment _edit_button_adjustment;
1085 SpinButton _edit_button_spin;
1086 Adjustment _insert_note_button_adjustment;
1087 SpinButton _insert_note_button_spin;
1091 class FontScalingOptions : public HSliderOption
1094 FontScalingOptions ()
1095 : HSliderOption ("font-scale", _("GUI and Font scaling"),
1096 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_font_scale),
1097 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_font_scale),
1101 const std::string dflt = _("100%");
1102 const std::string empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
1104 _hscale.set_name("FontScaleSlider");
1105 _hscale.set_draw_value(false);
1106 _hscale.add_mark(50, Gtk::POS_TOP, empty);
1107 _hscale.add_mark(60, Gtk::POS_TOP, empty);
1108 _hscale.add_mark(70, Gtk::POS_TOP, empty);
1109 _hscale.add_mark(80, Gtk::POS_TOP, empty);
1110 _hscale.add_mark(90, Gtk::POS_TOP, empty);
1111 _hscale.add_mark(100, Gtk::POS_TOP, dflt);
1112 _hscale.add_mark(125, Gtk::POS_TOP, empty);
1113 _hscale.add_mark(150, Gtk::POS_TOP, empty);
1114 _hscale.add_mark(175, Gtk::POS_TOP, empty);
1115 _hscale.add_mark(200, Gtk::POS_TOP, empty);
1116 _hscale.add_mark(250, Gtk::POS_TOP, empty);
1118 set_note (_("Adjusting the scale requires an application restart to re-layout."));
1123 HSliderOption::changed ();
1124 /* XXX: should be triggered from the parameter changed signal */
1125 UIConfiguration::instance().reset_dpi ();
1129 class VstTimeOutSliderOption : public HSliderOption
1132 VstTimeOutSliderOption (RCConfiguration* c)
1133 : HSliderOption ("vst-scan-timeout", _("Scan Time Out"),
1134 sigc::mem_fun (*c, &RCConfiguration::get_vst_scan_timeout),
1135 sigc::mem_fun (*c, &RCConfiguration::set_vst_scan_timeout),
1138 _label.set_alignment (1.0, 0.5); // match buttons below
1139 _hscale.set_digits (0);
1140 _hscale.set_draw_value(false);
1141 _hscale.add_mark( 0, Gtk::POS_TOP, _("\u221e")); // infinity
1142 _hscale.add_mark( 300, Gtk::POS_TOP, _("30 sec"));
1143 _hscale.add_mark( 600, Gtk::POS_TOP, _("1 min"));
1144 _hscale.add_mark(1200, Gtk::POS_TOP, _("2 mins"));
1145 _hscale.add_mark(1800, Gtk::POS_TOP, _("3 mins"));
1146 _hscale.add_mark(2400, Gtk::POS_TOP, _("4 mins"));
1147 _hscale.add_mark(3000, Gtk::POS_TOP, _("5 mins"));
1149 Gtkmm2ext::UI::instance()->set_tip(_hscale,
1150 _("Specify the default timeout for plugin instantiation. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1154 class ClipLevelOptions : public OptionEditorComponent
1158 : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1159 , _clip_level_slider (_clip_level_adjustment)
1160 , _label (_("Waveform Clip Level (dBFS):"))
1162 _label.set_name ("OptionsLabel");
1164 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ());
1166 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1168 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1171 void parameter_changed (string const & p)
1173 if (p == "waveform-clip-level") {
1174 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level());
1176 if (p == "show-waveform-clipping") {
1177 _clip_level_slider.set_sensitive (UIConfiguration::instance().get_show_waveform_clipping ());
1181 void set_state_from_config ()
1183 parameter_changed ("waveform-clip-level");
1184 parameter_changed ("show-waveform-clipping");
1187 void add_to_page (OptionEditorPage* p) {
1188 add_widgets_to_page (p, &_label, &_clip_level_slider);
1191 Gtk::Widget& tip_widget() {
1192 return _clip_level_slider;
1197 void clip_level_changed ()
1199 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1200 /* XXX: should be triggered from the parameter changed signal */
1201 ArdourWaveView::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1204 Adjustment _clip_level_adjustment;
1205 HScale _clip_level_slider;
1209 class BufferingOptions : public OptionEditorComponent
1212 BufferingOptions (RCConfiguration* c)
1214 , _label (_("Preset:"))
1215 , _playback ("playback-buffer-seconds", _("Playback (seconds of buffering)"),
1216 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_playback_buffer_seconds),
1217 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_playback_buffer_seconds),
1219 , _capture ("capture-buffer-seconds", _("Recording (seconds of buffering)"),
1220 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_capture_buffer_seconds),
1221 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_capture_buffer_seconds),
1224 // TODO use ComboOption
1225 vector<string> presets;
1227 /* these must match the order of the enums for BufferingPreset */
1228 presets.push_back (_("Small sessions (4-16 tracks)"));
1229 presets.push_back (_("Medium sessions (16-64 tracks)"));
1230 presets.push_back (_("Large sessions (64+ tracks)"));
1231 presets.push_back (_("Custom (set by sliders below)"));
1233 set_popdown_strings (_buffering_presets_combo, presets);
1234 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1236 _label.set_name ("OptionsLabel");
1237 _label.set_alignment (0, 0.5);
1241 add_to_page (OptionEditorPage* p)
1243 add_widgets_to_page (p, &_label, &_buffering_presets_combo);
1244 _playback.add_to_page (p);
1245 _capture.add_to_page (p);
1248 void parameter_changed (string const & p)
1250 if (p == "buffering-preset") {
1251 switch (_rc_config->get_buffering_preset()) {
1253 _playback.set_sensitive (false);
1254 _capture.set_sensitive (false);
1255 _buffering_presets_combo.set_active (0);
1258 _playback.set_sensitive (false);
1259 _capture.set_sensitive (false);
1260 _buffering_presets_combo.set_active (1);
1263 _playback.set_sensitive (false);
1264 _capture.set_sensitive (false);
1265 _buffering_presets_combo.set_active (2);
1268 _playback.set_sensitive (true);
1269 _capture.set_sensitive (true);
1270 _buffering_presets_combo.set_active (3);
1274 _playback.parameter_changed (p);
1275 _capture.parameter_changed (p);
1278 void set_state_from_config ()
1280 parameter_changed ("buffering-preset");
1281 _playback.set_state_from_config();
1282 _capture.set_state_from_config();
1285 Gtk::Widget& tip_widget() { return _buffering_presets_combo; }
1289 void preset_changed ()
1291 int index = _buffering_presets_combo.get_active_row_number ();
1297 _rc_config->set_buffering_preset (Small);
1300 _rc_config->set_buffering_preset (Medium);
1303 _rc_config->set_buffering_preset (Large);
1306 _rc_config->set_buffering_preset (Custom);
1309 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1314 RCConfiguration* _rc_config;
1316 HSliderOption _playback;
1317 HSliderOption _capture;
1318 ComboBoxText _buffering_presets_combo;
1321 class ControlSurfacesOptions : public OptionEditorMiniPage
1324 ControlSurfacesOptions ()
1325 : _ignore_view_change (0)
1327 _store = ListStore::create (_model);
1328 _view.set_model (_store);
1329 _view.append_column (_("Control Surface Protocol"), _model.name);
1330 _view.get_column(0)->set_resizable (true);
1331 _view.get_column(0)->set_expand (true);
1332 _view.append_column_editable (_("Enable"), _model.enabled);
1334 Gtk::HBox* edit_box = manage (new Gtk::HBox);
1335 edit_box->set_spacing(3);
1338 Label* label = manage (new Label);
1339 label->set_text (_("Edit the settings for selected protocol (it must be ENABLED first):"));
1340 edit_box->pack_start (*label, false, false);
1343 edit_button = manage (new Button(_("Show Protocol Settings")));
1344 edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
1345 edit_box->pack_start (*edit_button, true, true);
1346 edit_button->set_sensitive (false);
1347 edit_button->show ();
1349 int const n = table.property_n_rows();
1350 table.resize (n + 2, 3);
1351 table.attach (_view, 0, 3, n, n + 1);
1352 table.attach (*edit_box, 0, 3, n + 1, n + 2);
1354 ControlProtocolManager& m = ControlProtocolManager::instance ();
1355 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1356 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1358 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1359 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1360 _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
1363 void parameter_changed (std::string const &)
1368 void set_state_from_config ()
1372 ControlProtocolManager& m = ControlProtocolManager::instance ();
1373 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1375 if (!(*i)->mandatory) {
1376 TreeModel::Row r = *_store->append ();
1377 r[_model.name] = (*i)->name;
1378 r[_model.enabled] = 0 != (*i)->protocol;
1379 r[_model.protocol_info] = *i;
1386 void protocol_status_changed (ControlProtocolInfo* cpi) {
1388 TreeModel::Children rows = _store->children();
1390 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1391 string n = ((*x)[_model.name]);
1393 if ((*x)[_model.protocol_info] == cpi) {
1394 _ignore_view_change++;
1395 (*x)[_model.enabled] = 0 != cpi->protocol;
1396 _ignore_view_change--;
1397 selection_changed (); // update sensitivity
1403 void selection_changed ()
1405 //enable the Edit button when a row is selected for editing
1406 TreeModel::Row row = *(_view.get_selection()->get_selected());
1407 if (row && row[_model.enabled]) {
1408 ControlProtocolInfo* cpi = row[_model.protocol_info];
1409 edit_button->set_sensitive (cpi && cpi->protocol && cpi->protocol->has_editor ());
1411 edit_button->set_sensitive (false);
1415 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1417 TreeModel::Row r = *i;
1419 if (_ignore_view_change) {
1423 ControlProtocolInfo* cpi = r[_model.protocol_info];
1428 bool const was_enabled = (cpi->protocol != 0);
1429 bool const is_enabled = r[_model.enabled];
1432 if (was_enabled != is_enabled) {
1435 ControlProtocolManager::instance().activate (*cpi);
1437 ControlProtocolManager::instance().deactivate (*cpi);
1441 selection_changed ();
1444 void edit_btn_clicked ()
1447 ControlProtocolInfo* cpi;
1450 row = *(_view.get_selection()->get_selected());
1451 if (!row[_model.enabled]) {
1454 cpi = row[_model.protocol_info];
1455 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1458 Box* box = (Box*) cpi->protocol->get_gui ();
1462 if (box->get_parent()) {
1463 static_cast<ArdourWindow*>(box->get_parent())->present();
1466 WindowTitle title (Glib::get_application_name());
1467 title += row[_model.name];
1468 title += _("Configuration");
1469 /* once created, the window is managed by the surface itself (as ->get_parent())
1470 * Surface's tear_down_gui() is called on session close, when de-activating
1471 * or re-initializing a surface.
1472 * tear_down_gui() hides an deletes the Window if it exists.
1474 ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
1475 win->set_title (_("Control Protocol Settings"));
1481 void edit_clicked (GdkEventButton* ev)
1483 if (ev->type != GDK_2BUTTON_PRESS) {
1490 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1494 ControlSurfacesModelColumns ()
1498 add (protocol_info);
1501 TreeModelColumn<string> name;
1502 TreeModelColumn<bool> enabled;
1503 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1506 Glib::RefPtr<ListStore> _store;
1507 ControlSurfacesModelColumns _model;
1509 PBD::ScopedConnection protocol_status_connection;
1510 uint32_t _ignore_view_change;
1511 Gtk::Button* edit_button;
1514 class VideoTimelineOptions : public OptionEditorMiniPage
1517 VideoTimelineOptions (RCConfiguration* c)
1519 , _show_video_export_info_button (_("Show Video Export Info before export"))
1520 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1521 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1522 , _xjadeo_browse_button (_("Browse..."))
1525 int n = table.property_n_rows();
1527 t->attach (_show_video_export_info_button, 1, 4, n, n + 1);
1528 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1529 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1530 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1533 t->attach (_show_video_server_dialog_button, 1, 4, n, n + 1);
1534 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1535 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1536 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1539 t->attach (_video_advanced_setup_button, 1, 4, n, n + 1, FILL);
1540 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1541 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1542 _("<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."));
1545 Label* l = manage (new Label (_("Video Server URL:")));
1546 l->set_alignment (0, 0.5);
1547 t->attach (*l, 1, 2, n, n + 1, FILL);
1548 t->attach (_video_server_url_entry, 2, 4, n, n + 1, FILL);
1549 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1550 _("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"));
1553 l = manage (new Label (_("Video Folder:")));
1554 l->set_alignment (0, 0.5);
1555 t->attach (*l, 1, 2, n, n + 1, FILL);
1556 t->attach (_video_server_docroot_entry, 2, 4, n, n + 1);
1557 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1558 _("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."));
1561 l = manage (new Label (""));
1562 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1565 l = manage (new Label (string_compose ("<b>%1</b>", _("Video Monitor"))));
1566 l->set_use_markup (true);
1567 l->set_alignment (0, 0.5);
1568 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1571 l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"),
1574 #elif defined PLATFORM_WINDOWS
1580 l->set_alignment (0, 0.5);
1581 t->attach (*l, 1, 4, n, n + 1, FILL);
1584 t->attach (_custom_xjadeo_path, 2, 3, n, n + 1, EXPAND|FILL);
1585 Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart."));
1586 t->attach (_xjadeo_browse_button, 3, 4, n, n + 1, FILL);
1588 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1589 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1590 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1591 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1592 _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed));
1593 _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked));
1595 // xjadeo-path is a UIConfig parameter
1596 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &VideoTimelineOptions::parameter_changed));
1599 void server_url_changed ()
1601 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1604 void server_docroot_changed ()
1606 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1609 void show_video_export_info_toggled ()
1611 bool const x = _show_video_export_info_button.get_active ();
1612 _rc_config->set_show_video_export_info (x);
1615 void show_video_server_dialog_toggled ()
1617 bool const x = _show_video_server_dialog_button.get_active ();
1618 _rc_config->set_show_video_server_dialog (x);
1621 void video_advanced_setup_toggled ()
1623 bool const x = _video_advanced_setup_button.get_active ();
1624 _rc_config->set_video_advanced_setup(x);
1627 void custom_xjadeo_path_changed ()
1629 UIConfiguration::instance().set_xjadeo_binary (_custom_xjadeo_path.get_text());
1632 void xjadeo_browse_clicked ()
1634 Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN);
1635 dialog.set_filename (UIConfiguration::instance().get_xjadeo_binary());
1636 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1637 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1638 if (dialog.run () == Gtk::RESPONSE_OK) {
1639 const std::string& filename = dialog.get_filename();
1640 if (!filename.empty() && (
1642 Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) ||
1644 Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)
1646 UIConfiguration::instance().set_xjadeo_binary (filename);
1651 void parameter_changed (string const & p)
1653 if (p == "video-server-url") {
1654 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1655 } else if (p == "video-server-docroot") {
1656 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1657 } else if (p == "show-video-export-info") {
1658 bool const x = _rc_config->get_show_video_export_info();
1659 _show_video_export_info_button.set_active (x);
1660 } else if (p == "show-video-server-dialog") {
1661 bool const x = _rc_config->get_show_video_server_dialog();
1662 _show_video_server_dialog_button.set_active (x);
1663 } else if (p == "video-advanced-setup") {
1664 bool const x = _rc_config->get_video_advanced_setup();
1665 _video_advanced_setup_button.set_active(x);
1666 _video_server_docroot_entry.set_sensitive(x);
1667 _video_server_url_entry.set_sensitive(x);
1668 } else if (p == "xjadeo-binary") {
1669 _custom_xjadeo_path.set_text (UIConfiguration::instance().get_xjadeo_binary());
1673 void set_state_from_config ()
1675 parameter_changed ("video-server-url");
1676 parameter_changed ("video-server-docroot");
1677 parameter_changed ("video-monitor-setup-dialog");
1678 parameter_changed ("show-video-export-info");
1679 parameter_changed ("show-video-server-dialog");
1680 parameter_changed ("video-advanced-setup");
1681 parameter_changed ("xjadeo-binary");
1685 RCConfiguration* _rc_config;
1686 Entry _video_server_url_entry;
1687 Entry _video_server_docroot_entry;
1688 Entry _custom_xjadeo_path;
1689 CheckButton _show_video_export_info_button;
1690 CheckButton _show_video_server_dialog_button;
1691 CheckButton _video_advanced_setup_button;
1692 Button _xjadeo_browse_button;
1695 class ColumVisibilityOption : public Option
1698 ColumVisibilityOption (string id, string name, uint32_t n_col, sigc::slot<uint32_t> get, sigc::slot<bool, uint32_t> set)
1705 cb = (CheckButton**) malloc (sizeof (CheckButton*) * n_col);
1706 for (uint32_t i = 0; i < n_col; ++i) {
1707 CheckButton* col = manage (new CheckButton (string_compose (_("Column %1"), i + 1)));
1708 col->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ColumVisibilityOption::column_toggled), i));
1709 _hbox.pack_start (*col);
1712 parameter_changed (id);
1715 ~ColumVisibilityOption () {
1719 Gtk::Widget& tip_widget() { return _hbox; }
1721 void set_state_from_config ()
1723 uint32_t c = _get();
1724 for (uint32_t i = 0; i < _n_col; ++i) {
1725 bool en = (c & (1<<i)) ? true : false;
1726 if (cb[i]->get_active () != en) {
1727 cb[i]->set_active (en);
1732 void add_to_page (OptionEditorPage* p)
1734 _heading.add_to_page (p);
1735 add_widget_to_page (p, &_hbox);
1739 void column_toggled (int b) {
1740 uint32_t c = _get();
1742 if (cb[b]->get_active ()) {
1753 OptionEditorHeading _heading;
1757 sigc::slot<uint32_t> _get;
1758 sigc::slot<bool, uint32_t> _set;
1762 /** A class which allows control of visibility of some editor components usign
1763 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1764 * which has the correct members, but with null widget pointers. This
1765 * class allows the user to set visibility of the members, the details
1766 * of which are stored in a configuration variable which can be watched
1767 * by parts of the editor that actually contain the widgets whose visibility
1768 * is being controlled.
1771 class VisibilityOption : public Option
1774 /** @param name User-visible name for this group.
1775 * @param g `Dummy' VisibilityGroup (as described above).
1776 * @param get Method to get the value of the appropriate configuration variable.
1777 * @param set Method to set the value of the appropriate configuration variable.
1779 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1780 : Option (g->get_state_name(), name)
1782 , _visibility_group (g)
1786 /* Watch for changes made by the user to our members */
1787 _visibility_group->VisibilityChanged.connect_same_thread (
1788 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1792 void set_state_from_config ()
1794 /* Set our state from the current configuration */
1795 _visibility_group->set_state (_get ());
1798 void add_to_page (OptionEditorPage* p)
1800 _heading.add_to_page (p);
1801 add_widget_to_page (p, _visibility_group->list_view ());
1804 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1809 /* The user has changed something, so reflect this change
1810 in the RCConfiguration.
1812 _set (_visibility_group->get_state_value ());
1815 OptionEditorHeading _heading;
1816 VisibilityGroup* _visibility_group;
1817 sigc::slot<std::string> _get;
1818 sigc::slot<bool, std::string> _set;
1819 PBD::ScopedConnection _visibility_group_connection;
1823 class MidiPortOptions : public OptionEditorMiniPage, public sigc::trackable
1828 setup_midi_port_view (midi_output_view, false);
1829 setup_midi_port_view (midi_input_view, true);
1831 OptionEditorHeading* h = new OptionEditorHeading (_("MIDI Inputs"));
1832 h->add_to_page (this);
1834 Gtk::ScrolledWindow* scroller = manage (new Gtk::ScrolledWindow);
1835 scroller->add (midi_input_view);
1836 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1837 scroller->set_size_request (-1, 180);
1839 int n = table.property_n_rows();
1840 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1842 h = new OptionEditorHeading (_("MIDI Outputs"));
1843 h->add_to_page (this);
1845 scroller = manage (new Gtk::ScrolledWindow);
1846 scroller->add (midi_output_view);
1847 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1848 scroller->set_size_request (-1, 180);
1850 n = table.property_n_rows();
1851 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1853 midi_output_view.show ();
1854 midi_input_view.show ();
1856 table.signal_show().connect (sigc::mem_fun (*this, &MidiPortOptions::on_show));
1859 void parameter_changed (string const&) {}
1860 void set_state_from_config() {}
1865 AudioEngine::instance()->PortRegisteredOrUnregistered.connect (connections,
1866 invalidator (*this),
1867 boost::bind (&MidiPortOptions::refill, this),
1869 AudioEngine::instance()->MidiPortInfoChanged.connect (connections,
1870 invalidator (*this),
1871 boost::bind (&MidiPortOptions::refill, this),
1873 AudioEngine::instance()->MidiSelectionPortsChanged.connect (connections,
1874 invalidator (*this),
1875 boost::bind (&MidiPortOptions::refill, this),
1881 if (refill_midi_ports (true, midi_input_view)) {
1882 input_label.show ();
1884 input_label.hide ();
1886 if (refill_midi_ports (false, midi_output_view)) {
1887 output_label.show ();
1889 output_label.hide ();
1894 PBD::ScopedConnectionList connections;
1896 /* MIDI port management */
1897 struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord {
1899 MidiPortColumns () {
1908 Gtk::TreeModelColumn<std::string> pretty_name;
1909 Gtk::TreeModelColumn<bool> music_data;
1910 Gtk::TreeModelColumn<bool> control_data;
1911 Gtk::TreeModelColumn<bool> selection;
1912 Gtk::TreeModelColumn<std::string> name;
1913 Gtk::TreeModelColumn<std::string> filler;
1916 MidiPortColumns midi_port_columns;
1917 Gtk::TreeView midi_input_view;
1918 Gtk::TreeView midi_output_view;
1919 Gtk::Label input_label;
1920 Gtk::Label output_label;
1922 void setup_midi_port_view (Gtk::TreeView&, bool with_selection);
1923 bool refill_midi_ports (bool for_input, Gtk::TreeView&);
1924 void pretty_name_edit (std::string const & path, std::string const & new_text, Gtk::TreeView*);
1925 void midi_music_column_toggled (std::string const & path, Gtk::TreeView*);
1926 void midi_control_column_toggled (std::string const & path, Gtk::TreeView*);
1927 void midi_selection_column_toggled (std::string const & path, Gtk::TreeView*);
1931 MidiPortOptions::setup_midi_port_view (Gtk::TreeView& view, bool with_selection)
1933 int pretty_name_column;
1936 int selection_column;
1937 TreeViewColumn* col;
1940 pretty_name_column = view.append_column_editable (_("Name (click to edit)"), midi_port_columns.pretty_name) - 1;
1942 col = manage (new TreeViewColumn ("", midi_port_columns.music_data));
1943 col->set_alignment (ALIGN_CENTER);
1944 l = manage (new Label (_("Music Data")));
1945 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of music performance data."), PROGRAM_NAME));
1946 col->set_widget (*l);
1948 music_column = view.append_column (*col) - 1;
1950 col = manage (new TreeViewColumn ("", midi_port_columns.control_data));
1951 col->set_alignment (ALIGN_CENTER);
1952 l = manage (new Label (_("Control Data")));
1953 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of control data."), PROGRAM_NAME));
1954 col->set_widget (*l);
1956 control_column = view.append_column (*col) - 1;
1958 if (with_selection) {
1959 col = manage (new TreeViewColumn (_("Follow Selection"), midi_port_columns.selection));
1960 selection_column = view.append_column (*col) - 1;
1961 l = manage (new Label (_("Follow Selection")));
1962 set_tooltip (*l, string_compose (_("If ticked, and \"MIDI input follows selection\" is enabled,\n%1 will automatically connect the first selected MIDI track to this port.\n"), PROGRAM_NAME));
1963 col->set_widget (*l);
1967 /* filler column so that the last real column doesn't expand */
1968 view.append_column ("", midi_port_columns.filler);
1970 CellRendererText* pretty_name_cell = dynamic_cast<CellRendererText*> (view.get_column_cell_renderer (pretty_name_column));
1971 pretty_name_cell->property_editable() = true;
1972 pretty_name_cell->signal_edited().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::pretty_name_edit), &view));
1974 CellRendererToggle* toggle_cell;
1976 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (music_column));
1977 toggle_cell->property_activatable() = true;
1978 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_music_column_toggled), &view));
1980 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (control_column));
1981 toggle_cell->property_activatable() = true;
1982 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_control_column_toggled), &view));
1984 if (with_selection) {
1985 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (selection_column));
1986 toggle_cell->property_activatable() = true;
1987 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_selection_column_toggled), &view));
1990 view.get_selection()->set_mode (SELECTION_NONE);
1991 view.set_tooltip_column (4); /* port "real" name */
1992 view.get_column(0)->set_resizable (true);
1993 view.get_column(0)->set_expand (true);
1997 MidiPortOptions::refill_midi_ports (bool for_input, Gtk::TreeView& view)
1999 using namespace ARDOUR;
2001 std::vector<string> ports;
2003 AudioEngine::instance()->get_known_midi_ports (ports);
2005 if (ports.empty()) {
2010 Glib::RefPtr<ListStore> model = Gtk::ListStore::create (midi_port_columns);
2012 for (vector<string>::const_iterator s = ports.begin(); s != ports.end(); ++s) {
2014 if (AudioEngine::instance()->port_is_mine (*s)) {
2018 PortManager::MidiPortInformation mpi (AudioEngine::instance()->midi_port_information (*s));
2020 if (mpi.pretty_name.empty()) {
2021 /* vanished since get_known_midi_ports() */
2025 if (for_input != mpi.input) {
2029 TreeModel::Row row = *(model->append());
2031 row[midi_port_columns.pretty_name] = mpi.pretty_name;
2032 row[midi_port_columns.music_data] = mpi.properties & MidiPortMusic;
2033 row[midi_port_columns.control_data] = mpi.properties & MidiPortControl;
2034 row[midi_port_columns.selection] = mpi.properties & MidiPortSelection;
2035 row[midi_port_columns.name] = *s;
2038 view.set_model (model);
2044 MidiPortOptions::midi_music_column_toggled (string const & path, TreeView* view)
2046 TreeIter iter = view->get_model()->get_iter (path);
2052 bool new_value = ! bool ((*iter)[midi_port_columns.music_data]);
2054 /* don't reset model - wait for MidiPortInfoChanged signal */
2057 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2059 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2064 MidiPortOptions::midi_control_column_toggled (string const & path, TreeView* view)
2066 TreeIter iter = view->get_model()->get_iter (path);
2072 bool new_value = ! bool ((*iter)[midi_port_columns.control_data]);
2074 /* don't reset model - wait for MidiPortInfoChanged signal */
2077 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2079 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2084 MidiPortOptions::midi_selection_column_toggled (string const & path, TreeView* view)
2086 TreeIter iter = view->get_model()->get_iter (path);
2092 bool new_value = ! bool ((*iter)[midi_port_columns.selection]);
2094 /* don't reset model - wait for MidiSelectionPortsChanged signal */
2097 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2099 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2104 MidiPortOptions::pretty_name_edit (std::string const & path, string const & new_text, Gtk::TreeView* view)
2106 TreeIter iter = view->get_model()->get_iter (path);
2112 boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
2114 ARDOUR::PortEngine::PortHandle ph = backend->get_port_by_name ((*iter)[midi_port_columns.name]);
2116 backend->set_port_property (ph, "http://jackaudio.org/metadata/pretty-name", new_text, "");
2117 (*iter)[midi_port_columns.pretty_name] = new_text;
2125 RCOptionEditor::RCOptionEditor ()
2126 : OptionEditorContainer (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
2127 , Tabbable (*this, _("Preferences")
2129 , false // detached by default (first start, no instant.xml)
2131 ) /* pack self-as-vbox into tabbable */
2132 , _rc_config (Config)
2133 , _mixer_strip_visibility ("mixer-element-visibility")
2135 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
2139 uint32_t hwcpus = hardware_concurrency ();
2143 add_option (_("General"), new OptionEditorHeading (_("DSP CPU Utilization")));
2145 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
2147 _("Signal processing uses"),
2148 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
2149 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
2152 procs->add (-1, _("all but one processor"));
2153 procs->add (0, _("all available processors"));
2155 for (uint32_t i = 1; i <= hwcpus; ++i) {
2156 procs->add (i, string_compose (P_("%1 processor", "%1 processors", i), i));
2159 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
2161 add_option (_("General"), procs);
2164 /* Image cache size */
2165 add_option (_("General"), new OptionEditorHeading (_("Memory Usage")));
2167 HSliderOption *sics = new HSliderOption ("waveform-cache-size",
2168 _("Waveform image cache size (megabytes)"),
2169 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
2170 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size),
2171 1, 1024, 10 /* 1 MB to 1GB in steps of 10MB */
2173 sics->scale().set_digits (0);
2174 Gtkmm2ext::UI::instance()->set_tip (
2176 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
2177 add_option (_("General"), sics);
2179 add_option (_("General"), new OptionEditorHeading (_("Engine")));
2181 add_option (_("General"),
2183 "try-autostart-engine",
2184 _("Try to auto-launch audio/midi engine"),
2185 sigc::mem_fun (*_rc_config, &RCConfiguration::get_try_autostart_engine),
2186 sigc::mem_fun (*_rc_config, &RCConfiguration::set_try_autostart_engine)
2189 add_option (_("General"), new OptionEditorHeading (_("Automation")));
2191 add_option (_("General"),
2192 new SpinOption<double> (
2193 "automation-thinning-factor",
2194 _("Thinning factor (larger value => less data)"),
2195 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
2196 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
2200 add_option (_("General"),
2201 new SpinOption<double> (
2202 "automation-interval-msecs",
2203 _("Automation sampling interval (milliseconds)"),
2204 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
2205 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
2209 add_option (_("General"), new OptionEditorHeading (_("Tempo")));
2211 bo = new BoolOption (
2212 "allow-non-quarter-pulse",
2213 _("Allow non quarter-note pulse"),
2214 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_allow_non_quarter_pulse),
2215 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_allow_non_quarter_pulse)
2217 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2218 string_compose (_("<b>When enabled</b> %1 will allow tempo to be expressed in divisions per minute\n"
2219 "<b>When disabled</b> %1 will only allow tempo to be expressed in quarter notes per minute"),
2221 add_option (_("General"), bo);
2223 if (!ARDOUR::Profile->get_mixbus()) {
2224 add_option (_("General"), new OptionEditorHeading (_("GUI Lock")));
2225 /* Lock GUI timeout */
2227 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2228 _("Lock timeout (seconds)"),
2229 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
2230 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds),
2233 slts->scale().set_digits (0);
2234 Gtkmm2ext::UI::instance()->set_tip (
2236 _("Lock GUI after this many idle seconds (zero to never lock)"));
2237 add_option (_("General"), slts);
2240 add_option (_("General/Session"), new OptionEditorHeading (S_("Options|Undo")));
2242 add_option (_("General/Session"), new UndoOptions (_rc_config));
2244 add_option (_("General/Session"),
2246 "verify-remove-last-capture",
2247 _("Verify removal of last capture"),
2248 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
2249 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
2252 add_option (_("General/Session"), new OptionEditorHeading (_("Session Management")));
2254 add_option (_("General/Session"),
2256 "periodic-safety-backups",
2257 _("Make periodic backups of the session file"),
2258 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
2259 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
2262 add_option (_("General/Session"),
2264 "only-copy-imported-files",
2265 _("Always copy imported files"),
2266 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
2267 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
2270 add_option (_("General/Session"), new DirectoryOption (
2271 X_("default-session-parent-dir"),
2272 _("Default folder for new sessions:"),
2273 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
2274 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
2277 add_option (_("General/Session"),
2278 new SpinOption<uint32_t> (
2279 "max-recent-sessions",
2280 _("Maximum number of recent sessions"),
2281 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
2282 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
2289 add_option (_("General/Translation"), new OptionEditorHeading (_("Internationalization")));
2291 bo = new BoolOption (
2292 "enable-translation",
2293 _("Use translations"),
2294 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2295 sigc::ptr_fun (ARDOUR::set_translations_enabled)
2298 bo->set_note (string_compose (_("These settings will only take effect after %1 is restarted (if available for your language preferences)."), PROGRAM_NAME));
2300 add_option (_("General/Translation"), bo);
2302 parameter_changed ("enable-translation");
2303 #endif // ENABLE_NLS
2308 add_option (_("Editor"), new OptionEditorHeading (_("General")));
2310 bo = new BoolOption (
2312 _("Prompt for new marker names"),
2313 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2314 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2316 add_option (_("Editor"), bo);
2317 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."
2318 "\n\nYou can always rename markers by right-clicking on them"));
2320 add_option (_("Editor"),
2322 "draggable-playhead",
2323 _("Allow dragging of playhead"),
2324 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2325 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2328 ComboOption<float>* dps = new ComboOption<float> (
2329 "draggable-playhead-speed",
2330 _("Playhead dragging speed (%)"),
2331 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead_speed),
2332 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead_speed)
2334 dps->add (0.05, _("5%"));
2335 dps->add (0.1, _("10%"));
2336 dps->add (0.25, _("25%"));
2337 dps->add (0.5, _("50%"));
2338 dps->add (1.0, _("100%"));
2339 add_option (_("Editor"), dps);
2341 ComboOption<float>* eet = new ComboOption<float> (
2342 "extra-ui-extents-time",
2343 _("Limit zooming & summary view to X minutes beyond session extents"),
2344 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_extra_ui_extents_time),
2345 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_extra_ui_extents_time)
2347 eet->add (1, _("1 minute"));
2348 eet->add (2, _("2 minutes"));
2349 eet->add (20, _("20 minutes"));
2350 eet->add (60, _("1 hour"));
2351 eet->add (60*2, _("2 hours"));
2352 eet->add (60*24, _("24 hours"));
2353 add_option (_("Editor"), eet);
2355 if (!Profile->get_mixbus()) {
2357 add_option (_("Editor"),
2359 "use-mouse-position-as-zoom-focus-on-scroll",
2360 _("Zoom to mouse position when zooming with scroll wheel"),
2361 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2362 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2366 add_option (_("Editor"),
2368 "use-time-rulers-to-zoom-with-vertical-drag",
2369 _("Zoom with vertical drag in rulers"),
2370 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag),
2371 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag)
2374 add_option (_("Editor"),
2376 "use-double-click-to-zoom-to-selection",
2377 _("Double click zooms to selection"),
2378 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection),
2379 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection)
2382 add_option (_("Editor"),
2384 "update-editor-during-summary-drag",
2385 _("Update editor window during drags of the summary"),
2386 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2387 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2390 add_option (_("Editor"),
2392 "autoscroll-editor",
2393 _("Auto-scroll editor window when dragging near its edges"),
2394 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2395 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2398 add_option (_("Editor"),
2399 new BoolComboOption (
2400 "show-region-gain-envelopes",
2401 _("Show gain envelopes in audio regions"),
2403 _("only in Draw and Internal Edit modes"),
2404 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2405 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2408 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2410 add_option (_("Editor"),
2412 "automation-follows-regions",
2413 _("Move relevant automation when audio regions are moved"),
2414 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2415 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2418 bo = new BoolOption (
2419 "new-automation-points-on-lane",
2420 _("Ignore Y-axis click position when adding new automation-points"),
2421 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_new_automation_points_on_lane),
2422 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_new_automation_points_on_lane)
2424 add_option (_("Editor"), bo);
2425 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2426 _("<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."));
2428 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2429 "default-fade-shape",
2430 _("Default fade shape"),
2431 sigc::mem_fun (*_rc_config,
2432 &RCConfiguration::get_default_fade_shape),
2433 sigc::mem_fun (*_rc_config,
2434 &RCConfiguration::set_default_fade_shape)
2437 fadeshape->add (FadeLinear,
2438 _("Linear (for highly correlated material)"));
2439 fadeshape->add (FadeConstantPower, _("Constant power"));
2440 fadeshape->add (FadeSymmetric, _("Symmetric"));
2441 fadeshape->add (FadeSlow, _("Slow"));
2442 fadeshape->add (FadeFast, _("Fast"));
2444 add_option (_("Editor"), fadeshape);
2446 ComboOption<RegionEquivalence> *eqv = new ComboOption<RegionEquivalence> (
2447 "region-equivalence",
2448 _("Regions in active edit groups are edited together"),
2449 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_equivalence),
2450 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_equivalence)
2453 eqv->add (Overlap, _("whenever they overlap in time"));
2454 eqv->add (Enclosed, _("if either encloses the other"));
2455 eqv->add (Exact, _("only if they have identical length, position and origin"));
2457 add_option (_("Editor"), eqv);
2459 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2461 _("Layering model"),
2462 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2463 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2466 lm->add (LaterHigher, _("later is higher"));
2467 lm->add (Manual, _("manual layering"));
2468 add_option (_("Editor"), lm);
2470 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2471 "region-selection-after-split",
2472 _("After splitting selected regions, select"),
2473 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2474 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2476 // TODO: decide which of these modes are really useful
2477 rsas->add(None, _("no regions"));
2478 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2479 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2480 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2481 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2482 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2483 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2484 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2486 add_option (_("Editor"), rsas);
2488 add_option (_("Editor/Snap"), new OptionEditorHeading (_("General Snap options:")));
2490 add_option (_("Editor/Snap"),
2491 new SpinOption<uint32_t> (
2493 _("Snap Threshold (pixels)"),
2494 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_threshold),
2495 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_threshold),
2500 add_option (_("Editor/Snap"),
2502 "show-snapped-cursor",
2503 _("Show \"snapped cursor\""),
2504 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_snapped_cursor),
2505 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_snapped_cursor)
2508 add_option (_("Editor/Snap"),
2510 "rubberbanding-snaps-to-grid",
2511 _("Snap rubberband selection to grid"),
2512 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2513 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2516 add_option (_("Editor/Snap"),
2518 "grid-follows-internal",
2519 _("Grid switches to alternate selection for Internal Edit tools"),
2520 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_grid_follows_internal),
2521 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_grid_follows_internal)
2524 add_option (_("Editor/Snap"),
2526 "rulers-follow-grid",
2527 _("Rulers automatically change to follow the Grid mode selection"),
2528 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rulers_follow_grid),
2529 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rulers_follow_grid)
2532 add_option (_("Editor/Snap"), new OptionEditorHeading (_("When \"Snap\" is enabled, snap to:")));
2535 add_option (_("Editor/Snap"),
2539 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_marks),
2540 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_marks)
2543 add_option (_("Editor/Snap"),
2545 "snap-to-region-sync",
2546 _("Region Sync Points"),
2547 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_region_sync),
2548 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_region_sync)
2551 add_option (_("Editor/Snap"),
2553 "snap-to-region-start",
2555 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_region_start),
2556 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_region_start)
2559 add_option (_("Editor/Snap"),
2561 "snap-to-region-end",
2563 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_region_end),
2564 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_region_end)
2567 add_option (_("Editor/Snap"),
2571 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_grid),
2572 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_grid)
2575 add_option (_("Editor/Modifiers"), new OptionEditorHeading (_("Keyboard Modifiers")));
2576 add_option (_("Editor/Modifiers"), new KeyboardOptions);
2577 add_option (_("Editor/Modifiers"), new OptionEditorBlank ());
2579 /* MIXER -- SOLO AND MUTE */
2581 add_option (_("Mixer"), new OptionEditorHeading (_("Solo")));
2583 _solo_control_is_listen_control = new BoolOption (
2584 "solo-control-is-listen-control",
2585 _("Solo controls are Listen controls"),
2586 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2587 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2590 add_option (_("Mixer"), _solo_control_is_listen_control);
2592 add_option (_("Mixer"),
2595 _("Exclusive solo"),
2596 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2597 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2600 add_option (_("Mixer"),
2603 _("Show solo muting"),
2604 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2605 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2608 add_option (_("Mixer"),
2610 "solo-mute-override",
2611 _("Soloing overrides muting"),
2612 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2613 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2616 add_option (_("Mixer"),
2619 _("Solo-in-place mute cut (dB)"),
2620 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2621 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2624 _listen_position = new ComboOption<ListenPosition> (
2626 _("Listen Position"),
2627 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2628 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2631 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2632 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2634 add_option (_("Mixer"), _listen_position);
2636 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2638 _("PFL signals come from"),
2639 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2640 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2643 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2644 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2646 add_option (_("Mixer"), pp);
2648 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2650 _("AFL signals come from"),
2651 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2652 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2655 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2656 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2658 add_option (_("Mixer"), pa);
2660 add_option (_("Mixer"), new OptionEditorHeading (_("Default Track / Bus Muting Options")));
2662 add_option (_("Mixer"),
2664 "mute-affects-pre-fader",
2665 _("Mute affects pre-fader sends"),
2666 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2667 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2670 add_option (_("Mixer"),
2672 "mute-affects-post-fader",
2673 _("Mute affects post-fader sends"),
2674 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2675 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2678 add_option (_("Mixer"),
2680 "mute-affects-control-outs",
2681 _("Mute affects control outputs"),
2682 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2683 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2686 add_option (_("Mixer"),
2688 "mute-affects-main-outs",
2689 _("Mute affects main outputs"),
2690 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2691 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2695 if (!ARDOUR::Profile->get_mixbus()) {
2696 add_option (_("Mixer"), new OptionEditorHeading (_("Send Routing")));
2697 add_option (_("Mixer"),
2699 "link-send-and-route-panner",
2700 _("Link panners of Aux and External Sends with main panner by default"),
2701 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2702 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2708 add_option (_("Signal Flow"), new OptionEditorHeading (_("Monitoring")));
2710 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2712 _("Record monitoring handled by"),
2713 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2714 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2717 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2718 mm->add (HardwareMonitoring, _("via Audio Driver"));
2721 string prog (PROGRAM_NAME);
2722 boost::algorithm::to_lower (prog);
2723 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2724 mm->add (ExternalMonitoring, _("audio hardware"));
2726 add_option (_("Signal Flow"), mm);
2728 bo = new BoolOption (
2729 "tape-machine-mode",
2730 _("Tape machine mode"),
2731 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2732 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2734 add_option (_("Signal Flow"), bo);
2735 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2736 string_compose (_("<b>When enabled</b> %1 will not monitor a track's input if the transport is stopped."),
2739 if (!Profile->get_mixbus()) {
2741 add_option (_("Signal Flow"), new OptionEditorHeading (_("Track and Bus Connections")));
2743 add_option (_("Signal Flow"),
2745 "auto-connect-standard-busses",
2746 _("Auto-connect master/monitor busses"),
2747 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2748 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2751 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2752 "input-auto-connect",
2753 _("Connect track inputs"),
2754 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2755 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2758 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2759 iac->add (ManualConnect, _("manually"));
2761 add_option (_("Signal Flow"), iac);
2763 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2764 "output-auto-connect",
2765 _("Connect track and bus outputs"),
2766 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2767 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2770 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2771 oac->add (AutoConnectMaster, _("automatically to master bus"));
2772 oac->add (ManualConnect, _("manually"));
2774 add_option (_("Signal Flow"), oac);
2776 bo = new BoolOption (
2778 _("Use 'Strict-I/O' for new tracks or busses"),
2779 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2780 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2783 add_option (_("Signal Flow"), bo);
2784 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2785 _("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."));
2792 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2794 add_option (_("Audio"), new BufferingOptions (_rc_config));
2796 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2798 add_option (_("Audio"),
2800 "denormal-protection",
2801 _("Use DC bias to protect against denormals"),
2802 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2803 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2806 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2808 _("Processor handling"),
2809 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2810 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2814 dm->add (DenormalNone, _("no processor handling"));
2816 FPU* fpu = FPU::instance();
2818 if (fpu->has_flush_to_zero()) {
2820 dm->add (DenormalFTZ, _("use FlushToZero"));
2821 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2822 _rc_config->set_denormal_model(DenormalNone);
2825 if (fpu->has_denormals_are_zero()) {
2827 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2828 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2829 _rc_config->set_denormal_model(DenormalNone);
2832 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2834 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2835 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2836 _rc_config->set_denormal_model(DenormalNone);
2840 dm->set_sensitive(false);
2843 add_option (_("Audio"), dm);
2845 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2847 add_option (_("Audio"),
2849 "auto-analyse-audio",
2850 _("Enable automatic analysis of audio"),
2851 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2852 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2855 add_option (_("Audio"),
2857 "replicate-missing-region-channels",
2858 _("Replicate missing region channels"),
2859 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2860 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2865 add_option (_("MIDI"), new OptionEditorHeading (_("Buffering")));
2867 add_option (_("MIDI"),
2868 new SpinOption<float> (
2870 _("MIDI read-ahead time (seconds)"),
2871 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2872 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2877 add_option (_("MIDI"), new OptionEditorHeading (_("Session")));
2879 add_option (_("MIDI"),
2880 new SpinOption<int32_t> (
2881 "initial-program-change",
2882 _("Initial program change"),
2883 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2884 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2888 add_option (_("MIDI"), new OptionEditorHeading (_("Audition")));
2890 add_option (_("MIDI"),
2893 _("Sound MIDI notes as they are selected in the editor"),
2894 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2895 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2898 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2899 "midi-audition-synth-uri",
2900 _("MIDI Audition Synth (LV2)"),
2901 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2902 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2905 audition_synth->add(X_(""), _("None"));
2906 PluginInfoList all_plugs;
2907 PluginManager& manager (PluginManager::instance());
2909 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2911 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2912 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2913 if (!(*i)->is_instrument()) continue;
2914 if ((*i)->type != ARDOUR::LV2) continue;
2915 if ((*i)->name.length() > 46) {
2916 audition_synth->add((*i)->unique_id, (*i)->name.substr (0, 44) + "...");
2918 audition_synth->add((*i)->unique_id, (*i)->name);
2923 add_option (_("MIDI"), audition_synth);
2927 add_option (_("Metronome"), new OptionEditorHeading (_("Metronome")));
2928 add_option (_("Metronome"), new ClickOptions (_rc_config));
2929 add_option (_("Metronome"), new OptionEditorHeading (_("Options")));
2931 bo = new BoolOption (
2932 "click-record-only",
2933 _("Enable metronome only while recording"),
2934 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_record_only),
2935 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_record_only)
2938 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2939 string_compose (_("<b>When enabled</b> the metronome will remain silent if %1 is <b>not recording</b>."), PROGRAM_NAME));
2940 add_option (_("Metronome"), bo);
2941 add_option (_("Metronome"), new OptionEditorBlank ());
2946 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2948 ComboOption<float>* mht = new ComboOption<float> (
2950 _("Peak hold time"),
2951 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
2952 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
2955 mht->add (MeterHoldOff, _("off"));
2956 mht->add (MeterHoldShort, _("short"));
2957 mht->add (MeterHoldMedium, _("medium"));
2958 mht->add (MeterHoldLong, _("long"));
2960 add_option (S_("Preferences|Metering"), mht);
2962 ComboOption<float>* mfo = new ComboOption<float> (
2965 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2966 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2969 mfo->add (METER_FALLOFF_OFF, _("off"));
2970 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2971 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2972 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2973 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2974 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2975 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
2977 add_option (S_("Preferences|Metering"), mfo);
2979 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2980 "meter-line-up-level",
2981 _("Meter line-up level; 0dBu"),
2982 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
2983 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
2986 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2987 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2988 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2989 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2991 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."));
2993 add_option (S_("Preferences|Metering"), mlu);
2995 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2996 "meter-line-up-din",
2997 _("IEC1/DIN Meter line-up level; 0dBu"),
2998 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
2999 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
3002 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3003 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3004 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3005 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3007 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
3009 add_option (S_("Preferences|Metering"), mld);
3011 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
3012 "meter-vu-standard",
3013 _("VU Meter standard"),
3014 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
3015 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
3018 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
3019 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
3020 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
3021 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
3023 add_option (S_("Preferences|Metering"), mvu);
3025 HSliderOption *mpks = new HSliderOption("meter-peak",
3026 _("Peak indicator threshold [dBFS]"),
3027 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
3028 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak),
3032 Gtkmm2ext::UI::instance()->set_tip (
3034 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
3036 add_option (S_("Preferences|Metering"), mpks);
3038 OptionEditorHeading* default_meter_head = new OptionEditorHeading (_("Default Meter Types"));
3039 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."));
3041 add_option (S_("Preferences|Metering"), default_meter_head);
3043 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3044 "meter-type-master",
3045 _("Default Meter Type for Master Bus"),
3046 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3047 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3049 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3050 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3051 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3052 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3053 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3054 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3055 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3056 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3058 add_option (S_("Preferences|Metering"), mtm);
3061 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3063 _("Default meter type for busses"),
3064 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3065 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3067 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3068 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3069 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3070 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3071 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3072 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3073 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3074 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3076 add_option (S_("Preferences|Metering"), mtb);
3078 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3080 _("Default meter type for tracks"),
3081 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3082 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3084 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3085 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3087 add_option (S_("Preferences|Metering"), mtt);
3089 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
3091 add_option (S_("Preferences|Metering"),
3093 "save-export-analysis-image",
3094 _("Save loudness analysis as image file"),
3095 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
3096 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
3099 /* TRANSPORT & Sync */
3101 add_option (_("Transport"), new OptionEditorHeading (_("General")));
3103 bo = new BoolOption (
3104 "stop-at-session-end",
3105 _("Stop at the end of the session"),
3106 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
3107 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
3109 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3110 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
3111 "when it reaches the current session end marker\n\n"
3112 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
3114 add_option (_("Transport"), bo);
3116 bo = new BoolOption (
3117 "latched-record-enable",
3118 _("Keep record-enable engaged on stop"),
3119 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
3120 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
3122 add_option (_("Transport"), bo);
3123 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3124 _("<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."));
3126 bo = new BoolOption (
3127 "disable-disarm-during-roll",
3128 _("Disable per-track record disarm while rolling"),
3129 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
3130 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
3132 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."));
3133 add_option (_("Transport"), bo);
3135 bo = new BoolOption (
3137 _("12dB gain reduction during fast-forward and fast-rewind"),
3138 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
3139 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
3141 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3142 _("<b>When enabled</b> this will reduce the unpleasant increase in perceived volume "
3143 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
3144 add_option (_("Transport"), bo);
3146 ComboOption<float>* psc = new ComboOption<float> (
3149 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
3150 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
3152 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
3153 (_("The amount of preroll to apply when <b>Play with Preroll</b> or <b>Record with Preroll</b>is initiated.\n\n"
3154 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
3155 psc->add (-4.0, _("4 Bars"));
3156 psc->add (-2.0, _("2 Bars"));
3157 psc->add (-1.0, _("1 Bar"));
3158 psc->add (0.0, _("0 (no pre-roll)"));
3159 psc->add (0.1, _("0.1 second"));
3160 psc->add (0.25, _("0.25 second"));
3161 psc->add (0.5, _("0.5 second"));
3162 psc->add (1.0, _("1.0 second"));
3163 psc->add (2.0, _("2.0 seconds"));
3164 add_option (_("Transport"), psc);
3167 add_option (_("Transport"), new OptionEditorHeading (_("Looping")));
3169 bo = new BoolOption (
3171 _("Play loop is a transport mode"),
3172 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
3173 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
3175 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3176 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
3177 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
3178 add_option (_("Transport"), bo);
3180 bo = new BoolOption (
3182 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
3183 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
3184 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
3186 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3187 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
3188 "preventing any need to do a transport locate at the end of the loop\n\n"
3189 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
3190 "which will often cause a small click or delay"), PROGRAM_NAME));
3191 add_option (_("Transport"), bo);
3193 add_option (_("Transport"), new OptionEditorHeading (_("Dropout (xrun) Handling")));
3194 bo = new BoolOption (
3195 "stop-recording-on-xrun",
3196 _("Stop recording when an xrun occurs"),
3197 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
3198 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
3200 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3201 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
3203 add_option (_("Transport"), bo);
3205 bo = new BoolOption (
3206 "create-xrun-marker",
3207 _("Create markers where xruns occur"),
3208 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
3209 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
3211 add_option (_("Transport"), bo);
3216 add_option (_("Sync"), new OptionEditorHeading (_("External Synchronization")));
3218 _sync_source = new ComboOption<SyncSource> (
3220 _("External timecode source"),
3221 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
3222 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
3225 add_option (_("Sync"), _sync_source);
3227 _sync_framerate = new BoolOption (
3228 "timecode-sync-frame-rate",
3229 _("Match session video frame rate to external timecode"),
3230 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
3231 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
3233 Gtkmm2ext::UI::instance()->set_tip
3234 (_sync_framerate->tip_widget(),
3235 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
3236 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
3237 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
3238 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
3239 "timecode standard and the session standard."), PROGRAM_NAME));
3241 add_option (_("Sync"), _sync_framerate);
3243 _sync_genlock = new BoolOption (
3244 "timecode-source-is-synced",
3245 _("Sync-lock timecode to clock (disable drift compensation)"),
3246 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
3247 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
3249 Gtkmm2ext::UI::instance()->set_tip
3250 (_sync_genlock->tip_widget(),
3251 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
3252 "Sync Lock indicates that the selected external timecode source shares clock-sync "
3253 "(Black & Burst, Wordclock, etc) with the audio interface. "
3254 "This option disables drift compensation. The transport speed is fixed at 1.0. "
3255 "Vari-speed LTC will be ignored and cause drift."
3257 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
3258 "timecode sources shares clock sync."
3262 add_option (_("Sync"), _sync_genlock);
3264 _sync_source_2997 = new BoolOption (
3265 "timecode-source-2997",
3266 _("Lock to 29.9700 fps instead of 30000/1001"),
3267 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
3268 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
3270 Gtkmm2ext::UI::instance()->set_tip
3271 (_sync_source_2997->tip_widget(),
3272 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
3273 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
3274 "drop-sample timecode has an accumulated error of -86ms over a 24-hour period.\n"
3275 "Drop-sample timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
3276 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
3277 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
3280 add_option (_("Sync"), _sync_source_2997);
3282 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Reader")));
3284 _ltc_port = new ComboStringOption (
3286 _("LTC incoming port"),
3287 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
3288 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
3291 vector<string> physical_inputs;
3292 physical_inputs.push_back (_("None"));
3293 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
3294 _ltc_port->set_popdown_strings (physical_inputs);
3296 populate_sync_options ();
3297 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
3299 add_option (_("Sync/LTC"), _ltc_port);
3301 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Generator")));
3303 add_option (_("Sync/LTC"),
3306 _("Enable LTC generator"),
3307 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
3308 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
3311 _ltc_send_continuously = new BoolOption (
3312 "ltc-send-continuously",
3313 _("Send LTC while stopped"),
3314 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
3315 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
3317 Gtkmm2ext::UI::instance()->set_tip
3318 (_ltc_send_continuously->tip_widget(),
3319 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
3320 add_option (_("Sync/LTC"), _ltc_send_continuously);
3322 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level [dBFS]"),
3323 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_output_volume),
3324 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_output_volume),
3328 Gtkmm2ext::UI::instance()->set_tip
3329 (_ltc_volume_slider->tip_widget(),
3330 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
3332 add_option (_("Sync/LTC"), _ltc_volume_slider);
3335 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Beat Clock (Mclk) Generator")));
3337 add_option (_("Sync/MIDI"),
3340 _("Enable Mclk generator"),
3341 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
3342 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
3345 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC) Generator")));
3347 add_option (_("Sync/MIDI"),
3350 _("Enable MTC Generator"),
3351 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
3352 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
3355 add_option (_("Sync/MIDI"),
3356 new SpinOption<int> (
3357 "mtc-qf-speed-tolerance",
3358 _("Percentage either side of normal transport speed to transmit MTC"),
3359 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
3360 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
3364 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Machine Control (MMC)")));
3366 add_option (_("Sync/MIDI"),
3369 _("Respond to MMC commands"),
3370 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
3371 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
3374 add_option (_("Sync/MIDI"),
3377 _("Send MMC commands"),
3378 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
3379 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
3382 add_option (_("Sync/MIDI"),
3383 new SpinOption<uint8_t> (
3384 "mmc-receive-device-id",
3385 _("Inbound MMC device ID"),
3386 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
3387 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
3391 add_option (_("Sync/MIDI"),
3392 new SpinOption<uint8_t> (
3393 "mmc-send-device-id",
3394 _("Outbound MMC device ID"),
3395 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
3396 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
3401 /* Control Surfaces */
3403 add_option (_("Control Surfaces"), new OptionEditorHeading (_("Control Surfaces")));
3404 add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
3407 add_option (_("MIDI Ports"), new OptionEditorHeading (_("MIDI Port Options")));
3409 add_option (_("MIDI Ports"),
3411 "midi-input-follows-selection",
3412 _("MIDI input follows MIDI track selection"),
3413 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
3414 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
3417 add_option (_("MIDI Ports"), new MidiPortOptions ());
3418 add_option (_("MIDI Ports"), new OptionEditorBlank ());
3422 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3423 add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
3424 add_option (_("Plugins"),
3425 new RcActionButton (_("Scan for Plugins"),
3426 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3430 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
3432 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3433 bo = new BoolOption (
3434 "show-plugin-scan-window",
3435 _("Always Display Plugin Scan Progress"),
3436 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
3437 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
3439 add_option (_("Plugins"), bo);
3440 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3441 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
3444 bo = new BoolOption (
3445 "plugins-stop-with-transport",
3446 _("Silence plugins when the transport is stopped"),
3447 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
3448 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
3450 add_option (_("Plugins"), bo);
3451 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3452 _("<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."));
3454 bo = new BoolOption (
3455 "new-plugins-active",
3456 _("Make new plugins active"),
3457 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
3458 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
3460 add_option (_("Plugins"), bo);
3461 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3462 _("<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"));
3464 #if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
3465 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
3467 add_option (_("Plugins/VST"),
3468 new RcActionButton (_("Scan for Plugins"),
3469 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3472 #if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
3473 bo = new BoolOption (
3475 _("Enable Mac VST support (requires restart or re-scan)"),
3476 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
3477 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
3479 add_option (_("Plugins/VST"), bo);
3482 bo = new BoolOption (
3483 "discover-vst-on-start",
3484 _("Scan for [new] VST Plugins on Application Start"),
3485 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
3486 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
3488 add_option (_("Plugins/VST"), bo);
3489 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3490 _("<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"));
3492 #ifdef WINDOWS_VST_SUPPORT
3493 // currently verbose logging is only implemented for Windows VST.
3494 bo = new BoolOption (
3495 "verbose-plugin-scan",
3496 _("Verbose Plugin Scan"),
3497 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
3498 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
3500 add_option (_("Plugins/VST"), bo);
3501 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3502 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
3505 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
3507 add_option (_("Plugins/VST"),
3508 new RcActionButton (_("Clear"),
3509 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
3512 add_option (_("Plugins/VST"),
3513 new RcActionButton (_("Clear"),
3514 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
3515 _("VST Blacklist:")));
3518 #ifdef LXVST_SUPPORT
3519 add_option (_("Plugins/VST"),
3520 new RcActionButton (_("Edit"),
3521 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
3522 _("Linux VST Path:")));
3524 add_option (_("Plugins/VST"),
3525 new RcConfigDisplay (
3526 "plugin-path-lxvst",
3528 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
3532 #ifdef WINDOWS_VST_SUPPORT
3533 add_option (_("Plugins/VST"),
3534 new RcActionButton (_("Edit"),
3535 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
3536 _("Windows VST Path:")));
3537 add_option (_("Plugins/VST"),
3538 new RcConfigDisplay (
3541 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
3545 #ifdef AUDIOUNIT_SUPPORT
3547 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
3549 add_option (_("Plugins/Audio Unit"),
3550 new RcActionButton (_("Scan for Plugins"),
3551 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3554 bo = new BoolOption (
3555 "discover-audio-units",
3556 _("Scan for [new] AudioUnit Plugins on Application Start"),
3557 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
3558 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
3560 add_option (_("Plugins/Audio Unit"), bo);
3561 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3562 _("<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."));
3564 add_option (_("Plugins/Audio Unit"),
3565 new RcActionButton (_("Clear"),
3566 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
3569 add_option (_("Plugins/Audio Unit"),
3570 new RcActionButton (_("Clear"),
3571 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
3572 _("AU Blacklist:")));
3575 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
3576 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
3577 add_option (_("Plugins"),
3579 "open-gui-after-adding-plugin",
3580 _("Automatically open the plugin GUI when adding a new plugin"),
3581 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
3582 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3585 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3586 add_option (_("Plugins"),
3588 "show-inline-display-by-default",
3589 _("Show Plugin Inline Display on Mixerstrip by default"),
3590 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3591 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3594 _plugin_prefer_inline = new BoolOption (
3595 "prefer-inline-over-gui",
3596 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3597 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3598 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3600 add_option (_("Plugins"), _plugin_prefer_inline);
3603 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3605 bo = new BoolOption (
3606 "ask-replace-instrument",
3607 _("Ask to replace existing instrument plugin"),
3608 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3609 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3611 add_option (_("Plugins"), bo);
3613 bo = new BoolOption (
3614 "ask-setup_instrument",
3615 _("Interactively configure instrument plugins on insert"),
3616 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3617 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3619 add_option (_("Plugins"), bo);
3620 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3621 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3624 add_option (_("Plugins"), new OptionEditorBlank ());
3627 #if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
3628 add_option (_("Appearance"), new OptionEditorHeading (_("Graphics Acceleration")));
3631 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3632 BoolOption* bgc = new BoolOption (
3633 "cairo-image-surface",
3634 _("Disable Graphics Hardware Acceleration (requires restart)"),
3635 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3636 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3639 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3640 _("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));
3641 add_option (_("Appearance"), bgc);
3644 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3645 BoolOption* bgo = new BoolOption (
3647 _("Possibly improve slow graphical performance (requires restart)"),
3648 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3649 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3652 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));
3653 add_option (_("Appearance"), bgo);
3655 add_option (_("Appearance"), new OptionEditorHeading (_("Graphical User Interface")));
3657 add_option (_("Appearance"),
3660 _("Highlight widgets on mouseover"),
3661 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3662 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3665 add_option (_("Appearance"),
3668 _("Show tooltips if mouse hovers over a control"),
3669 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3670 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3673 bo = new BoolOption (
3674 "super-rapid-clock-update",
3675 _("Update clocks at TC Frame rate"),
3676 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3677 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3679 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3680 _("<b>When enabled</b> clock displays are updated every Timecode Frame (fps).\n\n"
3681 "<b>When disabled</b> clock displays are updated only every 100ms."
3683 add_option (_("Appearance"), bo);
3685 add_option (_("Appearance"),
3688 _("Blink Rec-Arm buttons"),
3689 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_rec_arm),
3690 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_rec_arm)
3693 add_option (_("Appearance"),
3695 "blink-alert-indicators",
3696 _("Blink Alert Indicators"),
3697 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_alert_indicators),
3698 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_alert_indicators)
3703 /* font scaling does nothing with GDK/Quartz */
3704 add_option (_("Appearance"), new FontScalingOptions ());
3706 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("General")));
3707 add_option (_("Appearance/Editor"),
3709 "show-name-highlight",
3710 _("Use name highlight bars in region displays (requires a restart)"),
3711 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3712 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3715 add_option (_("Appearance/Editor"),
3717 "color-regions-using-track-color",
3718 _("Region color follows track color"),
3719 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_color_regions_using_track_color),
3720 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_color_regions_using_track_color)
3723 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Waveforms")));
3725 if (!Profile->get_mixbus()) {
3726 add_option (_("Appearance/Editor"),
3729 _("Show waveforms in regions"),
3730 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
3731 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
3735 add_option (_("Appearance/Editor"),
3737 "show-waveforms-while-recording",
3738 _("Show waveforms while recording"),
3739 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
3740 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
3743 add_option (_("Appearance/Editor"),
3745 "show-waveform-clipping",
3746 _("Show waveform clipping"),
3747 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveform_clipping),
3748 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveform_clipping)
3751 add_option (_("Appearance/Editor"), new ClipLevelOptions ());
3753 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
3755 _("Waveform scale"),
3756 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
3757 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
3760 wfs->add (Linear, _("linear"));
3761 wfs->add (Logarithmic, _("logarithmic"));
3763 add_option (_("Appearance/Editor"), wfs);
3765 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
3767 _("Waveform shape"),
3768 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
3769 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
3772 wfsh->add (Traditional, _("traditional"));
3773 wfsh->add (Rectified, _("rectified"));
3775 add_option (_("Appearance/Editor"), wfsh);
3777 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Editor Meters")));
3779 add_option (_("Appearance/Editor"),
3781 "show-track-meters",
3782 _("Show meters in track headers"),
3783 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3784 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3787 add_option (_("Appearance/Editor"),
3789 "editor-stereo-only-meters",
3790 _("Limit track header meters to stereo"),
3791 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3792 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3795 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("MIDI Regions")));
3797 add_option (_("Appearance/Editor"),
3799 "display-first-midi-bank-as-zero",
3800 _("Display first MIDI bank/program as 0"),
3801 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
3802 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
3805 add_option (_("Appearance/Editor"),
3807 "never-display-periodic-midi",
3808 _("Don't display periodic (MTC, MMC) SysEx messages in MIDI Regions"),
3809 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
3810 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
3814 add_option (_("Appearance/Editor"),
3816 "use-note-bars-for-velocity",
3817 _("Show velocity horizontally inside notes"),
3818 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_note_bars_for_velocity),
3819 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_note_bars_for_velocity)
3822 add_option (_("Appearance/Editor"),
3824 "use-note-color-for-velocity",
3825 _("Use colors to show note velocity"),
3826 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_note_color_for_velocity),
3827 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_note_color_for_velocity)
3830 add_option (_("Appearance/Editor"), new OptionEditorBlank ());
3832 /* The names of these controls must be the same as those given in MixerStrip
3833 for the actual widgets being controlled.
3835 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3836 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3837 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3838 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3839 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3840 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3841 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3843 add_option (_("Appearance/Mixer"),
3844 new VisibilityOption (
3846 &_mixer_strip_visibility,
3847 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3848 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3852 add_option (_("Appearance/Mixer"),
3854 "default-narrow_ms",
3855 _("Use narrow strips in the mixer for new strips by default"),
3856 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3857 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3860 add_option (_("Appearance/Mixer"), new OptionEditorBlank ());
3862 add_option (_("Appearance/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items")));
3864 add_option (_("Appearance/Toolbar"),
3866 "show-toolbar-recpunch",
3867 _("Display Record/Punch Options"),
3868 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_recpunch),
3869 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_recpunch)
3872 add_option (_("Appearance/Toolbar"),
3874 "show-toolbar-monitoring",
3875 _("Display Monitor Options"),
3876 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_monitoring),
3877 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_monitoring)
3880 add_option (_("Appearance/Toolbar"),
3882 "show-toolbar-selclock",
3883 _("Display Selection Clock"),
3884 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
3885 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
3888 if (!ARDOUR::Profile->get_small_screen()) {
3889 add_option (_("Appearance/Toolbar"),
3891 "show-secondary-clock",
3892 _("Display Secondary Clock"),
3893 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
3894 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
3898 add_option (_("Appearance/Toolbar"),
3900 "show-mini-timeline",
3901 _("Display Navigation Timeline"),
3902 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
3903 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
3906 add_option (_("Appearance/Toolbar"),
3908 "show-editor-meter",
3909 _("Display Master Level Meter"),
3910 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
3911 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
3914 add_option (_("Appearance/Toolbar"),
3915 new ColumVisibilityOption (
3916 "action-table-columns", _("Display Action-Buttons"), 4,
3917 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3918 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3921 add_option (_("Appearance/Toolbar"), new OptionEditorBlank ());
3924 /* and now the theme manager */
3926 add_option (_("Appearance/Theme"), new OptionEditorHeading (_("Theme")));
3928 add_option (_("Appearance/Theme"), new BoolOption (
3930 _("Draw \"flat\" buttons"),
3931 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_flat_buttons),
3932 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_flat_buttons)
3935 add_option (_("Appearance/Theme"), new BoolOption (
3937 _("LED meter style"),
3938 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3939 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3943 HSliderOption *gui_hs = new HSliderOption(
3944 "timeline-item-gradient-depth",
3945 _("Waveforms color gradient depth"),
3946 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_gradient_depth),
3947 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_gradient_depth),
3950 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3951 add_option (_("Appearance/Theme"), gui_hs);
3953 gui_hs = new HSliderOption(
3954 "timeline-item-gradient-depth",
3955 _("Timeline item gradient depth"),
3956 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_timeline_item_gradient_depth),
3957 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_timeline_item_gradient_depth),
3960 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3961 add_option (_("Appearance/Theme"), gui_hs);
3963 vector<string> icon_sets = ::get_icon_sets ();
3964 if (icon_sets.size() > 1) {
3965 ComboOption<std::string>* io = new ComboOption<std::string> (
3966 "icon-set", _("Icon Set"),
3967 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_icon_set),
3968 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_icon_set)
3970 for (vector<string>::const_iterator i = icon_sets.begin (); i != icon_sets.end (); ++i) {
3973 add_option (_("Appearance/Theme"), io);
3976 add_option (_("Appearance/Colors"), new OptionEditorHeading (_("Colors")));
3977 add_option (_("Appearance/Colors"), new ColorThemeManager);
3978 add_option (_("Appearance/Colors"), new OptionEditorBlank ());
3982 OptionEditorHeading* quirks_head = new OptionEditorHeading (_("Various Workarounds for Windowing Systems"));
3984 quirks_head->set_note (string_compose (_("Rules for closing, minimizing, maximizing, and stay-on-top can vary \
3985 with each version of your OS, and the preferences that you've set in your OS.\n\n\
3986 You can adjust the options, below, to change how %1's windows and dialogs behave.\n\n\
3987 These settings will only take effect after %1 is restarted.\n\
3990 add_option (_("Appearance/Quirks"), quirks_head);
3992 bo = new BoolOption (
3993 "use-wm-visibility",
3994 _("Use visibility information provided by your Window Manager/Desktop"),
3995 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3996 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3998 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3999 _("If you have trouble toggling between hidden Editor and Mixer windows, try changing this setting."));
4000 add_option (_("Appearance/Quirks"), bo);
4003 bo = new BoolOption (
4004 "all-floating-windows-are-dialogs",
4005 _("All floating windows are dialogs"),
4006 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_all_floating_windows_are_dialogs),
4007 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_all_floating_windows_are_dialogs)
4009 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
4010 _("Mark all floating windows to be type \"Dialog\" rather than using \"Utility\" for some.\nThis may help with some window managers."));
4011 add_option (_("Appearance/Quirks"), bo);
4013 bo = new BoolOption (
4014 "transients-follow-front",
4015 _("Transient windows follow front window."),
4016 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_transients_follow_front),
4017 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_transients_follow_front)
4019 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
4020 _("Make transient windows follow the front window when toggling between the editor and mixer."));
4021 add_option (_("Appearance/Quirks"), bo);
4024 if (!Profile->get_mixbus()) {
4025 bo = new BoolOption (
4026 "floating-monitor-section",
4027 _("Float detached monitor-section window"),
4028 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_floating_monitor_section),
4029 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_floating_monitor_section)
4031 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
4032 _("When detaching the monitoring section, mark it as \"Utility\" window to stay in front."));
4033 add_option (_("Appearance/Quirks"), bo);
4036 add_option (_("Appearance/Quirks"), new OptionEditorBlank ());
4038 /* VIDEO Timeline */
4039 add_option (_("Video"), new OptionEditorHeading (_("Video Server")));
4040 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
4042 Widget::show_all ();
4044 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
4045 parameter_changed ("send-ltc");
4046 parameter_changed ("sync-source");
4047 parameter_changed ("use-monitor-bus");
4048 parameter_changed ("open-gui-after-adding-plugin");
4050 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
4052 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
4053 (Gtk::StateType) here !!!
4055 Tabbable::set_state (*node, Stateful::loading_state_version);
4058 set_current_page (_("General"));
4062 RCOptionEditor::parameter_changed (string const & p)
4064 OptionEditor::parameter_changed (p);
4066 if (p == "use-monitor-bus") {
4067 bool const s = Config->get_use_monitor_bus ();
4069 /* we can't use this if we don't have a monitor bus */
4070 Config->set_solo_control_is_listen_control (false);
4072 _solo_control_is_listen_control->set_sensitive (s);
4073 _listen_position->set_sensitive (s);
4074 } else if (p == "sync-source") {
4075 _sync_source->set_sensitive (true);
4077 _sync_source->set_sensitive (!_session->config.get_external_sync());
4079 switch(Config->get_sync_source()) {
4082 _sync_genlock->set_sensitive (true);
4083 _sync_framerate->set_sensitive (true);
4084 _sync_source_2997->set_sensitive (true);
4087 _sync_genlock->set_sensitive (false);
4088 _sync_framerate->set_sensitive (false);
4089 _sync_source_2997->set_sensitive (false);
4092 } else if (p == "send-ltc") {
4093 bool const s = Config->get_send_ltc ();
4094 _ltc_send_continuously->set_sensitive (s);
4095 _ltc_volume_slider->set_sensitive (s);
4096 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
4097 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
4098 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
4103 void RCOptionEditor::plugin_scan_refresh () {
4104 PluginManager::instance().refresh();
4107 void RCOptionEditor::clear_vst_cache () {
4108 PluginManager::instance().clear_vst_cache();
4111 void RCOptionEditor::clear_vst_blacklist () {
4112 PluginManager::instance().clear_vst_blacklist();
4115 void RCOptionEditor::clear_au_cache () {
4116 PluginManager::instance().clear_au_cache();
4119 void RCOptionEditor::clear_au_blacklist () {
4120 PluginManager::instance().clear_au_blacklist();
4123 void RCOptionEditor::edit_lxvst_path () {
4124 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
4125 PathsDialog *pd = new PathsDialog (
4126 *current_toplevel(), _("Set Linux VST Search Path"),
4127 _rc_config->get_plugin_path_lxvst(),
4128 PluginManager::instance().get_default_lxvst_path()
4130 ResponseType r = (ResponseType) pd->run ();
4132 if (r == RESPONSE_ACCEPT) {
4133 _rc_config->set_plugin_path_lxvst(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 ();
4146 void RCOptionEditor::edit_vst_path () {
4147 PathsDialog *pd = new PathsDialog (
4148 *current_toplevel(), _("Set Windows VST Search Path"),
4149 _rc_config->get_plugin_path_vst(),
4150 PluginManager::instance().get_default_windows_vst_path()
4152 ResponseType r = (ResponseType) pd->run ();
4154 if (r == RESPONSE_ACCEPT) {
4155 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
4156 MessageDialog msg (_("Re-scan Plugins now?"),
4157 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
4158 msg.set_default_response (Gtk::RESPONSE_YES);
4159 if (msg.run() == Gtk::RESPONSE_YES) {
4161 plugin_scan_refresh ();
4169 RCOptionEditor::populate_sync_options ()
4171 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
4173 _sync_source->clear ();
4175 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
4176 _sync_source->add (*i, sync_source_to_string (*i));
4179 if (sync_opts.empty()) {
4180 _sync_source->set_sensitive(false);
4182 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
4183 _rc_config->set_sync_source(sync_opts.front());
4187 parameter_changed ("sync-source");
4191 RCOptionEditor::use_own_window (bool and_fill_it)
4193 bool new_window = !own_window ();
4195 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
4197 if (win && new_window) {
4198 win->set_name ("PreferencesWindow");
4199 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
4201 win->set_resizable (false);
4208 RCOptionEditor::get_state ()
4210 XMLNode* node = new XMLNode (X_("Preferences"));
4211 node->add_child_nocopy (Tabbable::get_state());