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/slider_controller.h"
38 #include "gtkmm2ext/gtk_ui.h"
39 #include "gtkmm2ext/paths_dialog.h"
40 #include "gtkmm2ext/window_title.h"
46 #include "ardour/audio_backend.h"
47 #include "ardour/audioengine.h"
48 #include "ardour/profile.h"
49 #include "ardour/dB.h"
50 #include "ardour/rc_configuration.h"
51 #include "ardour/control_protocol_manager.h"
52 #include "ardour/port_manager.h"
53 #include "ardour/plugin_manager.h"
54 #include "control_protocol/control_protocol.h"
56 #include "canvas/wave_view.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 ArdourCanvas::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 edit_button->set_sensitive (true);
1410 edit_button->set_sensitive (false);
1413 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1415 TreeModel::Row r = *i;
1417 if (_ignore_view_change) {
1421 ControlProtocolInfo* cpi = r[_model.protocol_info];
1426 bool const was_enabled = (cpi->protocol != 0);
1427 bool const is_enabled = r[_model.enabled];
1430 if (was_enabled != is_enabled) {
1433 ControlProtocolManager::instance().activate (*cpi);
1435 ControlProtocolManager::instance().deactivate (*cpi);
1439 selection_changed ();
1442 void edit_btn_clicked ()
1445 ControlProtocolInfo* cpi;
1448 row = *(_view.get_selection()->get_selected());
1449 if (!row[_model.enabled]) {
1452 cpi = row[_model.protocol_info];
1453 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1456 Box* box = (Box*) cpi->protocol->get_gui ();
1460 if (box->get_parent()) {
1461 static_cast<ArdourWindow*>(box->get_parent())->present();
1464 WindowTitle title (Glib::get_application_name());
1465 title += row[_model.name];
1466 title += _("Configuration");
1467 /* once created, the window is managed by the surface itself (as ->get_parent())
1468 * Surface's tear_down_gui() is called on session close, when de-activating
1469 * or re-initializing a surface.
1470 * tear_down_gui() hides an deletes the Window if it exists.
1472 ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
1473 win->set_title (_("Control Protocol Settings"));
1479 void edit_clicked (GdkEventButton* ev)
1481 if (ev->type != GDK_2BUTTON_PRESS) {
1488 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1492 ControlSurfacesModelColumns ()
1496 add (protocol_info);
1499 TreeModelColumn<string> name;
1500 TreeModelColumn<bool> enabled;
1501 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1504 Glib::RefPtr<ListStore> _store;
1505 ControlSurfacesModelColumns _model;
1507 PBD::ScopedConnection protocol_status_connection;
1508 uint32_t _ignore_view_change;
1509 Gtk::Button* edit_button;
1512 class VideoTimelineOptions : public OptionEditorMiniPage
1515 VideoTimelineOptions (RCConfiguration* c)
1517 , _show_video_export_info_button (_("Show Video Export Info before export"))
1518 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1519 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1520 , _xjadeo_browse_button (_("Browse..."))
1523 int n = table.property_n_rows();
1525 t->attach (_show_video_export_info_button, 1, 4, n, n + 1);
1526 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1527 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1528 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1531 t->attach (_show_video_server_dialog_button, 1, 4, n, n + 1);
1532 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1533 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1534 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1537 t->attach (_video_advanced_setup_button, 1, 4, n, n + 1, FILL);
1538 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1539 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1540 _("<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."));
1543 Label* l = manage (new Label (_("Video Server URL:")));
1544 l->set_alignment (0, 0.5);
1545 t->attach (*l, 1, 2, n, n + 1, FILL);
1546 t->attach (_video_server_url_entry, 2, 4, n, n + 1, FILL);
1547 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1548 _("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"));
1551 l = manage (new Label (_("Video Folder:")));
1552 l->set_alignment (0, 0.5);
1553 t->attach (*l, 1, 2, n, n + 1, FILL);
1554 t->attach (_video_server_docroot_entry, 2, 4, n, n + 1);
1555 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1556 _("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."));
1559 l = manage (new Label (""));
1560 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1563 l = manage (new Label (string_compose ("<b>%1</b>", _("Video Monitor"))));
1564 l->set_use_markup (true);
1565 l->set_alignment (0, 0.5);
1566 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1569 l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"),
1572 #elif defined PLATFORM_WINDOWS
1578 l->set_alignment (0, 0.5);
1579 t->attach (*l, 1, 4, n, n + 1, FILL);
1582 t->attach (_custom_xjadeo_path, 2, 3, n, n + 1, EXPAND|FILL);
1583 Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart."));
1584 t->attach (_xjadeo_browse_button, 3, 4, n, n + 1, FILL);
1586 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1587 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1588 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1589 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1590 _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed));
1591 _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked));
1593 // xjadeo-path is a UIConfig parameter
1594 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &VideoTimelineOptions::parameter_changed));
1597 void server_url_changed ()
1599 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1602 void server_docroot_changed ()
1604 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1607 void show_video_export_info_toggled ()
1609 bool const x = _show_video_export_info_button.get_active ();
1610 _rc_config->set_show_video_export_info (x);
1613 void show_video_server_dialog_toggled ()
1615 bool const x = _show_video_server_dialog_button.get_active ();
1616 _rc_config->set_show_video_server_dialog (x);
1619 void video_advanced_setup_toggled ()
1621 bool const x = _video_advanced_setup_button.get_active ();
1622 _rc_config->set_video_advanced_setup(x);
1625 void custom_xjadeo_path_changed ()
1627 UIConfiguration::instance().set_xjadeo_binary (_custom_xjadeo_path.get_text());
1630 void xjadeo_browse_clicked ()
1632 Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN);
1633 dialog.set_filename (UIConfiguration::instance().get_xjadeo_binary());
1634 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1635 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1636 if (dialog.run () == Gtk::RESPONSE_OK) {
1637 const std::string& filename = dialog.get_filename();
1638 if (!filename.empty() && (
1640 Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) ||
1642 Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)
1644 UIConfiguration::instance().set_xjadeo_binary (filename);
1649 void parameter_changed (string const & p)
1651 if (p == "video-server-url") {
1652 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1653 } else if (p == "video-server-docroot") {
1654 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1655 } else if (p == "show-video-export-info") {
1656 bool const x = _rc_config->get_show_video_export_info();
1657 _show_video_export_info_button.set_active (x);
1658 } else if (p == "show-video-server-dialog") {
1659 bool const x = _rc_config->get_show_video_server_dialog();
1660 _show_video_server_dialog_button.set_active (x);
1661 } else if (p == "video-advanced-setup") {
1662 bool const x = _rc_config->get_video_advanced_setup();
1663 _video_advanced_setup_button.set_active(x);
1664 _video_server_docroot_entry.set_sensitive(x);
1665 _video_server_url_entry.set_sensitive(x);
1666 } else if (p == "xjadeo-binary") {
1667 _custom_xjadeo_path.set_text (UIConfiguration::instance().get_xjadeo_binary());
1671 void set_state_from_config ()
1673 parameter_changed ("video-server-url");
1674 parameter_changed ("video-server-docroot");
1675 parameter_changed ("video-monitor-setup-dialog");
1676 parameter_changed ("show-video-export-info");
1677 parameter_changed ("show-video-server-dialog");
1678 parameter_changed ("video-advanced-setup");
1679 parameter_changed ("xjadeo-binary");
1683 RCConfiguration* _rc_config;
1684 Entry _video_server_url_entry;
1685 Entry _video_server_docroot_entry;
1686 Entry _custom_xjadeo_path;
1687 CheckButton _show_video_export_info_button;
1688 CheckButton _show_video_server_dialog_button;
1689 CheckButton _video_advanced_setup_button;
1690 Button _xjadeo_browse_button;
1693 class ColumVisibilityOption : public Option
1696 ColumVisibilityOption (string id, string name, uint32_t n_col, sigc::slot<uint32_t> get, sigc::slot<bool, uint32_t> set)
1703 cb = (CheckButton**) malloc (sizeof (CheckButton*) * n_col);
1704 for (uint32_t i = 0; i < n_col; ++i) {
1705 CheckButton* col = manage (new CheckButton (string_compose (_("Column %1"), i + 1)));
1706 col->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ColumVisibilityOption::column_toggled), i));
1707 _hbox.pack_start (*col);
1710 parameter_changed (id);
1713 ~ColumVisibilityOption () {
1717 Gtk::Widget& tip_widget() { return _hbox; }
1719 void set_state_from_config ()
1721 uint32_t c = _get();
1722 for (uint32_t i = 0; i < _n_col; ++i) {
1723 bool en = (c & (1<<i)) ? true : false;
1724 if (cb[i]->get_active () != en) {
1725 cb[i]->set_active (en);
1730 void add_to_page (OptionEditorPage* p)
1732 _heading.add_to_page (p);
1733 add_widget_to_page (p, &_hbox);
1737 void column_toggled (int b) {
1738 uint32_t c = _get();
1740 if (cb[b]->get_active ()) {
1751 OptionEditorHeading _heading;
1755 sigc::slot<uint32_t> _get;
1756 sigc::slot<bool, uint32_t> _set;
1760 /** A class which allows control of visibility of some editor components usign
1761 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1762 * which has the correct members, but with null widget pointers. This
1763 * class allows the user to set visibility of the members, the details
1764 * of which are stored in a configuration variable which can be watched
1765 * by parts of the editor that actually contain the widgets whose visibility
1766 * is being controlled.
1769 class VisibilityOption : public Option
1772 /** @param name User-visible name for this group.
1773 * @param g `Dummy' VisibilityGroup (as described above).
1774 * @param get Method to get the value of the appropriate configuration variable.
1775 * @param set Method to set the value of the appropriate configuration variable.
1777 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1778 : Option (g->get_state_name(), name)
1780 , _visibility_group (g)
1784 /* Watch for changes made by the user to our members */
1785 _visibility_group->VisibilityChanged.connect_same_thread (
1786 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1790 void set_state_from_config ()
1792 /* Set our state from the current configuration */
1793 _visibility_group->set_state (_get ());
1796 void add_to_page (OptionEditorPage* p)
1798 _heading.add_to_page (p);
1799 add_widget_to_page (p, _visibility_group->list_view ());
1802 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1807 /* The user has changed something, so reflect this change
1808 in the RCConfiguration.
1810 _set (_visibility_group->get_state_value ());
1813 OptionEditorHeading _heading;
1814 VisibilityGroup* _visibility_group;
1815 sigc::slot<std::string> _get;
1816 sigc::slot<bool, std::string> _set;
1817 PBD::ScopedConnection _visibility_group_connection;
1821 class MidiPortOptions : public OptionEditorMiniPage, public sigc::trackable
1826 setup_midi_port_view (midi_output_view, false);
1827 setup_midi_port_view (midi_input_view, true);
1829 OptionEditorHeading* h = new OptionEditorHeading (_("MIDI Inputs"));
1830 h->add_to_page (this);
1832 Gtk::ScrolledWindow* scroller = manage (new Gtk::ScrolledWindow);
1833 scroller->add (midi_input_view);
1834 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1835 scroller->set_size_request (-1, 180);
1837 int n = table.property_n_rows();
1838 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1840 h = new OptionEditorHeading (_("MIDI Outputs"));
1841 h->add_to_page (this);
1843 scroller = manage (new Gtk::ScrolledWindow);
1844 scroller->add (midi_output_view);
1845 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1846 scroller->set_size_request (-1, 180);
1848 n = table.property_n_rows();
1849 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1851 midi_output_view.show ();
1852 midi_input_view.show ();
1854 table.signal_show().connect (sigc::mem_fun (*this, &MidiPortOptions::on_show));
1857 void parameter_changed (string const&) {}
1858 void set_state_from_config() {}
1863 AudioEngine::instance()->PortRegisteredOrUnregistered.connect (connections,
1864 invalidator (*this),
1865 boost::bind (&MidiPortOptions::refill, this),
1867 AudioEngine::instance()->MidiPortInfoChanged.connect (connections,
1868 invalidator (*this),
1869 boost::bind (&MidiPortOptions::refill, this),
1871 AudioEngine::instance()->MidiSelectionPortsChanged.connect (connections,
1872 invalidator (*this),
1873 boost::bind (&MidiPortOptions::refill, this),
1879 if (refill_midi_ports (true, midi_input_view)) {
1880 input_label.show ();
1882 input_label.hide ();
1884 if (refill_midi_ports (false, midi_output_view)) {
1885 output_label.show ();
1887 output_label.hide ();
1892 PBD::ScopedConnectionList connections;
1894 /* MIDI port management */
1895 struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord {
1897 MidiPortColumns () {
1906 Gtk::TreeModelColumn<std::string> pretty_name;
1907 Gtk::TreeModelColumn<bool> music_data;
1908 Gtk::TreeModelColumn<bool> control_data;
1909 Gtk::TreeModelColumn<bool> selection;
1910 Gtk::TreeModelColumn<std::string> name;
1911 Gtk::TreeModelColumn<std::string> filler;
1914 MidiPortColumns midi_port_columns;
1915 Gtk::TreeView midi_input_view;
1916 Gtk::TreeView midi_output_view;
1917 Gtk::Label input_label;
1918 Gtk::Label output_label;
1920 void setup_midi_port_view (Gtk::TreeView&, bool with_selection);
1921 bool refill_midi_ports (bool for_input, Gtk::TreeView&);
1922 void pretty_name_edit (std::string const & path, std::string const & new_text, Gtk::TreeView*);
1923 void midi_music_column_toggled (std::string const & path, Gtk::TreeView*);
1924 void midi_control_column_toggled (std::string const & path, Gtk::TreeView*);
1925 void midi_selection_column_toggled (std::string const & path, Gtk::TreeView*);
1929 MidiPortOptions::setup_midi_port_view (Gtk::TreeView& view, bool with_selection)
1931 int pretty_name_column;
1934 int selection_column;
1935 TreeViewColumn* col;
1938 pretty_name_column = view.append_column_editable (_("Name (click to edit)"), midi_port_columns.pretty_name) - 1;
1940 col = manage (new TreeViewColumn ("", midi_port_columns.music_data));
1941 col->set_alignment (ALIGN_CENTER);
1942 l = manage (new Label (_("Music Data")));
1943 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of music performance data."), PROGRAM_NAME));
1944 col->set_widget (*l);
1946 music_column = view.append_column (*col) - 1;
1948 col = manage (new TreeViewColumn ("", midi_port_columns.control_data));
1949 col->set_alignment (ALIGN_CENTER);
1950 l = manage (new Label (_("Control Data")));
1951 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of control data."), PROGRAM_NAME));
1952 col->set_widget (*l);
1954 control_column = view.append_column (*col) - 1;
1956 if (with_selection) {
1957 col = manage (new TreeViewColumn (_("Follow Selection"), midi_port_columns.selection));
1958 selection_column = view.append_column (*col) - 1;
1959 l = manage (new Label (_("Follow Selection")));
1960 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));
1961 col->set_widget (*l);
1965 /* filler column so that the last real column doesn't expand */
1966 view.append_column ("", midi_port_columns.filler);
1968 CellRendererText* pretty_name_cell = dynamic_cast<CellRendererText*> (view.get_column_cell_renderer (pretty_name_column));
1969 pretty_name_cell->property_editable() = true;
1970 pretty_name_cell->signal_edited().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::pretty_name_edit), &view));
1972 CellRendererToggle* toggle_cell;
1974 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (music_column));
1975 toggle_cell->property_activatable() = true;
1976 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_music_column_toggled), &view));
1978 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (control_column));
1979 toggle_cell->property_activatable() = true;
1980 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_control_column_toggled), &view));
1982 if (with_selection) {
1983 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (selection_column));
1984 toggle_cell->property_activatable() = true;
1985 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_selection_column_toggled), &view));
1988 view.get_selection()->set_mode (SELECTION_NONE);
1989 view.set_tooltip_column (4); /* port "real" name */
1990 view.get_column(0)->set_resizable (true);
1991 view.get_column(0)->set_expand (true);
1995 MidiPortOptions::refill_midi_ports (bool for_input, Gtk::TreeView& view)
1997 using namespace ARDOUR;
1999 std::vector<string> ports;
2001 AudioEngine::instance()->get_known_midi_ports (ports);
2003 if (ports.empty()) {
2008 Glib::RefPtr<ListStore> model = Gtk::ListStore::create (midi_port_columns);
2010 for (vector<string>::const_iterator s = ports.begin(); s != ports.end(); ++s) {
2012 if (AudioEngine::instance()->port_is_mine (*s)) {
2016 PortManager::MidiPortInformation mpi (AudioEngine::instance()->midi_port_information (*s));
2018 if (mpi.pretty_name.empty()) {
2019 /* vanished since get_known_midi_ports() */
2023 if (for_input != mpi.input) {
2027 TreeModel::Row row = *(model->append());
2029 row[midi_port_columns.pretty_name] = mpi.pretty_name;
2030 row[midi_port_columns.music_data] = mpi.properties & MidiPortMusic;
2031 row[midi_port_columns.control_data] = mpi.properties & MidiPortControl;
2032 row[midi_port_columns.selection] = mpi.properties & MidiPortSelection;
2033 row[midi_port_columns.name] = *s;
2036 view.set_model (model);
2042 MidiPortOptions::midi_music_column_toggled (string const & path, TreeView* view)
2044 TreeIter iter = view->get_model()->get_iter (path);
2050 bool new_value = ! bool ((*iter)[midi_port_columns.music_data]);
2052 /* don't reset model - wait for MidiPortInfoChanged signal */
2055 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2057 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2062 MidiPortOptions::midi_control_column_toggled (string const & path, TreeView* view)
2064 TreeIter iter = view->get_model()->get_iter (path);
2070 bool new_value = ! bool ((*iter)[midi_port_columns.control_data]);
2072 /* don't reset model - wait for MidiPortInfoChanged signal */
2075 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2077 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2082 MidiPortOptions::midi_selection_column_toggled (string const & path, TreeView* view)
2084 TreeIter iter = view->get_model()->get_iter (path);
2090 bool new_value = ! bool ((*iter)[midi_port_columns.selection]);
2092 /* don't reset model - wait for MidiSelectionPortsChanged signal */
2095 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2097 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2102 MidiPortOptions::pretty_name_edit (std::string const & path, string const & new_text, Gtk::TreeView* view)
2104 TreeIter iter = view->get_model()->get_iter (path);
2110 boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
2112 ARDOUR::PortEngine::PortHandle ph = backend->get_port_by_name ((*iter)[midi_port_columns.name]);
2114 backend->set_port_property (ph, "http://jackaudio.org/metadata/pretty-name", new_text, "");
2115 (*iter)[midi_port_columns.pretty_name] = new_text;
2123 RCOptionEditor::RCOptionEditor ()
2124 : OptionEditorContainer (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
2125 , Tabbable (*this, _("Preferences")
2127 , false // detached by default (first start, no instant.xml)
2129 ) /* pack self-as-vbox into tabbable */
2130 , _rc_config (Config)
2131 , _mixer_strip_visibility ("mixer-element-visibility")
2133 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
2137 uint32_t hwcpus = hardware_concurrency ();
2139 BoolComboOption* bco;
2142 add_option (_("General"), new OptionEditorHeading (_("DSP CPU Utilization")));
2144 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
2146 _("Signal processing uses"),
2147 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
2148 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
2151 procs->add (-1, _("all but one processor"));
2152 procs->add (0, _("all available processors"));
2154 for (uint32_t i = 1; i <= hwcpus; ++i) {
2155 procs->add (i, string_compose (P_("%1 processor", "%1 processors", i), i));
2158 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
2160 add_option (_("General"), procs);
2163 /* Image cache size */
2164 add_option (_("General"), new OptionEditorHeading (_("Memory Usage")));
2166 HSliderOption *sics = new HSliderOption ("waveform-cache-size",
2167 _("Waveform image cache size (megabytes)"),
2168 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
2169 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size),
2170 1, 1024, 10 /* 1 MB to 1GB in steps of 10MB */
2172 sics->scale().set_digits (0);
2173 Gtkmm2ext::UI::instance()->set_tip (
2175 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
2176 add_option (_("General"), sics);
2178 add_option (_("General"), new OptionEditorHeading (_("Engine")));
2180 add_option (_("General"),
2182 "try-autostart-engine",
2183 _("Try to auto-launch audio/midi engine"),
2184 sigc::mem_fun (*_rc_config, &RCConfiguration::get_try_autostart_engine),
2185 sigc::mem_fun (*_rc_config, &RCConfiguration::set_try_autostart_engine)
2188 add_option (_("General"), new OptionEditorHeading (_("Automation")));
2190 add_option (_("General"),
2191 new SpinOption<double> (
2192 "automation-thinning-factor",
2193 _("Thinning factor (larger value => less data)"),
2194 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
2195 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
2199 add_option (_("General"),
2200 new SpinOption<double> (
2201 "automation-interval-msecs",
2202 _("Automation sampling interval (milliseconds)"),
2203 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
2204 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
2208 add_option (_("General"), new OptionEditorHeading (_("Tempo")));
2210 bo = new BoolOption (
2211 "allow-non-quarter-pulse",
2212 _("Allow non quarter-note pulse"),
2213 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_allow_non_quarter_pulse),
2214 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_allow_non_quarter_pulse)
2216 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2217 string_compose (_("<b>When enabled</b> %1 will allow tempo to be expressed in divisions per minute\n"
2218 "<b>When disabled</b> %1 will only allow tempo to be expressed in quarter notes per minute"),
2220 add_option (_("General"), bo);
2222 if (!ARDOUR::Profile->get_mixbus()) {
2223 add_option (_("General"), new OptionEditorHeading (_("GUI Lock")));
2224 /* Lock GUI timeout */
2226 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2227 _("Lock timeout (seconds)"),
2228 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
2229 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds),
2232 slts->scale().set_digits (0);
2233 Gtkmm2ext::UI::instance()->set_tip (
2235 _("Lock GUI after this many idle seconds (zero to never lock)"));
2236 add_option (_("General"), slts);
2239 add_option (_("General/Session"), new OptionEditorHeading (S_("Options|Undo")));
2241 add_option (_("General/Session"), new UndoOptions (_rc_config));
2243 add_option (_("General/Session"),
2245 "verify-remove-last-capture",
2246 _("Verify removal of last capture"),
2247 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
2248 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
2251 add_option (_("General/Session"), new OptionEditorHeading (_("Session Management")));
2253 add_option (_("General/Session"),
2255 "periodic-safety-backups",
2256 _("Make periodic backups of the session file"),
2257 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
2258 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
2261 add_option (_("General/Session"),
2263 "only-copy-imported-files",
2264 _("Always copy imported files"),
2265 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
2266 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
2269 add_option (_("General/Session"), new DirectoryOption (
2270 X_("default-session-parent-dir"),
2271 _("Default folder for new sessions:"),
2272 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
2273 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
2276 add_option (_("General/Session"),
2277 new SpinOption<uint32_t> (
2278 "max-recent-sessions",
2279 _("Maximum number of recent sessions"),
2280 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
2281 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
2288 add_option (_("General/Translation"), new OptionEditorHeading (_("Internationalization")));
2290 bo = new BoolOption (
2291 "enable-translation",
2292 _("Use translations"),
2293 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2294 sigc::ptr_fun (ARDOUR::set_translations_enabled)
2297 bo->set_note (string_compose (_("These settings will only take effect after %1 is restarted (if available for your language preferences)."), PROGRAM_NAME));
2299 add_option (_("General/Translation"), bo);
2301 parameter_changed ("enable-translation");
2302 #endif // ENABLE_NLS
2307 add_option (_("Editor"), new OptionEditorHeading (_("General")));
2309 add_option (_("Editor"),
2311 "rubberbanding-snaps-to-grid",
2312 _("Snap rubberband to grid"),
2313 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2314 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2317 bo = new BoolOption (
2319 _("Prompt for new marker names"),
2320 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2321 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2323 add_option (_("Editor"), bo);
2324 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."
2325 "\n\nYou can always rename markers by right-clicking on them"));
2327 add_option (_("Editor"),
2329 "draggable-playhead",
2330 _("Allow dragging of playhead"),
2331 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2332 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2335 if (!Profile->get_mixbus()) {
2337 add_option (_("Editor"),
2339 "use-mouse-position-as-zoom-focus-on-scroll",
2340 _("Zoom to mouse position when zooming with scroll wheel"),
2341 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2342 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2346 add_option (_("Editor"),
2348 "use-time-rulers-to-zoom-with-vertical-drag",
2349 _("Zoom with vertical drag in rulers"),
2350 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag),
2351 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag)
2354 add_option (_("Editor"),
2356 "use-double-click-to-zoom-to-selection",
2357 _("Double click zooms to selection"),
2358 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection),
2359 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection)
2362 add_option (_("Editor"),
2364 "update-editor-during-summary-drag",
2365 _("Update editor window during drags of the summary"),
2366 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2367 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2370 add_option (_("Editor"),
2372 "autoscroll-editor",
2373 _("Auto-scroll editor window when dragging near its edges"),
2374 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2375 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2378 add_option (_("Editor"),
2379 new BoolComboOption (
2380 "show-region-gain-envelopes",
2381 _("Show gain envelopes in audio regions"),
2383 _("only in Draw and Internal Edit modes"),
2384 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2385 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2388 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2390 add_option (_("Editor"),
2392 "automation-follows-regions",
2393 _("Move relevant automation when audio regions are moved"),
2394 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2395 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2398 bo = new BoolOption (
2399 "new-automation-points-on-lane",
2400 _("Ignore Y-axis click position when adding new automation-points"),
2401 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_new_automation_points_on_lane),
2402 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_new_automation_points_on_lane)
2404 add_option (_("Editor"), bo);
2405 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2406 _("<b>When enabled</b> The new points drawn in any automation lane will be placed on the existing line, regardless of mouse y-axis position."));
2408 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2409 "default-fade-shape",
2410 _("Default fade shape"),
2411 sigc::mem_fun (*_rc_config,
2412 &RCConfiguration::get_default_fade_shape),
2413 sigc::mem_fun (*_rc_config,
2414 &RCConfiguration::set_default_fade_shape)
2417 fadeshape->add (FadeLinear,
2418 _("Linear (for highly correlated material)"));
2419 fadeshape->add (FadeConstantPower, _("Constant power"));
2420 fadeshape->add (FadeSymmetric, _("Symmetric"));
2421 fadeshape->add (FadeSlow, _("Slow"));
2422 fadeshape->add (FadeFast, _("Fast"));
2424 add_option (_("Editor"), fadeshape);
2426 bco = new BoolComboOption (
2427 "use-overlap-equivalency",
2428 _("Regions in edit groups are edited together"),
2429 _("whenever they overlap in time"),
2430 _("only if they have identical length and position"),
2431 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2432 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2435 add_option (_("Editor"), bco);
2437 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2439 _("Layering model"),
2440 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2441 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2444 lm->add (LaterHigher, _("later is higher"));
2445 lm->add (Manual, _("manual layering"));
2446 add_option (_("Editor"), lm);
2448 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2449 "region-selection-after-split",
2450 _("After splitting selected regions, select"),
2451 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2452 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2454 // TODO: decide which of these modes are really useful
2455 rsas->add(None, _("no regions"));
2456 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2457 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2458 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2459 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2460 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2461 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2462 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2464 add_option (_("Editor"), rsas);
2466 add_option (_("Editor/Modifiers"), new OptionEditorHeading (_("Keyboard Modifiers")));
2467 add_option (_("Editor/Modifiers"), new KeyboardOptions);
2468 add_option (_("Editor/Modifiers"), new OptionEditorBlank ());
2470 /* MIXER -- SOLO AND MUTE */
2472 add_option (_("Mixer"), new OptionEditorHeading (_("Solo")));
2474 _solo_control_is_listen_control = new BoolOption (
2475 "solo-control-is-listen-control",
2476 _("Solo controls are Listen controls"),
2477 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2478 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2481 add_option (_("Mixer"), _solo_control_is_listen_control);
2483 add_option (_("Mixer"),
2486 _("Exclusive solo"),
2487 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2488 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2491 add_option (_("Mixer"),
2494 _("Show solo muting"),
2495 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2496 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2499 add_option (_("Mixer"),
2501 "solo-mute-override",
2502 _("Soloing overrides muting"),
2503 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2504 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2507 add_option (_("Mixer"),
2510 _("Solo-in-place mute cut (dB)"),
2511 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2512 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2515 _listen_position = new ComboOption<ListenPosition> (
2517 _("Listen Position"),
2518 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2519 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2522 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2523 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2525 add_option (_("Mixer"), _listen_position);
2527 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2529 _("PFL signals come from"),
2530 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2531 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2534 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2535 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2537 add_option (_("Mixer"), pp);
2539 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2541 _("AFL signals come from"),
2542 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2543 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2546 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2547 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2549 add_option (_("Mixer"), pa);
2551 add_option (_("Mixer"), new OptionEditorHeading (_("Default Track / Bus Muting Options")));
2553 add_option (_("Mixer"),
2555 "mute-affects-pre-fader",
2556 _("Mute affects pre-fader sends"),
2557 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2558 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2561 add_option (_("Mixer"),
2563 "mute-affects-post-fader",
2564 _("Mute affects post-fader sends"),
2565 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2566 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2569 add_option (_("Mixer"),
2571 "mute-affects-control-outs",
2572 _("Mute affects control outputs"),
2573 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2574 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2577 add_option (_("Mixer"),
2579 "mute-affects-main-outs",
2580 _("Mute affects main outputs"),
2581 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2582 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2586 if (!ARDOUR::Profile->get_mixbus()) {
2587 add_option (_("Mixer"), new OptionEditorHeading (_("Send Routing")));
2588 add_option (_("Mixer"),
2590 "link-send-and-route-panner",
2591 _("Link panners of Aux and External Sends with main panner by default"),
2592 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2593 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2599 add_option (_("Signal Flow"), new OptionEditorHeading (_("Monitoring")));
2601 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2603 _("Record monitoring handled by"),
2604 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2605 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2608 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2609 mm->add (HardwareMonitoring, _("via Audio Driver"));
2612 string prog (PROGRAM_NAME);
2613 boost::algorithm::to_lower (prog);
2614 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2615 mm->add (ExternalMonitoring, _("audio hardware"));
2617 add_option (_("Signal Flow"), mm);
2619 bo = new BoolOption (
2620 "tape-machine-mode",
2621 _("Tape machine mode"),
2622 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2623 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2625 add_option (_("Signal Flow"), bo);
2626 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2627 string_compose (_("<b>When enabled</b> %1 will not monitor a track's input if the transport is stopped."),
2630 if (!Profile->get_mixbus()) {
2632 add_option (_("Signal Flow"), new OptionEditorHeading (_("Track and Bus Connections")));
2634 add_option (_("Signal Flow"),
2636 "auto-connect-standard-busses",
2637 _("Auto-connect master/monitor busses"),
2638 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2639 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2642 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2643 "input-auto-connect",
2644 _("Connect track inputs"),
2645 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2646 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2649 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2650 iac->add (ManualConnect, _("manually"));
2652 add_option (_("Signal Flow"), iac);
2654 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2655 "output-auto-connect",
2656 _("Connect track and bus outputs"),
2657 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2658 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2661 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2662 oac->add (AutoConnectMaster, _("automatically to master bus"));
2663 oac->add (ManualConnect, _("manually"));
2665 add_option (_("Signal Flow"), oac);
2667 bo = new BoolOption (
2669 _("Use 'Strict-I/O' for new tracks or busses"),
2670 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2671 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2674 add_option (_("Signal Flow"), bo);
2675 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2676 _("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."));
2683 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2685 add_option (_("Audio"), new BufferingOptions (_rc_config));
2687 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2689 add_option (_("Audio"),
2691 "denormal-protection",
2692 _("Use DC bias to protect against denormals"),
2693 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2694 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2697 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2699 _("Processor handling"),
2700 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2701 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2705 dm->add (DenormalNone, _("no processor handling"));
2707 FPU* fpu = FPU::instance();
2709 if (fpu->has_flush_to_zero()) {
2711 dm->add (DenormalFTZ, _("use FlushToZero"));
2712 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2713 _rc_config->set_denormal_model(DenormalNone);
2716 if (fpu->has_denormals_are_zero()) {
2718 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2719 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2720 _rc_config->set_denormal_model(DenormalNone);
2723 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2725 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2726 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2727 _rc_config->set_denormal_model(DenormalNone);
2731 dm->set_sensitive(false);
2734 add_option (_("Audio"), dm);
2736 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2738 add_option (_("Audio"),
2740 "auto-analyse-audio",
2741 _("Enable automatic analysis of audio"),
2742 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2743 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2746 add_option (_("Audio"),
2748 "replicate-missing-region-channels",
2749 _("Replicate missing region channels"),
2750 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2751 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2756 add_option (_("MIDI"), new OptionEditorHeading (_("Buffering")));
2758 add_option (_("MIDI"),
2759 new SpinOption<float> (
2761 _("MIDI read-ahead time (seconds)"),
2762 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2763 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2768 add_option (_("MIDI"), new OptionEditorHeading (_("Session")));
2770 add_option (_("MIDI"),
2771 new SpinOption<int32_t> (
2772 "initial-program-change",
2773 _("Initial program change"),
2774 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2775 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2779 add_option (_("MIDI"), new OptionEditorHeading (_("Audition")));
2781 add_option (_("MIDI"),
2784 _("Sound MIDI notes as they are selected in the editor"),
2785 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2786 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2789 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2790 "midi-audition-synth-uri",
2791 _("MIDI Audition Synth (LV2)"),
2792 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2793 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2796 audition_synth->add(X_(""), _("None"));
2797 PluginInfoList all_plugs;
2798 PluginManager& manager (PluginManager::instance());
2800 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2802 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2803 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2804 if (!(*i)->is_instrument()) continue;
2805 if ((*i)->type != ARDOUR::LV2) continue;
2806 if ((*i)->name.length() > 46) {
2807 audition_synth->add((*i)->unique_id, (*i)->name.substr (0, 44) + "...");
2809 audition_synth->add((*i)->unique_id, (*i)->name);
2814 add_option (_("MIDI"), audition_synth);
2818 add_option (_("Metronome"), new OptionEditorHeading (_("Metronome")));
2819 add_option (_("Metronome"), new ClickOptions (_rc_config));
2820 add_option (_("Metronome"), new OptionEditorHeading (_("Options")));
2822 bo = new BoolOption (
2823 "click-record-only",
2824 _("Enable metronome only while recording"),
2825 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_record_only),
2826 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_record_only)
2829 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2830 string_compose (_("<b>When enabled</b> the metronome will remain silent if %1 is <b>not recording</b>."), PROGRAM_NAME));
2831 add_option (_("Metronome"), bo);
2832 add_option (_("Metronome"), new OptionEditorBlank ());
2837 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2839 ComboOption<float>* mht = new ComboOption<float> (
2841 _("Peak hold time"),
2842 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
2843 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
2846 mht->add (MeterHoldOff, _("off"));
2847 mht->add (MeterHoldShort, _("short"));
2848 mht->add (MeterHoldMedium, _("medium"));
2849 mht->add (MeterHoldLong, _("long"));
2851 add_option (S_("Preferences|Metering"), mht);
2853 ComboOption<float>* mfo = new ComboOption<float> (
2856 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2857 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2860 mfo->add (METER_FALLOFF_OFF, _("off"));
2861 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2862 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2863 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2864 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2865 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2866 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
2868 add_option (S_("Preferences|Metering"), mfo);
2870 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2871 "meter-line-up-level",
2872 _("Meter line-up level; 0dBu"),
2873 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
2874 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
2877 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2878 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2879 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2880 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2882 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."));
2884 add_option (S_("Preferences|Metering"), mlu);
2886 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2887 "meter-line-up-din",
2888 _("IEC1/DIN Meter line-up level; 0dBu"),
2889 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
2890 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
2893 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2894 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2895 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2896 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2898 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2900 add_option (S_("Preferences|Metering"), mld);
2902 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2903 "meter-vu-standard",
2904 _("VU Meter standard"),
2905 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
2906 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
2909 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2910 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2911 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2912 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2914 add_option (S_("Preferences|Metering"), mvu);
2916 HSliderOption *mpks = new HSliderOption("meter-peak",
2917 _("Peak indicator threshold [dBFS]"),
2918 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
2919 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak),
2923 Gtkmm2ext::UI::instance()->set_tip (
2925 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
2927 add_option (S_("Preferences|Metering"), mpks);
2929 OptionEditorHeading* default_meter_head = new OptionEditorHeading (_("Default Meter Types"));
2930 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."));
2932 add_option (S_("Preferences|Metering"), default_meter_head);
2934 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
2935 "meter-type-master",
2936 _("Default Meter Type for Master Bus"),
2937 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
2938 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
2940 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2941 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2942 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2943 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2944 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2945 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2946 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2947 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
2949 add_option (S_("Preferences|Metering"), mtm);
2952 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
2954 _("Default meter type for busses"),
2955 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
2956 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
2958 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2959 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2960 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2961 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2962 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2963 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2964 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2965 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
2967 add_option (S_("Preferences|Metering"), mtb);
2969 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
2971 _("Default meter type for tracks"),
2972 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
2973 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
2975 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2976 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
2978 add_option (S_("Preferences|Metering"), mtt);
2980 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
2982 add_option (S_("Preferences|Metering"),
2984 "save-export-analysis-image",
2985 _("Save loudness analysis as image file"),
2986 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
2987 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
2990 /* TRANSPORT & Sync */
2992 add_option (_("Transport"), new OptionEditorHeading (_("General")));
2994 bo = new BoolOption (
2995 "stop-at-session-end",
2996 _("Stop at the end of the session"),
2997 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
2998 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
3000 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3001 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
3002 "when it reaches the current session end marker\n\n"
3003 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
3005 add_option (_("Transport"), bo);
3007 bo = new BoolOption (
3008 "latched-record-enable",
3009 _("Keep record-enable engaged on stop"),
3010 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
3011 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
3013 add_option (_("Transport"), bo);
3014 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3015 _("<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."));
3017 bo = new BoolOption (
3018 "disable-disarm-during-roll",
3019 _("Disable per-track record disarm while rolling"),
3020 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
3021 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
3023 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."));
3024 add_option (_("Transport"), bo);
3026 bo = new BoolOption (
3028 _("12dB gain reduction during fast-forward and fast-rewind"),
3029 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
3030 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
3032 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3033 _("<b>When enabled</b> this will reduce the unpleasant increase in perceived volume "
3034 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
3035 add_option (_("Transport"), bo);
3037 ComboOption<float>* psc = new ComboOption<float> (
3040 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
3041 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
3043 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
3044 (_("The amount of preroll to apply when <b>Play with Preroll</b> or <b>Record with Preroll</b>is initiated.\n\n"
3045 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
3046 psc->add (-4.0, _("4 Bars"));
3047 psc->add (-2.0, _("2 Bars"));
3048 psc->add (-1.0, _("1 Bar"));
3049 psc->add (0.0, _("0 (no pre-roll)"));
3050 psc->add (0.1, _("0.1 second"));
3051 psc->add (0.25, _("0.25 second"));
3052 psc->add (0.5, _("0.5 second"));
3053 psc->add (1.0, _("1.0 second"));
3054 psc->add (2.0, _("2.0 seconds"));
3055 add_option (_("Transport"), psc);
3058 add_option (_("Transport"), new OptionEditorHeading (_("Looping")));
3060 bo = new BoolOption (
3062 _("Play loop is a transport mode"),
3063 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
3064 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
3066 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3067 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
3068 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
3069 add_option (_("Transport"), bo);
3071 bo = new BoolOption (
3073 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
3074 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
3075 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
3077 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3078 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
3079 "preventing any need to do a transport locate at the end of the loop\n\n"
3080 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
3081 "which will often cause a small click or delay"), PROGRAM_NAME));
3082 add_option (_("Transport"), bo);
3084 add_option (_("Transport"), new OptionEditorHeading (_("Dropout (xrun) Handling")));
3085 bo = new BoolOption (
3086 "stop-recording-on-xrun",
3087 _("Stop recording when an xrun occurs"),
3088 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
3089 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
3091 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3092 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
3094 add_option (_("Transport"), bo);
3096 bo = new BoolOption (
3097 "create-xrun-marker",
3098 _("Create markers where xruns occur"),
3099 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
3100 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
3102 add_option (_("Transport"), bo);
3107 add_option (_("Sync"), new OptionEditorHeading (_("External Synchronization")));
3109 _sync_source = new ComboOption<SyncSource> (
3111 _("External timecode source"),
3112 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
3113 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
3116 add_option (_("Sync"), _sync_source);
3118 _sync_framerate = new BoolOption (
3119 "timecode-sync-frame-rate",
3120 _("Match session video frame rate to external timecode"),
3121 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
3122 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
3124 Gtkmm2ext::UI::instance()->set_tip
3125 (_sync_framerate->tip_widget(),
3126 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
3127 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
3128 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
3129 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
3130 "timecode standard and the session standard."), PROGRAM_NAME));
3132 add_option (_("Sync"), _sync_framerate);
3134 _sync_genlock = new BoolOption (
3135 "timecode-source-is-synced",
3136 _("Sync-lock timecode to clock (disable drift compensation)"),
3137 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
3138 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
3140 Gtkmm2ext::UI::instance()->set_tip
3141 (_sync_genlock->tip_widget(),
3142 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
3143 "Sync Lock indicates that the selected external timecode source shares clock-sync "
3144 "(Black & Burst, Wordclock, etc) with the audio interface. "
3145 "This option disables drift compensation. The transport speed is fixed at 1.0. "
3146 "Vari-speed LTC will be ignored and cause drift."
3148 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
3149 "timecode sources shares clock sync."
3153 add_option (_("Sync"), _sync_genlock);
3155 _sync_source_2997 = new BoolOption (
3156 "timecode-source-2997",
3157 _("Lock to 29.9700 fps instead of 30000/1001"),
3158 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
3159 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
3161 Gtkmm2ext::UI::instance()->set_tip
3162 (_sync_source_2997->tip_widget(),
3163 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
3164 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
3165 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
3166 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
3167 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
3168 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
3171 add_option (_("Sync"), _sync_source_2997);
3173 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Reader")));
3175 _ltc_port = new ComboStringOption (
3177 _("LTC incoming port"),
3178 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
3179 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
3182 vector<string> physical_inputs;
3183 physical_inputs.push_back (_("None"));
3184 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
3185 _ltc_port->set_popdown_strings (physical_inputs);
3187 populate_sync_options ();
3188 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
3190 add_option (_("Sync/LTC"), _ltc_port);
3192 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Generator")));
3194 add_option (_("Sync/LTC"),
3197 _("Enable LTC generator"),
3198 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
3199 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
3202 _ltc_send_continuously = new BoolOption (
3203 "ltc-send-continuously",
3204 _("Send LTC while stopped"),
3205 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
3206 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
3208 Gtkmm2ext::UI::instance()->set_tip
3209 (_ltc_send_continuously->tip_widget(),
3210 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
3211 add_option (_("Sync/LTC"), _ltc_send_continuously);
3213 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level [dBFS]"),
3214 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_output_volume),
3215 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_output_volume),
3219 Gtkmm2ext::UI::instance()->set_tip
3220 (_ltc_volume_slider->tip_widget(),
3221 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
3223 add_option (_("Sync/LTC"), _ltc_volume_slider);
3226 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Beat Clock (Mclk) Generator")));
3228 add_option (_("Sync/MIDI"),
3231 _("Enable Mclk generator"),
3232 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
3233 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
3236 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC) Generator")));
3238 add_option (_("Sync/MIDI"),
3241 _("Enable MTC Generator"),
3242 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
3243 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
3246 add_option (_("Sync/MIDI"),
3247 new SpinOption<int> (
3248 "mtc-qf-speed-tolerance",
3249 _("Percentage either side of normal transport speed to transmit MTC"),
3250 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
3251 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
3255 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Machine Control (MMC)")));
3257 add_option (_("Sync/MIDI"),
3260 _("Respond to MMC commands"),
3261 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
3262 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
3265 add_option (_("Sync/MIDI"),
3268 _("Send MMC commands"),
3269 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
3270 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
3273 add_option (_("Sync/MIDI"),
3274 new SpinOption<uint8_t> (
3275 "mmc-receive-device-id",
3276 _("Inbound MMC device ID"),
3277 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
3278 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
3282 add_option (_("Sync/MIDI"),
3283 new SpinOption<uint8_t> (
3284 "mmc-send-device-id",
3285 _("Outbound MMC device ID"),
3286 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
3287 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
3292 /* Control Surfaces */
3294 add_option (_("Control Surfaces"), new OptionEditorHeading (_("Control Surfaces")));
3295 add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
3298 add_option (_("MIDI Ports"), new OptionEditorHeading (_("MIDI Port Options")));
3300 add_option (_("MIDI Ports"),
3302 "get-midi-input-follows-selection",
3303 _("MIDI input follows MIDI track selection"),
3304 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
3305 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
3308 add_option (_("MIDI Ports"), new MidiPortOptions ());
3309 add_option (_("MIDI Ports"), new OptionEditorBlank ());
3313 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3314 add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
3315 add_option (_("Plugins"),
3316 new RcActionButton (_("Scan for Plugins"),
3317 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3321 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
3323 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3324 bo = new BoolOption (
3325 "show-plugin-scan-window",
3326 _("Always Display Plugin Scan Progress"),
3327 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
3328 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
3330 add_option (_("Plugins"), bo);
3331 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3332 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
3335 bo = new BoolOption (
3336 "plugins-stop-with-transport",
3337 _("Silence plugins when the transport is stopped"),
3338 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
3339 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
3341 add_option (_("Plugins"), bo);
3342 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3343 _("<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."));
3345 bo = new BoolOption (
3346 "new-plugins-active",
3347 _("Make new plugins active"),
3348 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
3349 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
3351 add_option (_("Plugins"), bo);
3352 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3353 _("<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"));
3355 #if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
3356 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
3358 add_option (_("Plugins/VST"),
3359 new RcActionButton (_("Scan for Plugins"),
3360 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3363 #if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
3364 bo = new BoolOption (
3366 _("Enable Mac VST support (requires restart or re-scan)"),
3367 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
3368 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
3370 add_option (_("Plugins/VST"), bo);
3373 bo = new BoolOption (
3374 "discover-vst-on-start",
3375 _("Scan for [new] VST Plugins on Application Start"),
3376 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
3377 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
3379 add_option (_("Plugins/VST"), bo);
3380 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3381 _("<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"));
3383 #ifdef WINDOWS_VST_SUPPORT
3384 // currently verbose logging is only implemented for Windows VST.
3385 bo = new BoolOption (
3386 "verbose-plugin-scan",
3387 _("Verbose Plugin Scan"),
3388 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
3389 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
3391 add_option (_("Plugins/VST"), bo);
3392 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3393 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
3396 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
3398 add_option (_("Plugins/VST"),
3399 new RcActionButton (_("Clear"),
3400 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
3403 add_option (_("Plugins/VST"),
3404 new RcActionButton (_("Clear"),
3405 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
3406 _("VST Blacklist:")));
3409 #ifdef LXVST_SUPPORT
3410 add_option (_("Plugins/VST"),
3411 new RcActionButton (_("Edit"),
3412 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
3413 _("Linux VST Path:")));
3415 add_option (_("Plugins/VST"),
3416 new RcConfigDisplay (
3417 "plugin-path-lxvst",
3419 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
3423 #ifdef WINDOWS_VST_SUPPORT
3424 add_option (_("Plugins/VST"),
3425 new RcActionButton (_("Edit"),
3426 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
3427 _("Windows VST Path:")));
3428 add_option (_("Plugins/VST"),
3429 new RcConfigDisplay (
3432 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
3436 #ifdef AUDIOUNIT_SUPPORT
3438 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
3440 add_option (_("Plugins/Audio Unit"),
3441 new RcActionButton (_("Scan for Plugins"),
3442 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3445 bo = new BoolOption (
3446 "discover-audio-units",
3447 _("Scan for [new] AudioUnit Plugins on Application Start"),
3448 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
3449 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
3451 add_option (_("Plugins/Audio Unit"), bo);
3452 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3453 _("<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."));
3455 add_option (_("Plugins/Audio Unit"),
3456 new RcActionButton (_("Clear"),
3457 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
3460 add_option (_("Plugins/Audio Unit"),
3461 new RcActionButton (_("Clear"),
3462 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
3463 _("AU Blacklist:")));
3466 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
3467 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
3468 add_option (_("Plugins"),
3470 "open-gui-after-adding-plugin",
3471 _("Automatically open the plugin GUI when adding a new plugin"),
3472 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
3473 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3476 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3477 add_option (_("Plugins"),
3479 "show-inline-display-by-default",
3480 _("Show Plugin Inline Display on Mixerstrip by default"),
3481 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3482 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3485 _plugin_prefer_inline = new BoolOption (
3486 "prefer-inline-over-gui",
3487 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3488 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3489 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3491 add_option (_("Plugins"), _plugin_prefer_inline);
3494 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3496 bo = new BoolOption (
3497 "ask-replace-instrument",
3498 _("Ask to replace existing instrument plugin"),
3499 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3500 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3502 add_option (_("Plugins"), bo);
3504 bo = new BoolOption (
3505 "ask-setup_instrument",
3506 _("Interactively configure instrument plugins on insert"),
3507 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3508 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3510 add_option (_("Plugins"), bo);
3511 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3512 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3515 add_option (_("Plugins"), new OptionEditorBlank ());
3518 #if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
3519 add_option (_("Appearance"), new OptionEditorHeading (_("Graphics Acceleration")));
3522 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3523 BoolOption* bgc = new BoolOption (
3524 "cairo-image-surface",
3525 _("Disable Graphics Hardware Acceleration (requires restart)"),
3526 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3527 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3530 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3531 _("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));
3532 add_option (_("Appearance"), bgc);
3535 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3536 BoolOption* bgo = new BoolOption (
3538 _("Possibly improve slow graphical performance (requires restart)"),
3539 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3540 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3543 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));
3544 add_option (_("Appearance"), bgo);
3546 add_option (_("Appearance"), new OptionEditorHeading (_("Graphical User Interface")));
3548 add_option (_("Appearance"),
3551 _("Highlight widgets on mouseover"),
3552 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3553 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3556 add_option (_("Appearance"),
3559 _("Show tooltips if mouse hovers over a control"),
3560 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3561 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3564 bo = new BoolOption (
3565 "super-rapid-clock-update",
3566 _("Update clocks at TC Frame rate"),
3567 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3568 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3570 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3571 _("<b>When enabled</b> clock displays are updated every Timecode Frame (fps).\n\n"
3572 "<b>When disabled</b> clock displays are updated only every 100ms."
3574 add_option (_("Appearance"), bo);
3576 add_option (_("Appearance"),
3579 _("Blink Rec-Arm buttons"),
3580 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_rec_arm),
3581 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_rec_arm)
3584 add_option (_("Appearance"),
3586 "blink-alert-indicators",
3587 _("Blink Alert Indicators"),
3588 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_alert_indicators),
3589 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_alert_indicators)
3594 /* font scaling does nothing with GDK/Quartz */
3595 add_option (_("Appearance"), new FontScalingOptions ());
3597 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("General")));
3598 add_option (_("Appearance/Editor"),
3600 "show-name-highlight",
3601 _("Use name highlight bars in region displays (requires a restart)"),
3602 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3603 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3606 add_option (_("Appearance/Editor"),
3608 "color-regions-using-track-color",
3609 _("Region color follows track color"),
3610 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_color_regions_using_track_color),
3611 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_color_regions_using_track_color)
3614 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Waveforms")));
3616 if (!Profile->get_mixbus()) {
3617 add_option (_("Appearance/Editor"),
3620 _("Show waveforms in regions"),
3621 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
3622 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
3626 add_option (_("Appearance/Editor"),
3628 "show-waveforms-while-recording",
3629 _("Show waveforms while recording"),
3630 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
3631 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
3634 add_option (_("Appearance/Editor"),
3636 "show-waveform-clipping",
3637 _("Show waveform clipping"),
3638 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveform_clipping),
3639 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveform_clipping)
3642 add_option (_("Appearance/Editor"), new ClipLevelOptions ());
3644 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
3646 _("Waveform scale"),
3647 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
3648 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
3651 wfs->add (Linear, _("linear"));
3652 wfs->add (Logarithmic, _("logarithmic"));
3654 add_option (_("Appearance/Editor"), wfs);
3656 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
3658 _("Waveform shape"),
3659 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
3660 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
3663 wfsh->add (Traditional, _("traditional"));
3664 wfsh->add (Rectified, _("rectified"));
3666 add_option (_("Appearance/Editor"), wfsh);
3668 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Editor Meters")));
3670 add_option (_("Appearance/Editor"),
3672 "show-track-meters",
3673 _("Show meters in track headers"),
3674 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3675 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3678 add_option (_("Appearance/Editor"),
3680 "editor-stereo-only-meters",
3681 _("Limit track header meters to stereo"),
3682 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3683 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3686 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("MIDI Regions")));
3688 add_option (_("Appearance/Editor"),
3690 "display-first-midi-bank-as-zero",
3691 _("Display first MIDI bank/program as 0"),
3692 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
3693 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
3696 add_option (_("Appearance/Editor"),
3698 "never-display-periodic-midi",
3699 _("Don't display periodic (MTC, MMC) SysEx messages in MIDI Regions"),
3700 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
3701 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
3704 add_option (_("Appearance/Editor"), new OptionEditorBlank ());
3706 /* The names of these controls must be the same as those given in MixerStrip
3707 for the actual widgets being controlled.
3709 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3710 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3711 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3712 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3713 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3714 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3715 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3717 add_option (_("Appearance/Mixer"),
3718 new VisibilityOption (
3720 &_mixer_strip_visibility,
3721 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3722 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3726 add_option (_("Appearance/Mixer"),
3728 "default-narrow_ms",
3729 _("Use narrow strips in the mixer for new strips by default"),
3730 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3731 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3734 add_option (_("Appearance/Mixer"), new OptionEditorBlank ());
3736 add_option (_("Appearance/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items")));
3738 add_option (_("Appearance/Toolbar"),
3740 "show-toolbar-recpunch",
3741 _("Display Record/Punch Options"),
3742 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_recpunch),
3743 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_recpunch)
3746 add_option (_("Appearance/Toolbar"),
3748 "show-toolbar-monitoring",
3749 _("Display Monitor Options"),
3750 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_monitoring),
3751 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_monitoring)
3754 add_option (_("Appearance/Toolbar"),
3756 "show-toolbar-selclock",
3757 _("Display Selection Clock"),
3758 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
3759 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
3762 if (!ARDOUR::Profile->get_small_screen()) {
3763 add_option (_("Appearance/Toolbar"),
3765 "show-secondary-clock",
3766 _("Display Secondary Clock"),
3767 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
3768 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
3772 add_option (_("Appearance/Toolbar"),
3774 "show-mini-timeline",
3775 _("Display Navigation Timeline"),
3776 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
3777 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
3780 add_option (_("Appearance/Toolbar"),
3782 "show-editor-meter",
3783 _("Display Master Level Meter"),
3784 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
3785 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
3788 add_option (_("Appearance/Toolbar"),
3789 new ColumVisibilityOption (
3790 "action-table-columns", _("Lua Action Script Button Visibility"), 4,
3791 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3792 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3795 add_option (_("Appearance/Toolbar"), new OptionEditorBlank ());
3798 /* and now the theme manager */
3800 add_option (_("Appearance/Theme"), new OptionEditorHeading (_("Theme")));
3802 add_option (_("Appearance/Theme"), new BoolOption (
3804 _("Draw \"flat\" buttons"),
3805 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_flat_buttons),
3806 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_flat_buttons)
3809 add_option (_("Appearance/Theme"), new BoolOption (
3811 _("LED meter style"),
3812 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3813 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3817 HSliderOption *gui_hs = new HSliderOption(
3818 "timeline-item-gradient-depth",
3819 _("Waveforms color gradient depth"),
3820 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_gradient_depth),
3821 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_gradient_depth),
3824 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3825 add_option (_("Appearance/Theme"), gui_hs);
3827 gui_hs = new HSliderOption(
3828 "timeline-item-gradient-depth",
3829 _("Timeline item gradient depth"),
3830 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_timeline_item_gradient_depth),
3831 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_timeline_item_gradient_depth),
3834 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3835 add_option (_("Appearance/Theme"), gui_hs);
3837 vector<string> icon_sets = ::get_icon_sets ();
3838 if (icon_sets.size() > 1) {
3839 ComboOption<std::string>* io = new ComboOption<std::string> (
3840 "icon-set", _("Icon Set"),
3841 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_icon_set),
3842 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_icon_set)
3844 for (vector<string>::const_iterator i = icon_sets.begin (); i != icon_sets.end (); ++i) {
3847 add_option (_("Appearance/Theme"), io);
3850 add_option (_("Appearance/Colors"), new OptionEditorHeading (_("Colors")));
3851 add_option (_("Appearance/Colors"), new ColorThemeManager);
3852 add_option (_("Appearance/Colors"), new OptionEditorBlank ());
3856 OptionEditorHeading* quirks_head = new OptionEditorHeading (_("Various Workarounds for Windowing Systems"));
3858 quirks_head->set_note (string_compose (_("Rules for closing, minimizing, maximizing, and stay-on-top can vary\
3859 with each version of your OS, and the preferences that you've set in your OS.\n\n\
3860 You can adjust the options, below, to change how %1's windows and dialogs behave.\n\n\
3861 These settings will only take effect after %1 is restarted.\n\
3864 add_option (_("Appearance/Quirks"), quirks_head);
3866 bo = new BoolOption (
3867 "use-wm-visibility",
3868 _("Use visibility information provided by your Window Manager/Desktop"),
3869 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3870 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3872 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3873 _("If you have trouble toggling between hidden Editor and Mixer windows, try changing this setting."));
3874 add_option (_("Appearance/Quirks"), bo);
3877 bo = new BoolOption (
3878 "all-floating-windows-are-dialogs",
3879 _("All floating windows are dialogs"),
3880 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_all_floating_windows_are_dialogs),
3881 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_all_floating_windows_are_dialogs)
3883 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3884 _("Mark all floating windows to be type \"Dialog\" rather than using \"Utility\" for some.\nThis may help with some window managers."));
3885 add_option (_("Appearance/Quirks"), bo);
3887 bo = new BoolOption (
3888 "transients-follow-front",
3889 _("Transient windows follow front window."),
3890 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_transients_follow_front),
3891 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_transients_follow_front)
3893 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3894 _("Make transient windows follow the front window when toggling between the editor and mixer."));
3895 add_option (_("Appearance/Quirks"), bo);
3898 if (!Profile->get_mixbus()) {
3899 bo = new BoolOption (
3900 "floating-monitor-section",
3901 _("Float detached monitor-section window"),
3902 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_floating_monitor_section),
3903 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_floating_monitor_section)
3905 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3906 _("When detaching the monitoring section, mark it as \"Utility\" window to stay in front."));
3907 add_option (_("Appearance/Quirks"), bo);
3910 add_option (_("Appearance/Quirks"), new OptionEditorBlank ());
3912 /* VIDEO Timeline */
3913 add_option (_("Video"), new OptionEditorHeading (_("Video Server")));
3914 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
3916 Widget::show_all ();
3918 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3919 parameter_changed ("send-ltc");
3920 parameter_changed ("sync-source");
3921 parameter_changed ("use-monitor-bus");
3922 parameter_changed ("open-gui-after-adding-plugin");
3924 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
3926 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
3927 (Gtk::StateType) here !!!
3929 Tabbable::set_state (*node, Stateful::loading_state_version);
3932 set_current_page (_("General"));
3936 RCOptionEditor::parameter_changed (string const & p)
3938 OptionEditor::parameter_changed (p);
3940 if (p == "use-monitor-bus") {
3941 bool const s = Config->get_use_monitor_bus ();
3943 /* we can't use this if we don't have a monitor bus */
3944 Config->set_solo_control_is_listen_control (false);
3946 _solo_control_is_listen_control->set_sensitive (s);
3947 _listen_position->set_sensitive (s);
3948 } else if (p == "sync-source") {
3949 _sync_source->set_sensitive (true);
3951 _sync_source->set_sensitive (!_session->config.get_external_sync());
3953 switch(Config->get_sync_source()) {
3956 _sync_genlock->set_sensitive (true);
3957 _sync_framerate->set_sensitive (true);
3958 _sync_source_2997->set_sensitive (true);
3961 _sync_genlock->set_sensitive (false);
3962 _sync_framerate->set_sensitive (false);
3963 _sync_source_2997->set_sensitive (false);
3966 } else if (p == "send-ltc") {
3967 bool const s = Config->get_send_ltc ();
3968 _ltc_send_continuously->set_sensitive (s);
3969 _ltc_volume_slider->set_sensitive (s);
3970 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
3971 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3972 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
3977 void RCOptionEditor::plugin_scan_refresh () {
3978 PluginManager::instance().refresh();
3981 void RCOptionEditor::clear_vst_cache () {
3982 PluginManager::instance().clear_vst_cache();
3985 void RCOptionEditor::clear_vst_blacklist () {
3986 PluginManager::instance().clear_vst_blacklist();
3989 void RCOptionEditor::clear_au_cache () {
3990 PluginManager::instance().clear_au_cache();
3993 void RCOptionEditor::clear_au_blacklist () {
3994 PluginManager::instance().clear_au_blacklist();
3997 void RCOptionEditor::edit_lxvst_path () {
3998 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
3999 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
4000 *current_toplevel(), _("Set Linux VST Search Path"),
4001 _rc_config->get_plugin_path_lxvst(),
4002 PluginManager::instance().get_default_lxvst_path()
4004 ResponseType r = (ResponseType) pd->run ();
4006 if (r == RESPONSE_ACCEPT) {
4007 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
4009 MessageDialog msg (_("Re-scan Plugins now?"),
4010 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
4011 msg.set_default_response (Gtk::RESPONSE_YES);
4012 if (msg.run() == Gtk::RESPONSE_YES) {
4014 plugin_scan_refresh ();
4020 void RCOptionEditor::edit_vst_path () {
4021 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
4022 *current_toplevel(), _("Set Windows VST Search Path"),
4023 _rc_config->get_plugin_path_vst(),
4024 PluginManager::instance().get_default_windows_vst_path()
4026 ResponseType r = (ResponseType) pd->run ();
4028 if (r == RESPONSE_ACCEPT) {
4029 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
4030 MessageDialog msg (_("Re-scan Plugins now?"),
4031 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
4032 msg.set_default_response (Gtk::RESPONSE_YES);
4033 if (msg.run() == Gtk::RESPONSE_YES) {
4035 plugin_scan_refresh ();
4043 RCOptionEditor::populate_sync_options ()
4045 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
4047 _sync_source->clear ();
4049 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
4050 _sync_source->add (*i, sync_source_to_string (*i));
4053 if (sync_opts.empty()) {
4054 _sync_source->set_sensitive(false);
4056 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
4057 _rc_config->set_sync_source(sync_opts.front());
4061 parameter_changed ("sync-source");
4065 RCOptionEditor::use_own_window (bool and_fill_it)
4067 bool new_window = !own_window ();
4069 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
4071 if (win && new_window) {
4072 win->set_name ("PreferencesWindow");
4073 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
4075 win->set_resizable (false);
4082 RCOptionEditor::get_state ()
4084 XMLNode* node = new XMLNode (X_("Preferences"));
4085 node->add_child_nocopy (Tabbable::get_state());