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