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