2 Copyright (C) 2001-2011 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "gtk2ardour-config.h"
24 #if !defined USE_CAIRO_IMAGE_SURFACE && !defined NDEBUG
25 #define OPTIONAL_CAIRO_IMAGE_SURFACE
28 #include <cairo/cairo.h>
30 #include <boost/algorithm/string.hpp>
32 #include <gtkmm/liststore.h>
33 #include <gtkmm/stock.h>
34 #include <gtkmm/scale.h>
36 #include "gtkmm2ext/utils.h"
37 #include "gtkmm2ext/gtk_ui.h"
38 #include "gtkmm2ext/window_title.h"
44 #include "ardour/audio_backend.h"
45 #include "ardour/audioengine.h"
46 #include "ardour/profile.h"
47 #include "ardour/dB.h"
48 #include "ardour/rc_configuration.h"
49 #include "ardour/control_protocol_manager.h"
50 #include "ardour/port_manager.h"
51 #include "ardour/plugin_manager.h"
52 #include "control_protocol/control_protocol.h"
54 #include "waveview/wave_view.h"
56 #include "widgets/paths_dialog.h"
57 #include "widgets/tooltips.h"
59 #include "ardour_dialog.h"
60 #include "ardour_ui.h"
61 #include "ardour_window.h"
62 #include "color_theme_manager.h"
63 #include "gui_thread.h"
65 #include "meter_patterns.h"
66 #include "midi_tracer.h"
67 #include "rc_option_editor.h"
69 #include "ui_config.h"
74 using namespace Gtkmm2ext;
76 using namespace ARDOUR;
77 using namespace ARDOUR_UI_UTILS;
78 using namespace ArdourWidgets;
80 class ClickOptions : public OptionEditorMiniPage
83 ClickOptions (RCConfiguration* c)
85 , _click_browse_button (_("Browse..."))
86 , _click_emphasis_browse_button (_("Browse..."))
88 // TODO get rid of GTK -> use OptionEditor Widgets
93 l = manage (left_aligned_label (_("Emphasis on first beat")));
94 _use_emphasis_on_click_check_button.add (*l);
95 t->attach (_use_emphasis_on_click_check_button, 1, 3, row, row + 1, FILL);
96 _use_emphasis_on_click_check_button.signal_toggled().connect (
97 sigc::mem_fun (*this, &ClickOptions::use_emphasis_on_click_toggled));
100 l = manage (left_aligned_label (_("Use built-in default sounds")));
101 _use_default_click_check_button.add (*l);
102 t->attach (_use_default_click_check_button, 1, 3, row, row + 1, FILL);
103 _use_default_click_check_button.signal_toggled().connect (
104 sigc::mem_fun (*this, &ClickOptions::use_default_click_toggled));
107 l = manage (left_aligned_label (_("Audio file:")));
108 t->attach (*l, 1, 2, row, row + 1, FILL);
109 t->attach (_click_path_entry, 2, 3, row, row + 1, FILL);
110 _click_browse_button.signal_clicked ().connect (
111 sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
112 t->attach (_click_browse_button, 3, 4, row, row + 1, FILL);
115 l = manage (left_aligned_label (_("Emphasis audio file:")));
116 t->attach (*l, 1, 2, row, row + 1, FILL);
117 t->attach (_click_emphasis_path_entry, 2, 3, row, row + 1, FILL);
118 _click_emphasis_browse_button.signal_clicked ().connect (
119 sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
120 t->attach (_click_emphasis_browse_button, 3, 4, row, row + 1, FILL);
123 _click_fader = new FaderOption (
126 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
127 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
130 _click_fader->add_to_page (this);
131 _click_fader->set_state_from_config ();
133 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
134 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
136 if (_rc_config->get_click_sound ().empty() &&
137 _rc_config->get_click_emphasis_sound().empty()) {
138 _use_default_click_check_button.set_active (true);
139 _use_emphasis_on_click_check_button.set_active (true);
142 _use_default_click_check_button.set_active (false);
143 _use_emphasis_on_click_check_button.set_active (false);
147 void parameter_changed (string const & p)
149 if (p == "click-sound") {
150 _click_path_entry.set_text (_rc_config->get_click_sound());
151 } else if (p == "click-emphasis-sound") {
152 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
153 } else if (p == "use-click-emphasis") {
154 bool x = _rc_config->get_use_click_emphasis ();
155 _use_emphasis_on_click_check_button.set_active (x);
156 } else if (p == "click-gain") {
157 _click_fader->set_state_from_config ();
161 void set_state_from_config ()
163 parameter_changed ("click-sound");
164 parameter_changed ("click-emphasis-sound");
165 parameter_changed ("use-click-emphasis");
170 void click_browse_clicked ()
172 SoundFileChooser sfdb (_("Choose Click"));
177 if (sfdb.run () == RESPONSE_OK) {
178 click_chosen (sfdb.get_filename());
182 void click_chosen (string const & path)
184 _click_path_entry.set_text (path);
185 _rc_config->set_click_sound (path);
188 void click_changed ()
190 click_chosen (_click_path_entry.get_text ());
193 void click_emphasis_browse_clicked ()
195 SoundFileChooser sfdb (_("Choose Click Emphasis"));
200 if (sfdb.run () == RESPONSE_OK) {
201 click_emphasis_chosen (sfdb.get_filename());
205 void click_emphasis_chosen (string const & path)
207 _click_emphasis_path_entry.set_text (path);
208 _rc_config->set_click_emphasis_sound (path);
211 void click_emphasis_changed ()
213 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
216 void use_default_click_toggled ()
218 if (_use_default_click_check_button.get_active ()) {
219 _rc_config->set_click_sound ("");
220 _rc_config->set_click_emphasis_sound ("");
221 _click_path_entry.set_sensitive (false);
222 _click_emphasis_path_entry.set_sensitive (false);
223 _click_browse_button.set_sensitive (false);
224 _click_emphasis_browse_button.set_sensitive (false);
226 _click_path_entry.set_sensitive (true);
227 _click_emphasis_path_entry.set_sensitive (true);
228 _click_browse_button.set_sensitive (true);
229 _click_emphasis_browse_button.set_sensitive (true);
233 void use_emphasis_on_click_toggled ()
235 if (_use_emphasis_on_click_check_button.get_active ()) {
236 _rc_config->set_use_click_emphasis(true);
238 _rc_config->set_use_click_emphasis(false);
242 RCConfiguration* _rc_config;
243 CheckButton _use_default_click_check_button;
244 CheckButton _use_emphasis_on_click_check_button;
245 Entry _click_path_entry;
246 Entry _click_emphasis_path_entry;
247 Button _click_browse_button;
248 Button _click_emphasis_browse_button;
249 FaderOption* _click_fader;
252 class UndoOptions : public OptionEditorComponent
255 UndoOptions (RCConfiguration* c) :
257 _limit_undo_button (_("Limit undo history to")),
258 _save_undo_button (_("Save undo history of"))
260 // TODO get rid of GTK -> use OptionEditor SpinOption
261 _limit_undo_spin.set_range (0, 512);
262 _limit_undo_spin.set_increments (1, 10);
264 _save_undo_spin.set_range (0, 512);
265 _save_undo_spin.set_increments (1, 10);
267 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
268 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
269 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
270 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
273 void parameter_changed (string const & p)
275 if (p == "history-depth") {
276 int32_t const d = _rc_config->get_history_depth();
277 _limit_undo_button.set_active (d != 0);
278 _limit_undo_spin.set_sensitive (d != 0);
279 _limit_undo_spin.set_value (d);
280 } else if (p == "save-history") {
281 bool const x = _rc_config->get_save_history ();
282 _save_undo_button.set_active (x);
283 _save_undo_spin.set_sensitive (x);
284 } else if (p == "save-history-depth") {
285 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
289 void set_state_from_config ()
291 parameter_changed ("save-history");
292 parameter_changed ("history-depth");
293 parameter_changed ("save-history-depth");
296 void limit_undo_toggled ()
298 bool const x = _limit_undo_button.get_active ();
299 _limit_undo_spin.set_sensitive (x);
300 int32_t const n = x ? 16 : 0;
301 _limit_undo_spin.set_value (n);
302 _rc_config->set_history_depth (n);
305 void limit_undo_changed ()
307 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
310 void save_undo_toggled ()
312 bool const x = _save_undo_button.get_active ();
313 _rc_config->set_save_history (x);
316 void save_undo_changed ()
318 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
321 void add_to_page (OptionEditorPage* p)
323 int const n = p->table.property_n_rows();
324 Table* t = & p->table;
326 t->resize (n + 2, 3);
328 Label* l = manage (left_aligned_label (_("commands")));
329 HBox* box = manage (new HBox());
330 box->set_spacing (4);
331 box->pack_start (_limit_undo_spin, false, false);
332 box->pack_start (*l, true, true);
333 t->attach (_limit_undo_button, 1, 2, n, n +1, FILL);
334 t->attach (*box, 2, 3, n, n + 1, FILL | EXPAND);
336 l = manage (left_aligned_label (_("commands")));
337 box = manage (new HBox());
338 box->set_spacing (4);
339 box->pack_start (_save_undo_spin, false, false);
340 box->pack_start (*l, true, true);
341 t->attach (_save_undo_button, 1, 2, n + 1, n + 2, FILL);
342 t->attach (*box, 2, 3, n + 1, n + 2, FILL | EXPAND);
345 Gtk::Widget& tip_widget() {
346 return _limit_undo_button; // unused
350 RCConfiguration* _rc_config;
351 CheckButton _limit_undo_button;
352 SpinButton _limit_undo_spin;
353 CheckButton _save_undo_button;
354 SpinButton _save_undo_spin;
358 static const struct {
370 { "Key|Shift", GDK_SHIFT_MASK },
371 { "Command", GDK_MOD2_MASK },
372 { "Control", GDK_CONTROL_MASK },
373 { "Option", GDK_MOD1_MASK },
374 { "Command-Shift", GDK_MOD2_MASK|GDK_SHIFT_MASK },
375 { "Command-Option", GDK_MOD2_MASK|GDK_MOD1_MASK },
376 { "Command-Control", GDK_MOD2_MASK|GDK_CONTROL_MASK },
377 { "Command-Option-Control", GDK_MOD2_MASK|GDK_MOD1_MASK|GDK_CONTROL_MASK },
378 { "Option-Control", GDK_MOD1_MASK|GDK_CONTROL_MASK },
379 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
380 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
381 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_MOD2_MASK },
384 { "Key|Shift", GDK_SHIFT_MASK },
385 { "Control", GDK_CONTROL_MASK },
386 { "Alt", GDK_MOD1_MASK },
387 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
388 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
389 { "Control-Windows", GDK_CONTROL_MASK|GDK_MOD4_MASK },
390 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
391 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
392 { "Alt-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
393 { "Alt-Shift-Windows", GDK_MOD1_MASK|GDK_SHIFT_MASK|GDK_MOD4_MASK },
394 { "Mod2", GDK_MOD2_MASK },
395 { "Mod3", GDK_MOD3_MASK },
396 { "Windows", GDK_MOD4_MASK },
397 { "Mod5", GDK_MOD5_MASK },
403 class KeyboardOptions : public OptionEditorMiniPage
407 : _delete_button_adjustment (3, 1, 12)
408 , _delete_button_spin (_delete_button_adjustment)
409 , _edit_button_adjustment (3, 1, 5)
410 , _edit_button_spin (_edit_button_adjustment)
411 , _insert_note_button_adjustment (3, 1, 5)
412 , _insert_note_button_spin (_insert_note_button_adjustment)
414 // TODO get rid of GTK -> use OptionEditor Widgets
416 const std::string restart_msg = _("\nChanges to this setting will only persist after your project has been saved.");
417 /* internationalize and prepare for use with combos */
420 for (int i = 0; modifiers[i].name; ++i) {
421 dumb.push_back (S_(modifiers[i].name));
424 set_popdown_strings (_edit_modifier_combo, dumb);
425 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
426 Gtkmm2ext::UI::instance()->set_tip (_edit_modifier_combo,
427 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
434 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
435 l->set_name ("OptionsLabel");
439 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
440 strs.push_back (bf->first);
443 set_popdown_strings (_keyboard_layout_selector, strs);
444 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
445 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
447 t->attach (*l, col + 1, col + 2, row, row + 1, FILL, FILL);
448 t->attach (_keyboard_layout_selector, col + 2, col + 3, row, row + 1, FILL | EXPAND, FILL);
453 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Clicking:"))));
454 l->set_name ("OptionEditorHeading");
455 l->set_use_markup (true);
456 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
461 l = manage (left_aligned_label (_("Edit using:")));
462 l->set_name ("OptionsLabel");
464 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
465 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
467 l = manage (new Label (_("+ button")));
468 l->set_name ("OptionsLabel");
470 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
471 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, SHRINK , FILL);
473 _edit_button_spin.set_name ("OptionsEntry");
474 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
479 set_popdown_strings (_delete_modifier_combo, dumb);
480 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
481 Gtkmm2ext::UI::instance()->set_tip (_delete_modifier_combo,
482 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
484 l = manage (left_aligned_label (_("Delete using:")));
485 l->set_name ("OptionsLabel");
487 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
488 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
490 l = manage (new Label (_("+ button")));
491 l->set_name ("OptionsLabel");
493 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
494 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, SHRINK, FILL);
496 _delete_button_spin.set_name ("OptionsEntry");
497 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
502 set_popdown_strings (_insert_note_modifier_combo, dumb);
503 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
504 Gtkmm2ext::UI::instance()->set_tip (_insert_note_modifier_combo,
505 (string_compose (_("<b>Recommended Setting: %1 + button 1 (left mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
507 l = manage (left_aligned_label (_("Insert note using:")));
508 l->set_name ("OptionsLabel");
510 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
511 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
513 l = manage (new Label (_("+ button")));
514 l->set_name ("OptionsLabel");
516 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
517 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, SHRINK, FILL);
519 _insert_note_button_spin.set_name ("OptionsEntry");
520 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
524 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Beginning a Drag:"))));
525 l->set_name ("OptionEditorHeading");
526 l->set_use_markup (true);
527 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
533 set_popdown_strings (_copy_modifier_combo, dumb);
534 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
535 Gtkmm2ext::UI::instance()->set_tip (_copy_modifier_combo,
536 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
538 Keyboard::secondary_modifier_name (),
540 Keyboard::primary_modifier_name (),
544 l = manage (left_aligned_label (_("Copy items using:")));
545 l->set_name ("OptionsLabel");
547 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
548 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
553 /* constraint modifier */
554 set_popdown_strings (_constraint_modifier_combo, dumb);
555 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
556 Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo,
557 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
559 Keyboard::primary_modifier_name (),
561 Keyboard::tertiary_modifier_name (),
565 l = manage (left_aligned_label (_("Constrain drag using:")));
566 l->set_name ("OptionsLabel");
568 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
569 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
575 set_popdown_strings (_push_points_combo, dumb);
576 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
578 std::string mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
579 Gtkmm2ext::UI::instance()->set_tip (_push_points_combo,
580 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
582 l = manage (left_aligned_label (_("Push points using:")));
583 l->set_name ("OptionsLabel");
585 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
586 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
590 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Beginning a Trim:"))));
591 l->set_name ("OptionEditorHeading");
592 l->set_use_markup (true);
593 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
599 set_popdown_strings (_trim_contents_combo, dumb);
600 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
601 Gtkmm2ext::UI::instance()->set_tip (_trim_contents_combo,
602 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
604 l = manage (left_aligned_label (_("Trim contents using:")));
605 l->set_name ("OptionsLabel");
607 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
608 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
614 set_popdown_strings (_trim_anchored_combo, dumb);
615 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
617 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::tertiary_modifier_name ());
618 Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo,
619 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
621 l = manage (left_aligned_label (_("Anchored trim using:")));
622 l->set_name ("OptionsLabel");
624 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
626 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
631 /* jump trim disabled for now
632 set_popdown_strings (_trim_jump_combo, dumb);
633 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
635 l = manage (left_aligned_label (_("Jump after trim using:")));
636 l->set_name ("OptionsLabel");
638 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
640 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
646 /* note resize relative */
647 set_popdown_strings (_note_size_relative_combo, dumb);
648 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
649 Gtkmm2ext::UI::instance()->set_tip (_note_size_relative_combo,
650 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg))); // XXX 2ndary
652 l = manage (left_aligned_label (_("Resize notes relatively using:")));
653 l->set_name ("OptionsLabel");
655 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
657 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
661 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Dragging:"))));
662 l->set_name ("OptionEditorHeading");
663 l->set_use_markup (true);
664 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
670 set_popdown_strings (_snap_modifier_combo, dumb);
671 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
673 mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ());
675 mod_str = Keyboard::secondary_modifier_name();
677 Gtkmm2ext::UI::instance()->set_tip (_snap_modifier_combo,
678 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
680 l = manage (left_aligned_label (_("Ignore snap using:")));
681 l->set_name ("OptionsLabel");
683 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
684 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
690 set_popdown_strings (_snap_delta_combo, dumb);
691 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
693 mod_str = Keyboard::level4_modifier_name ();
695 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::level4_modifier_name ());
697 Gtkmm2ext::UI::instance()->set_tip (_snap_delta_combo,
698 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
700 l = manage (left_aligned_label (_("Snap relatively using:")));
701 l->set_name ("OptionsLabel");
703 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
704 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
708 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Trimming:"))));
709 l->set_name ("OptionEditorHeading");
710 l->set_use_markup (true);
711 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
717 set_popdown_strings (_trim_overlap_combo, dumb);
718 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
720 Gtkmm2ext::UI::instance()->set_tip (_trim_overlap_combo,
721 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
723 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
724 l->set_name ("OptionsLabel");
726 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
727 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
731 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Dragging Control Points:"))));
732 l->set_name ("OptionEditorHeading");
733 l->set_use_markup (true);
734 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
740 set_popdown_strings (_fine_adjust_combo, dumb);
741 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
743 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::secondary_modifier_name ()); // XXX just 2ndary ?!
744 Gtkmm2ext::UI::instance()->set_tip (_fine_adjust_combo,
745 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
747 l = manage (left_aligned_label (_("Fine adjust using:")));
748 l->set_name ("OptionsLabel");
750 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
751 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
753 OptionEditorHeading* h = new OptionEditorHeading (_("Reset"));
754 h->add_to_page (this);
756 RcActionButton* rb = new RcActionButton (_("Reset to recommended defaults"),
757 sigc::mem_fun (*this, &KeyboardOptions::reset_to_defaults));
758 rb->add_to_page (this);
760 set_state_from_config ();
763 void parameter_changed (string const &)
765 /* XXX: these aren't really config options... */
768 void set_state_from_config ()
770 _delete_button_adjustment.set_value (Keyboard::delete_button());
771 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
772 _edit_button_adjustment.set_value (Keyboard::edit_button());
774 for (int x = 0; modifiers[x].name; ++x) {
775 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
776 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
778 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
779 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
781 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
782 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
784 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
785 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
787 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
788 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
790 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
791 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
793 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
794 _push_points_combo.set_active_text (S_(modifiers[x].name));
796 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
797 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
799 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
800 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
803 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
804 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
807 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
808 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
810 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
811 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
813 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
814 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
816 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
817 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
822 void add_to_page (OptionEditorPage* p)
824 int const n = p->table.property_n_rows();
825 p->table.resize (n + 1, 3);
826 p->table.attach (box, 1, 3, n, n + 1, FILL | EXPAND, SHRINK, 0, 0);
831 void bindings_changed ()
833 string const txt = _keyboard_layout_selector.get_active_text();
835 /* XXX: config...? for all this keyboard stuff */
837 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
838 if (txt == i->first) {
839 if (Keyboard::load_keybindings (i->second)) {
840 Keyboard::save_keybindings ();
846 void edit_modifier_chosen ()
848 string const txt = _edit_modifier_combo.get_active_text();
850 for (int i = 0; modifiers[i].name; ++i) {
851 if (txt == S_(modifiers[i].name)) {
852 Keyboard::set_edit_modifier (modifiers[i].modifier);
858 void delete_modifier_chosen ()
860 string const txt = _delete_modifier_combo.get_active_text();
862 for (int i = 0; modifiers[i].name; ++i) {
863 if (txt == S_(modifiers[i].name)) {
864 Keyboard::set_delete_modifier (modifiers[i].modifier);
870 void copy_modifier_chosen ()
872 string const txt = _copy_modifier_combo.get_active_text();
874 for (int i = 0; modifiers[i].name; ++i) {
875 if (txt == S_(modifiers[i].name)) {
876 Keyboard::set_copy_modifier (modifiers[i].modifier);
882 void insert_note_modifier_chosen ()
884 string const txt = _insert_note_modifier_combo.get_active_text();
886 for (int i = 0; modifiers[i].name; ++i) {
887 if (txt == S_(modifiers[i].name)) {
888 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
894 void snap_modifier_chosen ()
896 string const txt = _snap_modifier_combo.get_active_text();
898 for (int i = 0; modifiers[i].name; ++i) {
899 if (txt == S_(modifiers[i].name)) {
900 Keyboard::set_snap_modifier (modifiers[i].modifier);
906 void snap_delta_modifier_chosen ()
908 string const txt = _snap_delta_combo.get_active_text();
910 for (int i = 0; modifiers[i].name; ++i) {
911 if (txt == S_(modifiers[i].name)) {
912 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
918 void constraint_modifier_chosen ()
920 string const txt = _constraint_modifier_combo.get_active_text();
922 for (int i = 0; modifiers[i].name; ++i) {
923 if (txt == S_(modifiers[i].name)) {
924 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
930 void trim_contents_modifier_chosen ()
932 string const txt = _trim_contents_combo.get_active_text();
934 for (int i = 0; modifiers[i].name; ++i) {
935 if (txt == S_(modifiers[i].name)) {
936 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
942 void trim_overlap_modifier_chosen ()
944 string const txt = _trim_overlap_combo.get_active_text();
946 for (int i = 0; modifiers[i].name; ++i) {
947 if (txt == S_(modifiers[i].name)) {
948 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
954 void trim_anchored_modifier_chosen ()
956 string const txt = _trim_anchored_combo.get_active_text();
958 for (int i = 0; modifiers[i].name; ++i) {
959 if (txt == S_(modifiers[i].name)) {
960 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
966 void fine_adjust_modifier_chosen ()
968 string const txt = _fine_adjust_combo.get_active_text();
970 for (int i = 0; modifiers[i].name; ++i) {
971 if (txt == S_(modifiers[i].name)) {
972 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
978 void push_points_modifier_chosen ()
980 string const txt = _push_points_combo.get_active_text();
982 for (int i = 0; modifiers[i].name; ++i) {
983 if (txt == S_(modifiers[i].name)) {
984 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
990 void note_size_relative_modifier_chosen ()
992 string const txt = _note_size_relative_combo.get_active_text();
994 for (int i = 0; modifiers[i].name; ++i) {
995 if (txt == S_(modifiers[i].name)) {
996 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
1002 void delete_button_changed ()
1004 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
1007 void edit_button_changed ()
1009 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
1012 void insert_note_button_changed ()
1014 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
1017 void reset_to_defaults ()
1020 Keyboard::set_edit_modifier (Keyboard::PrimaryModifier);
1021 Keyboard::set_edit_button (3);
1022 Keyboard::set_delete_modifier (Keyboard::TertiaryModifier);
1023 Keyboard::set_delete_button (3);
1024 Keyboard::set_insert_note_modifier (Keyboard::PrimaryModifier);
1025 Keyboard::set_insert_note_button (1);
1027 /* when beginning a drag */
1029 Keyboard::set_copy_modifier (Keyboard::SecondaryModifier);
1031 Keyboard::set_copy_modifier (Keyboard::PrimaryModifier);
1035 ArdourKeyboard::set_constraint_modifier (Keyboard::PrimaryModifier);
1037 ArdourKeyboard::set_constraint_modifier (Keyboard::TertiaryModifier);
1039 ArdourKeyboard::set_push_points_modifier (Keyboard::PrimaryModifier | Keyboard::Level4Modifier);
1041 /* when beginning a trim */
1042 ArdourKeyboard::set_trim_contents_modifier (Keyboard::PrimaryModifier);
1043 ArdourKeyboard::set_trim_anchored_modifier (Keyboard::PrimaryModifier | Keyboard::TertiaryModifier);
1044 ArdourKeyboard::set_note_size_relative_modifier (Keyboard::TertiaryModifier); // XXX better: 2ndary
1046 /* while dragging */
1048 Keyboard::set_snap_modifier (Keyboard::TertiaryModifier);
1050 Keyboard::set_snap_modifier (Keyboard::SecondaryModifier);
1053 Keyboard::set_snap_delta_modifier (Keyboard::Level4Modifier);
1055 Keyboard::set_snap_delta_modifier (Keyboard::SecondaryModifier | Keyboard::Level4Modifier);
1058 /* while trimming */
1059 ArdourKeyboard::set_trim_overlap_modifier (Keyboard::TertiaryModifier);
1061 /* while dragging ctrl points */
1062 ArdourKeyboard::set_fine_adjust_modifier (/*Keyboard::PrimaryModifier | */Keyboard::SecondaryModifier); // XXX
1064 set_state_from_config ();
1067 ComboBoxText _keyboard_layout_selector;
1068 ComboBoxText _edit_modifier_combo;
1069 ComboBoxText _delete_modifier_combo;
1070 ComboBoxText _copy_modifier_combo;
1071 ComboBoxText _insert_note_modifier_combo;
1072 ComboBoxText _snap_modifier_combo;
1073 ComboBoxText _snap_delta_combo;
1074 ComboBoxText _constraint_modifier_combo;
1075 ComboBoxText _trim_contents_combo;
1076 ComboBoxText _trim_overlap_combo;
1077 ComboBoxText _trim_anchored_combo;
1078 ComboBoxText _trim_jump_combo;
1079 ComboBoxText _fine_adjust_combo;
1080 ComboBoxText _push_points_combo;
1081 ComboBoxText _note_size_relative_combo;
1082 Adjustment _delete_button_adjustment;
1083 SpinButton _delete_button_spin;
1084 Adjustment _edit_button_adjustment;
1085 SpinButton _edit_button_spin;
1086 Adjustment _insert_note_button_adjustment;
1087 SpinButton _insert_note_button_spin;
1091 class FontScalingOptions : public HSliderOption
1094 FontScalingOptions ()
1095 : HSliderOption ("font-scale", _("GUI and Font scaling"),
1096 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_font_scale),
1097 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_font_scale),
1101 const std::string dflt = _("100%");
1102 const std::string empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
1104 _hscale.set_name("FontScaleSlider");
1105 _hscale.set_draw_value(false);
1106 _hscale.add_mark(50, Gtk::POS_TOP, empty);
1107 _hscale.add_mark(60, Gtk::POS_TOP, empty);
1108 _hscale.add_mark(70, Gtk::POS_TOP, empty);
1109 _hscale.add_mark(80, Gtk::POS_TOP, empty);
1110 _hscale.add_mark(90, Gtk::POS_TOP, empty);
1111 _hscale.add_mark(100, Gtk::POS_TOP, dflt);
1112 _hscale.add_mark(125, Gtk::POS_TOP, empty);
1113 _hscale.add_mark(150, Gtk::POS_TOP, empty);
1114 _hscale.add_mark(175, Gtk::POS_TOP, empty);
1115 _hscale.add_mark(200, Gtk::POS_TOP, empty);
1116 _hscale.add_mark(250, Gtk::POS_TOP, empty);
1118 set_note (_("Adjusting the scale requires an application restart to re-layout."));
1123 HSliderOption::changed ();
1124 /* XXX: should be triggered from the parameter changed signal */
1125 UIConfiguration::instance().reset_dpi ();
1129 class VstTimeOutSliderOption : public HSliderOption
1132 VstTimeOutSliderOption (RCConfiguration* c)
1133 : HSliderOption ("vst-scan-timeout", _("Scan Time Out"),
1134 sigc::mem_fun (*c, &RCConfiguration::get_vst_scan_timeout),
1135 sigc::mem_fun (*c, &RCConfiguration::set_vst_scan_timeout),
1138 _label.set_alignment (1.0, 0.5); // match buttons below
1139 _hscale.set_digits (0);
1140 _hscale.set_draw_value(false);
1141 _hscale.add_mark( 0, Gtk::POS_TOP, _("\u221e")); // infinity
1142 _hscale.add_mark( 300, Gtk::POS_TOP, _("30 sec"));
1143 _hscale.add_mark( 600, Gtk::POS_TOP, _("1 min"));
1144 _hscale.add_mark(1200, Gtk::POS_TOP, _("2 mins"));
1145 _hscale.add_mark(1800, Gtk::POS_TOP, _("3 mins"));
1146 _hscale.add_mark(2400, Gtk::POS_TOP, _("4 mins"));
1147 _hscale.add_mark(3000, Gtk::POS_TOP, _("5 mins"));
1149 Gtkmm2ext::UI::instance()->set_tip(_hscale,
1150 _("Specify the default timeout for plugin instantiation. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1154 class ClipLevelOptions : public OptionEditorComponent
1158 : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1159 , _clip_level_slider (_clip_level_adjustment)
1160 , _label (_("Waveform Clip Level (dBFS):"))
1162 _label.set_name ("OptionsLabel");
1164 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ());
1166 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1168 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1171 void parameter_changed (string const & p)
1173 if (p == "waveform-clip-level") {
1174 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level());
1176 if (p == "show-waveform-clipping") {
1177 _clip_level_slider.set_sensitive (UIConfiguration::instance().get_show_waveform_clipping ());
1181 void set_state_from_config ()
1183 parameter_changed ("waveform-clip-level");
1184 parameter_changed ("show-waveform-clipping");
1187 void add_to_page (OptionEditorPage* p) {
1188 add_widgets_to_page (p, &_label, &_clip_level_slider);
1191 Gtk::Widget& tip_widget() {
1192 return _clip_level_slider;
1197 void clip_level_changed ()
1199 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1200 /* XXX: should be triggered from the parameter changed signal */
1201 ArdourWaveView::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1204 Adjustment _clip_level_adjustment;
1205 HScale _clip_level_slider;
1209 class BufferingOptions : public OptionEditorComponent
1212 BufferingOptions (RCConfiguration* c)
1214 , _label (_("Preset:"))
1215 , _playback ("playback-buffer-seconds", _("Playback (seconds of buffering)"),
1216 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_playback_buffer_seconds),
1217 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_playback_buffer_seconds),
1219 , _capture ("capture-buffer-seconds", _("Recording (seconds of buffering)"),
1220 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_capture_buffer_seconds),
1221 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_capture_buffer_seconds),
1224 // TODO use ComboOption
1225 vector<string> presets;
1227 /* these must match the order of the enums for BufferingPreset */
1228 presets.push_back (_("Small sessions (4-16 tracks)"));
1229 presets.push_back (_("Medium sessions (16-64 tracks)"));
1230 presets.push_back (_("Large sessions (64+ tracks)"));
1231 presets.push_back (_("Custom (set by sliders below)"));
1233 set_popdown_strings (_buffering_presets_combo, presets);
1234 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1236 _label.set_name ("OptionsLabel");
1237 _label.set_alignment (0, 0.5);
1241 add_to_page (OptionEditorPage* p)
1243 add_widgets_to_page (p, &_label, &_buffering_presets_combo);
1244 _playback.add_to_page (p);
1245 _capture.add_to_page (p);
1248 void parameter_changed (string const & p)
1250 if (p == "buffering-preset") {
1251 switch (_rc_config->get_buffering_preset()) {
1253 _playback.set_sensitive (false);
1254 _capture.set_sensitive (false);
1255 _buffering_presets_combo.set_active (0);
1258 _playback.set_sensitive (false);
1259 _capture.set_sensitive (false);
1260 _buffering_presets_combo.set_active (1);
1263 _playback.set_sensitive (false);
1264 _capture.set_sensitive (false);
1265 _buffering_presets_combo.set_active (2);
1268 _playback.set_sensitive (true);
1269 _capture.set_sensitive (true);
1270 _buffering_presets_combo.set_active (3);
1274 _playback.parameter_changed (p);
1275 _capture.parameter_changed (p);
1278 void set_state_from_config ()
1280 parameter_changed ("buffering-preset");
1281 _playback.set_state_from_config();
1282 _capture.set_state_from_config();
1285 Gtk::Widget& tip_widget() { return _buffering_presets_combo; }
1289 void preset_changed ()
1291 int index = _buffering_presets_combo.get_active_row_number ();
1297 _rc_config->set_buffering_preset (Small);
1300 _rc_config->set_buffering_preset (Medium);
1303 _rc_config->set_buffering_preset (Large);
1306 _rc_config->set_buffering_preset (Custom);
1309 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1314 RCConfiguration* _rc_config;
1316 HSliderOption _playback;
1317 HSliderOption _capture;
1318 ComboBoxText _buffering_presets_combo;
1321 class ControlSurfacesOptions : public OptionEditorMiniPage
1324 ControlSurfacesOptions ()
1325 : _ignore_view_change (0)
1327 _store = ListStore::create (_model);
1328 _view.set_model (_store);
1329 _view.append_column (_("Control Surface Protocol"), _model.name);
1330 _view.get_column(0)->set_resizable (true);
1331 _view.get_column(0)->set_expand (true);
1332 _view.append_column_editable (_("Enable"), _model.enabled);
1334 Gtk::HBox* edit_box = manage (new Gtk::HBox);
1335 edit_box->set_spacing(3);
1338 Label* label = manage (new Label);
1339 label->set_text (_("Edit the settings for selected protocol (it must be ENABLED first):"));
1340 edit_box->pack_start (*label, false, false);
1343 edit_button = manage (new Button(_("Show Protocol Settings")));
1344 edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
1345 edit_box->pack_start (*edit_button, true, true);
1346 edit_button->set_sensitive (false);
1347 edit_button->show ();
1349 int const n = table.property_n_rows();
1350 table.resize (n + 2, 3);
1351 table.attach (_view, 0, 3, n, n + 1);
1352 table.attach (*edit_box, 0, 3, n + 1, n + 2);
1354 ControlProtocolManager& m = ControlProtocolManager::instance ();
1355 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1356 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1358 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1359 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1360 _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
1363 void parameter_changed (std::string const &)
1368 void set_state_from_config ()
1372 ControlProtocolManager& m = ControlProtocolManager::instance ();
1373 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1375 if (!(*i)->mandatory) {
1376 TreeModel::Row r = *_store->append ();
1377 r[_model.name] = (*i)->name;
1378 r[_model.enabled] = 0 != (*i)->protocol;
1379 r[_model.protocol_info] = *i;
1386 void protocol_status_changed (ControlProtocolInfo* cpi) {
1388 TreeModel::Children rows = _store->children();
1390 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1391 string n = ((*x)[_model.name]);
1393 if ((*x)[_model.protocol_info] == cpi) {
1394 _ignore_view_change++;
1395 (*x)[_model.enabled] = 0 != cpi->protocol;
1396 _ignore_view_change--;
1397 selection_changed (); // update sensitivity
1403 void selection_changed ()
1405 //enable the Edit button when a row is selected for editing
1406 TreeModel::Row row = *(_view.get_selection()->get_selected());
1407 if (row && row[_model.enabled])
1408 edit_button->set_sensitive (true);
1410 edit_button->set_sensitive (false);
1413 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1415 TreeModel::Row r = *i;
1417 if (_ignore_view_change) {
1421 ControlProtocolInfo* cpi = r[_model.protocol_info];
1426 bool const was_enabled = (cpi->protocol != 0);
1427 bool const is_enabled = r[_model.enabled];
1430 if (was_enabled != is_enabled) {
1433 ControlProtocolManager::instance().activate (*cpi);
1435 ControlProtocolManager::instance().deactivate (*cpi);
1439 selection_changed ();
1442 void edit_btn_clicked ()
1445 ControlProtocolInfo* cpi;
1448 row = *(_view.get_selection()->get_selected());
1449 if (!row[_model.enabled]) {
1452 cpi = row[_model.protocol_info];
1453 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1456 Box* box = (Box*) cpi->protocol->get_gui ();
1460 if (box->get_parent()) {
1461 static_cast<ArdourWindow*>(box->get_parent())->present();
1464 WindowTitle title (Glib::get_application_name());
1465 title += row[_model.name];
1466 title += _("Configuration");
1467 /* once created, the window is managed by the surface itself (as ->get_parent())
1468 * Surface's tear_down_gui() is called on session close, when de-activating
1469 * or re-initializing a surface.
1470 * tear_down_gui() hides an deletes the Window if it exists.
1472 ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
1473 win->set_title (_("Control Protocol Settings"));
1479 void edit_clicked (GdkEventButton* ev)
1481 if (ev->type != GDK_2BUTTON_PRESS) {
1488 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1492 ControlSurfacesModelColumns ()
1496 add (protocol_info);
1499 TreeModelColumn<string> name;
1500 TreeModelColumn<bool> enabled;
1501 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1504 Glib::RefPtr<ListStore> _store;
1505 ControlSurfacesModelColumns _model;
1507 PBD::ScopedConnection protocol_status_connection;
1508 uint32_t _ignore_view_change;
1509 Gtk::Button* edit_button;
1512 class VideoTimelineOptions : public OptionEditorMiniPage
1515 VideoTimelineOptions (RCConfiguration* c)
1517 , _show_video_export_info_button (_("Show Video Export Info before export"))
1518 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1519 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1520 , _xjadeo_browse_button (_("Browse..."))
1523 int n = table.property_n_rows();
1525 t->attach (_show_video_export_info_button, 1, 4, n, n + 1);
1526 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1527 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1528 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1531 t->attach (_show_video_server_dialog_button, 1, 4, n, n + 1);
1532 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1533 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1534 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1537 t->attach (_video_advanced_setup_button, 1, 4, n, n + 1, FILL);
1538 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1539 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1540 _("<b>When enabled</b> you can specify a custom video-server URL and docroot. - Do not enable this option unless you know what you are doing."));
1543 Label* l = manage (new Label (_("Video Server URL:")));
1544 l->set_alignment (0, 0.5);
1545 t->attach (*l, 1, 2, n, n + 1, FILL);
1546 t->attach (_video_server_url_entry, 2, 4, n, n + 1, FILL);
1547 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1548 _("Base URL of the video-server including http prefix. This is usually 'http://hostname.example.org:1554/' and defaults to 'http://localhost:1554/' when the video-server is running locally"));
1551 l = manage (new Label (_("Video Folder:")));
1552 l->set_alignment (0, 0.5);
1553 t->attach (*l, 1, 2, n, n + 1, FILL);
1554 t->attach (_video_server_docroot_entry, 2, 4, n, n + 1);
1555 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1556 _("Local path to the video-server document-root. Only files below this directory will be accessible by the video-server. If the server run on a remote host, it should point to a network mounted folder of the server's docroot or be left empty if it is unavailable. It is used for the local video-monitor and file-browsing when opening/adding a video file."));
1559 l = manage (new Label (""));
1560 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1563 l = manage (new Label (string_compose ("<b>%1</b>", _("Video Monitor"))));
1564 l->set_use_markup (true);
1565 l->set_alignment (0, 0.5);
1566 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1569 l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"),
1572 #elif defined PLATFORM_WINDOWS
1578 l->set_alignment (0, 0.5);
1579 t->attach (*l, 1, 4, n, n + 1, FILL);
1582 t->attach (_custom_xjadeo_path, 2, 3, n, n + 1, EXPAND|FILL);
1583 Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart."));
1584 t->attach (_xjadeo_browse_button, 3, 4, n, n + 1, FILL);
1586 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1587 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1588 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1589 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1590 _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed));
1591 _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked));
1593 // xjadeo-path is a UIConfig parameter
1594 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &VideoTimelineOptions::parameter_changed));
1597 void server_url_changed ()
1599 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1602 void server_docroot_changed ()
1604 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1607 void show_video_export_info_toggled ()
1609 bool const x = _show_video_export_info_button.get_active ();
1610 _rc_config->set_show_video_export_info (x);
1613 void show_video_server_dialog_toggled ()
1615 bool const x = _show_video_server_dialog_button.get_active ();
1616 _rc_config->set_show_video_server_dialog (x);
1619 void video_advanced_setup_toggled ()
1621 bool const x = _video_advanced_setup_button.get_active ();
1622 _rc_config->set_video_advanced_setup(x);
1625 void custom_xjadeo_path_changed ()
1627 UIConfiguration::instance().set_xjadeo_binary (_custom_xjadeo_path.get_text());
1630 void xjadeo_browse_clicked ()
1632 Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN);
1633 dialog.set_filename (UIConfiguration::instance().get_xjadeo_binary());
1634 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1635 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1636 if (dialog.run () == Gtk::RESPONSE_OK) {
1637 const std::string& filename = dialog.get_filename();
1638 if (!filename.empty() && (
1640 Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) ||
1642 Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)
1644 UIConfiguration::instance().set_xjadeo_binary (filename);
1649 void parameter_changed (string const & p)
1651 if (p == "video-server-url") {
1652 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1653 } else if (p == "video-server-docroot") {
1654 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1655 } else if (p == "show-video-export-info") {
1656 bool const x = _rc_config->get_show_video_export_info();
1657 _show_video_export_info_button.set_active (x);
1658 } else if (p == "show-video-server-dialog") {
1659 bool const x = _rc_config->get_show_video_server_dialog();
1660 _show_video_server_dialog_button.set_active (x);
1661 } else if (p == "video-advanced-setup") {
1662 bool const x = _rc_config->get_video_advanced_setup();
1663 _video_advanced_setup_button.set_active(x);
1664 _video_server_docroot_entry.set_sensitive(x);
1665 _video_server_url_entry.set_sensitive(x);
1666 } else if (p == "xjadeo-binary") {
1667 _custom_xjadeo_path.set_text (UIConfiguration::instance().get_xjadeo_binary());
1671 void set_state_from_config ()
1673 parameter_changed ("video-server-url");
1674 parameter_changed ("video-server-docroot");
1675 parameter_changed ("video-monitor-setup-dialog");
1676 parameter_changed ("show-video-export-info");
1677 parameter_changed ("show-video-server-dialog");
1678 parameter_changed ("video-advanced-setup");
1679 parameter_changed ("xjadeo-binary");
1683 RCConfiguration* _rc_config;
1684 Entry _video_server_url_entry;
1685 Entry _video_server_docroot_entry;
1686 Entry _custom_xjadeo_path;
1687 CheckButton _show_video_export_info_button;
1688 CheckButton _show_video_server_dialog_button;
1689 CheckButton _video_advanced_setup_button;
1690 Button _xjadeo_browse_button;
1693 class ColumVisibilityOption : public Option
1696 ColumVisibilityOption (string id, string name, uint32_t n_col, sigc::slot<uint32_t> get, sigc::slot<bool, uint32_t> set)
1703 cb = (CheckButton**) malloc (sizeof (CheckButton*) * n_col);
1704 for (uint32_t i = 0; i < n_col; ++i) {
1705 CheckButton* col = manage (new CheckButton (string_compose (_("Column %1"), i + 1)));
1706 col->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ColumVisibilityOption::column_toggled), i));
1707 _hbox.pack_start (*col);
1710 parameter_changed (id);
1713 ~ColumVisibilityOption () {
1717 Gtk::Widget& tip_widget() { return _hbox; }
1719 void set_state_from_config ()
1721 uint32_t c = _get();
1722 for (uint32_t i = 0; i < _n_col; ++i) {
1723 bool en = (c & (1<<i)) ? true : false;
1724 if (cb[i]->get_active () != en) {
1725 cb[i]->set_active (en);
1730 void add_to_page (OptionEditorPage* p)
1732 _heading.add_to_page (p);
1733 add_widget_to_page (p, &_hbox);
1737 void column_toggled (int b) {
1738 uint32_t c = _get();
1740 if (cb[b]->get_active ()) {
1751 OptionEditorHeading _heading;
1755 sigc::slot<uint32_t> _get;
1756 sigc::slot<bool, uint32_t> _set;
1760 /** A class which allows control of visibility of some editor components usign
1761 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1762 * which has the correct members, but with null widget pointers. This
1763 * class allows the user to set visibility of the members, the details
1764 * of which are stored in a configuration variable which can be watched
1765 * by parts of the editor that actually contain the widgets whose visibility
1766 * is being controlled.
1769 class VisibilityOption : public Option
1772 /** @param name User-visible name for this group.
1773 * @param g `Dummy' VisibilityGroup (as described above).
1774 * @param get Method to get the value of the appropriate configuration variable.
1775 * @param set Method to set the value of the appropriate configuration variable.
1777 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1778 : Option (g->get_state_name(), name)
1780 , _visibility_group (g)
1784 /* Watch for changes made by the user to our members */
1785 _visibility_group->VisibilityChanged.connect_same_thread (
1786 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1790 void set_state_from_config ()
1792 /* Set our state from the current configuration */
1793 _visibility_group->set_state (_get ());
1796 void add_to_page (OptionEditorPage* p)
1798 _heading.add_to_page (p);
1799 add_widget_to_page (p, _visibility_group->list_view ());
1802 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1807 /* The user has changed something, so reflect this change
1808 in the RCConfiguration.
1810 _set (_visibility_group->get_state_value ());
1813 OptionEditorHeading _heading;
1814 VisibilityGroup* _visibility_group;
1815 sigc::slot<std::string> _get;
1816 sigc::slot<bool, std::string> _set;
1817 PBD::ScopedConnection _visibility_group_connection;
1821 class MidiPortOptions : public OptionEditorMiniPage, public sigc::trackable
1826 setup_midi_port_view (midi_output_view, false);
1827 setup_midi_port_view (midi_input_view, true);
1829 OptionEditorHeading* h = new OptionEditorHeading (_("MIDI Inputs"));
1830 h->add_to_page (this);
1832 Gtk::ScrolledWindow* scroller = manage (new Gtk::ScrolledWindow);
1833 scroller->add (midi_input_view);
1834 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1835 scroller->set_size_request (-1, 180);
1837 int n = table.property_n_rows();
1838 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1840 h = new OptionEditorHeading (_("MIDI Outputs"));
1841 h->add_to_page (this);
1843 scroller = manage (new Gtk::ScrolledWindow);
1844 scroller->add (midi_output_view);
1845 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1846 scroller->set_size_request (-1, 180);
1848 n = table.property_n_rows();
1849 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1851 midi_output_view.show ();
1852 midi_input_view.show ();
1854 table.signal_show().connect (sigc::mem_fun (*this, &MidiPortOptions::on_show));
1857 void parameter_changed (string const&) {}
1858 void set_state_from_config() {}
1863 AudioEngine::instance()->PortRegisteredOrUnregistered.connect (connections,
1864 invalidator (*this),
1865 boost::bind (&MidiPortOptions::refill, this),
1867 AudioEngine::instance()->MidiPortInfoChanged.connect (connections,
1868 invalidator (*this),
1869 boost::bind (&MidiPortOptions::refill, this),
1871 AudioEngine::instance()->MidiSelectionPortsChanged.connect (connections,
1872 invalidator (*this),
1873 boost::bind (&MidiPortOptions::refill, this),
1879 if (refill_midi_ports (true, midi_input_view)) {
1880 input_label.show ();
1882 input_label.hide ();
1884 if (refill_midi_ports (false, midi_output_view)) {
1885 output_label.show ();
1887 output_label.hide ();
1892 PBD::ScopedConnectionList connections;
1894 /* MIDI port management */
1895 struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord {
1897 MidiPortColumns () {
1906 Gtk::TreeModelColumn<std::string> pretty_name;
1907 Gtk::TreeModelColumn<bool> music_data;
1908 Gtk::TreeModelColumn<bool> control_data;
1909 Gtk::TreeModelColumn<bool> selection;
1910 Gtk::TreeModelColumn<std::string> name;
1911 Gtk::TreeModelColumn<std::string> filler;
1914 MidiPortColumns midi_port_columns;
1915 Gtk::TreeView midi_input_view;
1916 Gtk::TreeView midi_output_view;
1917 Gtk::Label input_label;
1918 Gtk::Label output_label;
1920 void setup_midi_port_view (Gtk::TreeView&, bool with_selection);
1921 bool refill_midi_ports (bool for_input, Gtk::TreeView&);
1922 void pretty_name_edit (std::string const & path, std::string const & new_text, Gtk::TreeView*);
1923 void midi_music_column_toggled (std::string const & path, Gtk::TreeView*);
1924 void midi_control_column_toggled (std::string const & path, Gtk::TreeView*);
1925 void midi_selection_column_toggled (std::string const & path, Gtk::TreeView*);
1929 MidiPortOptions::setup_midi_port_view (Gtk::TreeView& view, bool with_selection)
1931 int pretty_name_column;
1934 int selection_column;
1935 TreeViewColumn* col;
1938 pretty_name_column = view.append_column_editable (_("Name (click to edit)"), midi_port_columns.pretty_name) - 1;
1940 col = manage (new TreeViewColumn ("", midi_port_columns.music_data));
1941 col->set_alignment (ALIGN_CENTER);
1942 l = manage (new Label (_("Music Data")));
1943 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of music performance data."), PROGRAM_NAME));
1944 col->set_widget (*l);
1946 music_column = view.append_column (*col) - 1;
1948 col = manage (new TreeViewColumn ("", midi_port_columns.control_data));
1949 col->set_alignment (ALIGN_CENTER);
1950 l = manage (new Label (_("Control Data")));
1951 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of control data."), PROGRAM_NAME));
1952 col->set_widget (*l);
1954 control_column = view.append_column (*col) - 1;
1956 if (with_selection) {
1957 col = manage (new TreeViewColumn (_("Follow Selection"), midi_port_columns.selection));
1958 selection_column = view.append_column (*col) - 1;
1959 l = manage (new Label (_("Follow Selection")));
1960 set_tooltip (*l, string_compose (_("If ticked, and \"MIDI input follows selection\" is enabled,\n%1 will automatically connect the first selected MIDI track to this port.\n"), PROGRAM_NAME));
1961 col->set_widget (*l);
1965 /* filler column so that the last real column doesn't expand */
1966 view.append_column ("", midi_port_columns.filler);
1968 CellRendererText* pretty_name_cell = dynamic_cast<CellRendererText*> (view.get_column_cell_renderer (pretty_name_column));
1969 pretty_name_cell->property_editable() = true;
1970 pretty_name_cell->signal_edited().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::pretty_name_edit), &view));
1972 CellRendererToggle* toggle_cell;
1974 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (music_column));
1975 toggle_cell->property_activatable() = true;
1976 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_music_column_toggled), &view));
1978 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (control_column));
1979 toggle_cell->property_activatable() = true;
1980 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_control_column_toggled), &view));
1982 if (with_selection) {
1983 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (selection_column));
1984 toggle_cell->property_activatable() = true;
1985 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_selection_column_toggled), &view));
1988 view.get_selection()->set_mode (SELECTION_NONE);
1989 view.set_tooltip_column (4); /* port "real" name */
1990 view.get_column(0)->set_resizable (true);
1991 view.get_column(0)->set_expand (true);
1995 MidiPortOptions::refill_midi_ports (bool for_input, Gtk::TreeView& view)
1997 using namespace ARDOUR;
1999 std::vector<string> ports;
2001 AudioEngine::instance()->get_known_midi_ports (ports);
2003 if (ports.empty()) {
2008 Glib::RefPtr<ListStore> model = Gtk::ListStore::create (midi_port_columns);
2010 for (vector<string>::const_iterator s = ports.begin(); s != ports.end(); ++s) {
2012 if (AudioEngine::instance()->port_is_mine (*s)) {
2016 PortManager::MidiPortInformation mpi (AudioEngine::instance()->midi_port_information (*s));
2018 if (mpi.pretty_name.empty()) {
2019 /* vanished since get_known_midi_ports() */
2023 if (for_input != mpi.input) {
2027 TreeModel::Row row = *(model->append());
2029 row[midi_port_columns.pretty_name] = mpi.pretty_name;
2030 row[midi_port_columns.music_data] = mpi.properties & MidiPortMusic;
2031 row[midi_port_columns.control_data] = mpi.properties & MidiPortControl;
2032 row[midi_port_columns.selection] = mpi.properties & MidiPortSelection;
2033 row[midi_port_columns.name] = *s;
2036 view.set_model (model);
2042 MidiPortOptions::midi_music_column_toggled (string const & path, TreeView* view)
2044 TreeIter iter = view->get_model()->get_iter (path);
2050 bool new_value = ! bool ((*iter)[midi_port_columns.music_data]);
2052 /* don't reset model - wait for MidiPortInfoChanged signal */
2055 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2057 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2062 MidiPortOptions::midi_control_column_toggled (string const & path, TreeView* view)
2064 TreeIter iter = view->get_model()->get_iter (path);
2070 bool new_value = ! bool ((*iter)[midi_port_columns.control_data]);
2072 /* don't reset model - wait for MidiPortInfoChanged signal */
2075 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2077 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2082 MidiPortOptions::midi_selection_column_toggled (string const & path, TreeView* view)
2084 TreeIter iter = view->get_model()->get_iter (path);
2090 bool new_value = ! bool ((*iter)[midi_port_columns.selection]);
2092 /* don't reset model - wait for MidiSelectionPortsChanged signal */
2095 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2097 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2102 MidiPortOptions::pretty_name_edit (std::string const & path, string const & new_text, Gtk::TreeView* view)
2104 TreeIter iter = view->get_model()->get_iter (path);
2110 boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
2112 ARDOUR::PortEngine::PortHandle ph = backend->get_port_by_name ((*iter)[midi_port_columns.name]);
2114 backend->set_port_property (ph, "http://jackaudio.org/metadata/pretty-name", new_text, "");
2115 (*iter)[midi_port_columns.pretty_name] = new_text;
2123 RCOptionEditor::RCOptionEditor ()
2124 : OptionEditorContainer (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
2125 , Tabbable (*this, _("Preferences")
2127 , false // detached by default (first start, no instant.xml)
2129 ) /* pack self-as-vbox into tabbable */
2130 , _rc_config (Config)
2131 , _mixer_strip_visibility ("mixer-element-visibility")
2133 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
2137 uint32_t hwcpus = hardware_concurrency ();
2139 BoolComboOption* bco;
2142 add_option (_("General"), new OptionEditorHeading (_("DSP CPU Utilization")));
2144 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
2146 _("Signal processing uses"),
2147 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
2148 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
2151 procs->add (-1, _("all but one processor"));
2152 procs->add (0, _("all available processors"));
2154 for (uint32_t i = 1; i <= hwcpus; ++i) {
2155 procs->add (i, string_compose (P_("%1 processor", "%1 processors", i), i));
2158 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
2160 add_option (_("General"), procs);
2163 /* Image cache size */
2164 add_option (_("General"), new OptionEditorHeading (_("Memory Usage")));
2166 HSliderOption *sics = new HSliderOption ("waveform-cache-size",
2167 _("Waveform image cache size (megabytes)"),
2168 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
2169 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size),
2170 1, 1024, 10 /* 1 MB to 1GB in steps of 10MB */
2172 sics->scale().set_digits (0);
2173 Gtkmm2ext::UI::instance()->set_tip (
2175 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
2176 add_option (_("General"), sics);
2178 add_option (_("General"), new OptionEditorHeading (_("Engine")));
2180 add_option (_("General"),
2182 "try-autostart-engine",
2183 _("Try to auto-launch audio/midi engine"),
2184 sigc::mem_fun (*_rc_config, &RCConfiguration::get_try_autostart_engine),
2185 sigc::mem_fun (*_rc_config, &RCConfiguration::set_try_autostart_engine)
2188 add_option (_("General"), new OptionEditorHeading (_("Automation")));
2190 add_option (_("General"),
2191 new SpinOption<double> (
2192 "automation-thinning-factor",
2193 _("Thinning factor (larger value => less data)"),
2194 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
2195 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
2199 add_option (_("General"),
2200 new SpinOption<double> (
2201 "automation-interval-msecs",
2202 _("Automation sampling interval (milliseconds)"),
2203 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
2204 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
2208 add_option (_("General"), new OptionEditorHeading (_("Tempo")));
2210 bo = new BoolOption (
2211 "allow-non-quarter-pulse",
2212 _("Allow non quarter-note pulse"),
2213 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_allow_non_quarter_pulse),
2214 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_allow_non_quarter_pulse)
2216 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2217 string_compose (_("<b>When enabled</b> %1 will allow tempo to be expressed in divisions per minute\n"
2218 "<b>When disabled</b> %1 will only allow tempo to be expressed in quarter notes per minute"),
2220 add_option (_("General"), bo);
2222 if (!ARDOUR::Profile->get_mixbus()) {
2223 add_option (_("General"), new OptionEditorHeading (_("GUI Lock")));
2224 /* Lock GUI timeout */
2226 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2227 _("Lock timeout (seconds)"),
2228 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
2229 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds),
2232 slts->scale().set_digits (0);
2233 Gtkmm2ext::UI::instance()->set_tip (
2235 _("Lock GUI after this many idle seconds (zero to never lock)"));
2236 add_option (_("General"), slts);
2239 add_option (_("General/Session"), new OptionEditorHeading (S_("Options|Undo")));
2241 add_option (_("General/Session"), new UndoOptions (_rc_config));
2243 add_option (_("General/Session"),
2245 "verify-remove-last-capture",
2246 _("Verify removal of last capture"),
2247 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
2248 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
2251 add_option (_("General/Session"), new OptionEditorHeading (_("Session Management")));
2253 add_option (_("General/Session"),
2255 "periodic-safety-backups",
2256 _("Make periodic backups of the session file"),
2257 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
2258 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
2261 add_option (_("General/Session"),
2263 "only-copy-imported-files",
2264 _("Always copy imported files"),
2265 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
2266 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
2269 add_option (_("General/Session"), new DirectoryOption (
2270 X_("default-session-parent-dir"),
2271 _("Default folder for new sessions:"),
2272 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
2273 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
2276 add_option (_("General/Session"),
2277 new SpinOption<uint32_t> (
2278 "max-recent-sessions",
2279 _("Maximum number of recent sessions"),
2280 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
2281 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
2288 add_option (_("General/Translation"), new OptionEditorHeading (_("Internationalization")));
2290 bo = new BoolOption (
2291 "enable-translation",
2292 _("Use translations"),
2293 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2294 sigc::ptr_fun (ARDOUR::set_translations_enabled)
2297 bo->set_note (string_compose (_("These settings will only take effect after %1 is restarted (if available for your language preferences)."), PROGRAM_NAME));
2299 add_option (_("General/Translation"), bo);
2301 parameter_changed ("enable-translation");
2302 #endif // ENABLE_NLS
2307 add_option (_("Editor"), new OptionEditorHeading (_("General")));
2309 add_option (_("Editor"),
2311 "rubberbanding-snaps-to-grid",
2312 _("Snap rubberband to grid"),
2313 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2314 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2317 bo = new BoolOption (
2319 _("Prompt for new marker names"),
2320 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2321 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2323 add_option (_("Editor"), bo);
2324 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(), _("If enabled, popup a dialog when a new marker is created to allow its name to be set as it is created."
2325 "\n\nYou can always rename markers by right-clicking on them"));
2327 add_option (_("Editor"),
2329 "draggable-playhead",
2330 _("Allow dragging of playhead"),
2331 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2332 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2335 ComboOption<float>* dps = new ComboOption<float> (
2336 "draggable-playhead-speed",
2337 _("Playhead dragging speed (%)"),
2338 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead_speed),
2339 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead_speed)
2341 dps->add (0.05, _("5%"));
2342 dps->add (0.1, _("10%"));
2343 dps->add (0.25, _("25%"));
2344 dps->add (0.5, _("50%"));
2345 dps->add (1.0, _("100%"));
2346 add_option (_("Editor"), dps);
2348 ComboOption<float>* eet = new ComboOption<float> (
2349 "extra-ui-extents-time",
2350 _("Limit zooming & summary view to X minutes beyond session extents"),
2351 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_extra_ui_extents_time),
2352 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_extra_ui_extents_time)
2354 eet->add (1, _("1 minute"));
2355 eet->add (2, _("2 minutes"));
2356 eet->add (20, _("20 minutes"));
2357 eet->add (60, _("1 hour"));
2358 add_option (_("Editor"), eet);
2360 if (!Profile->get_mixbus()) {
2362 add_option (_("Editor"),
2364 "use-mouse-position-as-zoom-focus-on-scroll",
2365 _("Zoom to mouse position when zooming with scroll wheel"),
2366 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2367 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2371 add_option (_("Editor"),
2373 "use-time-rulers-to-zoom-with-vertical-drag",
2374 _("Zoom with vertical drag in rulers"),
2375 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag),
2376 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag)
2379 add_option (_("Editor"),
2381 "use-double-click-to-zoom-to-selection",
2382 _("Double click zooms to selection"),
2383 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection),
2384 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection)
2387 add_option (_("Editor"),
2389 "update-editor-during-summary-drag",
2390 _("Update editor window during drags of the summary"),
2391 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2392 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2395 add_option (_("Editor"),
2397 "autoscroll-editor",
2398 _("Auto-scroll editor window when dragging near its edges"),
2399 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2400 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2403 add_option (_("Editor"),
2404 new BoolComboOption (
2405 "show-region-gain-envelopes",
2406 _("Show gain envelopes in audio regions"),
2408 _("only in Draw and Internal Edit modes"),
2409 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2410 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2413 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2415 add_option (_("Editor"),
2417 "automation-follows-regions",
2418 _("Move relevant automation when audio regions are moved"),
2419 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2420 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2423 bo = new BoolOption (
2424 "new-automation-points-on-lane",
2425 _("Ignore Y-axis click position when adding new automation-points"),
2426 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_new_automation_points_on_lane),
2427 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_new_automation_points_on_lane)
2429 add_option (_("Editor"), bo);
2430 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2431 _("<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."));
2433 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2434 "default-fade-shape",
2435 _("Default fade shape"),
2436 sigc::mem_fun (*_rc_config,
2437 &RCConfiguration::get_default_fade_shape),
2438 sigc::mem_fun (*_rc_config,
2439 &RCConfiguration::set_default_fade_shape)
2442 fadeshape->add (FadeLinear,
2443 _("Linear (for highly correlated material)"));
2444 fadeshape->add (FadeConstantPower, _("Constant power"));
2445 fadeshape->add (FadeSymmetric, _("Symmetric"));
2446 fadeshape->add (FadeSlow, _("Slow"));
2447 fadeshape->add (FadeFast, _("Fast"));
2449 add_option (_("Editor"), fadeshape);
2451 bco = new BoolComboOption (
2452 "use-overlap-equivalency",
2453 _("Regions in edit groups are edited together"),
2454 _("whenever they overlap in time"),
2455 _("only if they have identical length and position"),
2456 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2457 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2460 add_option (_("Editor"), bco);
2462 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2464 _("Layering model"),
2465 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2466 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2469 lm->add (LaterHigher, _("later is higher"));
2470 lm->add (Manual, _("manual layering"));
2471 add_option (_("Editor"), lm);
2473 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2474 "region-selection-after-split",
2475 _("After splitting selected regions, select"),
2476 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2477 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2479 // TODO: decide which of these modes are really useful
2480 rsas->add(None, _("no regions"));
2481 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2482 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2483 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2484 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2485 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2486 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2487 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2489 add_option (_("Editor"), rsas);
2491 add_option (_("Editor/Modifiers"), new OptionEditorHeading (_("Keyboard Modifiers")));
2492 add_option (_("Editor/Modifiers"), new KeyboardOptions);
2493 add_option (_("Editor/Modifiers"), new OptionEditorBlank ());
2495 /* MIXER -- SOLO AND MUTE */
2497 add_option (_("Mixer"), new OptionEditorHeading (_("Solo")));
2499 _solo_control_is_listen_control = new BoolOption (
2500 "solo-control-is-listen-control",
2501 _("Solo controls are Listen controls"),
2502 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2503 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2506 add_option (_("Mixer"), _solo_control_is_listen_control);
2508 add_option (_("Mixer"),
2511 _("Exclusive solo"),
2512 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2513 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2516 add_option (_("Mixer"),
2519 _("Show solo muting"),
2520 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2521 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2524 add_option (_("Mixer"),
2526 "solo-mute-override",
2527 _("Soloing overrides muting"),
2528 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2529 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2532 add_option (_("Mixer"),
2535 _("Solo-in-place mute cut (dB)"),
2536 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2537 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2540 _listen_position = new ComboOption<ListenPosition> (
2542 _("Listen Position"),
2543 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2544 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2547 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2548 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2550 add_option (_("Mixer"), _listen_position);
2552 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2554 _("PFL signals come from"),
2555 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2556 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2559 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2560 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2562 add_option (_("Mixer"), pp);
2564 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2566 _("AFL signals come from"),
2567 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2568 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2571 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2572 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2574 add_option (_("Mixer"), pa);
2576 add_option (_("Mixer"), new OptionEditorHeading (_("Default Track / Bus Muting Options")));
2578 add_option (_("Mixer"),
2580 "mute-affects-pre-fader",
2581 _("Mute affects pre-fader sends"),
2582 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2583 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2586 add_option (_("Mixer"),
2588 "mute-affects-post-fader",
2589 _("Mute affects post-fader sends"),
2590 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2591 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2594 add_option (_("Mixer"),
2596 "mute-affects-control-outs",
2597 _("Mute affects control outputs"),
2598 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2599 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2602 add_option (_("Mixer"),
2604 "mute-affects-main-outs",
2605 _("Mute affects main outputs"),
2606 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2607 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2611 if (!ARDOUR::Profile->get_mixbus()) {
2612 add_option (_("Mixer"), new OptionEditorHeading (_("Send Routing")));
2613 add_option (_("Mixer"),
2615 "link-send-and-route-panner",
2616 _("Link panners of Aux and External Sends with main panner by default"),
2617 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2618 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2624 add_option (_("Signal Flow"), new OptionEditorHeading (_("Monitoring")));
2626 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2628 _("Record monitoring handled by"),
2629 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2630 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2633 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2634 mm->add (HardwareMonitoring, _("via Audio Driver"));
2637 string prog (PROGRAM_NAME);
2638 boost::algorithm::to_lower (prog);
2639 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2640 mm->add (ExternalMonitoring, _("audio hardware"));
2642 add_option (_("Signal Flow"), mm);
2644 bo = new BoolOption (
2645 "tape-machine-mode",
2646 _("Tape machine mode"),
2647 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2648 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2650 add_option (_("Signal Flow"), bo);
2651 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2652 string_compose (_("<b>When enabled</b> %1 will not monitor a track's input if the transport is stopped."),
2655 if (!Profile->get_mixbus()) {
2657 add_option (_("Signal Flow"), new OptionEditorHeading (_("Track and Bus Connections")));
2659 add_option (_("Signal Flow"),
2661 "auto-connect-standard-busses",
2662 _("Auto-connect master/monitor busses"),
2663 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2664 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2667 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2668 "input-auto-connect",
2669 _("Connect track inputs"),
2670 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2671 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2674 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2675 iac->add (ManualConnect, _("manually"));
2677 add_option (_("Signal Flow"), iac);
2679 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2680 "output-auto-connect",
2681 _("Connect track and bus outputs"),
2682 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2683 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2686 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2687 oac->add (AutoConnectMaster, _("automatically to master bus"));
2688 oac->add (ManualConnect, _("manually"));
2690 add_option (_("Signal Flow"), oac);
2692 bo = new BoolOption (
2694 _("Use 'Strict-I/O' for new tracks or busses"),
2695 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2696 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2699 add_option (_("Signal Flow"), bo);
2700 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2701 _("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."));
2708 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2710 add_option (_("Audio"), new BufferingOptions (_rc_config));
2712 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2714 add_option (_("Audio"),
2716 "denormal-protection",
2717 _("Use DC bias to protect against denormals"),
2718 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2719 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2722 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2724 _("Processor handling"),
2725 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2726 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2730 dm->add (DenormalNone, _("no processor handling"));
2732 FPU* fpu = FPU::instance();
2734 if (fpu->has_flush_to_zero()) {
2736 dm->add (DenormalFTZ, _("use FlushToZero"));
2737 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2738 _rc_config->set_denormal_model(DenormalNone);
2741 if (fpu->has_denormals_are_zero()) {
2743 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2744 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2745 _rc_config->set_denormal_model(DenormalNone);
2748 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2750 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2751 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2752 _rc_config->set_denormal_model(DenormalNone);
2756 dm->set_sensitive(false);
2759 add_option (_("Audio"), dm);
2761 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2763 add_option (_("Audio"),
2765 "auto-analyse-audio",
2766 _("Enable automatic analysis of audio"),
2767 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2768 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2771 add_option (_("Audio"),
2773 "replicate-missing-region-channels",
2774 _("Replicate missing region channels"),
2775 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2776 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2781 add_option (_("MIDI"), new OptionEditorHeading (_("Buffering")));
2783 add_option (_("MIDI"),
2784 new SpinOption<float> (
2786 _("MIDI read-ahead time (seconds)"),
2787 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2788 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2793 add_option (_("MIDI"), new OptionEditorHeading (_("Session")));
2795 add_option (_("MIDI"),
2796 new SpinOption<int32_t> (
2797 "initial-program-change",
2798 _("Initial program change"),
2799 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2800 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2804 add_option (_("MIDI"), new OptionEditorHeading (_("Audition")));
2806 add_option (_("MIDI"),
2809 _("Sound MIDI notes as they are selected in the editor"),
2810 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2811 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2814 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2815 "midi-audition-synth-uri",
2816 _("MIDI Audition Synth (LV2)"),
2817 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2818 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2821 audition_synth->add(X_(""), _("None"));
2822 PluginInfoList all_plugs;
2823 PluginManager& manager (PluginManager::instance());
2825 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2827 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2828 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2829 if (!(*i)->is_instrument()) continue;
2830 if ((*i)->type != ARDOUR::LV2) continue;
2831 if ((*i)->name.length() > 46) {
2832 audition_synth->add((*i)->unique_id, (*i)->name.substr (0, 44) + "...");
2834 audition_synth->add((*i)->unique_id, (*i)->name);
2839 add_option (_("MIDI"), audition_synth);
2843 add_option (_("Metronome"), new OptionEditorHeading (_("Metronome")));
2844 add_option (_("Metronome"), new ClickOptions (_rc_config));
2845 add_option (_("Metronome"), new OptionEditorHeading (_("Options")));
2847 bo = new BoolOption (
2848 "click-record-only",
2849 _("Enable metronome only while recording"),
2850 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_record_only),
2851 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_record_only)
2854 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2855 string_compose (_("<b>When enabled</b> the metronome will remain silent if %1 is <b>not recording</b>."), PROGRAM_NAME));
2856 add_option (_("Metronome"), bo);
2857 add_option (_("Metronome"), new OptionEditorBlank ());
2862 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2864 ComboOption<float>* mht = new ComboOption<float> (
2866 _("Peak hold time"),
2867 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
2868 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
2871 mht->add (MeterHoldOff, _("off"));
2872 mht->add (MeterHoldShort, _("short"));
2873 mht->add (MeterHoldMedium, _("medium"));
2874 mht->add (MeterHoldLong, _("long"));
2876 add_option (S_("Preferences|Metering"), mht);
2878 ComboOption<float>* mfo = new ComboOption<float> (
2881 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2882 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2885 mfo->add (METER_FALLOFF_OFF, _("off"));
2886 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2887 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2888 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2889 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2890 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2891 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
2893 add_option (S_("Preferences|Metering"), mfo);
2895 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2896 "meter-line-up-level",
2897 _("Meter line-up level; 0dBu"),
2898 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
2899 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
2902 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2903 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2904 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2905 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2907 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."));
2909 add_option (S_("Preferences|Metering"), mlu);
2911 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2912 "meter-line-up-din",
2913 _("IEC1/DIN Meter line-up level; 0dBu"),
2914 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
2915 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
2918 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2919 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2920 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2921 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2923 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2925 add_option (S_("Preferences|Metering"), mld);
2927 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2928 "meter-vu-standard",
2929 _("VU Meter standard"),
2930 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
2931 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
2934 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2935 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2936 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2937 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2939 add_option (S_("Preferences|Metering"), mvu);
2941 HSliderOption *mpks = new HSliderOption("meter-peak",
2942 _("Peak indicator threshold [dBFS]"),
2943 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
2944 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak),
2948 Gtkmm2ext::UI::instance()->set_tip (
2950 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
2952 add_option (S_("Preferences|Metering"), mpks);
2954 OptionEditorHeading* default_meter_head = new OptionEditorHeading (_("Default Meter Types"));
2955 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."));
2957 add_option (S_("Preferences|Metering"), default_meter_head);
2959 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
2960 "meter-type-master",
2961 _("Default Meter Type for Master Bus"),
2962 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
2963 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
2965 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2966 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2967 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2968 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2969 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2970 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2971 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2972 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
2974 add_option (S_("Preferences|Metering"), mtm);
2977 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
2979 _("Default meter type for busses"),
2980 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
2981 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
2983 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2984 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2985 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2986 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2987 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2988 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2989 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2990 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
2992 add_option (S_("Preferences|Metering"), mtb);
2994 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
2996 _("Default meter type for tracks"),
2997 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
2998 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3000 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3001 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3003 add_option (S_("Preferences|Metering"), mtt);
3005 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
3007 add_option (S_("Preferences|Metering"),
3009 "save-export-analysis-image",
3010 _("Save loudness analysis as image file"),
3011 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
3012 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
3015 /* TRANSPORT & Sync */
3017 add_option (_("Transport"), new OptionEditorHeading (_("General")));
3019 bo = new BoolOption (
3020 "stop-at-session-end",
3021 _("Stop at the end of the session"),
3022 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
3023 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
3025 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3026 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
3027 "when it reaches the current session end marker\n\n"
3028 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
3030 add_option (_("Transport"), bo);
3032 bo = new BoolOption (
3033 "latched-record-enable",
3034 _("Keep record-enable engaged on stop"),
3035 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
3036 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
3038 add_option (_("Transport"), bo);
3039 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3040 _("<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."));
3042 bo = new BoolOption (
3043 "disable-disarm-during-roll",
3044 _("Disable per-track record disarm while rolling"),
3045 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
3046 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
3048 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."));
3049 add_option (_("Transport"), bo);
3051 bo = new BoolOption (
3053 _("12dB gain reduction during fast-forward and fast-rewind"),
3054 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
3055 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
3057 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3058 _("<b>When enabled</b> this will reduce the unpleasant increase in perceived volume "
3059 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
3060 add_option (_("Transport"), bo);
3062 ComboOption<float>* psc = new ComboOption<float> (
3065 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
3066 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
3068 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
3069 (_("The amount of preroll to apply when <b>Play with Preroll</b> or <b>Record with Preroll</b>is initiated.\n\n"
3070 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
3071 psc->add (-4.0, _("4 Bars"));
3072 psc->add (-2.0, _("2 Bars"));
3073 psc->add (-1.0, _("1 Bar"));
3074 psc->add (0.0, _("0 (no pre-roll)"));
3075 psc->add (0.1, _("0.1 second"));
3076 psc->add (0.25, _("0.25 second"));
3077 psc->add (0.5, _("0.5 second"));
3078 psc->add (1.0, _("1.0 second"));
3079 psc->add (2.0, _("2.0 seconds"));
3080 add_option (_("Transport"), psc);
3083 add_option (_("Transport"), new OptionEditorHeading (_("Looping")));
3085 bo = new BoolOption (
3087 _("Play loop is a transport mode"),
3088 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
3089 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
3091 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3092 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
3093 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
3094 add_option (_("Transport"), bo);
3096 bo = new BoolOption (
3098 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
3099 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
3100 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
3102 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3103 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
3104 "preventing any need to do a transport locate at the end of the loop\n\n"
3105 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
3106 "which will often cause a small click or delay"), PROGRAM_NAME));
3107 add_option (_("Transport"), bo);
3109 add_option (_("Transport"), new OptionEditorHeading (_("Dropout (xrun) Handling")));
3110 bo = new BoolOption (
3111 "stop-recording-on-xrun",
3112 _("Stop recording when an xrun occurs"),
3113 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
3114 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
3116 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3117 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
3119 add_option (_("Transport"), bo);
3121 bo = new BoolOption (
3122 "create-xrun-marker",
3123 _("Create markers where xruns occur"),
3124 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
3125 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
3127 add_option (_("Transport"), bo);
3132 add_option (_("Sync"), new OptionEditorHeading (_("External Synchronization")));
3134 _sync_source = new ComboOption<SyncSource> (
3136 _("External timecode source"),
3137 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
3138 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
3141 add_option (_("Sync"), _sync_source);
3143 _sync_framerate = new BoolOption (
3144 "timecode-sync-frame-rate",
3145 _("Match session video frame rate to external timecode"),
3146 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
3147 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
3149 Gtkmm2ext::UI::instance()->set_tip
3150 (_sync_framerate->tip_widget(),
3151 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
3152 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
3153 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
3154 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
3155 "timecode standard and the session standard."), PROGRAM_NAME));
3157 add_option (_("Sync"), _sync_framerate);
3159 _sync_genlock = new BoolOption (
3160 "timecode-source-is-synced",
3161 _("Sync-lock timecode to clock (disable drift compensation)"),
3162 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
3163 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
3165 Gtkmm2ext::UI::instance()->set_tip
3166 (_sync_genlock->tip_widget(),
3167 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
3168 "Sync Lock indicates that the selected external timecode source shares clock-sync "
3169 "(Black & Burst, Wordclock, etc) with the audio interface. "
3170 "This option disables drift compensation. The transport speed is fixed at 1.0. "
3171 "Vari-speed LTC will be ignored and cause drift."
3173 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
3174 "timecode sources shares clock sync."
3178 add_option (_("Sync"), _sync_genlock);
3180 _sync_source_2997 = new BoolOption (
3181 "timecode-source-2997",
3182 _("Lock to 29.9700 fps instead of 30000/1001"),
3183 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
3184 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
3186 Gtkmm2ext::UI::instance()->set_tip
3187 (_sync_source_2997->tip_widget(),
3188 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
3189 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
3190 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
3191 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
3192 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
3193 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
3196 add_option (_("Sync"), _sync_source_2997);
3198 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Reader")));
3200 _ltc_port = new ComboStringOption (
3202 _("LTC incoming port"),
3203 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
3204 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
3207 vector<string> physical_inputs;
3208 physical_inputs.push_back (_("None"));
3209 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
3210 _ltc_port->set_popdown_strings (physical_inputs);
3212 populate_sync_options ();
3213 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
3215 add_option (_("Sync/LTC"), _ltc_port);
3217 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Generator")));
3219 add_option (_("Sync/LTC"),
3222 _("Enable LTC generator"),
3223 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
3224 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
3227 _ltc_send_continuously = new BoolOption (
3228 "ltc-send-continuously",
3229 _("Send LTC while stopped"),
3230 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
3231 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
3233 Gtkmm2ext::UI::instance()->set_tip
3234 (_ltc_send_continuously->tip_widget(),
3235 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
3236 add_option (_("Sync/LTC"), _ltc_send_continuously);
3238 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level [dBFS]"),
3239 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_output_volume),
3240 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_output_volume),
3244 Gtkmm2ext::UI::instance()->set_tip
3245 (_ltc_volume_slider->tip_widget(),
3246 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
3248 add_option (_("Sync/LTC"), _ltc_volume_slider);
3251 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Beat Clock (Mclk) Generator")));
3253 add_option (_("Sync/MIDI"),
3256 _("Enable Mclk generator"),
3257 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
3258 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
3261 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC) Generator")));
3263 add_option (_("Sync/MIDI"),
3266 _("Enable MTC Generator"),
3267 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
3268 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
3271 add_option (_("Sync/MIDI"),
3272 new SpinOption<int> (
3273 "mtc-qf-speed-tolerance",
3274 _("Percentage either side of normal transport speed to transmit MTC"),
3275 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
3276 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
3280 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Machine Control (MMC)")));
3282 add_option (_("Sync/MIDI"),
3285 _("Respond to MMC commands"),
3286 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
3287 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
3290 add_option (_("Sync/MIDI"),
3293 _("Send MMC commands"),
3294 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
3295 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
3298 add_option (_("Sync/MIDI"),
3299 new SpinOption<uint8_t> (
3300 "mmc-receive-device-id",
3301 _("Inbound MMC device ID"),
3302 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
3303 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
3307 add_option (_("Sync/MIDI"),
3308 new SpinOption<uint8_t> (
3309 "mmc-send-device-id",
3310 _("Outbound MMC device ID"),
3311 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
3312 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
3317 /* Control Surfaces */
3319 add_option (_("Control Surfaces"), new OptionEditorHeading (_("Control Surfaces")));
3320 add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
3323 add_option (_("MIDI Ports"), new OptionEditorHeading (_("MIDI Port Options")));
3325 add_option (_("MIDI Ports"),
3327 "get-midi-input-follows-selection",
3328 _("MIDI input follows MIDI track selection"),
3329 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
3330 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
3333 add_option (_("MIDI Ports"), new MidiPortOptions ());
3334 add_option (_("MIDI Ports"), new OptionEditorBlank ());
3338 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3339 add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
3340 add_option (_("Plugins"),
3341 new RcActionButton (_("Scan for Plugins"),
3342 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3346 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
3348 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3349 bo = new BoolOption (
3350 "show-plugin-scan-window",
3351 _("Always Display Plugin Scan Progress"),
3352 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
3353 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
3355 add_option (_("Plugins"), bo);
3356 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3357 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
3360 bo = new BoolOption (
3361 "plugins-stop-with-transport",
3362 _("Silence plugins when the transport is stopped"),
3363 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
3364 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
3366 add_option (_("Plugins"), bo);
3367 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3368 _("<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."));
3370 bo = new BoolOption (
3371 "new-plugins-active",
3372 _("Make new plugins active"),
3373 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
3374 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
3376 add_option (_("Plugins"), bo);
3377 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3378 _("<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"));
3380 #if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
3381 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
3383 add_option (_("Plugins/VST"),
3384 new RcActionButton (_("Scan for Plugins"),
3385 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3388 #if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
3389 bo = new BoolOption (
3391 _("Enable Mac VST support (requires restart or re-scan)"),
3392 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
3393 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
3395 add_option (_("Plugins/VST"), bo);
3398 bo = new BoolOption (
3399 "discover-vst-on-start",
3400 _("Scan for [new] VST Plugins on Application Start"),
3401 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
3402 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
3404 add_option (_("Plugins/VST"), bo);
3405 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3406 _("<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"));
3408 #ifdef WINDOWS_VST_SUPPORT
3409 // currently verbose logging is only implemented for Windows VST.
3410 bo = new BoolOption (
3411 "verbose-plugin-scan",
3412 _("Verbose Plugin Scan"),
3413 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
3414 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
3416 add_option (_("Plugins/VST"), bo);
3417 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3418 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
3421 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
3423 add_option (_("Plugins/VST"),
3424 new RcActionButton (_("Clear"),
3425 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
3428 add_option (_("Plugins/VST"),
3429 new RcActionButton (_("Clear"),
3430 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
3431 _("VST Blacklist:")));
3434 #ifdef LXVST_SUPPORT
3435 add_option (_("Plugins/VST"),
3436 new RcActionButton (_("Edit"),
3437 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
3438 _("Linux VST Path:")));
3440 add_option (_("Plugins/VST"),
3441 new RcConfigDisplay (
3442 "plugin-path-lxvst",
3444 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
3448 #ifdef WINDOWS_VST_SUPPORT
3449 add_option (_("Plugins/VST"),
3450 new RcActionButton (_("Edit"),
3451 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
3452 _("Windows VST Path:")));
3453 add_option (_("Plugins/VST"),
3454 new RcConfigDisplay (
3457 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
3461 #ifdef AUDIOUNIT_SUPPORT
3463 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
3465 add_option (_("Plugins/Audio Unit"),
3466 new RcActionButton (_("Scan for Plugins"),
3467 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3470 bo = new BoolOption (
3471 "discover-audio-units",
3472 _("Scan for [new] AudioUnit Plugins on Application Start"),
3473 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
3474 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
3476 add_option (_("Plugins/Audio Unit"), bo);
3477 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3478 _("<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."));
3480 add_option (_("Plugins/Audio Unit"),
3481 new RcActionButton (_("Clear"),
3482 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
3485 add_option (_("Plugins/Audio Unit"),
3486 new RcActionButton (_("Clear"),
3487 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
3488 _("AU Blacklist:")));
3491 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
3492 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
3493 add_option (_("Plugins"),
3495 "open-gui-after-adding-plugin",
3496 _("Automatically open the plugin GUI when adding a new plugin"),
3497 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
3498 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3501 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3502 add_option (_("Plugins"),
3504 "show-inline-display-by-default",
3505 _("Show Plugin Inline Display on Mixerstrip by default"),
3506 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3507 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3510 _plugin_prefer_inline = new BoolOption (
3511 "prefer-inline-over-gui",
3512 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3513 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3514 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3516 add_option (_("Plugins"), _plugin_prefer_inline);
3519 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3521 bo = new BoolOption (
3522 "ask-replace-instrument",
3523 _("Ask to replace existing instrument plugin"),
3524 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3525 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3527 add_option (_("Plugins"), bo);
3529 bo = new BoolOption (
3530 "ask-setup_instrument",
3531 _("Interactively configure instrument plugins on insert"),
3532 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3533 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3535 add_option (_("Plugins"), bo);
3536 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3537 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3540 add_option (_("Plugins"), new OptionEditorBlank ());
3543 #if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
3544 add_option (_("Appearance"), new OptionEditorHeading (_("Graphics Acceleration")));
3547 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3548 BoolOption* bgc = new BoolOption (
3549 "cairo-image-surface",
3550 _("Disable Graphics Hardware Acceleration (requires restart)"),
3551 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3552 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3555 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3556 _("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));
3557 add_option (_("Appearance"), bgc);
3560 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3561 BoolOption* bgo = new BoolOption (
3563 _("Possibly improve slow graphical performance (requires restart)"),
3564 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3565 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3568 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));
3569 add_option (_("Appearance"), bgo);
3571 add_option (_("Appearance"), new OptionEditorHeading (_("Graphical User Interface")));
3573 add_option (_("Appearance"),
3576 _("Highlight widgets on mouseover"),
3577 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3578 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3581 add_option (_("Appearance"),
3584 _("Show tooltips if mouse hovers over a control"),
3585 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3586 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3589 bo = new BoolOption (
3590 "super-rapid-clock-update",
3591 _("Update clocks at TC Frame rate"),
3592 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3593 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3595 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3596 _("<b>When enabled</b> clock displays are updated every Timecode Frame (fps).\n\n"
3597 "<b>When disabled</b> clock displays are updated only every 100ms."
3599 add_option (_("Appearance"), bo);
3601 add_option (_("Appearance"),
3604 _("Blink Rec-Arm buttons"),
3605 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_rec_arm),
3606 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_rec_arm)
3609 add_option (_("Appearance"),
3611 "blink-alert-indicators",
3612 _("Blink Alert Indicators"),
3613 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_alert_indicators),
3614 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_alert_indicators)
3619 /* font scaling does nothing with GDK/Quartz */
3620 add_option (_("Appearance"), new FontScalingOptions ());
3622 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("General")));
3623 add_option (_("Appearance/Editor"),
3625 "show-name-highlight",
3626 _("Use name highlight bars in region displays (requires a restart)"),
3627 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3628 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3631 add_option (_("Appearance/Editor"),
3633 "color-regions-using-track-color",
3634 _("Region color follows track color"),
3635 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_color_regions_using_track_color),
3636 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_color_regions_using_track_color)
3639 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Waveforms")));
3641 if (!Profile->get_mixbus()) {
3642 add_option (_("Appearance/Editor"),
3645 _("Show waveforms in regions"),
3646 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
3647 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
3651 add_option (_("Appearance/Editor"),
3653 "show-waveforms-while-recording",
3654 _("Show waveforms while recording"),
3655 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
3656 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
3659 add_option (_("Appearance/Editor"),
3661 "show-waveform-clipping",
3662 _("Show waveform clipping"),
3663 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveform_clipping),
3664 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveform_clipping)
3667 add_option (_("Appearance/Editor"), new ClipLevelOptions ());
3669 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
3671 _("Waveform scale"),
3672 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
3673 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
3676 wfs->add (Linear, _("linear"));
3677 wfs->add (Logarithmic, _("logarithmic"));
3679 add_option (_("Appearance/Editor"), wfs);
3681 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
3683 _("Waveform shape"),
3684 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
3685 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
3688 wfsh->add (Traditional, _("traditional"));
3689 wfsh->add (Rectified, _("rectified"));
3691 add_option (_("Appearance/Editor"), wfsh);
3693 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Editor Meters")));
3695 add_option (_("Appearance/Editor"),
3697 "show-track-meters",
3698 _("Show meters in track headers"),
3699 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3700 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3703 add_option (_("Appearance/Editor"),
3705 "editor-stereo-only-meters",
3706 _("Limit track header meters to stereo"),
3707 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3708 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3711 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("MIDI Regions")));
3713 add_option (_("Appearance/Editor"),
3715 "display-first-midi-bank-as-zero",
3716 _("Display first MIDI bank/program as 0"),
3717 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
3718 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
3721 add_option (_("Appearance/Editor"),
3723 "never-display-periodic-midi",
3724 _("Don't display periodic (MTC, MMC) SysEx messages in MIDI Regions"),
3725 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
3726 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
3729 add_option (_("Appearance/Editor"), new OptionEditorBlank ());
3731 /* The names of these controls must be the same as those given in MixerStrip
3732 for the actual widgets being controlled.
3734 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3735 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3736 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3737 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3738 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3739 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3740 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3742 add_option (_("Appearance/Mixer"),
3743 new VisibilityOption (
3745 &_mixer_strip_visibility,
3746 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3747 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3751 add_option (_("Appearance/Mixer"),
3753 "default-narrow_ms",
3754 _("Use narrow strips in the mixer for new strips by default"),
3755 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3756 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3759 add_option (_("Appearance/Mixer"), new OptionEditorBlank ());
3761 add_option (_("Appearance/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items")));
3763 add_option (_("Appearance/Toolbar"),
3765 "show-toolbar-recpunch",
3766 _("Display Record/Punch Options"),
3767 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_recpunch),
3768 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_recpunch)
3771 add_option (_("Appearance/Toolbar"),
3773 "show-toolbar-monitoring",
3774 _("Display Monitor Options"),
3775 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_monitoring),
3776 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_monitoring)
3779 add_option (_("Appearance/Toolbar"),
3781 "show-toolbar-selclock",
3782 _("Display Selection Clock"),
3783 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
3784 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
3787 if (!ARDOUR::Profile->get_small_screen()) {
3788 add_option (_("Appearance/Toolbar"),
3790 "show-secondary-clock",
3791 _("Display Secondary Clock"),
3792 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
3793 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
3797 add_option (_("Appearance/Toolbar"),
3799 "show-mini-timeline",
3800 _("Display Navigation Timeline"),
3801 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
3802 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
3805 add_option (_("Appearance/Toolbar"),
3807 "show-editor-meter",
3808 _("Display Master Level Meter"),
3809 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
3810 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
3813 add_option (_("Appearance/Toolbar"),
3814 new ColumVisibilityOption (
3815 "action-table-columns", _("Lua Action Script Button Visibility"), 4,
3816 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3817 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3820 add_option (_("Appearance/Toolbar"), new OptionEditorBlank ());
3823 /* and now the theme manager */
3825 add_option (_("Appearance/Theme"), new OptionEditorHeading (_("Theme")));
3827 add_option (_("Appearance/Theme"), new BoolOption (
3829 _("Draw \"flat\" buttons"),
3830 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_flat_buttons),
3831 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_flat_buttons)
3834 add_option (_("Appearance/Theme"), new BoolOption (
3836 _("LED meter style"),
3837 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3838 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3842 HSliderOption *gui_hs = new HSliderOption(
3843 "timeline-item-gradient-depth",
3844 _("Waveforms color gradient depth"),
3845 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_gradient_depth),
3846 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_gradient_depth),
3849 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3850 add_option (_("Appearance/Theme"), gui_hs);
3852 gui_hs = new HSliderOption(
3853 "timeline-item-gradient-depth",
3854 _("Timeline item gradient depth"),
3855 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_timeline_item_gradient_depth),
3856 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_timeline_item_gradient_depth),
3859 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3860 add_option (_("Appearance/Theme"), gui_hs);
3862 vector<string> icon_sets = ::get_icon_sets ();
3863 if (icon_sets.size() > 1) {
3864 ComboOption<std::string>* io = new ComboOption<std::string> (
3865 "icon-set", _("Icon Set"),
3866 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_icon_set),
3867 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_icon_set)
3869 for (vector<string>::const_iterator i = icon_sets.begin (); i != icon_sets.end (); ++i) {
3872 add_option (_("Appearance/Theme"), io);
3875 add_option (_("Appearance/Colors"), new OptionEditorHeading (_("Colors")));
3876 add_option (_("Appearance/Colors"), new ColorThemeManager);
3877 add_option (_("Appearance/Colors"), new OptionEditorBlank ());
3881 OptionEditorHeading* quirks_head = new OptionEditorHeading (_("Various Workarounds for Windowing Systems"));
3883 quirks_head->set_note (string_compose (_("Rules for closing, minimizing, maximizing, and stay-on-top can vary\
3884 with each version of your OS, and the preferences that you've set in your OS.\n\n\
3885 You can adjust the options, below, to change how %1's windows and dialogs behave.\n\n\
3886 These settings will only take effect after %1 is restarted.\n\
3889 add_option (_("Appearance/Quirks"), quirks_head);
3891 bo = new BoolOption (
3892 "use-wm-visibility",
3893 _("Use visibility information provided by your Window Manager/Desktop"),
3894 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3895 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3897 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3898 _("If you have trouble toggling between hidden Editor and Mixer windows, try changing this setting."));
3899 add_option (_("Appearance/Quirks"), bo);
3902 bo = new BoolOption (
3903 "all-floating-windows-are-dialogs",
3904 _("All floating windows are dialogs"),
3905 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_all_floating_windows_are_dialogs),
3906 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_all_floating_windows_are_dialogs)
3908 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3909 _("Mark all floating windows to be type \"Dialog\" rather than using \"Utility\" for some.\nThis may help with some window managers."));
3910 add_option (_("Appearance/Quirks"), bo);
3912 bo = new BoolOption (
3913 "transients-follow-front",
3914 _("Transient windows follow front window."),
3915 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_transients_follow_front),
3916 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_transients_follow_front)
3918 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3919 _("Make transient windows follow the front window when toggling between the editor and mixer."));
3920 add_option (_("Appearance/Quirks"), bo);
3923 if (!Profile->get_mixbus()) {
3924 bo = new BoolOption (
3925 "floating-monitor-section",
3926 _("Float detached monitor-section window"),
3927 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_floating_monitor_section),
3928 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_floating_monitor_section)
3930 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3931 _("When detaching the monitoring section, mark it as \"Utility\" window to stay in front."));
3932 add_option (_("Appearance/Quirks"), bo);
3935 add_option (_("Appearance/Quirks"), new OptionEditorBlank ());
3937 /* VIDEO Timeline */
3938 add_option (_("Video"), new OptionEditorHeading (_("Video Server")));
3939 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
3941 Widget::show_all ();
3943 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3944 parameter_changed ("send-ltc");
3945 parameter_changed ("sync-source");
3946 parameter_changed ("use-monitor-bus");
3947 parameter_changed ("open-gui-after-adding-plugin");
3949 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
3951 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
3952 (Gtk::StateType) here !!!
3954 Tabbable::set_state (*node, Stateful::loading_state_version);
3957 set_current_page (_("General"));
3961 RCOptionEditor::parameter_changed (string const & p)
3963 OptionEditor::parameter_changed (p);
3965 if (p == "use-monitor-bus") {
3966 bool const s = Config->get_use_monitor_bus ();
3968 /* we can't use this if we don't have a monitor bus */
3969 Config->set_solo_control_is_listen_control (false);
3971 _solo_control_is_listen_control->set_sensitive (s);
3972 _listen_position->set_sensitive (s);
3973 } else if (p == "sync-source") {
3974 _sync_source->set_sensitive (true);
3976 _sync_source->set_sensitive (!_session->config.get_external_sync());
3978 switch(Config->get_sync_source()) {
3981 _sync_genlock->set_sensitive (true);
3982 _sync_framerate->set_sensitive (true);
3983 _sync_source_2997->set_sensitive (true);
3986 _sync_genlock->set_sensitive (false);
3987 _sync_framerate->set_sensitive (false);
3988 _sync_source_2997->set_sensitive (false);
3991 } else if (p == "send-ltc") {
3992 bool const s = Config->get_send_ltc ();
3993 _ltc_send_continuously->set_sensitive (s);
3994 _ltc_volume_slider->set_sensitive (s);
3995 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
3996 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3997 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
4002 void RCOptionEditor::plugin_scan_refresh () {
4003 PluginManager::instance().refresh();
4006 void RCOptionEditor::clear_vst_cache () {
4007 PluginManager::instance().clear_vst_cache();
4010 void RCOptionEditor::clear_vst_blacklist () {
4011 PluginManager::instance().clear_vst_blacklist();
4014 void RCOptionEditor::clear_au_cache () {
4015 PluginManager::instance().clear_au_cache();
4018 void RCOptionEditor::clear_au_blacklist () {
4019 PluginManager::instance().clear_au_blacklist();
4022 void RCOptionEditor::edit_lxvst_path () {
4023 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
4024 PathsDialog *pd = new PathsDialog (
4025 *current_toplevel(), _("Set Linux VST Search Path"),
4026 _rc_config->get_plugin_path_lxvst(),
4027 PluginManager::instance().get_default_lxvst_path()
4029 ResponseType r = (ResponseType) pd->run ();
4031 if (r == RESPONSE_ACCEPT) {
4032 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
4034 MessageDialog msg (_("Re-scan Plugins now?"),
4035 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
4036 msg.set_default_response (Gtk::RESPONSE_YES);
4037 if (msg.run() == Gtk::RESPONSE_YES) {
4039 plugin_scan_refresh ();
4045 void RCOptionEditor::edit_vst_path () {
4046 PathsDialog *pd = new PathsDialog (
4047 *current_toplevel(), _("Set Windows VST Search Path"),
4048 _rc_config->get_plugin_path_vst(),
4049 PluginManager::instance().get_default_windows_vst_path()
4051 ResponseType r = (ResponseType) pd->run ();
4053 if (r == RESPONSE_ACCEPT) {
4054 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
4055 MessageDialog msg (_("Re-scan Plugins now?"),
4056 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
4057 msg.set_default_response (Gtk::RESPONSE_YES);
4058 if (msg.run() == Gtk::RESPONSE_YES) {
4060 plugin_scan_refresh ();
4068 RCOptionEditor::populate_sync_options ()
4070 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
4072 _sync_source->clear ();
4074 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
4075 _sync_source->add (*i, sync_source_to_string (*i));
4078 if (sync_opts.empty()) {
4079 _sync_source->set_sensitive(false);
4081 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
4082 _rc_config->set_sync_source(sync_opts.front());
4086 parameter_changed ("sync-source");
4090 RCOptionEditor::use_own_window (bool and_fill_it)
4092 bool new_window = !own_window ();
4094 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
4096 if (win && new_window) {
4097 win->set_name ("PreferencesWindow");
4098 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
4100 win->set_resizable (false);
4107 RCOptionEditor::get_state ()
4109 XMLNode* node = new XMLNode (X_("Preferences"));
4110 node->add_child_nocopy (Tabbable::get_state());