2 Copyright (C) 2001-2011 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "gtk2ardour-config.h"
24 #if !defined USE_CAIRO_IMAGE_SURFACE && !defined NDEBUG
25 #define OPTIONAL_CAIRO_IMAGE_SURFACE
28 #include <cairo/cairo.h>
30 #include <boost/algorithm/string.hpp>
32 #include <gtkmm/liststore.h>
33 #include <gtkmm/stock.h>
34 #include <gtkmm/scale.h>
36 #include "gtkmm2ext/utils.h"
37 #include "gtkmm2ext/gtk_ui.h"
38 #include "gtkmm2ext/window_title.h"
44 #include "ardour/audio_backend.h"
45 #include "ardour/audioengine.h"
46 #include "ardour/profile.h"
47 #include "ardour/dB.h"
48 #include "ardour/rc_configuration.h"
49 #include "ardour/control_protocol_manager.h"
50 #include "ardour/port_manager.h"
51 #include "ardour/plugin_manager.h"
52 #include "control_protocol/control_protocol.h"
54 #include "waveview/wave_view.h"
56 #include "widgets/paths_dialog.h"
57 #include "widgets/tooltips.h"
59 #include "ardour_dialog.h"
60 #include "ardour_ui.h"
61 #include "ardour_window.h"
62 #include "color_theme_manager.h"
63 #include "gui_thread.h"
65 #include "meter_patterns.h"
66 #include "midi_tracer.h"
67 #include "rc_option_editor.h"
69 #include "ui_config.h"
74 using namespace Gtkmm2ext;
76 using namespace ARDOUR;
77 using namespace ARDOUR_UI_UTILS;
78 using namespace ArdourWidgets;
80 class ClickOptions : public OptionEditorMiniPage
83 ClickOptions (RCConfiguration* c)
85 , _click_browse_button (_("Browse..."))
86 , _click_emphasis_browse_button (_("Browse..."))
88 // TODO get rid of GTK -> use OptionEditor Widgets
93 l = manage (left_aligned_label (_("Emphasis on first beat")));
94 _use_emphasis_on_click_check_button.add (*l);
95 t->attach (_use_emphasis_on_click_check_button, 1, 3, row, row + 1, FILL);
96 _use_emphasis_on_click_check_button.signal_toggled().connect (
97 sigc::mem_fun (*this, &ClickOptions::use_emphasis_on_click_toggled));
100 l = manage (left_aligned_label (_("Use built-in default sounds")));
101 _use_default_click_check_button.add (*l);
102 t->attach (_use_default_click_check_button, 1, 3, row, row + 1, FILL);
103 _use_default_click_check_button.signal_toggled().connect (
104 sigc::mem_fun (*this, &ClickOptions::use_default_click_toggled));
107 l = manage (left_aligned_label (_("Audio file:")));
108 t->attach (*l, 1, 2, row, row + 1, FILL);
109 t->attach (_click_path_entry, 2, 3, row, row + 1, FILL);
110 _click_browse_button.signal_clicked ().connect (
111 sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
112 t->attach (_click_browse_button, 3, 4, row, row + 1, FILL);
115 l = manage (left_aligned_label (_("Emphasis audio file:")));
116 t->attach (*l, 1, 2, row, row + 1, FILL);
117 t->attach (_click_emphasis_path_entry, 2, 3, row, row + 1, FILL);
118 _click_emphasis_browse_button.signal_clicked ().connect (
119 sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
120 t->attach (_click_emphasis_browse_button, 3, 4, row, row + 1, FILL);
123 _click_fader = new FaderOption (
126 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
127 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
130 _click_fader->add_to_page (this);
131 _click_fader->set_state_from_config ();
133 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
134 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
136 if (_rc_config->get_click_sound ().empty() &&
137 _rc_config->get_click_emphasis_sound().empty()) {
138 _use_default_click_check_button.set_active (true);
139 _use_emphasis_on_click_check_button.set_active (true);
142 _use_default_click_check_button.set_active (false);
143 _use_emphasis_on_click_check_button.set_active (false);
147 void parameter_changed (string const & p)
149 if (p == "click-sound") {
150 _click_path_entry.set_text (_rc_config->get_click_sound());
151 } else if (p == "click-emphasis-sound") {
152 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
153 } else if (p == "use-click-emphasis") {
154 bool x = _rc_config->get_use_click_emphasis ();
155 _use_emphasis_on_click_check_button.set_active (x);
156 } else if (p == "click-gain") {
157 _click_fader->set_state_from_config ();
161 void set_state_from_config ()
163 parameter_changed ("click-sound");
164 parameter_changed ("click-emphasis-sound");
165 parameter_changed ("use-click-emphasis");
170 void click_browse_clicked ()
172 SoundFileChooser sfdb (_("Choose Click"));
177 if (sfdb.run () == RESPONSE_OK) {
178 click_chosen (sfdb.get_filename());
182 void click_chosen (string const & path)
184 _click_path_entry.set_text (path);
185 _rc_config->set_click_sound (path);
188 void click_changed ()
190 click_chosen (_click_path_entry.get_text ());
193 void click_emphasis_browse_clicked ()
195 SoundFileChooser sfdb (_("Choose Click Emphasis"));
200 if (sfdb.run () == RESPONSE_OK) {
201 click_emphasis_chosen (sfdb.get_filename());
205 void click_emphasis_chosen (string const & path)
207 _click_emphasis_path_entry.set_text (path);
208 _rc_config->set_click_emphasis_sound (path);
211 void click_emphasis_changed ()
213 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
216 void use_default_click_toggled ()
218 if (_use_default_click_check_button.get_active ()) {
219 _rc_config->set_click_sound ("");
220 _rc_config->set_click_emphasis_sound ("");
221 _click_path_entry.set_sensitive (false);
222 _click_emphasis_path_entry.set_sensitive (false);
223 _click_browse_button.set_sensitive (false);
224 _click_emphasis_browse_button.set_sensitive (false);
226 _click_path_entry.set_sensitive (true);
227 _click_emphasis_path_entry.set_sensitive (true);
228 _click_browse_button.set_sensitive (true);
229 _click_emphasis_browse_button.set_sensitive (true);
233 void use_emphasis_on_click_toggled ()
235 if (_use_emphasis_on_click_check_button.get_active ()) {
236 _rc_config->set_use_click_emphasis(true);
238 _rc_config->set_use_click_emphasis(false);
242 RCConfiguration* _rc_config;
243 CheckButton _use_default_click_check_button;
244 CheckButton _use_emphasis_on_click_check_button;
245 Entry _click_path_entry;
246 Entry _click_emphasis_path_entry;
247 Button _click_browse_button;
248 Button _click_emphasis_browse_button;
249 FaderOption* _click_fader;
252 class UndoOptions : public OptionEditorComponent
255 UndoOptions (RCConfiguration* c) :
257 _limit_undo_button (_("Limit undo history to")),
258 _save_undo_button (_("Save undo history of"))
260 // TODO get rid of GTK -> use OptionEditor SpinOption
261 _limit_undo_spin.set_range (0, 512);
262 _limit_undo_spin.set_increments (1, 10);
264 _save_undo_spin.set_range (0, 512);
265 _save_undo_spin.set_increments (1, 10);
267 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
268 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
269 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
270 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
273 void parameter_changed (string const & p)
275 if (p == "history-depth") {
276 int32_t const d = _rc_config->get_history_depth();
277 _limit_undo_button.set_active (d != 0);
278 _limit_undo_spin.set_sensitive (d != 0);
279 _limit_undo_spin.set_value (d);
280 } else if (p == "save-history") {
281 bool const x = _rc_config->get_save_history ();
282 _save_undo_button.set_active (x);
283 _save_undo_spin.set_sensitive (x);
284 } else if (p == "save-history-depth") {
285 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
289 void set_state_from_config ()
291 parameter_changed ("save-history");
292 parameter_changed ("history-depth");
293 parameter_changed ("save-history-depth");
296 void limit_undo_toggled ()
298 bool const x = _limit_undo_button.get_active ();
299 _limit_undo_spin.set_sensitive (x);
300 int32_t const n = x ? 16 : 0;
301 _limit_undo_spin.set_value (n);
302 _rc_config->set_history_depth (n);
305 void limit_undo_changed ()
307 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
310 void save_undo_toggled ()
312 bool const x = _save_undo_button.get_active ();
313 _rc_config->set_save_history (x);
316 void save_undo_changed ()
318 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
321 void add_to_page (OptionEditorPage* p)
323 int const n = p->table.property_n_rows();
324 Table* t = & p->table;
326 t->resize (n + 2, 3);
328 Label* l = manage (left_aligned_label (_("commands")));
329 HBox* box = manage (new HBox());
330 box->set_spacing (4);
331 box->pack_start (_limit_undo_spin, false, false);
332 box->pack_start (*l, true, true);
333 t->attach (_limit_undo_button, 1, 2, n, n +1, FILL);
334 t->attach (*box, 2, 3, n, n + 1, FILL | EXPAND);
336 l = manage (left_aligned_label (_("commands")));
337 box = manage (new HBox());
338 box->set_spacing (4);
339 box->pack_start (_save_undo_spin, false, false);
340 box->pack_start (*l, true, true);
341 t->attach (_save_undo_button, 1, 2, n + 1, n + 2, FILL);
342 t->attach (*box, 2, 3, n + 1, n + 2, FILL | EXPAND);
345 Gtk::Widget& tip_widget() {
346 return _limit_undo_button; // unused
350 RCConfiguration* _rc_config;
351 CheckButton _limit_undo_button;
352 SpinButton _limit_undo_spin;
353 CheckButton _save_undo_button;
354 SpinButton _save_undo_spin;
358 static const struct {
370 { "Key|Shift", GDK_SHIFT_MASK },
371 { "Command", GDK_MOD2_MASK },
372 { "Control", GDK_CONTROL_MASK },
373 { "Option", GDK_MOD1_MASK },
374 { "Command-Shift", GDK_MOD2_MASK|GDK_SHIFT_MASK },
375 { "Command-Option", GDK_MOD2_MASK|GDK_MOD1_MASK },
376 { "Command-Control", GDK_MOD2_MASK|GDK_CONTROL_MASK },
377 { "Command-Option-Control", GDK_MOD2_MASK|GDK_MOD1_MASK|GDK_CONTROL_MASK },
378 { "Option-Control", GDK_MOD1_MASK|GDK_CONTROL_MASK },
379 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
380 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
381 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_MOD2_MASK },
384 { "Key|Shift", GDK_SHIFT_MASK },
385 { "Control", GDK_CONTROL_MASK },
386 { "Alt", GDK_MOD1_MASK },
387 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
388 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
389 { "Control-Windows", GDK_CONTROL_MASK|GDK_MOD4_MASK },
390 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
391 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
392 { "Alt-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
393 { "Alt-Shift-Windows", GDK_MOD1_MASK|GDK_SHIFT_MASK|GDK_MOD4_MASK },
394 { "Mod2", GDK_MOD2_MASK },
395 { "Mod3", GDK_MOD3_MASK },
396 { "Windows", GDK_MOD4_MASK },
397 { "Mod5", GDK_MOD5_MASK },
403 class KeyboardOptions : public OptionEditorMiniPage
407 : _delete_button_adjustment (3, 1, 12)
408 , _delete_button_spin (_delete_button_adjustment)
409 , _edit_button_adjustment (3, 1, 5)
410 , _edit_button_spin (_edit_button_adjustment)
411 , _insert_note_button_adjustment (3, 1, 5)
412 , _insert_note_button_spin (_insert_note_button_adjustment)
414 // TODO get rid of GTK -> use OptionEditor Widgets
416 const std::string restart_msg = _("\nChanges to this setting will only persist after your project has been saved.");
417 /* internationalize and prepare for use with combos */
420 for (int i = 0; modifiers[i].name; ++i) {
421 dumb.push_back (S_(modifiers[i].name));
424 set_popdown_strings (_edit_modifier_combo, dumb);
425 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
426 Gtkmm2ext::UI::instance()->set_tip (_edit_modifier_combo,
427 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
434 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
435 l->set_name ("OptionsLabel");
439 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
440 strs.push_back (bf->first);
443 set_popdown_strings (_keyboard_layout_selector, strs);
444 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
445 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
447 t->attach (*l, col + 1, col + 2, row, row + 1, FILL, FILL);
448 t->attach (_keyboard_layout_selector, col + 2, col + 3, row, row + 1, FILL | EXPAND, FILL);
453 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Clicking:"))));
454 l->set_name ("OptionEditorHeading");
455 l->set_use_markup (true);
456 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
461 l = manage (left_aligned_label (_("Edit using:")));
462 l->set_name ("OptionsLabel");
464 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
465 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
467 l = manage (new Label (_("+ button")));
468 l->set_name ("OptionsLabel");
470 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
471 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, SHRINK , FILL);
473 _edit_button_spin.set_name ("OptionsEntry");
474 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
479 set_popdown_strings (_delete_modifier_combo, dumb);
480 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
481 Gtkmm2ext::UI::instance()->set_tip (_delete_modifier_combo,
482 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
484 l = manage (left_aligned_label (_("Delete using:")));
485 l->set_name ("OptionsLabel");
487 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
488 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
490 l = manage (new Label (_("+ button")));
491 l->set_name ("OptionsLabel");
493 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
494 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, SHRINK, FILL);
496 _delete_button_spin.set_name ("OptionsEntry");
497 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
502 set_popdown_strings (_insert_note_modifier_combo, dumb);
503 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
504 Gtkmm2ext::UI::instance()->set_tip (_insert_note_modifier_combo,
505 (string_compose (_("<b>Recommended Setting: %1 + button 1 (left mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
507 l = manage (left_aligned_label (_("Insert note using:")));
508 l->set_name ("OptionsLabel");
510 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
511 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
513 l = manage (new Label (_("+ button")));
514 l->set_name ("OptionsLabel");
516 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
517 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, SHRINK, FILL);
519 _insert_note_button_spin.set_name ("OptionsEntry");
520 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
524 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Beginning a Drag:"))));
525 l->set_name ("OptionEditorHeading");
526 l->set_use_markup (true);
527 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
533 set_popdown_strings (_copy_modifier_combo, dumb);
534 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
535 Gtkmm2ext::UI::instance()->set_tip (_copy_modifier_combo,
536 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
538 Keyboard::secondary_modifier_name (),
540 Keyboard::primary_modifier_name (),
544 l = manage (left_aligned_label (_("Copy items using:")));
545 l->set_name ("OptionsLabel");
547 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
548 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
553 /* constraint modifier */
554 set_popdown_strings (_constraint_modifier_combo, dumb);
555 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
556 Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo,
557 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
559 Keyboard::primary_modifier_name (),
561 Keyboard::tertiary_modifier_name (),
565 l = manage (left_aligned_label (_("Constrain drag using:")));
566 l->set_name ("OptionsLabel");
568 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
569 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
575 set_popdown_strings (_push_points_combo, dumb);
576 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
578 std::string mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
579 Gtkmm2ext::UI::instance()->set_tip (_push_points_combo,
580 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
582 l = manage (left_aligned_label (_("Push points using:")));
583 l->set_name ("OptionsLabel");
585 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
586 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
590 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Beginning a Trim:"))));
591 l->set_name ("OptionEditorHeading");
592 l->set_use_markup (true);
593 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
599 set_popdown_strings (_trim_contents_combo, dumb);
600 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
601 Gtkmm2ext::UI::instance()->set_tip (_trim_contents_combo,
602 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
604 l = manage (left_aligned_label (_("Trim contents using:")));
605 l->set_name ("OptionsLabel");
607 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
608 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
614 set_popdown_strings (_trim_anchored_combo, dumb);
615 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
617 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::tertiary_modifier_name ());
618 Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo,
619 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
621 l = manage (left_aligned_label (_("Anchored trim using:")));
622 l->set_name ("OptionsLabel");
624 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
626 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
631 /* jump trim disabled for now
632 set_popdown_strings (_trim_jump_combo, dumb);
633 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
635 l = manage (left_aligned_label (_("Jump after trim using:")));
636 l->set_name ("OptionsLabel");
638 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
640 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
646 /* note resize relative */
647 set_popdown_strings (_note_size_relative_combo, dumb);
648 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
649 Gtkmm2ext::UI::instance()->set_tip (_note_size_relative_combo,
650 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg))); // XXX 2ndary
652 l = manage (left_aligned_label (_("Resize notes relatively using:")));
653 l->set_name ("OptionsLabel");
655 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
657 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
661 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Dragging:"))));
662 l->set_name ("OptionEditorHeading");
663 l->set_use_markup (true);
664 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
670 set_popdown_strings (_snap_modifier_combo, dumb);
671 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
673 mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ());
675 mod_str = Keyboard::secondary_modifier_name();
677 Gtkmm2ext::UI::instance()->set_tip (_snap_modifier_combo,
678 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
680 l = manage (left_aligned_label (_("Ignore snap using:")));
681 l->set_name ("OptionsLabel");
683 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
684 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
690 set_popdown_strings (_snap_delta_combo, dumb);
691 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
693 mod_str = Keyboard::level4_modifier_name ();
695 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::level4_modifier_name ());
697 Gtkmm2ext::UI::instance()->set_tip (_snap_delta_combo,
698 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
700 l = manage (left_aligned_label (_("Snap relatively using:")));
701 l->set_name ("OptionsLabel");
703 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
704 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
708 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Trimming:"))));
709 l->set_name ("OptionEditorHeading");
710 l->set_use_markup (true);
711 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
717 set_popdown_strings (_trim_overlap_combo, dumb);
718 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
720 Gtkmm2ext::UI::instance()->set_tip (_trim_overlap_combo,
721 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
723 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
724 l->set_name ("OptionsLabel");
726 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
727 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
731 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Dragging Control Points:"))));
732 l->set_name ("OptionEditorHeading");
733 l->set_use_markup (true);
734 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
740 set_popdown_strings (_fine_adjust_combo, dumb);
741 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
743 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::secondary_modifier_name ()); // XXX just 2ndary ?!
744 Gtkmm2ext::UI::instance()->set_tip (_fine_adjust_combo,
745 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
747 l = manage (left_aligned_label (_("Fine adjust using:")));
748 l->set_name ("OptionsLabel");
750 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
751 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
753 OptionEditorHeading* h = new OptionEditorHeading (_("Reset"));
754 h->add_to_page (this);
756 RcActionButton* rb = new RcActionButton (_("Reset to recommended defaults"),
757 sigc::mem_fun (*this, &KeyboardOptions::reset_to_defaults));
758 rb->add_to_page (this);
760 set_state_from_config ();
763 void parameter_changed (string const &)
765 /* XXX: these aren't really config options... */
768 void set_state_from_config ()
770 _delete_button_adjustment.set_value (Keyboard::delete_button());
771 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
772 _edit_button_adjustment.set_value (Keyboard::edit_button());
774 for (int x = 0; modifiers[x].name; ++x) {
775 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
776 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
778 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
779 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
781 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
782 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
784 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
785 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
787 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
788 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
790 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
791 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
793 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
794 _push_points_combo.set_active_text (S_(modifiers[x].name));
796 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
797 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
799 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
800 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
803 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
804 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
807 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
808 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
810 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
811 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
813 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
814 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
816 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
817 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
822 void add_to_page (OptionEditorPage* p)
824 int const n = p->table.property_n_rows();
825 p->table.resize (n + 1, 3);
826 p->table.attach (box, 1, 3, n, n + 1, FILL | EXPAND, SHRINK, 0, 0);
831 void bindings_changed ()
833 string const txt = _keyboard_layout_selector.get_active_text();
835 /* XXX: config...? for all this keyboard stuff */
837 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
838 if (txt == i->first) {
839 if (Keyboard::load_keybindings (i->second)) {
840 Keyboard::save_keybindings ();
846 void edit_modifier_chosen ()
848 string const txt = _edit_modifier_combo.get_active_text();
850 for (int i = 0; modifiers[i].name; ++i) {
851 if (txt == S_(modifiers[i].name)) {
852 Keyboard::set_edit_modifier (modifiers[i].modifier);
858 void delete_modifier_chosen ()
860 string const txt = _delete_modifier_combo.get_active_text();
862 for (int i = 0; modifiers[i].name; ++i) {
863 if (txt == S_(modifiers[i].name)) {
864 Keyboard::set_delete_modifier (modifiers[i].modifier);
870 void copy_modifier_chosen ()
872 string const txt = _copy_modifier_combo.get_active_text();
874 for (int i = 0; modifiers[i].name; ++i) {
875 if (txt == S_(modifiers[i].name)) {
876 Keyboard::set_copy_modifier (modifiers[i].modifier);
882 void insert_note_modifier_chosen ()
884 string const txt = _insert_note_modifier_combo.get_active_text();
886 for (int i = 0; modifiers[i].name; ++i) {
887 if (txt == S_(modifiers[i].name)) {
888 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
894 void snap_modifier_chosen ()
896 string const txt = _snap_modifier_combo.get_active_text();
898 for (int i = 0; modifiers[i].name; ++i) {
899 if (txt == S_(modifiers[i].name)) {
900 Keyboard::set_snap_modifier (modifiers[i].modifier);
906 void snap_delta_modifier_chosen ()
908 string const txt = _snap_delta_combo.get_active_text();
910 for (int i = 0; modifiers[i].name; ++i) {
911 if (txt == S_(modifiers[i].name)) {
912 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
918 void constraint_modifier_chosen ()
920 string const txt = _constraint_modifier_combo.get_active_text();
922 for (int i = 0; modifiers[i].name; ++i) {
923 if (txt == S_(modifiers[i].name)) {
924 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
930 void trim_contents_modifier_chosen ()
932 string const txt = _trim_contents_combo.get_active_text();
934 for (int i = 0; modifiers[i].name; ++i) {
935 if (txt == S_(modifiers[i].name)) {
936 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
942 void trim_overlap_modifier_chosen ()
944 string const txt = _trim_overlap_combo.get_active_text();
946 for (int i = 0; modifiers[i].name; ++i) {
947 if (txt == S_(modifiers[i].name)) {
948 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
954 void trim_anchored_modifier_chosen ()
956 string const txt = _trim_anchored_combo.get_active_text();
958 for (int i = 0; modifiers[i].name; ++i) {
959 if (txt == S_(modifiers[i].name)) {
960 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
966 void fine_adjust_modifier_chosen ()
968 string const txt = _fine_adjust_combo.get_active_text();
970 for (int i = 0; modifiers[i].name; ++i) {
971 if (txt == S_(modifiers[i].name)) {
972 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
978 void push_points_modifier_chosen ()
980 string const txt = _push_points_combo.get_active_text();
982 for (int i = 0; modifiers[i].name; ++i) {
983 if (txt == S_(modifiers[i].name)) {
984 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
990 void note_size_relative_modifier_chosen ()
992 string const txt = _note_size_relative_combo.get_active_text();
994 for (int i = 0; modifiers[i].name; ++i) {
995 if (txt == S_(modifiers[i].name)) {
996 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
1002 void delete_button_changed ()
1004 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
1007 void edit_button_changed ()
1009 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
1012 void insert_note_button_changed ()
1014 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
1017 void reset_to_defaults ()
1020 Keyboard::set_edit_modifier (Keyboard::PrimaryModifier);
1021 Keyboard::set_edit_button (3);
1022 Keyboard::set_delete_modifier (Keyboard::TertiaryModifier);
1023 Keyboard::set_delete_button (3);
1024 Keyboard::set_insert_note_modifier (Keyboard::PrimaryModifier);
1025 Keyboard::set_insert_note_button (1);
1027 /* when beginning a drag */
1029 Keyboard::set_copy_modifier (Keyboard::SecondaryModifier);
1031 Keyboard::set_copy_modifier (Keyboard::PrimaryModifier);
1035 ArdourKeyboard::set_constraint_modifier (Keyboard::PrimaryModifier);
1037 ArdourKeyboard::set_constraint_modifier (Keyboard::TertiaryModifier);
1039 ArdourKeyboard::set_push_points_modifier (Keyboard::PrimaryModifier | Keyboard::Level4Modifier);
1041 /* when beginning a trim */
1042 ArdourKeyboard::set_trim_contents_modifier (Keyboard::PrimaryModifier);
1043 ArdourKeyboard::set_trim_anchored_modifier (Keyboard::PrimaryModifier | Keyboard::TertiaryModifier);
1044 ArdourKeyboard::set_note_size_relative_modifier (Keyboard::TertiaryModifier); // XXX better: 2ndary
1046 /* while dragging */
1048 Keyboard::set_snap_modifier (Keyboard::TertiaryModifier);
1050 Keyboard::set_snap_modifier (Keyboard::SecondaryModifier);
1053 Keyboard::set_snap_delta_modifier (Keyboard::Level4Modifier);
1055 Keyboard::set_snap_delta_modifier (Keyboard::SecondaryModifier | Keyboard::Level4Modifier);
1058 /* while trimming */
1059 ArdourKeyboard::set_trim_overlap_modifier (Keyboard::TertiaryModifier);
1061 /* while dragging ctrl points */
1062 ArdourKeyboard::set_fine_adjust_modifier (/*Keyboard::PrimaryModifier | */Keyboard::SecondaryModifier); // XXX
1064 set_state_from_config ();
1067 ComboBoxText _keyboard_layout_selector;
1068 ComboBoxText _edit_modifier_combo;
1069 ComboBoxText _delete_modifier_combo;
1070 ComboBoxText _copy_modifier_combo;
1071 ComboBoxText _insert_note_modifier_combo;
1072 ComboBoxText _snap_modifier_combo;
1073 ComboBoxText _snap_delta_combo;
1074 ComboBoxText _constraint_modifier_combo;
1075 ComboBoxText _trim_contents_combo;
1076 ComboBoxText _trim_overlap_combo;
1077 ComboBoxText _trim_anchored_combo;
1078 ComboBoxText _trim_jump_combo;
1079 ComboBoxText _fine_adjust_combo;
1080 ComboBoxText _push_points_combo;
1081 ComboBoxText _note_size_relative_combo;
1082 Adjustment _delete_button_adjustment;
1083 SpinButton _delete_button_spin;
1084 Adjustment _edit_button_adjustment;
1085 SpinButton _edit_button_spin;
1086 Adjustment _insert_note_button_adjustment;
1087 SpinButton _insert_note_button_spin;
1091 class FontScalingOptions : public HSliderOption
1094 FontScalingOptions ()
1095 : HSliderOption ("font-scale", _("GUI and Font scaling"),
1096 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_font_scale),
1097 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_font_scale),
1101 const std::string dflt = _("100%");
1102 const std::string empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
1104 _hscale.set_name("FontScaleSlider");
1105 _hscale.set_draw_value(false);
1106 _hscale.add_mark(50, Gtk::POS_TOP, empty);
1107 _hscale.add_mark(60, Gtk::POS_TOP, empty);
1108 _hscale.add_mark(70, Gtk::POS_TOP, empty);
1109 _hscale.add_mark(80, Gtk::POS_TOP, empty);
1110 _hscale.add_mark(90, Gtk::POS_TOP, empty);
1111 _hscale.add_mark(100, Gtk::POS_TOP, dflt);
1112 _hscale.add_mark(125, Gtk::POS_TOP, empty);
1113 _hscale.add_mark(150, Gtk::POS_TOP, empty);
1114 _hscale.add_mark(175, Gtk::POS_TOP, empty);
1115 _hscale.add_mark(200, Gtk::POS_TOP, empty);
1116 _hscale.add_mark(250, Gtk::POS_TOP, empty);
1118 set_note (_("Adjusting the scale requires an application restart to re-layout."));
1123 HSliderOption::changed ();
1124 /* XXX: should be triggered from the parameter changed signal */
1125 UIConfiguration::instance().reset_dpi ();
1129 class VstTimeOutSliderOption : public HSliderOption
1132 VstTimeOutSliderOption (RCConfiguration* c)
1133 : HSliderOption ("vst-scan-timeout", _("Scan Time Out"),
1134 sigc::mem_fun (*c, &RCConfiguration::get_vst_scan_timeout),
1135 sigc::mem_fun (*c, &RCConfiguration::set_vst_scan_timeout),
1138 _label.set_alignment (1.0, 0.5); // match buttons below
1139 _hscale.set_digits (0);
1140 _hscale.set_draw_value(false);
1141 _hscale.add_mark( 0, Gtk::POS_TOP, _("\u221e")); // infinity
1142 _hscale.add_mark( 300, Gtk::POS_TOP, _("30 sec"));
1143 _hscale.add_mark( 600, Gtk::POS_TOP, _("1 min"));
1144 _hscale.add_mark(1200, Gtk::POS_TOP, _("2 mins"));
1145 _hscale.add_mark(1800, Gtk::POS_TOP, _("3 mins"));
1146 _hscale.add_mark(2400, Gtk::POS_TOP, _("4 mins"));
1147 _hscale.add_mark(3000, Gtk::POS_TOP, _("5 mins"));
1149 Gtkmm2ext::UI::instance()->set_tip(_hscale,
1150 _("Specify the default timeout for plugin instantiation. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1154 class ClipLevelOptions : public OptionEditorComponent
1158 : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1159 , _clip_level_slider (_clip_level_adjustment)
1160 , _label (_("Waveform Clip Level (dBFS):"))
1162 _label.set_name ("OptionsLabel");
1164 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ());
1166 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1168 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1171 void parameter_changed (string const & p)
1173 if (p == "waveform-clip-level") {
1174 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level());
1176 if (p == "show-waveform-clipping") {
1177 _clip_level_slider.set_sensitive (UIConfiguration::instance().get_show_waveform_clipping ());
1181 void set_state_from_config ()
1183 parameter_changed ("waveform-clip-level");
1184 parameter_changed ("show-waveform-clipping");
1187 void add_to_page (OptionEditorPage* p) {
1188 add_widgets_to_page (p, &_label, &_clip_level_slider);
1191 Gtk::Widget& tip_widget() {
1192 return _clip_level_slider;
1197 void clip_level_changed ()
1199 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1200 /* XXX: should be triggered from the parameter changed signal */
1201 ArdourWaveView::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1204 Adjustment _clip_level_adjustment;
1205 HScale _clip_level_slider;
1209 class BufferingOptions : public OptionEditorComponent
1212 BufferingOptions (RCConfiguration* c)
1214 , _label (_("Preset:"))
1215 , _playback ("playback-buffer-seconds", _("Playback (seconds of buffering)"),
1216 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_playback_buffer_seconds),
1217 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_playback_buffer_seconds),
1219 , _capture ("capture-buffer-seconds", _("Recording (seconds of buffering)"),
1220 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_capture_buffer_seconds),
1221 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_capture_buffer_seconds),
1224 // TODO use ComboOption
1225 vector<string> presets;
1227 /* these must match the order of the enums for BufferingPreset */
1228 presets.push_back (_("Small sessions (4-16 tracks)"));
1229 presets.push_back (_("Medium sessions (16-64 tracks)"));
1230 presets.push_back (_("Large sessions (64+ tracks)"));
1231 presets.push_back (_("Custom (set by sliders below)"));
1233 set_popdown_strings (_buffering_presets_combo, presets);
1234 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1236 _label.set_name ("OptionsLabel");
1237 _label.set_alignment (0, 0.5);
1241 add_to_page (OptionEditorPage* p)
1243 add_widgets_to_page (p, &_label, &_buffering_presets_combo);
1244 _playback.add_to_page (p);
1245 _capture.add_to_page (p);
1248 void parameter_changed (string const & p)
1250 if (p == "buffering-preset") {
1251 switch (_rc_config->get_buffering_preset()) {
1253 _playback.set_sensitive (false);
1254 _capture.set_sensitive (false);
1255 _buffering_presets_combo.set_active (0);
1258 _playback.set_sensitive (false);
1259 _capture.set_sensitive (false);
1260 _buffering_presets_combo.set_active (1);
1263 _playback.set_sensitive (false);
1264 _capture.set_sensitive (false);
1265 _buffering_presets_combo.set_active (2);
1268 _playback.set_sensitive (true);
1269 _capture.set_sensitive (true);
1270 _buffering_presets_combo.set_active (3);
1274 _playback.parameter_changed (p);
1275 _capture.parameter_changed (p);
1278 void set_state_from_config ()
1280 parameter_changed ("buffering-preset");
1281 _playback.set_state_from_config();
1282 _capture.set_state_from_config();
1285 Gtk::Widget& tip_widget() { return _buffering_presets_combo; }
1289 void preset_changed ()
1291 int index = _buffering_presets_combo.get_active_row_number ();
1297 _rc_config->set_buffering_preset (Small);
1300 _rc_config->set_buffering_preset (Medium);
1303 _rc_config->set_buffering_preset (Large);
1306 _rc_config->set_buffering_preset (Custom);
1309 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1314 RCConfiguration* _rc_config;
1316 HSliderOption _playback;
1317 HSliderOption _capture;
1318 ComboBoxText _buffering_presets_combo;
1321 class ControlSurfacesOptions : public OptionEditorMiniPage
1324 ControlSurfacesOptions ()
1325 : _ignore_view_change (0)
1327 _store = ListStore::create (_model);
1328 _view.set_model (_store);
1329 _view.append_column (_("Control Surface Protocol"), _model.name);
1330 _view.get_column(0)->set_resizable (true);
1331 _view.get_column(0)->set_expand (true);
1332 _view.append_column_editable (_("Enable"), _model.enabled);
1334 Gtk::HBox* edit_box = manage (new Gtk::HBox);
1335 edit_box->set_spacing(3);
1338 Label* label = manage (new Label);
1339 label->set_text (_("Edit the settings for selected protocol (it must be ENABLED first):"));
1340 edit_box->pack_start (*label, false, false);
1343 edit_button = manage (new Button(_("Show Protocol Settings")));
1344 edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
1345 edit_box->pack_start (*edit_button, true, true);
1346 edit_button->set_sensitive (false);
1347 edit_button->show ();
1349 int const n = table.property_n_rows();
1350 table.resize (n + 2, 3);
1351 table.attach (_view, 0, 3, n, n + 1);
1352 table.attach (*edit_box, 0, 3, n + 1, n + 2);
1354 ControlProtocolManager& m = ControlProtocolManager::instance ();
1355 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1356 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1358 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1359 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1360 _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
1363 void parameter_changed (std::string const &)
1368 void set_state_from_config ()
1372 ControlProtocolManager& m = ControlProtocolManager::instance ();
1373 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1375 if (!(*i)->mandatory) {
1376 TreeModel::Row r = *_store->append ();
1377 r[_model.name] = (*i)->name;
1378 r[_model.enabled] = 0 != (*i)->protocol;
1379 r[_model.protocol_info] = *i;
1386 void protocol_status_changed (ControlProtocolInfo* cpi) {
1388 TreeModel::Children rows = _store->children();
1390 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1391 string n = ((*x)[_model.name]);
1393 if ((*x)[_model.protocol_info] == cpi) {
1394 _ignore_view_change++;
1395 (*x)[_model.enabled] = 0 != cpi->protocol;
1396 _ignore_view_change--;
1397 selection_changed (); // update sensitivity
1403 void selection_changed ()
1405 //enable the Edit button when a row is selected for editing
1406 TreeModel::Row row = *(_view.get_selection()->get_selected());
1407 if (row && row[_model.enabled])
1408 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 ComboOption<float>* dps = new ComboOption<float> (
2336 "draggable-playhead-speed",
2337 _("Playhead dragging speed (%)"),
2338 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead_speed),
2339 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead_speed)
2341 dps->add (0.05, _("5%"));
2342 dps->add (0.1, _("10%"));
2343 dps->add (0.25, _("25%"));
2344 dps->add (0.5, _("50%"));
2345 dps->add (1.0, _("100%"));
2346 add_option (_("Editor"), dps);
2348 ComboOption<float>* eet = new ComboOption<float> (
2349 "extra-ui-extents-time",
2350 _("Limit zooming & summary view to X minutes beyond session extents"),
2351 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_extra_ui_extents_time),
2352 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_extra_ui_extents_time)
2354 eet->add (1, _("1 minute"));
2355 eet->add (2, _("2 minutes"));
2356 eet->add (20, _("20 minutes"));
2357 eet->add (60, _("1 hour"));
2358 eet->add (60*2, _("2 hours"));
2359 eet->add (60*24, _("24 hours"));
2360 add_option (_("Editor"), eet);
2362 if (!Profile->get_mixbus()) {
2364 add_option (_("Editor"),
2366 "use-mouse-position-as-zoom-focus-on-scroll",
2367 _("Zoom to mouse position when zooming with scroll wheel"),
2368 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2369 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2373 add_option (_("Editor"),
2375 "use-time-rulers-to-zoom-with-vertical-drag",
2376 _("Zoom with vertical drag in rulers"),
2377 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag),
2378 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag)
2381 add_option (_("Editor"),
2383 "use-double-click-to-zoom-to-selection",
2384 _("Double click zooms to selection"),
2385 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection),
2386 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection)
2389 add_option (_("Editor"),
2391 "update-editor-during-summary-drag",
2392 _("Update editor window during drags of the summary"),
2393 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2394 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2397 add_option (_("Editor"),
2399 "autoscroll-editor",
2400 _("Auto-scroll editor window when dragging near its edges"),
2401 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2402 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2405 add_option (_("Editor"),
2406 new BoolComboOption (
2407 "show-region-gain-envelopes",
2408 _("Show gain envelopes in audio regions"),
2410 _("only in Draw and Internal Edit modes"),
2411 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2412 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2415 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2417 add_option (_("Editor"),
2419 "automation-follows-regions",
2420 _("Move relevant automation when audio regions are moved"),
2421 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2422 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2425 bo = new BoolOption (
2426 "new-automation-points-on-lane",
2427 _("Ignore Y-axis click position when adding new automation-points"),
2428 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_new_automation_points_on_lane),
2429 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_new_automation_points_on_lane)
2431 add_option (_("Editor"), bo);
2432 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2433 _("<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."));
2435 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2436 "default-fade-shape",
2437 _("Default fade shape"),
2438 sigc::mem_fun (*_rc_config,
2439 &RCConfiguration::get_default_fade_shape),
2440 sigc::mem_fun (*_rc_config,
2441 &RCConfiguration::set_default_fade_shape)
2444 fadeshape->add (FadeLinear,
2445 _("Linear (for highly correlated material)"));
2446 fadeshape->add (FadeConstantPower, _("Constant power"));
2447 fadeshape->add (FadeSymmetric, _("Symmetric"));
2448 fadeshape->add (FadeSlow, _("Slow"));
2449 fadeshape->add (FadeFast, _("Fast"));
2451 add_option (_("Editor"), fadeshape);
2453 bco = new BoolComboOption (
2454 "use-overlap-equivalency",
2455 _("Regions in edit groups are edited together"),
2456 _("whenever they overlap in time"),
2457 _("only if they have identical length and position"),
2458 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2459 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2462 add_option (_("Editor"), bco);
2464 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2466 _("Layering model"),
2467 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2468 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2471 lm->add (LaterHigher, _("later is higher"));
2472 lm->add (Manual, _("manual layering"));
2473 add_option (_("Editor"), lm);
2475 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2476 "region-selection-after-split",
2477 _("After splitting selected regions, select"),
2478 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2479 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2481 // TODO: decide which of these modes are really useful
2482 rsas->add(None, _("no regions"));
2483 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2484 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2485 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2486 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2487 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2488 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2489 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2491 add_option (_("Editor"), rsas);
2493 add_option (_("Editor/Snap"), new OptionEditorHeading (_("General Snap options:")));
2495 add_option (_("Editor/Snap"),
2496 new SpinOption<uint32_t> (
2498 _("Snap Threshold (pixels)"),
2499 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_threshold),
2500 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_threshold),
2505 add_option (_("Editor/Snap"),
2507 "show-snapped-cursor",
2508 _("Show Snapped Cursor"),
2509 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_snapped_cursor),
2510 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_snapped_cursor)
2513 add_option (_("Editor/Modifiers"), new OptionEditorHeading (_("Keyboard Modifiers")));
2514 add_option (_("Editor/Modifiers"), new KeyboardOptions);
2515 add_option (_("Editor/Modifiers"), new OptionEditorBlank ());
2517 /* MIXER -- SOLO AND MUTE */
2519 add_option (_("Mixer"), new OptionEditorHeading (_("Solo")));
2521 _solo_control_is_listen_control = new BoolOption (
2522 "solo-control-is-listen-control",
2523 _("Solo controls are Listen controls"),
2524 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2525 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2528 add_option (_("Mixer"), _solo_control_is_listen_control);
2530 add_option (_("Mixer"),
2533 _("Exclusive solo"),
2534 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2535 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2538 add_option (_("Mixer"),
2541 _("Show solo muting"),
2542 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2543 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2546 add_option (_("Mixer"),
2548 "solo-mute-override",
2549 _("Soloing overrides muting"),
2550 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2551 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2554 add_option (_("Mixer"),
2557 _("Solo-in-place mute cut (dB)"),
2558 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2559 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2562 _listen_position = new ComboOption<ListenPosition> (
2564 _("Listen Position"),
2565 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2566 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2569 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2570 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2572 add_option (_("Mixer"), _listen_position);
2574 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2576 _("PFL signals come from"),
2577 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2578 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2581 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2582 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2584 add_option (_("Mixer"), pp);
2586 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2588 _("AFL signals come from"),
2589 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2590 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2593 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2594 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2596 add_option (_("Mixer"), pa);
2598 add_option (_("Mixer"), new OptionEditorHeading (_("Default Track / Bus Muting Options")));
2600 add_option (_("Mixer"),
2602 "mute-affects-pre-fader",
2603 _("Mute affects pre-fader sends"),
2604 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2605 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2608 add_option (_("Mixer"),
2610 "mute-affects-post-fader",
2611 _("Mute affects post-fader sends"),
2612 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2613 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2616 add_option (_("Mixer"),
2618 "mute-affects-control-outs",
2619 _("Mute affects control outputs"),
2620 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2621 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2624 add_option (_("Mixer"),
2626 "mute-affects-main-outs",
2627 _("Mute affects main outputs"),
2628 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2629 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2633 if (!ARDOUR::Profile->get_mixbus()) {
2634 add_option (_("Mixer"), new OptionEditorHeading (_("Send Routing")));
2635 add_option (_("Mixer"),
2637 "link-send-and-route-panner",
2638 _("Link panners of Aux and External Sends with main panner by default"),
2639 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2640 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2646 add_option (_("Signal Flow"), new OptionEditorHeading (_("Monitoring")));
2648 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2650 _("Record monitoring handled by"),
2651 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2652 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2655 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2656 mm->add (HardwareMonitoring, _("via Audio Driver"));
2659 string prog (PROGRAM_NAME);
2660 boost::algorithm::to_lower (prog);
2661 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2662 mm->add (ExternalMonitoring, _("audio hardware"));
2664 add_option (_("Signal Flow"), mm);
2666 bo = new BoolOption (
2667 "tape-machine-mode",
2668 _("Tape machine mode"),
2669 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2670 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2672 add_option (_("Signal Flow"), bo);
2673 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2674 string_compose (_("<b>When enabled</b> %1 will not monitor a track's input if the transport is stopped."),
2677 if (!Profile->get_mixbus()) {
2679 add_option (_("Signal Flow"), new OptionEditorHeading (_("Track and Bus Connections")));
2681 add_option (_("Signal Flow"),
2683 "auto-connect-standard-busses",
2684 _("Auto-connect master/monitor busses"),
2685 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2686 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2689 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2690 "input-auto-connect",
2691 _("Connect track inputs"),
2692 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2693 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2696 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2697 iac->add (ManualConnect, _("manually"));
2699 add_option (_("Signal Flow"), iac);
2701 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2702 "output-auto-connect",
2703 _("Connect track and bus outputs"),
2704 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2705 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2708 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2709 oac->add (AutoConnectMaster, _("automatically to master bus"));
2710 oac->add (ManualConnect, _("manually"));
2712 add_option (_("Signal Flow"), oac);
2714 bo = new BoolOption (
2716 _("Use 'Strict-I/O' for new tracks or busses"),
2717 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2718 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2721 add_option (_("Signal Flow"), bo);
2722 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2723 _("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."));
2730 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2732 add_option (_("Audio"), new BufferingOptions (_rc_config));
2734 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2736 add_option (_("Audio"),
2738 "denormal-protection",
2739 _("Use DC bias to protect against denormals"),
2740 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2741 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2744 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2746 _("Processor handling"),
2747 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2748 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2752 dm->add (DenormalNone, _("no processor handling"));
2754 FPU* fpu = FPU::instance();
2756 if (fpu->has_flush_to_zero()) {
2758 dm->add (DenormalFTZ, _("use FlushToZero"));
2759 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2760 _rc_config->set_denormal_model(DenormalNone);
2763 if (fpu->has_denormals_are_zero()) {
2765 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2766 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2767 _rc_config->set_denormal_model(DenormalNone);
2770 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2772 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2773 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2774 _rc_config->set_denormal_model(DenormalNone);
2778 dm->set_sensitive(false);
2781 add_option (_("Audio"), dm);
2783 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2785 add_option (_("Audio"),
2787 "auto-analyse-audio",
2788 _("Enable automatic analysis of audio"),
2789 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2790 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2793 add_option (_("Audio"),
2795 "replicate-missing-region-channels",
2796 _("Replicate missing region channels"),
2797 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2798 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2803 add_option (_("MIDI"), new OptionEditorHeading (_("Buffering")));
2805 add_option (_("MIDI"),
2806 new SpinOption<float> (
2808 _("MIDI read-ahead time (seconds)"),
2809 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2810 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2815 add_option (_("MIDI"), new OptionEditorHeading (_("Session")));
2817 add_option (_("MIDI"),
2818 new SpinOption<int32_t> (
2819 "initial-program-change",
2820 _("Initial program change"),
2821 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2822 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2826 add_option (_("MIDI"), new OptionEditorHeading (_("Audition")));
2828 add_option (_("MIDI"),
2831 _("Sound MIDI notes as they are selected in the editor"),
2832 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2833 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2836 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2837 "midi-audition-synth-uri",
2838 _("MIDI Audition Synth (LV2)"),
2839 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2840 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2843 audition_synth->add(X_(""), _("None"));
2844 PluginInfoList all_plugs;
2845 PluginManager& manager (PluginManager::instance());
2847 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2849 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2850 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2851 if (!(*i)->is_instrument()) continue;
2852 if ((*i)->type != ARDOUR::LV2) continue;
2853 if ((*i)->name.length() > 46) {
2854 audition_synth->add((*i)->unique_id, (*i)->name.substr (0, 44) + "...");
2856 audition_synth->add((*i)->unique_id, (*i)->name);
2861 add_option (_("MIDI"), audition_synth);
2865 add_option (_("Metronome"), new OptionEditorHeading (_("Metronome")));
2866 add_option (_("Metronome"), new ClickOptions (_rc_config));
2867 add_option (_("Metronome"), new OptionEditorHeading (_("Options")));
2869 bo = new BoolOption (
2870 "click-record-only",
2871 _("Enable metronome only while recording"),
2872 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_record_only),
2873 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_record_only)
2876 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2877 string_compose (_("<b>When enabled</b> the metronome will remain silent if %1 is <b>not recording</b>."), PROGRAM_NAME));
2878 add_option (_("Metronome"), bo);
2879 add_option (_("Metronome"), new OptionEditorBlank ());
2884 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2886 ComboOption<float>* mht = new ComboOption<float> (
2888 _("Peak hold time"),
2889 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
2890 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
2893 mht->add (MeterHoldOff, _("off"));
2894 mht->add (MeterHoldShort, _("short"));
2895 mht->add (MeterHoldMedium, _("medium"));
2896 mht->add (MeterHoldLong, _("long"));
2898 add_option (S_("Preferences|Metering"), mht);
2900 ComboOption<float>* mfo = new ComboOption<float> (
2903 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2904 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2907 mfo->add (METER_FALLOFF_OFF, _("off"));
2908 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2909 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2910 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2911 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2912 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2913 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
2915 add_option (S_("Preferences|Metering"), mfo);
2917 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2918 "meter-line-up-level",
2919 _("Meter line-up level; 0dBu"),
2920 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
2921 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
2924 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2925 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2926 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2927 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2929 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."));
2931 add_option (S_("Preferences|Metering"), mlu);
2933 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2934 "meter-line-up-din",
2935 _("IEC1/DIN Meter line-up level; 0dBu"),
2936 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
2937 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
2940 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2941 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2942 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2943 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2945 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2947 add_option (S_("Preferences|Metering"), mld);
2949 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2950 "meter-vu-standard",
2951 _("VU Meter standard"),
2952 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
2953 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
2956 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2957 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2958 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2959 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2961 add_option (S_("Preferences|Metering"), mvu);
2963 HSliderOption *mpks = new HSliderOption("meter-peak",
2964 _("Peak indicator threshold [dBFS]"),
2965 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
2966 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak),
2970 Gtkmm2ext::UI::instance()->set_tip (
2972 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
2974 add_option (S_("Preferences|Metering"), mpks);
2976 OptionEditorHeading* default_meter_head = new OptionEditorHeading (_("Default Meter Types"));
2977 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."));
2979 add_option (S_("Preferences|Metering"), default_meter_head);
2981 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
2982 "meter-type-master",
2983 _("Default Meter Type for Master Bus"),
2984 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
2985 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
2987 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2988 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2989 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2990 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2991 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2992 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2993 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2994 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
2996 add_option (S_("Preferences|Metering"), mtm);
2999 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3001 _("Default meter type for busses"),
3002 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3003 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3005 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3006 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3007 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3008 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3009 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3010 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3011 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3012 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3014 add_option (S_("Preferences|Metering"), mtb);
3016 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3018 _("Default meter type for tracks"),
3019 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3020 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3022 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3023 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3025 add_option (S_("Preferences|Metering"), mtt);
3027 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
3029 add_option (S_("Preferences|Metering"),
3031 "save-export-analysis-image",
3032 _("Save loudness analysis as image file"),
3033 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
3034 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
3037 /* TRANSPORT & Sync */
3039 add_option (_("Transport"), new OptionEditorHeading (_("General")));
3041 bo = new BoolOption (
3042 "stop-at-session-end",
3043 _("Stop at the end of the session"),
3044 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
3045 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
3047 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3048 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
3049 "when it reaches the current session end marker\n\n"
3050 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
3052 add_option (_("Transport"), bo);
3054 bo = new BoolOption (
3055 "latched-record-enable",
3056 _("Keep record-enable engaged on stop"),
3057 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
3058 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
3060 add_option (_("Transport"), bo);
3061 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3062 _("<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."));
3064 bo = new BoolOption (
3065 "disable-disarm-during-roll",
3066 _("Disable per-track record disarm while rolling"),
3067 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
3068 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
3070 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."));
3071 add_option (_("Transport"), bo);
3073 bo = new BoolOption (
3075 _("12dB gain reduction during fast-forward and fast-rewind"),
3076 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
3077 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
3079 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3080 _("<b>When enabled</b> this will reduce the unpleasant increase in perceived volume "
3081 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
3082 add_option (_("Transport"), bo);
3084 ComboOption<float>* psc = new ComboOption<float> (
3087 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
3088 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
3090 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
3091 (_("The amount of preroll to apply when <b>Play with Preroll</b> or <b>Record with Preroll</b>is initiated.\n\n"
3092 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
3093 psc->add (-4.0, _("4 Bars"));
3094 psc->add (-2.0, _("2 Bars"));
3095 psc->add (-1.0, _("1 Bar"));
3096 psc->add (0.0, _("0 (no pre-roll)"));
3097 psc->add (0.1, _("0.1 second"));
3098 psc->add (0.25, _("0.25 second"));
3099 psc->add (0.5, _("0.5 second"));
3100 psc->add (1.0, _("1.0 second"));
3101 psc->add (2.0, _("2.0 seconds"));
3102 add_option (_("Transport"), psc);
3105 add_option (_("Transport"), new OptionEditorHeading (_("Looping")));
3107 bo = new BoolOption (
3109 _("Play loop is a transport mode"),
3110 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
3111 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
3113 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3114 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
3115 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
3116 add_option (_("Transport"), bo);
3118 bo = new BoolOption (
3120 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
3121 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
3122 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
3124 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3125 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
3126 "preventing any need to do a transport locate at the end of the loop\n\n"
3127 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
3128 "which will often cause a small click or delay"), PROGRAM_NAME));
3129 add_option (_("Transport"), bo);
3131 add_option (_("Transport"), new OptionEditorHeading (_("Dropout (xrun) Handling")));
3132 bo = new BoolOption (
3133 "stop-recording-on-xrun",
3134 _("Stop recording when an xrun occurs"),
3135 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
3136 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
3138 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3139 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
3141 add_option (_("Transport"), bo);
3143 bo = new BoolOption (
3144 "create-xrun-marker",
3145 _("Create markers where xruns occur"),
3146 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
3147 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
3149 add_option (_("Transport"), bo);
3154 add_option (_("Sync"), new OptionEditorHeading (_("External Synchronization")));
3156 _sync_source = new ComboOption<SyncSource> (
3158 _("External timecode source"),
3159 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
3160 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
3163 add_option (_("Sync"), _sync_source);
3165 _sync_framerate = new BoolOption (
3166 "timecode-sync-frame-rate",
3167 _("Match session video frame rate to external timecode"),
3168 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
3169 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
3171 Gtkmm2ext::UI::instance()->set_tip
3172 (_sync_framerate->tip_widget(),
3173 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
3174 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
3175 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
3176 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
3177 "timecode standard and the session standard."), PROGRAM_NAME));
3179 add_option (_("Sync"), _sync_framerate);
3181 _sync_genlock = new BoolOption (
3182 "timecode-source-is-synced",
3183 _("Sync-lock timecode to clock (disable drift compensation)"),
3184 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
3185 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
3187 Gtkmm2ext::UI::instance()->set_tip
3188 (_sync_genlock->tip_widget(),
3189 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
3190 "Sync Lock indicates that the selected external timecode source shares clock-sync "
3191 "(Black & Burst, Wordclock, etc) with the audio interface. "
3192 "This option disables drift compensation. The transport speed is fixed at 1.0. "
3193 "Vari-speed LTC will be ignored and cause drift."
3195 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
3196 "timecode sources shares clock sync."
3200 add_option (_("Sync"), _sync_genlock);
3202 _sync_source_2997 = new BoolOption (
3203 "timecode-source-2997",
3204 _("Lock to 29.9700 fps instead of 30000/1001"),
3205 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
3206 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
3208 Gtkmm2ext::UI::instance()->set_tip
3209 (_sync_source_2997->tip_widget(),
3210 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
3211 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
3212 "drop-sample timecode has an accumulated error of -86ms over a 24-hour period.\n"
3213 "Drop-sample timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
3214 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
3215 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
3218 add_option (_("Sync"), _sync_source_2997);
3220 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Reader")));
3222 _ltc_port = new ComboStringOption (
3224 _("LTC incoming port"),
3225 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
3226 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
3229 vector<string> physical_inputs;
3230 physical_inputs.push_back (_("None"));
3231 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
3232 _ltc_port->set_popdown_strings (physical_inputs);
3234 populate_sync_options ();
3235 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
3237 add_option (_("Sync/LTC"), _ltc_port);
3239 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Generator")));
3241 add_option (_("Sync/LTC"),
3244 _("Enable LTC generator"),
3245 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
3246 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
3249 _ltc_send_continuously = new BoolOption (
3250 "ltc-send-continuously",
3251 _("Send LTC while stopped"),
3252 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
3253 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
3255 Gtkmm2ext::UI::instance()->set_tip
3256 (_ltc_send_continuously->tip_widget(),
3257 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
3258 add_option (_("Sync/LTC"), _ltc_send_continuously);
3260 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level [dBFS]"),
3261 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_output_volume),
3262 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_output_volume),
3266 Gtkmm2ext::UI::instance()->set_tip
3267 (_ltc_volume_slider->tip_widget(),
3268 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
3270 add_option (_("Sync/LTC"), _ltc_volume_slider);
3273 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Beat Clock (Mclk) Generator")));
3275 add_option (_("Sync/MIDI"),
3278 _("Enable Mclk generator"),
3279 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
3280 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
3283 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC) Generator")));
3285 add_option (_("Sync/MIDI"),
3288 _("Enable MTC Generator"),
3289 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
3290 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
3293 add_option (_("Sync/MIDI"),
3294 new SpinOption<int> (
3295 "mtc-qf-speed-tolerance",
3296 _("Percentage either side of normal transport speed to transmit MTC"),
3297 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
3298 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
3302 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Machine Control (MMC)")));
3304 add_option (_("Sync/MIDI"),
3307 _("Respond to MMC commands"),
3308 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
3309 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
3312 add_option (_("Sync/MIDI"),
3315 _("Send MMC commands"),
3316 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
3317 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
3320 add_option (_("Sync/MIDI"),
3321 new SpinOption<uint8_t> (
3322 "mmc-receive-device-id",
3323 _("Inbound MMC device ID"),
3324 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
3325 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
3329 add_option (_("Sync/MIDI"),
3330 new SpinOption<uint8_t> (
3331 "mmc-send-device-id",
3332 _("Outbound MMC device ID"),
3333 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
3334 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
3339 /* Control Surfaces */
3341 add_option (_("Control Surfaces"), new OptionEditorHeading (_("Control Surfaces")));
3342 add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
3345 add_option (_("MIDI Ports"), new OptionEditorHeading (_("MIDI Port Options")));
3347 add_option (_("MIDI Ports"),
3349 "get-midi-input-follows-selection",
3350 _("MIDI input follows MIDI track selection"),
3351 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
3352 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
3355 add_option (_("MIDI Ports"), new MidiPortOptions ());
3356 add_option (_("MIDI Ports"), new OptionEditorBlank ());
3360 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3361 add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
3362 add_option (_("Plugins"),
3363 new RcActionButton (_("Scan for Plugins"),
3364 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3368 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
3370 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3371 bo = new BoolOption (
3372 "show-plugin-scan-window",
3373 _("Always Display Plugin Scan Progress"),
3374 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
3375 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
3377 add_option (_("Plugins"), bo);
3378 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3379 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
3382 bo = new BoolOption (
3383 "plugins-stop-with-transport",
3384 _("Silence plugins when the transport is stopped"),
3385 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
3386 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
3388 add_option (_("Plugins"), bo);
3389 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3390 _("<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."));
3392 bo = new BoolOption (
3393 "new-plugins-active",
3394 _("Make new plugins active"),
3395 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
3396 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
3398 add_option (_("Plugins"), bo);
3399 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3400 _("<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"));
3402 #if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
3403 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
3405 add_option (_("Plugins/VST"),
3406 new RcActionButton (_("Scan for Plugins"),
3407 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3410 #if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
3411 bo = new BoolOption (
3413 _("Enable Mac VST support (requires restart or re-scan)"),
3414 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
3415 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
3417 add_option (_("Plugins/VST"), bo);
3420 bo = new BoolOption (
3421 "discover-vst-on-start",
3422 _("Scan for [new] VST Plugins on Application Start"),
3423 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
3424 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
3426 add_option (_("Plugins/VST"), bo);
3427 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3428 _("<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"));
3430 #ifdef WINDOWS_VST_SUPPORT
3431 // currently verbose logging is only implemented for Windows VST.
3432 bo = new BoolOption (
3433 "verbose-plugin-scan",
3434 _("Verbose Plugin Scan"),
3435 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
3436 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
3438 add_option (_("Plugins/VST"), bo);
3439 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3440 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
3443 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
3445 add_option (_("Plugins/VST"),
3446 new RcActionButton (_("Clear"),
3447 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
3450 add_option (_("Plugins/VST"),
3451 new RcActionButton (_("Clear"),
3452 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
3453 _("VST Blacklist:")));
3456 #ifdef LXVST_SUPPORT
3457 add_option (_("Plugins/VST"),
3458 new RcActionButton (_("Edit"),
3459 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
3460 _("Linux VST Path:")));
3462 add_option (_("Plugins/VST"),
3463 new RcConfigDisplay (
3464 "plugin-path-lxvst",
3466 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
3470 #ifdef WINDOWS_VST_SUPPORT
3471 add_option (_("Plugins/VST"),
3472 new RcActionButton (_("Edit"),
3473 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
3474 _("Windows VST Path:")));
3475 add_option (_("Plugins/VST"),
3476 new RcConfigDisplay (
3479 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
3483 #ifdef AUDIOUNIT_SUPPORT
3485 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
3487 add_option (_("Plugins/Audio Unit"),
3488 new RcActionButton (_("Scan for Plugins"),
3489 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3492 bo = new BoolOption (
3493 "discover-audio-units",
3494 _("Scan for [new] AudioUnit Plugins on Application Start"),
3495 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
3496 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
3498 add_option (_("Plugins/Audio Unit"), bo);
3499 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3500 _("<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."));
3502 add_option (_("Plugins/Audio Unit"),
3503 new RcActionButton (_("Clear"),
3504 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
3507 add_option (_("Plugins/Audio Unit"),
3508 new RcActionButton (_("Clear"),
3509 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
3510 _("AU Blacklist:")));
3513 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
3514 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
3515 add_option (_("Plugins"),
3517 "open-gui-after-adding-plugin",
3518 _("Automatically open the plugin GUI when adding a new plugin"),
3519 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
3520 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3523 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3524 add_option (_("Plugins"),
3526 "show-inline-display-by-default",
3527 _("Show Plugin Inline Display on Mixerstrip by default"),
3528 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3529 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3532 _plugin_prefer_inline = new BoolOption (
3533 "prefer-inline-over-gui",
3534 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3535 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3536 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3538 add_option (_("Plugins"), _plugin_prefer_inline);
3541 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3543 bo = new BoolOption (
3544 "ask-replace-instrument",
3545 _("Ask to replace existing instrument plugin"),
3546 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3547 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3549 add_option (_("Plugins"), bo);
3551 bo = new BoolOption (
3552 "ask-setup_instrument",
3553 _("Interactively configure instrument plugins on insert"),
3554 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3555 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3557 add_option (_("Plugins"), bo);
3558 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3559 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3562 add_option (_("Plugins"), new OptionEditorBlank ());
3565 #if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
3566 add_option (_("Appearance"), new OptionEditorHeading (_("Graphics Acceleration")));
3569 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3570 BoolOption* bgc = new BoolOption (
3571 "cairo-image-surface",
3572 _("Disable Graphics Hardware Acceleration (requires restart)"),
3573 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3574 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3577 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3578 _("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));
3579 add_option (_("Appearance"), bgc);
3582 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3583 BoolOption* bgo = new BoolOption (
3585 _("Possibly improve slow graphical performance (requires restart)"),
3586 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3587 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3590 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));
3591 add_option (_("Appearance"), bgo);
3593 add_option (_("Appearance"), new OptionEditorHeading (_("Graphical User Interface")));
3595 add_option (_("Appearance"),
3598 _("Highlight widgets on mouseover"),
3599 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3600 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3603 add_option (_("Appearance"),
3606 _("Show tooltips if mouse hovers over a control"),
3607 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3608 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3611 bo = new BoolOption (
3612 "super-rapid-clock-update",
3613 _("Update clocks at TC Frame rate"),
3614 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3615 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3617 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3618 _("<b>When enabled</b> clock displays are updated every Timecode Frame (fps).\n\n"
3619 "<b>When disabled</b> clock displays are updated only every 100ms."
3621 add_option (_("Appearance"), bo);
3623 add_option (_("Appearance"),
3626 _("Blink Rec-Arm buttons"),
3627 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_rec_arm),
3628 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_rec_arm)
3631 add_option (_("Appearance"),
3633 "blink-alert-indicators",
3634 _("Blink Alert Indicators"),
3635 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_alert_indicators),
3636 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_alert_indicators)
3641 /* font scaling does nothing with GDK/Quartz */
3642 add_option (_("Appearance"), new FontScalingOptions ());
3644 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("General")));
3645 add_option (_("Appearance/Editor"),
3647 "show-name-highlight",
3648 _("Use name highlight bars in region displays (requires a restart)"),
3649 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3650 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3653 add_option (_("Appearance/Editor"),
3655 "color-regions-using-track-color",
3656 _("Region color follows track color"),
3657 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_color_regions_using_track_color),
3658 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_color_regions_using_track_color)
3661 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Waveforms")));
3663 if (!Profile->get_mixbus()) {
3664 add_option (_("Appearance/Editor"),
3667 _("Show waveforms in regions"),
3668 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
3669 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
3673 add_option (_("Appearance/Editor"),
3675 "show-waveforms-while-recording",
3676 _("Show waveforms while recording"),
3677 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
3678 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
3681 add_option (_("Appearance/Editor"),
3683 "show-waveform-clipping",
3684 _("Show waveform clipping"),
3685 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveform_clipping),
3686 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveform_clipping)
3689 add_option (_("Appearance/Editor"), new ClipLevelOptions ());
3691 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
3693 _("Waveform scale"),
3694 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
3695 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
3698 wfs->add (Linear, _("linear"));
3699 wfs->add (Logarithmic, _("logarithmic"));
3701 add_option (_("Appearance/Editor"), wfs);
3703 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
3705 _("Waveform shape"),
3706 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
3707 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
3710 wfsh->add (Traditional, _("traditional"));
3711 wfsh->add (Rectified, _("rectified"));
3713 add_option (_("Appearance/Editor"), wfsh);
3715 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Editor Meters")));
3717 add_option (_("Appearance/Editor"),
3719 "show-track-meters",
3720 _("Show meters in track headers"),
3721 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3722 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3725 add_option (_("Appearance/Editor"),
3727 "editor-stereo-only-meters",
3728 _("Limit track header meters to stereo"),
3729 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3730 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3733 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("MIDI Regions")));
3735 add_option (_("Appearance/Editor"),
3737 "display-first-midi-bank-as-zero",
3738 _("Display first MIDI bank/program as 0"),
3739 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
3740 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
3743 add_option (_("Appearance/Editor"),
3745 "never-display-periodic-midi",
3746 _("Don't display periodic (MTC, MMC) SysEx messages in MIDI Regions"),
3747 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
3748 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
3751 add_option (_("Appearance/Editor"), new OptionEditorBlank ());
3753 /* The names of these controls must be the same as those given in MixerStrip
3754 for the actual widgets being controlled.
3756 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3757 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3758 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3759 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3760 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3761 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3762 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3764 add_option (_("Appearance/Mixer"),
3765 new VisibilityOption (
3767 &_mixer_strip_visibility,
3768 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3769 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3773 add_option (_("Appearance/Mixer"),
3775 "default-narrow_ms",
3776 _("Use narrow strips in the mixer for new strips by default"),
3777 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3778 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3781 add_option (_("Appearance/Mixer"), new OptionEditorBlank ());
3783 add_option (_("Appearance/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items")));
3785 add_option (_("Appearance/Toolbar"),
3787 "show-toolbar-recpunch",
3788 _("Display Record/Punch Options"),
3789 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_recpunch),
3790 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_recpunch)
3793 add_option (_("Appearance/Toolbar"),
3795 "show-toolbar-monitoring",
3796 _("Display Monitor Options"),
3797 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_monitoring),
3798 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_monitoring)
3801 add_option (_("Appearance/Toolbar"),
3803 "show-toolbar-selclock",
3804 _("Display Selection Clock"),
3805 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
3806 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
3809 if (!ARDOUR::Profile->get_small_screen()) {
3810 add_option (_("Appearance/Toolbar"),
3812 "show-secondary-clock",
3813 _("Display Secondary Clock"),
3814 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
3815 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
3819 add_option (_("Appearance/Toolbar"),
3821 "show-dsp-load-info",
3822 _("Display DSP Load Information"),
3823 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_dsp_load_info),
3824 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_dsp_load_info)
3827 add_option (_("Appearance/Toolbar"),
3829 "show-disk-space-info",
3830 _("Display Disk Space Information"),
3831 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_disk_space_info),
3832 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_disk_space_info)
3835 add_option (_("Appearance/Toolbar"),
3837 "show-mini-timeline",
3838 _("Display Navigation Timeline"),
3839 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
3840 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
3843 add_option (_("Appearance/Toolbar"),
3845 "show-editor-meter",
3846 _("Display Master Level Meter"),
3847 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
3848 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
3851 add_option (_("Appearance/Toolbar"),
3852 new ColumVisibilityOption (
3853 "action-table-columns", _("Display Action-Buttons"), 4,
3854 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3855 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3858 add_option (_("Appearance/Toolbar"), new OptionEditorBlank ());
3861 /* and now the theme manager */
3863 add_option (_("Appearance/Theme"), new OptionEditorHeading (_("Theme")));
3865 add_option (_("Appearance/Theme"), new BoolOption (
3867 _("Draw \"flat\" buttons"),
3868 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_flat_buttons),
3869 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_flat_buttons)
3872 add_option (_("Appearance/Theme"), new BoolOption (
3874 _("LED meter style"),
3875 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3876 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3880 HSliderOption *gui_hs = new HSliderOption(
3881 "timeline-item-gradient-depth",
3882 _("Waveforms color gradient depth"),
3883 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_gradient_depth),
3884 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_gradient_depth),
3887 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3888 add_option (_("Appearance/Theme"), gui_hs);
3890 gui_hs = new HSliderOption(
3891 "timeline-item-gradient-depth",
3892 _("Timeline item gradient depth"),
3893 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_timeline_item_gradient_depth),
3894 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_timeline_item_gradient_depth),
3897 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3898 add_option (_("Appearance/Theme"), gui_hs);
3900 vector<string> icon_sets = ::get_icon_sets ();
3901 if (icon_sets.size() > 1) {
3902 ComboOption<std::string>* io = new ComboOption<std::string> (
3903 "icon-set", _("Icon Set"),
3904 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_icon_set),
3905 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_icon_set)
3907 for (vector<string>::const_iterator i = icon_sets.begin (); i != icon_sets.end (); ++i) {
3910 add_option (_("Appearance/Theme"), io);
3913 add_option (_("Appearance/Colors"), new OptionEditorHeading (_("Colors")));
3914 add_option (_("Appearance/Colors"), new ColorThemeManager);
3915 add_option (_("Appearance/Colors"), new OptionEditorBlank ());
3919 OptionEditorHeading* quirks_head = new OptionEditorHeading (_("Various Workarounds for Windowing Systems"));
3921 quirks_head->set_note (string_compose (_("Rules for closing, minimizing, maximizing, and stay-on-top can vary \
3922 with each version of your OS, and the preferences that you've set in your OS.\n\n\
3923 You can adjust the options, below, to change how %1's windows and dialogs behave.\n\n\
3924 These settings will only take effect after %1 is restarted.\n\
3927 add_option (_("Appearance/Quirks"), quirks_head);
3929 bo = new BoolOption (
3930 "use-wm-visibility",
3931 _("Use visibility information provided by your Window Manager/Desktop"),
3932 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3933 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3935 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3936 _("If you have trouble toggling between hidden Editor and Mixer windows, try changing this setting."));
3937 add_option (_("Appearance/Quirks"), bo);
3940 bo = new BoolOption (
3941 "all-floating-windows-are-dialogs",
3942 _("All floating windows are dialogs"),
3943 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_all_floating_windows_are_dialogs),
3944 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_all_floating_windows_are_dialogs)
3946 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3947 _("Mark all floating windows to be type \"Dialog\" rather than using \"Utility\" for some.\nThis may help with some window managers."));
3948 add_option (_("Appearance/Quirks"), bo);
3950 bo = new BoolOption (
3951 "transients-follow-front",
3952 _("Transient windows follow front window."),
3953 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_transients_follow_front),
3954 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_transients_follow_front)
3956 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3957 _("Make transient windows follow the front window when toggling between the editor and mixer."));
3958 add_option (_("Appearance/Quirks"), bo);
3961 if (!Profile->get_mixbus()) {
3962 bo = new BoolOption (
3963 "floating-monitor-section",
3964 _("Float detached monitor-section window"),
3965 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_floating_monitor_section),
3966 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_floating_monitor_section)
3968 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3969 _("When detaching the monitoring section, mark it as \"Utility\" window to stay in front."));
3970 add_option (_("Appearance/Quirks"), bo);
3973 add_option (_("Appearance/Quirks"), new OptionEditorBlank ());
3975 /* VIDEO Timeline */
3976 add_option (_("Video"), new OptionEditorHeading (_("Video Server")));
3977 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
3979 Widget::show_all ();
3981 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3982 parameter_changed ("send-ltc");
3983 parameter_changed ("sync-source");
3984 parameter_changed ("use-monitor-bus");
3985 parameter_changed ("open-gui-after-adding-plugin");
3987 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
3989 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
3990 (Gtk::StateType) here !!!
3992 Tabbable::set_state (*node, Stateful::loading_state_version);
3995 set_current_page (_("General"));
3999 RCOptionEditor::parameter_changed (string const & p)
4001 OptionEditor::parameter_changed (p);
4003 if (p == "use-monitor-bus") {
4004 bool const s = Config->get_use_monitor_bus ();
4006 /* we can't use this if we don't have a monitor bus */
4007 Config->set_solo_control_is_listen_control (false);
4009 _solo_control_is_listen_control->set_sensitive (s);
4010 _listen_position->set_sensitive (s);
4011 } else if (p == "sync-source") {
4012 _sync_source->set_sensitive (true);
4014 _sync_source->set_sensitive (!_session->config.get_external_sync());
4016 switch(Config->get_sync_source()) {
4019 _sync_genlock->set_sensitive (true);
4020 _sync_framerate->set_sensitive (true);
4021 _sync_source_2997->set_sensitive (true);
4024 _sync_genlock->set_sensitive (false);
4025 _sync_framerate->set_sensitive (false);
4026 _sync_source_2997->set_sensitive (false);
4029 } else if (p == "send-ltc") {
4030 bool const s = Config->get_send_ltc ();
4031 _ltc_send_continuously->set_sensitive (s);
4032 _ltc_volume_slider->set_sensitive (s);
4033 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
4034 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
4035 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
4040 void RCOptionEditor::plugin_scan_refresh () {
4041 PluginManager::instance().refresh();
4044 void RCOptionEditor::clear_vst_cache () {
4045 PluginManager::instance().clear_vst_cache();
4048 void RCOptionEditor::clear_vst_blacklist () {
4049 PluginManager::instance().clear_vst_blacklist();
4052 void RCOptionEditor::clear_au_cache () {
4053 PluginManager::instance().clear_au_cache();
4056 void RCOptionEditor::clear_au_blacklist () {
4057 PluginManager::instance().clear_au_blacklist();
4060 void RCOptionEditor::edit_lxvst_path () {
4061 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
4062 PathsDialog *pd = new PathsDialog (
4063 *current_toplevel(), _("Set Linux VST Search Path"),
4064 _rc_config->get_plugin_path_lxvst(),
4065 PluginManager::instance().get_default_lxvst_path()
4067 ResponseType r = (ResponseType) pd->run ();
4069 if (r == RESPONSE_ACCEPT) {
4070 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
4072 MessageDialog msg (_("Re-scan Plugins now?"),
4073 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
4074 msg.set_default_response (Gtk::RESPONSE_YES);
4075 if (msg.run() == Gtk::RESPONSE_YES) {
4077 plugin_scan_refresh ();
4083 void RCOptionEditor::edit_vst_path () {
4084 PathsDialog *pd = new PathsDialog (
4085 *current_toplevel(), _("Set Windows VST Search Path"),
4086 _rc_config->get_plugin_path_vst(),
4087 PluginManager::instance().get_default_windows_vst_path()
4089 ResponseType r = (ResponseType) pd->run ();
4091 if (r == RESPONSE_ACCEPT) {
4092 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
4093 MessageDialog msg (_("Re-scan Plugins now?"),
4094 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
4095 msg.set_default_response (Gtk::RESPONSE_YES);
4096 if (msg.run() == Gtk::RESPONSE_YES) {
4098 plugin_scan_refresh ();
4106 RCOptionEditor::populate_sync_options ()
4108 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
4110 _sync_source->clear ();
4112 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
4113 _sync_source->add (*i, sync_source_to_string (*i));
4116 if (sync_opts.empty()) {
4117 _sync_source->set_sensitive(false);
4119 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
4120 _rc_config->set_sync_source(sync_opts.front());
4124 parameter_changed ("sync-source");
4128 RCOptionEditor::use_own_window (bool and_fill_it)
4130 bool new_window = !own_window ();
4132 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
4134 if (win && new_window) {
4135 win->set_name ("PreferencesWindow");
4136 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
4138 win->set_resizable (false);
4145 RCOptionEditor::get_state ()
4147 XMLNode* node = new XMLNode (X_("Preferences"));
4148 node->add_child_nocopy (Tabbable::get_state());