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 bo = new BoolOption (
2311 _("Prompt for new marker names"),
2312 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2313 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2315 add_option (_("Editor"), bo);
2316 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."
2317 "\n\nYou can always rename markers by right-clicking on them"));
2319 add_option (_("Editor"),
2321 "draggable-playhead",
2322 _("Allow dragging of playhead"),
2323 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2324 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2327 ComboOption<float>* dps = new ComboOption<float> (
2328 "draggable-playhead-speed",
2329 _("Playhead dragging speed (%)"),
2330 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead_speed),
2331 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead_speed)
2333 dps->add (0.05, _("5%"));
2334 dps->add (0.1, _("10%"));
2335 dps->add (0.25, _("25%"));
2336 dps->add (0.5, _("50%"));
2337 dps->add (1.0, _("100%"));
2338 add_option (_("Editor"), dps);
2340 ComboOption<float>* eet = new ComboOption<float> (
2341 "extra-ui-extents-time",
2342 _("Limit zooming & summary view to X minutes beyond session extents"),
2343 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_extra_ui_extents_time),
2344 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_extra_ui_extents_time)
2346 eet->add (1, _("1 minute"));
2347 eet->add (2, _("2 minutes"));
2348 eet->add (20, _("20 minutes"));
2349 eet->add (60, _("1 hour"));
2350 eet->add (60*2, _("2 hours"));
2351 eet->add (60*24, _("24 hours"));
2352 add_option (_("Editor"), eet);
2354 if (!Profile->get_mixbus()) {
2356 add_option (_("Editor"),
2358 "use-mouse-position-as-zoom-focus-on-scroll",
2359 _("Zoom to mouse position when zooming with scroll wheel"),
2360 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2361 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2365 add_option (_("Editor"),
2367 "use-time-rulers-to-zoom-with-vertical-drag",
2368 _("Zoom with vertical drag in rulers"),
2369 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag),
2370 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag)
2373 add_option (_("Editor"),
2375 "use-double-click-to-zoom-to-selection",
2376 _("Double click zooms to selection"),
2377 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection),
2378 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection)
2381 add_option (_("Editor"),
2383 "update-editor-during-summary-drag",
2384 _("Update editor window during drags of the summary"),
2385 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2386 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2389 add_option (_("Editor"),
2391 "autoscroll-editor",
2392 _("Auto-scroll editor window when dragging near its edges"),
2393 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2394 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2397 add_option (_("Editor"),
2398 new BoolComboOption (
2399 "show-region-gain-envelopes",
2400 _("Show gain envelopes in audio regions"),
2402 _("only in Draw and Internal Edit modes"),
2403 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2404 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2407 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2409 add_option (_("Editor"),
2411 "automation-follows-regions",
2412 _("Move relevant automation when audio regions are moved"),
2413 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2414 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2417 bo = new BoolOption (
2418 "new-automation-points-on-lane",
2419 _("Ignore Y-axis click position when adding new automation-points"),
2420 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_new_automation_points_on_lane),
2421 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_new_automation_points_on_lane)
2423 add_option (_("Editor"), bo);
2424 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2425 _("<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."));
2427 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2428 "default-fade-shape",
2429 _("Default fade shape"),
2430 sigc::mem_fun (*_rc_config,
2431 &RCConfiguration::get_default_fade_shape),
2432 sigc::mem_fun (*_rc_config,
2433 &RCConfiguration::set_default_fade_shape)
2436 fadeshape->add (FadeLinear,
2437 _("Linear (for highly correlated material)"));
2438 fadeshape->add (FadeConstantPower, _("Constant power"));
2439 fadeshape->add (FadeSymmetric, _("Symmetric"));
2440 fadeshape->add (FadeSlow, _("Slow"));
2441 fadeshape->add (FadeFast, _("Fast"));
2443 add_option (_("Editor"), fadeshape);
2445 bco = new BoolComboOption (
2446 "use-overlap-equivalency",
2447 _("Regions in edit groups are edited together"),
2448 _("whenever they overlap in time"),
2449 _("only if they have identical length and position"),
2450 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2451 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2454 add_option (_("Editor"), bco);
2456 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2458 _("Layering model"),
2459 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2460 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2463 lm->add (LaterHigher, _("later is higher"));
2464 lm->add (Manual, _("manual layering"));
2465 add_option (_("Editor"), lm);
2467 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2468 "region-selection-after-split",
2469 _("After splitting selected regions, select"),
2470 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2471 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2473 // TODO: decide which of these modes are really useful
2474 rsas->add(None, _("no regions"));
2475 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2476 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2477 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2478 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2479 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2480 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2481 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2483 add_option (_("Editor"), rsas);
2485 add_option (_("Editor/Snap"), new OptionEditorHeading (_("General Snap options:")));
2487 add_option (_("Editor/Snap"),
2488 new SpinOption<uint32_t> (
2490 _("Snap Threshold (pixels)"),
2491 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_threshold),
2492 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_threshold),
2497 add_option (_("Editor/Snap"),
2499 "show-snapped-cursor",
2500 _("Show Snapped Cursor"),
2501 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_snapped_cursor),
2502 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_snapped_cursor)
2505 add_option (_("Editor/Snap"),
2507 "rubberbanding-snaps-to-grid",
2508 _("Snap rubberband to grid"),
2509 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2510 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2513 add_option (_("Editor/Snap"), new OptionEditorHeading (_("When \"Snap\" is enabled, snap to:")));
2516 add_option (_("Editor/Snap"),
2518 "snap-to-region-sync",
2519 _("Region Sync Points"),
2520 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_region_sync),
2521 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_region_sync)
2524 add_option (_("Editor/Snap"),
2526 "snap-to-region-start",
2528 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_region_start),
2529 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_region_start)
2532 add_option (_("Editor/Snap"),
2534 "snap-to-region-end",
2536 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_region_end),
2537 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_region_end)
2540 add_option (_("Editor/Snap"),
2544 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_grid),
2545 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_grid)
2548 add_option (_("Editor/Modifiers"), new OptionEditorHeading (_("Keyboard Modifiers")));
2549 add_option (_("Editor/Modifiers"), new KeyboardOptions);
2550 add_option (_("Editor/Modifiers"), new OptionEditorBlank ());
2552 /* MIXER -- SOLO AND MUTE */
2554 add_option (_("Mixer"), new OptionEditorHeading (_("Solo")));
2556 _solo_control_is_listen_control = new BoolOption (
2557 "solo-control-is-listen-control",
2558 _("Solo controls are Listen controls"),
2559 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2560 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2563 add_option (_("Mixer"), _solo_control_is_listen_control);
2565 add_option (_("Mixer"),
2568 _("Exclusive solo"),
2569 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2570 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2573 add_option (_("Mixer"),
2576 _("Show solo muting"),
2577 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2578 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2581 add_option (_("Mixer"),
2583 "solo-mute-override",
2584 _("Soloing overrides muting"),
2585 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2586 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2589 add_option (_("Mixer"),
2592 _("Solo-in-place mute cut (dB)"),
2593 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2594 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2597 _listen_position = new ComboOption<ListenPosition> (
2599 _("Listen Position"),
2600 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2601 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2604 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2605 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2607 add_option (_("Mixer"), _listen_position);
2609 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2611 _("PFL signals come from"),
2612 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2613 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2616 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2617 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2619 add_option (_("Mixer"), pp);
2621 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2623 _("AFL signals come from"),
2624 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2625 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2628 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2629 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2631 add_option (_("Mixer"), pa);
2633 add_option (_("Mixer"), new OptionEditorHeading (_("Default Track / Bus Muting Options")));
2635 add_option (_("Mixer"),
2637 "mute-affects-pre-fader",
2638 _("Mute affects pre-fader sends"),
2639 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2640 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2643 add_option (_("Mixer"),
2645 "mute-affects-post-fader",
2646 _("Mute affects post-fader sends"),
2647 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2648 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2651 add_option (_("Mixer"),
2653 "mute-affects-control-outs",
2654 _("Mute affects control outputs"),
2655 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2656 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2659 add_option (_("Mixer"),
2661 "mute-affects-main-outs",
2662 _("Mute affects main outputs"),
2663 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2664 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2668 if (!ARDOUR::Profile->get_mixbus()) {
2669 add_option (_("Mixer"), new OptionEditorHeading (_("Send Routing")));
2670 add_option (_("Mixer"),
2672 "link-send-and-route-panner",
2673 _("Link panners of Aux and External Sends with main panner by default"),
2674 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2675 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2681 add_option (_("Signal Flow"), new OptionEditorHeading (_("Monitoring")));
2683 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2685 _("Record monitoring handled by"),
2686 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2687 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2690 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2691 mm->add (HardwareMonitoring, _("via Audio Driver"));
2694 string prog (PROGRAM_NAME);
2695 boost::algorithm::to_lower (prog);
2696 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2697 mm->add (ExternalMonitoring, _("audio hardware"));
2699 add_option (_("Signal Flow"), mm);
2701 bo = new BoolOption (
2702 "tape-machine-mode",
2703 _("Tape machine mode"),
2704 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2705 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2707 add_option (_("Signal Flow"), bo);
2708 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2709 string_compose (_("<b>When enabled</b> %1 will not monitor a track's input if the transport is stopped."),
2712 if (!Profile->get_mixbus()) {
2714 add_option (_("Signal Flow"), new OptionEditorHeading (_("Track and Bus Connections")));
2716 add_option (_("Signal Flow"),
2718 "auto-connect-standard-busses",
2719 _("Auto-connect master/monitor busses"),
2720 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2721 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2724 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2725 "input-auto-connect",
2726 _("Connect track inputs"),
2727 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2728 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2731 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2732 iac->add (ManualConnect, _("manually"));
2734 add_option (_("Signal Flow"), iac);
2736 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2737 "output-auto-connect",
2738 _("Connect track and bus outputs"),
2739 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2740 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2743 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2744 oac->add (AutoConnectMaster, _("automatically to master bus"));
2745 oac->add (ManualConnect, _("manually"));
2747 add_option (_("Signal Flow"), oac);
2749 bo = new BoolOption (
2751 _("Use 'Strict-I/O' for new tracks or busses"),
2752 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2753 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2756 add_option (_("Signal Flow"), bo);
2757 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2758 _("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."));
2765 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2767 add_option (_("Audio"), new BufferingOptions (_rc_config));
2769 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2771 add_option (_("Audio"),
2773 "denormal-protection",
2774 _("Use DC bias to protect against denormals"),
2775 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2776 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2779 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2781 _("Processor handling"),
2782 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2783 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2787 dm->add (DenormalNone, _("no processor handling"));
2789 FPU* fpu = FPU::instance();
2791 if (fpu->has_flush_to_zero()) {
2793 dm->add (DenormalFTZ, _("use FlushToZero"));
2794 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2795 _rc_config->set_denormal_model(DenormalNone);
2798 if (fpu->has_denormals_are_zero()) {
2800 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2801 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2802 _rc_config->set_denormal_model(DenormalNone);
2805 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2807 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2808 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2809 _rc_config->set_denormal_model(DenormalNone);
2813 dm->set_sensitive(false);
2816 add_option (_("Audio"), dm);
2818 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2820 add_option (_("Audio"),
2822 "auto-analyse-audio",
2823 _("Enable automatic analysis of audio"),
2824 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2825 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2828 add_option (_("Audio"),
2830 "replicate-missing-region-channels",
2831 _("Replicate missing region channels"),
2832 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2833 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2838 add_option (_("MIDI"), new OptionEditorHeading (_("Buffering")));
2840 add_option (_("MIDI"),
2841 new SpinOption<float> (
2843 _("MIDI read-ahead time (seconds)"),
2844 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2845 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2850 add_option (_("MIDI"), new OptionEditorHeading (_("Session")));
2852 add_option (_("MIDI"),
2853 new SpinOption<int32_t> (
2854 "initial-program-change",
2855 _("Initial program change"),
2856 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2857 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2861 add_option (_("MIDI"), new OptionEditorHeading (_("Audition")));
2863 add_option (_("MIDI"),
2866 _("Sound MIDI notes as they are selected in the editor"),
2867 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2868 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2871 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2872 "midi-audition-synth-uri",
2873 _("MIDI Audition Synth (LV2)"),
2874 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2875 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2878 audition_synth->add(X_(""), _("None"));
2879 PluginInfoList all_plugs;
2880 PluginManager& manager (PluginManager::instance());
2882 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2884 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2885 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2886 if (!(*i)->is_instrument()) continue;
2887 if ((*i)->type != ARDOUR::LV2) continue;
2888 if ((*i)->name.length() > 46) {
2889 audition_synth->add((*i)->unique_id, (*i)->name.substr (0, 44) + "...");
2891 audition_synth->add((*i)->unique_id, (*i)->name);
2896 add_option (_("MIDI"), audition_synth);
2900 add_option (_("Metronome"), new OptionEditorHeading (_("Metronome")));
2901 add_option (_("Metronome"), new ClickOptions (_rc_config));
2902 add_option (_("Metronome"), new OptionEditorHeading (_("Options")));
2904 bo = new BoolOption (
2905 "click-record-only",
2906 _("Enable metronome only while recording"),
2907 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_record_only),
2908 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_record_only)
2911 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2912 string_compose (_("<b>When enabled</b> the metronome will remain silent if %1 is <b>not recording</b>."), PROGRAM_NAME));
2913 add_option (_("Metronome"), bo);
2914 add_option (_("Metronome"), new OptionEditorBlank ());
2919 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2921 ComboOption<float>* mht = new ComboOption<float> (
2923 _("Peak hold time"),
2924 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
2925 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
2928 mht->add (MeterHoldOff, _("off"));
2929 mht->add (MeterHoldShort, _("short"));
2930 mht->add (MeterHoldMedium, _("medium"));
2931 mht->add (MeterHoldLong, _("long"));
2933 add_option (S_("Preferences|Metering"), mht);
2935 ComboOption<float>* mfo = new ComboOption<float> (
2938 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2939 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2942 mfo->add (METER_FALLOFF_OFF, _("off"));
2943 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2944 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2945 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2946 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2947 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2948 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
2950 add_option (S_("Preferences|Metering"), mfo);
2952 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2953 "meter-line-up-level",
2954 _("Meter line-up level; 0dBu"),
2955 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
2956 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
2959 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2960 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2961 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2962 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2964 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."));
2966 add_option (S_("Preferences|Metering"), mlu);
2968 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2969 "meter-line-up-din",
2970 _("IEC1/DIN Meter line-up level; 0dBu"),
2971 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
2972 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
2975 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2976 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2977 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2978 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2980 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2982 add_option (S_("Preferences|Metering"), mld);
2984 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2985 "meter-vu-standard",
2986 _("VU Meter standard"),
2987 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
2988 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
2991 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2992 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2993 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2994 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2996 add_option (S_("Preferences|Metering"), mvu);
2998 HSliderOption *mpks = new HSliderOption("meter-peak",
2999 _("Peak indicator threshold [dBFS]"),
3000 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
3001 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak),
3005 Gtkmm2ext::UI::instance()->set_tip (
3007 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
3009 add_option (S_("Preferences|Metering"), mpks);
3011 OptionEditorHeading* default_meter_head = new OptionEditorHeading (_("Default Meter Types"));
3012 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."));
3014 add_option (S_("Preferences|Metering"), default_meter_head);
3016 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3017 "meter-type-master",
3018 _("Default Meter Type for Master Bus"),
3019 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3020 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3022 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3023 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3024 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3025 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3026 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3027 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3028 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3029 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3031 add_option (S_("Preferences|Metering"), mtm);
3034 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3036 _("Default meter type for busses"),
3037 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3038 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3040 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3041 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3042 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3043 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3044 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3045 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3046 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3047 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3049 add_option (S_("Preferences|Metering"), mtb);
3051 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3053 _("Default meter type for tracks"),
3054 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3055 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3057 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3058 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3060 add_option (S_("Preferences|Metering"), mtt);
3062 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
3064 add_option (S_("Preferences|Metering"),
3066 "save-export-analysis-image",
3067 _("Save loudness analysis as image file"),
3068 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
3069 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
3072 /* TRANSPORT & Sync */
3074 add_option (_("Transport"), new OptionEditorHeading (_("General")));
3076 bo = new BoolOption (
3077 "stop-at-session-end",
3078 _("Stop at the end of the session"),
3079 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
3080 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
3082 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3083 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
3084 "when it reaches the current session end marker\n\n"
3085 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
3087 add_option (_("Transport"), bo);
3089 bo = new BoolOption (
3090 "latched-record-enable",
3091 _("Keep record-enable engaged on stop"),
3092 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
3093 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
3095 add_option (_("Transport"), bo);
3096 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3097 _("<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."));
3099 bo = new BoolOption (
3100 "disable-disarm-during-roll",
3101 _("Disable per-track record disarm while rolling"),
3102 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
3103 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
3105 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."));
3106 add_option (_("Transport"), bo);
3108 bo = new BoolOption (
3110 _("12dB gain reduction during fast-forward and fast-rewind"),
3111 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
3112 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
3114 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3115 _("<b>When enabled</b> this will reduce the unpleasant increase in perceived volume "
3116 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
3117 add_option (_("Transport"), bo);
3119 ComboOption<float>* psc = new ComboOption<float> (
3122 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
3123 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
3125 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
3126 (_("The amount of preroll to apply when <b>Play with Preroll</b> or <b>Record with Preroll</b>is initiated.\n\n"
3127 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
3128 psc->add (-4.0, _("4 Bars"));
3129 psc->add (-2.0, _("2 Bars"));
3130 psc->add (-1.0, _("1 Bar"));
3131 psc->add (0.0, _("0 (no pre-roll)"));
3132 psc->add (0.1, _("0.1 second"));
3133 psc->add (0.25, _("0.25 second"));
3134 psc->add (0.5, _("0.5 second"));
3135 psc->add (1.0, _("1.0 second"));
3136 psc->add (2.0, _("2.0 seconds"));
3137 add_option (_("Transport"), psc);
3140 add_option (_("Transport"), new OptionEditorHeading (_("Looping")));
3142 bo = new BoolOption (
3144 _("Play loop is a transport mode"),
3145 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
3146 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
3148 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3149 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
3150 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
3151 add_option (_("Transport"), bo);
3153 bo = new BoolOption (
3155 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
3156 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
3157 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
3159 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3160 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
3161 "preventing any need to do a transport locate at the end of the loop\n\n"
3162 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
3163 "which will often cause a small click or delay"), PROGRAM_NAME));
3164 add_option (_("Transport"), bo);
3166 add_option (_("Transport"), new OptionEditorHeading (_("Dropout (xrun) Handling")));
3167 bo = new BoolOption (
3168 "stop-recording-on-xrun",
3169 _("Stop recording when an xrun occurs"),
3170 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
3171 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
3173 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3174 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
3176 add_option (_("Transport"), bo);
3178 bo = new BoolOption (
3179 "create-xrun-marker",
3180 _("Create markers where xruns occur"),
3181 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
3182 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
3184 add_option (_("Transport"), bo);
3189 add_option (_("Sync"), new OptionEditorHeading (_("External Synchronization")));
3191 _sync_source = new ComboOption<SyncSource> (
3193 _("External timecode source"),
3194 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
3195 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
3198 add_option (_("Sync"), _sync_source);
3200 _sync_framerate = new BoolOption (
3201 "timecode-sync-frame-rate",
3202 _("Match session video frame rate to external timecode"),
3203 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
3204 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
3206 Gtkmm2ext::UI::instance()->set_tip
3207 (_sync_framerate->tip_widget(),
3208 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
3209 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
3210 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
3211 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
3212 "timecode standard and the session standard."), PROGRAM_NAME));
3214 add_option (_("Sync"), _sync_framerate);
3216 _sync_genlock = new BoolOption (
3217 "timecode-source-is-synced",
3218 _("Sync-lock timecode to clock (disable drift compensation)"),
3219 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
3220 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
3222 Gtkmm2ext::UI::instance()->set_tip
3223 (_sync_genlock->tip_widget(),
3224 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
3225 "Sync Lock indicates that the selected external timecode source shares clock-sync "
3226 "(Black & Burst, Wordclock, etc) with the audio interface. "
3227 "This option disables drift compensation. The transport speed is fixed at 1.0. "
3228 "Vari-speed LTC will be ignored and cause drift."
3230 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
3231 "timecode sources shares clock sync."
3235 add_option (_("Sync"), _sync_genlock);
3237 _sync_source_2997 = new BoolOption (
3238 "timecode-source-2997",
3239 _("Lock to 29.9700 fps instead of 30000/1001"),
3240 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
3241 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
3243 Gtkmm2ext::UI::instance()->set_tip
3244 (_sync_source_2997->tip_widget(),
3245 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
3246 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
3247 "drop-sample timecode has an accumulated error of -86ms over a 24-hour period.\n"
3248 "Drop-sample timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
3249 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
3250 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
3253 add_option (_("Sync"), _sync_source_2997);
3255 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Reader")));
3257 _ltc_port = new ComboStringOption (
3259 _("LTC incoming port"),
3260 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
3261 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
3264 vector<string> physical_inputs;
3265 physical_inputs.push_back (_("None"));
3266 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
3267 _ltc_port->set_popdown_strings (physical_inputs);
3269 populate_sync_options ();
3270 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
3272 add_option (_("Sync/LTC"), _ltc_port);
3274 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Generator")));
3276 add_option (_("Sync/LTC"),
3279 _("Enable LTC generator"),
3280 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
3281 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
3284 _ltc_send_continuously = new BoolOption (
3285 "ltc-send-continuously",
3286 _("Send LTC while stopped"),
3287 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
3288 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
3290 Gtkmm2ext::UI::instance()->set_tip
3291 (_ltc_send_continuously->tip_widget(),
3292 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
3293 add_option (_("Sync/LTC"), _ltc_send_continuously);
3295 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level [dBFS]"),
3296 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_output_volume),
3297 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_output_volume),
3301 Gtkmm2ext::UI::instance()->set_tip
3302 (_ltc_volume_slider->tip_widget(),
3303 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
3305 add_option (_("Sync/LTC"), _ltc_volume_slider);
3308 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Beat Clock (Mclk) Generator")));
3310 add_option (_("Sync/MIDI"),
3313 _("Enable Mclk generator"),
3314 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
3315 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
3318 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC) Generator")));
3320 add_option (_("Sync/MIDI"),
3323 _("Enable MTC Generator"),
3324 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
3325 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
3328 add_option (_("Sync/MIDI"),
3329 new SpinOption<int> (
3330 "mtc-qf-speed-tolerance",
3331 _("Percentage either side of normal transport speed to transmit MTC"),
3332 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
3333 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
3337 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Machine Control (MMC)")));
3339 add_option (_("Sync/MIDI"),
3342 _("Respond to MMC commands"),
3343 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
3344 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
3347 add_option (_("Sync/MIDI"),
3350 _("Send MMC commands"),
3351 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
3352 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
3355 add_option (_("Sync/MIDI"),
3356 new SpinOption<uint8_t> (
3357 "mmc-receive-device-id",
3358 _("Inbound MMC device ID"),
3359 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
3360 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
3364 add_option (_("Sync/MIDI"),
3365 new SpinOption<uint8_t> (
3366 "mmc-send-device-id",
3367 _("Outbound MMC device ID"),
3368 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
3369 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
3374 /* Control Surfaces */
3376 add_option (_("Control Surfaces"), new OptionEditorHeading (_("Control Surfaces")));
3377 add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
3380 add_option (_("MIDI Ports"), new OptionEditorHeading (_("MIDI Port Options")));
3382 add_option (_("MIDI Ports"),
3384 "get-midi-input-follows-selection",
3385 _("MIDI input follows MIDI track selection"),
3386 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
3387 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
3390 add_option (_("MIDI Ports"), new MidiPortOptions ());
3391 add_option (_("MIDI Ports"), new OptionEditorBlank ());
3395 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3396 add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
3397 add_option (_("Plugins"),
3398 new RcActionButton (_("Scan for Plugins"),
3399 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3403 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
3405 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3406 bo = new BoolOption (
3407 "show-plugin-scan-window",
3408 _("Always Display Plugin Scan Progress"),
3409 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
3410 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
3412 add_option (_("Plugins"), bo);
3413 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3414 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
3417 bo = new BoolOption (
3418 "plugins-stop-with-transport",
3419 _("Silence plugins when the transport is stopped"),
3420 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
3421 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
3423 add_option (_("Plugins"), bo);
3424 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3425 _("<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."));
3427 bo = new BoolOption (
3428 "new-plugins-active",
3429 _("Make new plugins active"),
3430 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
3431 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
3433 add_option (_("Plugins"), bo);
3434 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3435 _("<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"));
3437 #if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
3438 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
3440 add_option (_("Plugins/VST"),
3441 new RcActionButton (_("Scan for Plugins"),
3442 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3445 #if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
3446 bo = new BoolOption (
3448 _("Enable Mac VST support (requires restart or re-scan)"),
3449 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
3450 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
3452 add_option (_("Plugins/VST"), bo);
3455 bo = new BoolOption (
3456 "discover-vst-on-start",
3457 _("Scan for [new] VST Plugins on Application Start"),
3458 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
3459 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
3461 add_option (_("Plugins/VST"), bo);
3462 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3463 _("<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"));
3465 #ifdef WINDOWS_VST_SUPPORT
3466 // currently verbose logging is only implemented for Windows VST.
3467 bo = new BoolOption (
3468 "verbose-plugin-scan",
3469 _("Verbose Plugin Scan"),
3470 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
3471 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
3473 add_option (_("Plugins/VST"), bo);
3474 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3475 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
3478 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
3480 add_option (_("Plugins/VST"),
3481 new RcActionButton (_("Clear"),
3482 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
3485 add_option (_("Plugins/VST"),
3486 new RcActionButton (_("Clear"),
3487 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
3488 _("VST Blacklist:")));
3491 #ifdef LXVST_SUPPORT
3492 add_option (_("Plugins/VST"),
3493 new RcActionButton (_("Edit"),
3494 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
3495 _("Linux VST Path:")));
3497 add_option (_("Plugins/VST"),
3498 new RcConfigDisplay (
3499 "plugin-path-lxvst",
3501 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
3505 #ifdef WINDOWS_VST_SUPPORT
3506 add_option (_("Plugins/VST"),
3507 new RcActionButton (_("Edit"),
3508 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
3509 _("Windows VST Path:")));
3510 add_option (_("Plugins/VST"),
3511 new RcConfigDisplay (
3514 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
3518 #ifdef AUDIOUNIT_SUPPORT
3520 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
3522 add_option (_("Plugins/Audio Unit"),
3523 new RcActionButton (_("Scan for Plugins"),
3524 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3527 bo = new BoolOption (
3528 "discover-audio-units",
3529 _("Scan for [new] AudioUnit Plugins on Application Start"),
3530 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
3531 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
3533 add_option (_("Plugins/Audio Unit"), bo);
3534 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3535 _("<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."));
3537 add_option (_("Plugins/Audio Unit"),
3538 new RcActionButton (_("Clear"),
3539 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
3542 add_option (_("Plugins/Audio Unit"),
3543 new RcActionButton (_("Clear"),
3544 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
3545 _("AU Blacklist:")));
3548 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
3549 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
3550 add_option (_("Plugins"),
3552 "open-gui-after-adding-plugin",
3553 _("Automatically open the plugin GUI when adding a new plugin"),
3554 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
3555 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3558 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3559 add_option (_("Plugins"),
3561 "show-inline-display-by-default",
3562 _("Show Plugin Inline Display on Mixerstrip by default"),
3563 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3564 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3567 _plugin_prefer_inline = new BoolOption (
3568 "prefer-inline-over-gui",
3569 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3570 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3571 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3573 add_option (_("Plugins"), _plugin_prefer_inline);
3576 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3578 bo = new BoolOption (
3579 "ask-replace-instrument",
3580 _("Ask to replace existing instrument plugin"),
3581 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3582 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3584 add_option (_("Plugins"), bo);
3586 bo = new BoolOption (
3587 "ask-setup_instrument",
3588 _("Interactively configure instrument plugins on insert"),
3589 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3590 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3592 add_option (_("Plugins"), bo);
3593 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3594 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3597 add_option (_("Plugins"), new OptionEditorBlank ());
3600 #if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
3601 add_option (_("Appearance"), new OptionEditorHeading (_("Graphics Acceleration")));
3604 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3605 BoolOption* bgc = new BoolOption (
3606 "cairo-image-surface",
3607 _("Disable Graphics Hardware Acceleration (requires restart)"),
3608 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3609 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3612 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3613 _("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));
3614 add_option (_("Appearance"), bgc);
3617 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3618 BoolOption* bgo = new BoolOption (
3620 _("Possibly improve slow graphical performance (requires restart)"),
3621 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3622 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3625 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));
3626 add_option (_("Appearance"), bgo);
3628 add_option (_("Appearance"), new OptionEditorHeading (_("Graphical User Interface")));
3630 add_option (_("Appearance"),
3633 _("Highlight widgets on mouseover"),
3634 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3635 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3638 add_option (_("Appearance"),
3641 _("Show tooltips if mouse hovers over a control"),
3642 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3643 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3646 bo = new BoolOption (
3647 "super-rapid-clock-update",
3648 _("Update clocks at TC Frame rate"),
3649 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3650 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3652 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3653 _("<b>When enabled</b> clock displays are updated every Timecode Frame (fps).\n\n"
3654 "<b>When disabled</b> clock displays are updated only every 100ms."
3656 add_option (_("Appearance"), bo);
3658 add_option (_("Appearance"),
3661 _("Blink Rec-Arm buttons"),
3662 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_rec_arm),
3663 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_rec_arm)
3666 add_option (_("Appearance"),
3668 "blink-alert-indicators",
3669 _("Blink Alert Indicators"),
3670 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_alert_indicators),
3671 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_alert_indicators)
3676 /* font scaling does nothing with GDK/Quartz */
3677 add_option (_("Appearance"), new FontScalingOptions ());
3679 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("General")));
3680 add_option (_("Appearance/Editor"),
3682 "show-name-highlight",
3683 _("Use name highlight bars in region displays (requires a restart)"),
3684 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3685 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3688 add_option (_("Appearance/Editor"),
3690 "color-regions-using-track-color",
3691 _("Region color follows track color"),
3692 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_color_regions_using_track_color),
3693 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_color_regions_using_track_color)
3696 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Waveforms")));
3698 if (!Profile->get_mixbus()) {
3699 add_option (_("Appearance/Editor"),
3702 _("Show waveforms in regions"),
3703 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
3704 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
3708 add_option (_("Appearance/Editor"),
3710 "show-waveforms-while-recording",
3711 _("Show waveforms while recording"),
3712 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
3713 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
3716 add_option (_("Appearance/Editor"),
3718 "show-waveform-clipping",
3719 _("Show waveform clipping"),
3720 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveform_clipping),
3721 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveform_clipping)
3724 add_option (_("Appearance/Editor"), new ClipLevelOptions ());
3726 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
3728 _("Waveform scale"),
3729 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
3730 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
3733 wfs->add (Linear, _("linear"));
3734 wfs->add (Logarithmic, _("logarithmic"));
3736 add_option (_("Appearance/Editor"), wfs);
3738 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
3740 _("Waveform shape"),
3741 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
3742 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
3745 wfsh->add (Traditional, _("traditional"));
3746 wfsh->add (Rectified, _("rectified"));
3748 add_option (_("Appearance/Editor"), wfsh);
3750 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Editor Meters")));
3752 add_option (_("Appearance/Editor"),
3754 "show-track-meters",
3755 _("Show meters in track headers"),
3756 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3757 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3760 add_option (_("Appearance/Editor"),
3762 "editor-stereo-only-meters",
3763 _("Limit track header meters to stereo"),
3764 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3765 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3768 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("MIDI Regions")));
3770 add_option (_("Appearance/Editor"),
3772 "display-first-midi-bank-as-zero",
3773 _("Display first MIDI bank/program as 0"),
3774 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
3775 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
3778 add_option (_("Appearance/Editor"),
3780 "never-display-periodic-midi",
3781 _("Don't display periodic (MTC, MMC) SysEx messages in MIDI Regions"),
3782 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
3783 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
3786 add_option (_("Appearance/Editor"), new OptionEditorBlank ());
3788 /* The names of these controls must be the same as those given in MixerStrip
3789 for the actual widgets being controlled.
3791 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3792 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3793 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3794 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3795 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3796 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3797 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3799 add_option (_("Appearance/Mixer"),
3800 new VisibilityOption (
3802 &_mixer_strip_visibility,
3803 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3804 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3808 add_option (_("Appearance/Mixer"),
3810 "default-narrow_ms",
3811 _("Use narrow strips in the mixer for new strips by default"),
3812 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3813 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3816 add_option (_("Appearance/Mixer"), new OptionEditorBlank ());
3818 add_option (_("Appearance/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items")));
3820 add_option (_("Appearance/Toolbar"),
3822 "show-toolbar-recpunch",
3823 _("Display Record/Punch Options"),
3824 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_recpunch),
3825 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_recpunch)
3828 add_option (_("Appearance/Toolbar"),
3830 "show-toolbar-monitoring",
3831 _("Display Monitor Options"),
3832 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_monitoring),
3833 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_monitoring)
3836 add_option (_("Appearance/Toolbar"),
3838 "show-toolbar-selclock",
3839 _("Display Selection Clock"),
3840 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
3841 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
3844 if (!ARDOUR::Profile->get_small_screen()) {
3845 add_option (_("Appearance/Toolbar"),
3847 "show-secondary-clock",
3848 _("Display Secondary Clock"),
3849 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
3850 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
3854 add_option (_("Appearance/Toolbar"),
3856 "show-dsp-load-info",
3857 _("Display DSP Load Information"),
3858 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_dsp_load_info),
3859 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_dsp_load_info)
3862 add_option (_("Appearance/Toolbar"),
3864 "show-disk-space-info",
3865 _("Display Disk Space Information"),
3866 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_disk_space_info),
3867 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_disk_space_info)
3870 add_option (_("Appearance/Toolbar"),
3872 "show-mini-timeline",
3873 _("Display Navigation Timeline"),
3874 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
3875 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
3878 add_option (_("Appearance/Toolbar"),
3880 "show-editor-meter",
3881 _("Display Master Level Meter"),
3882 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
3883 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
3886 add_option (_("Appearance/Toolbar"),
3887 new ColumVisibilityOption (
3888 "action-table-columns", _("Display Action-Buttons"), 4,
3889 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3890 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3893 add_option (_("Appearance/Toolbar"), new OptionEditorBlank ());
3896 /* and now the theme manager */
3898 add_option (_("Appearance/Theme"), new OptionEditorHeading (_("Theme")));
3900 add_option (_("Appearance/Theme"), new BoolOption (
3902 _("Draw \"flat\" buttons"),
3903 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_flat_buttons),
3904 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_flat_buttons)
3907 add_option (_("Appearance/Theme"), new BoolOption (
3909 _("LED meter style"),
3910 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3911 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3915 HSliderOption *gui_hs = new HSliderOption(
3916 "timeline-item-gradient-depth",
3917 _("Waveforms color gradient depth"),
3918 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_gradient_depth),
3919 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_gradient_depth),
3922 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3923 add_option (_("Appearance/Theme"), gui_hs);
3925 gui_hs = new HSliderOption(
3926 "timeline-item-gradient-depth",
3927 _("Timeline item gradient depth"),
3928 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_timeline_item_gradient_depth),
3929 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_timeline_item_gradient_depth),
3932 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3933 add_option (_("Appearance/Theme"), gui_hs);
3935 vector<string> icon_sets = ::get_icon_sets ();
3936 if (icon_sets.size() > 1) {
3937 ComboOption<std::string>* io = new ComboOption<std::string> (
3938 "icon-set", _("Icon Set"),
3939 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_icon_set),
3940 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_icon_set)
3942 for (vector<string>::const_iterator i = icon_sets.begin (); i != icon_sets.end (); ++i) {
3945 add_option (_("Appearance/Theme"), io);
3948 add_option (_("Appearance/Colors"), new OptionEditorHeading (_("Colors")));
3949 add_option (_("Appearance/Colors"), new ColorThemeManager);
3950 add_option (_("Appearance/Colors"), new OptionEditorBlank ());
3954 OptionEditorHeading* quirks_head = new OptionEditorHeading (_("Various Workarounds for Windowing Systems"));
3956 quirks_head->set_note (string_compose (_("Rules for closing, minimizing, maximizing, and stay-on-top can vary \
3957 with each version of your OS, and the preferences that you've set in your OS.\n\n\
3958 You can adjust the options, below, to change how %1's windows and dialogs behave.\n\n\
3959 These settings will only take effect after %1 is restarted.\n\
3962 add_option (_("Appearance/Quirks"), quirks_head);
3964 bo = new BoolOption (
3965 "use-wm-visibility",
3966 _("Use visibility information provided by your Window Manager/Desktop"),
3967 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3968 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3970 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3971 _("If you have trouble toggling between hidden Editor and Mixer windows, try changing this setting."));
3972 add_option (_("Appearance/Quirks"), bo);
3975 bo = new BoolOption (
3976 "all-floating-windows-are-dialogs",
3977 _("All floating windows are dialogs"),
3978 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_all_floating_windows_are_dialogs),
3979 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_all_floating_windows_are_dialogs)
3981 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3982 _("Mark all floating windows to be type \"Dialog\" rather than using \"Utility\" for some.\nThis may help with some window managers."));
3983 add_option (_("Appearance/Quirks"), bo);
3985 bo = new BoolOption (
3986 "transients-follow-front",
3987 _("Transient windows follow front window."),
3988 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_transients_follow_front),
3989 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_transients_follow_front)
3991 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3992 _("Make transient windows follow the front window when toggling between the editor and mixer."));
3993 add_option (_("Appearance/Quirks"), bo);
3996 if (!Profile->get_mixbus()) {
3997 bo = new BoolOption (
3998 "floating-monitor-section",
3999 _("Float detached monitor-section window"),
4000 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_floating_monitor_section),
4001 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_floating_monitor_section)
4003 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
4004 _("When detaching the monitoring section, mark it as \"Utility\" window to stay in front."));
4005 add_option (_("Appearance/Quirks"), bo);
4008 add_option (_("Appearance/Quirks"), new OptionEditorBlank ());
4010 /* VIDEO Timeline */
4011 add_option (_("Video"), new OptionEditorHeading (_("Video Server")));
4012 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
4014 Widget::show_all ();
4016 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
4017 parameter_changed ("send-ltc");
4018 parameter_changed ("sync-source");
4019 parameter_changed ("use-monitor-bus");
4020 parameter_changed ("open-gui-after-adding-plugin");
4022 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
4024 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
4025 (Gtk::StateType) here !!!
4027 Tabbable::set_state (*node, Stateful::loading_state_version);
4030 set_current_page (_("General"));
4034 RCOptionEditor::parameter_changed (string const & p)
4036 OptionEditor::parameter_changed (p);
4038 if (p == "use-monitor-bus") {
4039 bool const s = Config->get_use_monitor_bus ();
4041 /* we can't use this if we don't have a monitor bus */
4042 Config->set_solo_control_is_listen_control (false);
4044 _solo_control_is_listen_control->set_sensitive (s);
4045 _listen_position->set_sensitive (s);
4046 } else if (p == "sync-source") {
4047 _sync_source->set_sensitive (true);
4049 _sync_source->set_sensitive (!_session->config.get_external_sync());
4051 switch(Config->get_sync_source()) {
4054 _sync_genlock->set_sensitive (true);
4055 _sync_framerate->set_sensitive (true);
4056 _sync_source_2997->set_sensitive (true);
4059 _sync_genlock->set_sensitive (false);
4060 _sync_framerate->set_sensitive (false);
4061 _sync_source_2997->set_sensitive (false);
4064 } else if (p == "send-ltc") {
4065 bool const s = Config->get_send_ltc ();
4066 _ltc_send_continuously->set_sensitive (s);
4067 _ltc_volume_slider->set_sensitive (s);
4068 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
4069 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
4070 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
4075 void RCOptionEditor::plugin_scan_refresh () {
4076 PluginManager::instance().refresh();
4079 void RCOptionEditor::clear_vst_cache () {
4080 PluginManager::instance().clear_vst_cache();
4083 void RCOptionEditor::clear_vst_blacklist () {
4084 PluginManager::instance().clear_vst_blacklist();
4087 void RCOptionEditor::clear_au_cache () {
4088 PluginManager::instance().clear_au_cache();
4091 void RCOptionEditor::clear_au_blacklist () {
4092 PluginManager::instance().clear_au_blacklist();
4095 void RCOptionEditor::edit_lxvst_path () {
4096 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
4097 PathsDialog *pd = new PathsDialog (
4098 *current_toplevel(), _("Set Linux VST Search Path"),
4099 _rc_config->get_plugin_path_lxvst(),
4100 PluginManager::instance().get_default_lxvst_path()
4102 ResponseType r = (ResponseType) pd->run ();
4104 if (r == RESPONSE_ACCEPT) {
4105 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
4107 MessageDialog msg (_("Re-scan Plugins now?"),
4108 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
4109 msg.set_default_response (Gtk::RESPONSE_YES);
4110 if (msg.run() == Gtk::RESPONSE_YES) {
4112 plugin_scan_refresh ();
4118 void RCOptionEditor::edit_vst_path () {
4119 PathsDialog *pd = new PathsDialog (
4120 *current_toplevel(), _("Set Windows VST Search Path"),
4121 _rc_config->get_plugin_path_vst(),
4122 PluginManager::instance().get_default_windows_vst_path()
4124 ResponseType r = (ResponseType) pd->run ();
4126 if (r == RESPONSE_ACCEPT) {
4127 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
4128 MessageDialog msg (_("Re-scan Plugins now?"),
4129 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
4130 msg.set_default_response (Gtk::RESPONSE_YES);
4131 if (msg.run() == Gtk::RESPONSE_YES) {
4133 plugin_scan_refresh ();
4141 RCOptionEditor::populate_sync_options ()
4143 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
4145 _sync_source->clear ();
4147 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
4148 _sync_source->add (*i, sync_source_to_string (*i));
4151 if (sync_opts.empty()) {
4152 _sync_source->set_sensitive(false);
4154 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
4155 _rc_config->set_sync_source(sync_opts.front());
4159 parameter_changed ("sync-source");
4163 RCOptionEditor::use_own_window (bool and_fill_it)
4165 bool new_window = !own_window ();
4167 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
4169 if (win && new_window) {
4170 win->set_name ("PreferencesWindow");
4171 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
4173 win->set_resizable (false);
4180 RCOptionEditor::get_state ()
4182 XMLNode* node = new XMLNode (X_("Preferences"));
4183 node->add_child_nocopy (Tabbable::get_state());