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/control_protocol_manager.h"
47 #include "ardour/dB.h"
48 #include "ardour/port_manager.h"
49 #include "ardour/plugin_manager.h"
50 #include "ardour/profile.h"
51 #include "ardour/rc_configuration.h"
52 #include "ardour/transport_master_manager.h"
54 #include "control_protocol/control_protocol.h"
56 #include "waveview/wave_view.h"
58 #include "widgets/paths_dialog.h"
59 #include "widgets/tooltips.h"
61 #include "ardour_dialog.h"
62 #include "ardour_ui.h"
63 #include "ardour_window.h"
64 #include "color_theme_manager.h"
65 #include "gui_thread.h"
67 #include "meter_patterns.h"
68 #include "midi_tracer.h"
69 #include "rc_option_editor.h"
71 #include "transport_masters_dialog.h"
72 #include "ui_config.h"
77 using namespace Gtkmm2ext;
79 using namespace ARDOUR;
80 using namespace ARDOUR_UI_UTILS;
81 using namespace ArdourWidgets;
83 class ClickOptions : public OptionEditorMiniPage
86 ClickOptions (RCConfiguration* c)
88 , _click_browse_button (_("Browse..."))
89 , _click_emphasis_browse_button (_("Browse..."))
91 // TODO get rid of GTK -> use OptionEditor Widgets
96 l = manage (left_aligned_label (_("Emphasis on first beat")));
97 _use_emphasis_on_click_check_button.add (*l);
98 t->attach (_use_emphasis_on_click_check_button, 1, 3, row, row + 1, FILL);
99 _use_emphasis_on_click_check_button.signal_toggled().connect (
100 sigc::mem_fun (*this, &ClickOptions::use_emphasis_on_click_toggled));
103 l = manage (left_aligned_label (_("Use built-in default sounds")));
104 _use_default_click_check_button.add (*l);
105 t->attach (_use_default_click_check_button, 1, 3, row, row + 1, FILL);
106 _use_default_click_check_button.signal_toggled().connect (
107 sigc::mem_fun (*this, &ClickOptions::use_default_click_toggled));
110 l = manage (left_aligned_label (_("Audio file:")));
111 t->attach (*l, 1, 2, row, row + 1, FILL);
112 t->attach (_click_path_entry, 2, 3, row, row + 1, FILL);
113 _click_browse_button.signal_clicked ().connect (
114 sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
115 t->attach (_click_browse_button, 3, 4, row, row + 1, FILL);
118 l = manage (left_aligned_label (_("Emphasis audio file:")));
119 t->attach (*l, 1, 2, row, row + 1, FILL);
120 t->attach (_click_emphasis_path_entry, 2, 3, row, row + 1, FILL);
121 _click_emphasis_browse_button.signal_clicked ().connect (
122 sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
123 t->attach (_click_emphasis_browse_button, 3, 4, row, row + 1, FILL);
126 _click_fader = new FaderOption (
129 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
130 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
133 _click_fader->add_to_page (this);
134 _click_fader->set_state_from_config ();
136 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
137 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
139 if (_rc_config->get_click_sound ().empty() &&
140 _rc_config->get_click_emphasis_sound().empty()) {
141 _use_default_click_check_button.set_active (true);
142 _use_emphasis_on_click_check_button.set_active (_rc_config->get_use_click_emphasis ());
145 _use_default_click_check_button.set_active (false);
146 _use_emphasis_on_click_check_button.set_active (false);
150 void parameter_changed (string const & p)
152 if (p == "click-sound") {
153 _click_path_entry.set_text (_rc_config->get_click_sound());
154 } else if (p == "click-emphasis-sound") {
155 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
156 } else if (p == "use-click-emphasis") {
157 bool x = _rc_config->get_use_click_emphasis ();
158 _use_emphasis_on_click_check_button.set_active (x);
159 } else if (p == "click-gain") {
160 _click_fader->set_state_from_config ();
164 void set_state_from_config ()
166 parameter_changed ("click-sound");
167 parameter_changed ("click-emphasis-sound");
168 parameter_changed ("use-click-emphasis");
173 void click_browse_clicked ()
175 SoundFileChooser sfdb (_("Choose Click"));
180 if (sfdb.run () == RESPONSE_OK) {
181 click_chosen (sfdb.get_filename());
185 void click_chosen (string const & path)
187 _click_path_entry.set_text (path);
188 _rc_config->set_click_sound (path);
191 void click_changed ()
193 click_chosen (_click_path_entry.get_text ());
196 void click_emphasis_browse_clicked ()
198 SoundFileChooser sfdb (_("Choose Click Emphasis"));
203 if (sfdb.run () == RESPONSE_OK) {
204 click_emphasis_chosen (sfdb.get_filename());
208 void click_emphasis_chosen (string const & path)
210 _click_emphasis_path_entry.set_text (path);
211 _rc_config->set_click_emphasis_sound (path);
214 void click_emphasis_changed ()
216 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
219 void use_default_click_toggled ()
221 if (_use_default_click_check_button.get_active ()) {
222 _rc_config->set_click_sound ("");
223 _rc_config->set_click_emphasis_sound ("");
224 _click_path_entry.set_sensitive (false);
225 _click_emphasis_path_entry.set_sensitive (false);
226 _click_browse_button.set_sensitive (false);
227 _click_emphasis_browse_button.set_sensitive (false);
229 _click_path_entry.set_sensitive (true);
230 _click_emphasis_path_entry.set_sensitive (true);
231 _click_browse_button.set_sensitive (true);
232 _click_emphasis_browse_button.set_sensitive (true);
236 void use_emphasis_on_click_toggled ()
238 if (_use_emphasis_on_click_check_button.get_active ()) {
239 _rc_config->set_use_click_emphasis(true);
241 _rc_config->set_use_click_emphasis(false);
245 RCConfiguration* _rc_config;
246 CheckButton _use_default_click_check_button;
247 CheckButton _use_emphasis_on_click_check_button;
248 Entry _click_path_entry;
249 Entry _click_emphasis_path_entry;
250 Button _click_browse_button;
251 Button _click_emphasis_browse_button;
252 FaderOption* _click_fader;
255 class UndoOptions : public OptionEditorComponent
258 UndoOptions (RCConfiguration* c) :
260 _limit_undo_button (_("Limit undo history to")),
261 _save_undo_button (_("Save undo history of"))
263 // TODO get rid of GTK -> use OptionEditor SpinOption
264 _limit_undo_spin.set_range (0, 512);
265 _limit_undo_spin.set_increments (1, 10);
267 _save_undo_spin.set_range (0, 512);
268 _save_undo_spin.set_increments (1, 10);
270 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
271 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
272 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
273 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
276 void parameter_changed (string const & p)
278 if (p == "history-depth") {
279 int32_t const d = _rc_config->get_history_depth();
280 _limit_undo_button.set_active (d != 0);
281 _limit_undo_spin.set_sensitive (d != 0);
282 _limit_undo_spin.set_value (d);
283 } else if (p == "save-history") {
284 bool const x = _rc_config->get_save_history ();
285 _save_undo_button.set_active (x);
286 _save_undo_spin.set_sensitive (x);
287 } else if (p == "save-history-depth") {
288 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
292 void set_state_from_config ()
294 parameter_changed ("save-history");
295 parameter_changed ("history-depth");
296 parameter_changed ("save-history-depth");
299 void limit_undo_toggled ()
301 bool const x = _limit_undo_button.get_active ();
302 _limit_undo_spin.set_sensitive (x);
303 int32_t const n = x ? 16 : 0;
304 _limit_undo_spin.set_value (n);
305 _rc_config->set_history_depth (n);
308 void limit_undo_changed ()
310 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
313 void save_undo_toggled ()
315 bool const x = _save_undo_button.get_active ();
316 _rc_config->set_save_history (x);
319 void save_undo_changed ()
321 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
324 void add_to_page (OptionEditorPage* p)
326 int const n = p->table.property_n_rows();
327 Table* t = & p->table;
329 t->resize (n + 2, 3);
331 Label* l = manage (left_aligned_label (_("commands")));
332 HBox* box = manage (new HBox());
333 box->set_spacing (4);
334 box->pack_start (_limit_undo_spin, false, false);
335 box->pack_start (*l, true, true);
336 t->attach (_limit_undo_button, 1, 2, n, n +1, FILL);
337 t->attach (*box, 2, 3, n, n + 1, FILL | EXPAND);
339 l = manage (left_aligned_label (_("commands")));
340 box = manage (new HBox());
341 box->set_spacing (4);
342 box->pack_start (_save_undo_spin, false, false);
343 box->pack_start (*l, true, true);
344 t->attach (_save_undo_button, 1, 2, n + 1, n + 2, FILL);
345 t->attach (*box, 2, 3, n + 1, n + 2, FILL | EXPAND);
348 Gtk::Widget& tip_widget() {
349 return _limit_undo_button; // unused
353 RCConfiguration* _rc_config;
354 CheckButton _limit_undo_button;
355 SpinButton _limit_undo_spin;
356 CheckButton _save_undo_button;
357 SpinButton _save_undo_spin;
361 static const struct {
373 { "Key|Shift", GDK_SHIFT_MASK },
374 { "Command", GDK_MOD2_MASK },
375 { "Control", GDK_CONTROL_MASK },
376 { "Option", GDK_MOD1_MASK },
377 { "Command-Shift", GDK_MOD2_MASK|GDK_SHIFT_MASK },
378 { "Command-Option", GDK_MOD2_MASK|GDK_MOD1_MASK },
379 { "Command-Control", GDK_MOD2_MASK|GDK_CONTROL_MASK },
380 { "Command-Option-Control", GDK_MOD2_MASK|GDK_MOD1_MASK|GDK_CONTROL_MASK },
381 { "Option-Control", GDK_MOD1_MASK|GDK_CONTROL_MASK },
382 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
383 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
384 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_MOD2_MASK },
387 { "Key|Shift", GDK_SHIFT_MASK },
388 { "Control", GDK_CONTROL_MASK },
389 { "Alt", GDK_MOD1_MASK },
390 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
391 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
392 { "Control-Windows", GDK_CONTROL_MASK|GDK_MOD4_MASK },
393 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
394 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
395 { "Alt-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
396 { "Alt-Shift-Windows", GDK_MOD1_MASK|GDK_SHIFT_MASK|GDK_MOD4_MASK },
397 { "Mod2", GDK_MOD2_MASK },
398 { "Mod3", GDK_MOD3_MASK },
399 { "Windows", GDK_MOD4_MASK },
400 { "Mod5", GDK_MOD5_MASK },
406 class KeyboardOptions : public OptionEditorMiniPage
410 : _delete_button_adjustment (3, 1, 12)
411 , _delete_button_spin (_delete_button_adjustment)
412 , _edit_button_adjustment (3, 1, 5)
413 , _edit_button_spin (_edit_button_adjustment)
414 , _insert_note_button_adjustment (3, 1, 5)
415 , _insert_note_button_spin (_insert_note_button_adjustment)
417 // TODO get rid of GTK -> use OptionEditor Widgets
419 const std::string restart_msg = _("\nChanges to this setting will only persist after your project has been saved.");
420 /* internationalize and prepare for use with combos */
423 for (int i = 0; modifiers[i].name; ++i) {
424 dumb.push_back (S_(modifiers[i].name));
427 set_popdown_strings (_edit_modifier_combo, dumb);
428 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
429 Gtkmm2ext::UI::instance()->set_tip (_edit_modifier_combo,
430 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
437 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
438 l->set_name ("OptionsLabel");
442 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
443 strs.push_back (bf->first);
446 set_popdown_strings (_keyboard_layout_selector, strs);
447 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
448 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
450 t->attach (*l, col + 1, col + 2, row, row + 1, FILL, FILL);
451 t->attach (_keyboard_layout_selector, col + 2, col + 3, row, row + 1, FILL | EXPAND, FILL);
456 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Clicking:"))));
457 l->set_name ("OptionEditorHeading");
458 l->set_use_markup (true);
459 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
464 l = manage (left_aligned_label (_("Edit using:")));
465 l->set_name ("OptionsLabel");
467 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
468 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
470 l = manage (new Label (_("+ button")));
471 l->set_name ("OptionsLabel");
473 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
474 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, SHRINK , FILL);
476 _edit_button_spin.set_name ("OptionsEntry");
477 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
482 set_popdown_strings (_delete_modifier_combo, dumb);
483 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
484 Gtkmm2ext::UI::instance()->set_tip (_delete_modifier_combo,
485 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
487 l = manage (left_aligned_label (_("Delete using:")));
488 l->set_name ("OptionsLabel");
490 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
491 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
493 l = manage (new Label (_("+ button")));
494 l->set_name ("OptionsLabel");
496 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
497 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, SHRINK, FILL);
499 _delete_button_spin.set_name ("OptionsEntry");
500 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
505 set_popdown_strings (_insert_note_modifier_combo, dumb);
506 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
507 Gtkmm2ext::UI::instance()->set_tip (_insert_note_modifier_combo,
508 (string_compose (_("<b>Recommended Setting: %1 + button 1 (left mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
510 l = manage (left_aligned_label (_("Insert note using:")));
511 l->set_name ("OptionsLabel");
513 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
514 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
516 l = manage (new Label (_("+ button")));
517 l->set_name ("OptionsLabel");
519 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
520 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, SHRINK, FILL);
522 _insert_note_button_spin.set_name ("OptionsEntry");
523 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
527 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Beginning a Drag:"))));
528 l->set_name ("OptionEditorHeading");
529 l->set_use_markup (true);
530 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
536 set_popdown_strings (_copy_modifier_combo, dumb);
537 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
538 Gtkmm2ext::UI::instance()->set_tip (_copy_modifier_combo,
539 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
541 Keyboard::secondary_modifier_name (),
543 Keyboard::primary_modifier_name (),
547 l = manage (left_aligned_label (_("Copy items using:")));
548 l->set_name ("OptionsLabel");
550 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
551 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
556 /* constraint modifier */
557 set_popdown_strings (_constraint_modifier_combo, dumb);
558 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
559 Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo,
560 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
562 Keyboard::primary_modifier_name (),
564 Keyboard::tertiary_modifier_name (),
568 l = manage (left_aligned_label (_("Constrain drag using:")));
569 l->set_name ("OptionsLabel");
571 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
572 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
578 set_popdown_strings (_push_points_combo, dumb);
579 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
581 std::string mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
582 Gtkmm2ext::UI::instance()->set_tip (_push_points_combo,
583 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
585 l = manage (left_aligned_label (_("Push points using:")));
586 l->set_name ("OptionsLabel");
588 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
589 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
593 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Beginning a Trim:"))));
594 l->set_name ("OptionEditorHeading");
595 l->set_use_markup (true);
596 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
602 set_popdown_strings (_trim_contents_combo, dumb);
603 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
604 Gtkmm2ext::UI::instance()->set_tip (_trim_contents_combo,
605 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
607 l = manage (left_aligned_label (_("Trim contents using:")));
608 l->set_name ("OptionsLabel");
610 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
611 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
617 set_popdown_strings (_trim_anchored_combo, dumb);
618 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
620 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::tertiary_modifier_name ());
621 Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo,
622 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
624 l = manage (left_aligned_label (_("Anchored trim using:")));
625 l->set_name ("OptionsLabel");
627 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
629 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
634 /* jump trim disabled for now
635 set_popdown_strings (_trim_jump_combo, dumb);
636 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
638 l = manage (left_aligned_label (_("Jump after trim using:")));
639 l->set_name ("OptionsLabel");
641 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
643 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
649 /* note resize relative */
650 set_popdown_strings (_note_size_relative_combo, dumb);
651 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
652 Gtkmm2ext::UI::instance()->set_tip (_note_size_relative_combo,
653 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg))); // XXX 2ndary
655 l = manage (left_aligned_label (_("Resize notes relatively using:")));
656 l->set_name ("OptionsLabel");
658 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
660 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
664 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Dragging:"))));
665 l->set_name ("OptionEditorHeading");
666 l->set_use_markup (true);
667 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
673 set_popdown_strings (_snap_modifier_combo, dumb);
674 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
676 mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ());
678 mod_str = Keyboard::secondary_modifier_name();
680 Gtkmm2ext::UI::instance()->set_tip (_snap_modifier_combo,
681 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
683 l = manage (left_aligned_label (_("Ignore snap using:")));
684 l->set_name ("OptionsLabel");
686 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
687 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
693 set_popdown_strings (_snap_delta_combo, dumb);
694 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
696 mod_str = Keyboard::level4_modifier_name ();
698 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::level4_modifier_name ());
700 Gtkmm2ext::UI::instance()->set_tip (_snap_delta_combo,
701 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
703 l = manage (left_aligned_label (_("Snap relatively using:")));
704 l->set_name ("OptionsLabel");
706 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
707 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
711 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Trimming:"))));
712 l->set_name ("OptionEditorHeading");
713 l->set_use_markup (true);
714 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
720 set_popdown_strings (_trim_overlap_combo, dumb);
721 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
723 Gtkmm2ext::UI::instance()->set_tip (_trim_overlap_combo,
724 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
726 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
727 l->set_name ("OptionsLabel");
729 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
730 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
734 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Dragging Control Points:"))));
735 l->set_name ("OptionEditorHeading");
736 l->set_use_markup (true);
737 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
743 set_popdown_strings (_fine_adjust_combo, dumb);
744 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
746 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::secondary_modifier_name ()); // XXX just 2ndary ?!
747 Gtkmm2ext::UI::instance()->set_tip (_fine_adjust_combo,
748 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
750 l = manage (left_aligned_label (_("Fine adjust using:")));
751 l->set_name ("OptionsLabel");
753 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
754 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
756 OptionEditorHeading* h = new OptionEditorHeading (_("Reset"));
757 h->add_to_page (this);
759 RcActionButton* rb = new RcActionButton (_("Reset to recommended defaults"),
760 sigc::mem_fun (*this, &KeyboardOptions::reset_to_defaults));
761 rb->add_to_page (this);
763 set_state_from_config ();
766 void parameter_changed (string const &)
768 /* XXX: these aren't really config options... */
771 void set_state_from_config ()
773 _delete_button_adjustment.set_value (Keyboard::delete_button());
774 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
775 _edit_button_adjustment.set_value (Keyboard::edit_button());
777 for (int x = 0; modifiers[x].name; ++x) {
778 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
779 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
781 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
782 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
784 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
785 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
787 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
788 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
790 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
791 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
793 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
794 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
796 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
797 _push_points_combo.set_active_text (S_(modifiers[x].name));
799 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
800 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
802 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
803 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
806 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
807 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
810 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
811 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
813 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
814 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
816 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
817 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
819 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
820 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
825 void add_to_page (OptionEditorPage* p)
827 int const n = p->table.property_n_rows();
828 p->table.resize (n + 1, 3);
829 p->table.attach (box, 1, 3, n, n + 1, FILL | EXPAND, SHRINK, 0, 0);
834 void bindings_changed ()
836 string const txt = _keyboard_layout_selector.get_active_text();
838 /* XXX: config...? for all this keyboard stuff */
840 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
841 if (txt == i->first) {
842 if (Keyboard::load_keybindings (i->second)) {
843 Keyboard::save_keybindings ();
849 void edit_modifier_chosen ()
851 string const txt = _edit_modifier_combo.get_active_text();
853 for (int i = 0; modifiers[i].name; ++i) {
854 if (txt == S_(modifiers[i].name)) {
855 Keyboard::set_edit_modifier (modifiers[i].modifier);
861 void delete_modifier_chosen ()
863 string const txt = _delete_modifier_combo.get_active_text();
865 for (int i = 0; modifiers[i].name; ++i) {
866 if (txt == S_(modifiers[i].name)) {
867 Keyboard::set_delete_modifier (modifiers[i].modifier);
873 void copy_modifier_chosen ()
875 string const txt = _copy_modifier_combo.get_active_text();
877 for (int i = 0; modifiers[i].name; ++i) {
878 if (txt == S_(modifiers[i].name)) {
879 Keyboard::set_copy_modifier (modifiers[i].modifier);
885 void insert_note_modifier_chosen ()
887 string const txt = _insert_note_modifier_combo.get_active_text();
889 for (int i = 0; modifiers[i].name; ++i) {
890 if (txt == S_(modifiers[i].name)) {
891 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
897 void snap_modifier_chosen ()
899 string const txt = _snap_modifier_combo.get_active_text();
901 for (int i = 0; modifiers[i].name; ++i) {
902 if (txt == S_(modifiers[i].name)) {
903 Keyboard::set_snap_modifier (modifiers[i].modifier);
909 void snap_delta_modifier_chosen ()
911 string const txt = _snap_delta_combo.get_active_text();
913 for (int i = 0; modifiers[i].name; ++i) {
914 if (txt == S_(modifiers[i].name)) {
915 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
921 void constraint_modifier_chosen ()
923 string const txt = _constraint_modifier_combo.get_active_text();
925 for (int i = 0; modifiers[i].name; ++i) {
926 if (txt == S_(modifiers[i].name)) {
927 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
933 void trim_contents_modifier_chosen ()
935 string const txt = _trim_contents_combo.get_active_text();
937 for (int i = 0; modifiers[i].name; ++i) {
938 if (txt == S_(modifiers[i].name)) {
939 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
945 void trim_overlap_modifier_chosen ()
947 string const txt = _trim_overlap_combo.get_active_text();
949 for (int i = 0; modifiers[i].name; ++i) {
950 if (txt == S_(modifiers[i].name)) {
951 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
957 void trim_anchored_modifier_chosen ()
959 string const txt = _trim_anchored_combo.get_active_text();
961 for (int i = 0; modifiers[i].name; ++i) {
962 if (txt == S_(modifiers[i].name)) {
963 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
969 void fine_adjust_modifier_chosen ()
971 string const txt = _fine_adjust_combo.get_active_text();
973 for (int i = 0; modifiers[i].name; ++i) {
974 if (txt == S_(modifiers[i].name)) {
975 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
981 void push_points_modifier_chosen ()
983 string const txt = _push_points_combo.get_active_text();
985 for (int i = 0; modifiers[i].name; ++i) {
986 if (txt == S_(modifiers[i].name)) {
987 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
993 void note_size_relative_modifier_chosen ()
995 string const txt = _note_size_relative_combo.get_active_text();
997 for (int i = 0; modifiers[i].name; ++i) {
998 if (txt == S_(modifiers[i].name)) {
999 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
1005 void delete_button_changed ()
1007 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
1010 void edit_button_changed ()
1012 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
1015 void insert_note_button_changed ()
1017 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
1020 void reset_to_defaults ()
1023 Keyboard::set_edit_modifier (Keyboard::PrimaryModifier);
1024 Keyboard::set_edit_button (3);
1025 Keyboard::set_delete_modifier (Keyboard::TertiaryModifier);
1026 Keyboard::set_delete_button (3);
1027 Keyboard::set_insert_note_modifier (Keyboard::PrimaryModifier);
1028 Keyboard::set_insert_note_button (1);
1030 /* when beginning a drag */
1032 Keyboard::set_copy_modifier (Keyboard::SecondaryModifier);
1034 Keyboard::set_copy_modifier (Keyboard::PrimaryModifier);
1038 ArdourKeyboard::set_constraint_modifier (Keyboard::PrimaryModifier);
1040 ArdourKeyboard::set_constraint_modifier (Keyboard::TertiaryModifier);
1042 ArdourKeyboard::set_push_points_modifier (Keyboard::PrimaryModifier | Keyboard::Level4Modifier);
1044 /* when beginning a trim */
1045 ArdourKeyboard::set_trim_contents_modifier (Keyboard::PrimaryModifier);
1046 ArdourKeyboard::set_trim_anchored_modifier (Keyboard::PrimaryModifier | Keyboard::TertiaryModifier);
1047 ArdourKeyboard::set_note_size_relative_modifier (Keyboard::TertiaryModifier); // XXX better: 2ndary
1049 /* while dragging */
1051 Keyboard::set_snap_modifier (Keyboard::TertiaryModifier);
1053 Keyboard::set_snap_modifier (Keyboard::SecondaryModifier);
1056 Keyboard::set_snap_delta_modifier (Keyboard::Level4Modifier);
1058 Keyboard::set_snap_delta_modifier (Keyboard::SecondaryModifier | Keyboard::Level4Modifier);
1061 /* while trimming */
1062 ArdourKeyboard::set_trim_overlap_modifier (Keyboard::TertiaryModifier);
1064 /* while dragging ctrl points */
1065 ArdourKeyboard::set_fine_adjust_modifier (/*Keyboard::PrimaryModifier | */Keyboard::SecondaryModifier); // XXX
1067 set_state_from_config ();
1070 ComboBoxText _keyboard_layout_selector;
1071 ComboBoxText _edit_modifier_combo;
1072 ComboBoxText _delete_modifier_combo;
1073 ComboBoxText _copy_modifier_combo;
1074 ComboBoxText _insert_note_modifier_combo;
1075 ComboBoxText _snap_modifier_combo;
1076 ComboBoxText _snap_delta_combo;
1077 ComboBoxText _constraint_modifier_combo;
1078 ComboBoxText _trim_contents_combo;
1079 ComboBoxText _trim_overlap_combo;
1080 ComboBoxText _trim_anchored_combo;
1081 ComboBoxText _trim_jump_combo;
1082 ComboBoxText _fine_adjust_combo;
1083 ComboBoxText _push_points_combo;
1084 ComboBoxText _note_size_relative_combo;
1085 Adjustment _delete_button_adjustment;
1086 SpinButton _delete_button_spin;
1087 Adjustment _edit_button_adjustment;
1088 SpinButton _edit_button_spin;
1089 Adjustment _insert_note_button_adjustment;
1090 SpinButton _insert_note_button_spin;
1094 class FontScalingOptions : public HSliderOption
1097 FontScalingOptions ()
1098 : HSliderOption ("font-scale", _("GUI and Font scaling"),
1099 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_font_scale),
1100 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_font_scale),
1104 const std::string dflt = _("100%");
1105 const std::string empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
1107 _hscale.set_name("FontScaleSlider");
1108 _hscale.set_draw_value(false);
1109 _hscale.add_mark(50, Gtk::POS_TOP, empty);
1110 _hscale.add_mark(60, Gtk::POS_TOP, empty);
1111 _hscale.add_mark(70, Gtk::POS_TOP, empty);
1112 _hscale.add_mark(80, Gtk::POS_TOP, empty);
1113 _hscale.add_mark(90, Gtk::POS_TOP, empty);
1114 _hscale.add_mark(100, Gtk::POS_TOP, dflt);
1115 _hscale.add_mark(125, Gtk::POS_TOP, empty);
1116 _hscale.add_mark(150, Gtk::POS_TOP, empty);
1117 _hscale.add_mark(175, Gtk::POS_TOP, empty);
1118 _hscale.add_mark(200, Gtk::POS_TOP, empty);
1119 _hscale.add_mark(250, Gtk::POS_TOP, empty);
1121 set_note (_("Adjusting the scale requires an application restart to re-layout."));
1126 HSliderOption::changed ();
1127 /* XXX: should be triggered from the parameter changed signal */
1128 UIConfiguration::instance().reset_dpi ();
1132 class VstTimeOutSliderOption : public HSliderOption
1135 VstTimeOutSliderOption (RCConfiguration* c)
1136 : HSliderOption ("vst-scan-timeout", _("Scan Time Out"),
1137 sigc::mem_fun (*c, &RCConfiguration::get_vst_scan_timeout),
1138 sigc::mem_fun (*c, &RCConfiguration::set_vst_scan_timeout),
1141 _label.set_alignment (1.0, 0.5); // match buttons below
1142 _hscale.set_digits (0);
1143 _hscale.set_draw_value(false);
1144 _hscale.add_mark( 0, Gtk::POS_TOP, _("\u221e")); // infinity
1145 _hscale.add_mark( 300, Gtk::POS_TOP, _("30 sec"));
1146 _hscale.add_mark( 600, Gtk::POS_TOP, _("1 min"));
1147 _hscale.add_mark(1200, Gtk::POS_TOP, _("2 mins"));
1148 _hscale.add_mark(1800, Gtk::POS_TOP, _("3 mins"));
1149 _hscale.add_mark(2400, Gtk::POS_TOP, _("4 mins"));
1150 _hscale.add_mark(3000, Gtk::POS_TOP, _("5 mins"));
1152 Gtkmm2ext::UI::instance()->set_tip(_hscale,
1153 _("Specify the default timeout for plugin instantiation. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1157 class ClipLevelOptions : public OptionEditorComponent
1161 : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1162 , _clip_level_slider (_clip_level_adjustment)
1163 , _label (_("Waveform Clip Level (dBFS):"))
1165 _label.set_name ("OptionsLabel");
1167 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ());
1169 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1171 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1174 void parameter_changed (string const & p)
1176 if (p == "waveform-clip-level") {
1177 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level());
1179 if (p == "show-waveform-clipping") {
1180 _clip_level_slider.set_sensitive (UIConfiguration::instance().get_show_waveform_clipping ());
1184 void set_state_from_config ()
1186 parameter_changed ("waveform-clip-level");
1187 parameter_changed ("show-waveform-clipping");
1190 void add_to_page (OptionEditorPage* p) {
1191 add_widgets_to_page (p, &_label, &_clip_level_slider);
1194 Gtk::Widget& tip_widget() {
1195 return _clip_level_slider;
1200 void clip_level_changed ()
1202 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1203 /* XXX: should be triggered from the parameter changed signal */
1204 ArdourWaveView::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1207 Adjustment _clip_level_adjustment;
1208 HScale _clip_level_slider;
1212 class BufferingOptions : public OptionEditorComponent
1215 BufferingOptions (RCConfiguration* c)
1217 , _label (_("Preset:"))
1218 , _playback ("playback-buffer-seconds", _("Playback (seconds of buffering)"),
1219 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_playback_buffer_seconds),
1220 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_playback_buffer_seconds),
1222 , _capture ("capture-buffer-seconds", _("Recording (seconds of buffering)"),
1223 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_capture_buffer_seconds),
1224 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_capture_buffer_seconds),
1227 // TODO use ComboOption
1228 vector<string> presets;
1230 /* these must match the order of the enums for BufferingPreset */
1231 presets.push_back (_("Small sessions (4-16 tracks)"));
1232 presets.push_back (_("Medium sessions (16-64 tracks)"));
1233 presets.push_back (_("Large sessions (64+ tracks)"));
1234 presets.push_back (_("Custom (set by sliders below)"));
1236 set_popdown_strings (_buffering_presets_combo, presets);
1237 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1239 _label.set_name ("OptionsLabel");
1240 _label.set_alignment (0, 0.5);
1244 add_to_page (OptionEditorPage* p)
1246 add_widgets_to_page (p, &_label, &_buffering_presets_combo);
1247 _playback.add_to_page (p);
1248 _capture.add_to_page (p);
1251 void parameter_changed (string const & p)
1253 if (p == "buffering-preset") {
1254 switch (_rc_config->get_buffering_preset()) {
1256 _playback.set_sensitive (false);
1257 _capture.set_sensitive (false);
1258 _buffering_presets_combo.set_active (0);
1261 _playback.set_sensitive (false);
1262 _capture.set_sensitive (false);
1263 _buffering_presets_combo.set_active (1);
1266 _playback.set_sensitive (false);
1267 _capture.set_sensitive (false);
1268 _buffering_presets_combo.set_active (2);
1271 _playback.set_sensitive (true);
1272 _capture.set_sensitive (true);
1273 _buffering_presets_combo.set_active (3);
1277 _playback.parameter_changed (p);
1278 _capture.parameter_changed (p);
1281 void set_state_from_config ()
1283 parameter_changed ("buffering-preset");
1284 _playback.set_state_from_config();
1285 _capture.set_state_from_config();
1288 Gtk::Widget& tip_widget() { return _buffering_presets_combo; }
1292 void preset_changed ()
1294 int index = _buffering_presets_combo.get_active_row_number ();
1300 _rc_config->set_buffering_preset (Small);
1303 _rc_config->set_buffering_preset (Medium);
1306 _rc_config->set_buffering_preset (Large);
1309 _rc_config->set_buffering_preset (Custom);
1312 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1317 RCConfiguration* _rc_config;
1319 HSliderOption _playback;
1320 HSliderOption _capture;
1321 ComboBoxText _buffering_presets_combo;
1324 class ControlSurfacesOptions : public OptionEditorMiniPage
1327 ControlSurfacesOptions ()
1328 : _ignore_view_change (0)
1330 _store = ListStore::create (_model);
1331 _view.set_model (_store);
1332 _view.append_column (_("Control Surface Protocol"), _model.name);
1333 _view.get_column(0)->set_resizable (true);
1334 _view.get_column(0)->set_expand (true);
1335 _view.append_column_editable (_("Enable"), _model.enabled);
1337 Gtk::HBox* edit_box = manage (new Gtk::HBox);
1338 edit_box->set_spacing(3);
1341 Label* label = manage (new Label);
1342 label->set_text (_("Edit the settings for selected protocol (it must be ENABLED first):"));
1343 edit_box->pack_start (*label, false, false);
1346 edit_button = manage (new Button(_("Show Protocol Settings")));
1347 edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
1348 edit_box->pack_start (*edit_button, true, true);
1349 edit_button->set_sensitive (false);
1350 edit_button->show ();
1352 int const n = table.property_n_rows();
1353 table.resize (n + 2, 3);
1354 table.attach (_view, 0, 3, n, n + 1);
1355 table.attach (*edit_box, 0, 3, n + 1, n + 2);
1357 ControlProtocolManager& m = ControlProtocolManager::instance ();
1358 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1359 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1361 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1362 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1363 _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
1366 void parameter_changed (std::string const &)
1371 void set_state_from_config ()
1375 ControlProtocolManager& m = ControlProtocolManager::instance ();
1376 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1378 if (!(*i)->mandatory) {
1379 TreeModel::Row r = *_store->append ();
1380 r[_model.name] = (*i)->name;
1381 r[_model.enabled] = 0 != (*i)->protocol;
1382 r[_model.protocol_info] = *i;
1389 void protocol_status_changed (ControlProtocolInfo* cpi) {
1391 TreeModel::Children rows = _store->children();
1393 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1394 string n = ((*x)[_model.name]);
1396 if ((*x)[_model.protocol_info] == cpi) {
1397 _ignore_view_change++;
1398 (*x)[_model.enabled] = 0 != cpi->protocol;
1399 _ignore_view_change--;
1400 selection_changed (); // update sensitivity
1406 void selection_changed ()
1408 //enable the Edit button when a row is selected for editing
1409 TreeModel::Row row = *(_view.get_selection()->get_selected());
1410 if (row && row[_model.enabled]) {
1411 ControlProtocolInfo* cpi = row[_model.protocol_info];
1412 edit_button->set_sensitive (cpi && cpi->protocol && cpi->protocol->has_editor ());
1414 edit_button->set_sensitive (false);
1418 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1420 TreeModel::Row r = *i;
1422 if (_ignore_view_change) {
1426 ControlProtocolInfo* cpi = r[_model.protocol_info];
1431 bool const was_enabled = (cpi->protocol != 0);
1432 bool const is_enabled = r[_model.enabled];
1435 if (was_enabled != is_enabled) {
1438 ControlProtocolManager::instance().activate (*cpi);
1440 ControlProtocolManager::instance().deactivate (*cpi);
1444 selection_changed ();
1447 void edit_btn_clicked ()
1450 ControlProtocolInfo* cpi;
1453 row = *(_view.get_selection()->get_selected());
1454 if (!row[_model.enabled]) {
1457 cpi = row[_model.protocol_info];
1458 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1461 Box* box = (Box*) cpi->protocol->get_gui ();
1465 if (box->get_parent()) {
1466 static_cast<ArdourWindow*>(box->get_parent())->present();
1469 WindowTitle title (Glib::get_application_name());
1470 title += row[_model.name];
1471 title += _("Configuration");
1472 /* once created, the window is managed by the surface itself (as ->get_parent())
1473 * Surface's tear_down_gui() is called on session close, when de-activating
1474 * or re-initializing a surface.
1475 * tear_down_gui() hides an deletes the Window if it exists.
1477 ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
1478 win->set_title (_("Control Protocol Settings"));
1484 void edit_clicked (GdkEventButton* ev)
1486 if (ev->type != GDK_2BUTTON_PRESS) {
1493 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1497 ControlSurfacesModelColumns ()
1501 add (protocol_info);
1504 TreeModelColumn<string> name;
1505 TreeModelColumn<bool> enabled;
1506 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1509 Glib::RefPtr<ListStore> _store;
1510 ControlSurfacesModelColumns _model;
1512 PBD::ScopedConnection protocol_status_connection;
1513 uint32_t _ignore_view_change;
1514 Gtk::Button* edit_button;
1517 class VideoTimelineOptions : public OptionEditorMiniPage
1520 VideoTimelineOptions (RCConfiguration* c)
1522 , _show_video_export_info_button (_("Show Video Export Info before export"))
1523 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1524 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1525 , _xjadeo_browse_button (_("Browse..."))
1528 int n = table.property_n_rows();
1530 t->attach (_show_video_export_info_button, 1, 4, n, n + 1);
1531 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1532 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1533 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1536 t->attach (_show_video_server_dialog_button, 1, 4, n, n + 1);
1537 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1538 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1539 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1542 t->attach (_video_advanced_setup_button, 1, 4, n, n + 1, FILL);
1543 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1544 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1545 _("<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."));
1548 Label* l = manage (new Label (_("Video Server URL:")));
1549 l->set_alignment (0, 0.5);
1550 t->attach (*l, 1, 2, n, n + 1, FILL);
1551 t->attach (_video_server_url_entry, 2, 4, n, n + 1, FILL);
1552 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1553 _("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"));
1556 l = manage (new Label (_("Video Folder:")));
1557 l->set_alignment (0, 0.5);
1558 t->attach (*l, 1, 2, n, n + 1, FILL);
1559 t->attach (_video_server_docroot_entry, 2, 4, n, n + 1);
1560 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1561 _("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."));
1564 l = manage (new Label (""));
1565 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1568 l = manage (new Label (string_compose ("<b>%1</b>", _("Video Monitor"))));
1569 l->set_use_markup (true);
1570 l->set_alignment (0, 0.5);
1571 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1574 l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"),
1577 #elif defined PLATFORM_WINDOWS
1583 l->set_alignment (0, 0.5);
1584 t->attach (*l, 1, 4, n, n + 1, FILL);
1587 t->attach (_custom_xjadeo_path, 2, 3, n, n + 1, EXPAND|FILL);
1588 Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart."));
1589 t->attach (_xjadeo_browse_button, 3, 4, n, n + 1, FILL);
1591 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1592 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1593 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1594 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1595 _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed));
1596 _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked));
1598 // xjadeo-path is a UIConfig parameter
1599 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &VideoTimelineOptions::parameter_changed));
1602 void server_url_changed ()
1604 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1607 void server_docroot_changed ()
1609 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1612 void show_video_export_info_toggled ()
1614 bool const x = _show_video_export_info_button.get_active ();
1615 _rc_config->set_show_video_export_info (x);
1618 void show_video_server_dialog_toggled ()
1620 bool const x = _show_video_server_dialog_button.get_active ();
1621 _rc_config->set_show_video_server_dialog (x);
1624 void video_advanced_setup_toggled ()
1626 bool const x = _video_advanced_setup_button.get_active ();
1627 _rc_config->set_video_advanced_setup(x);
1630 void custom_xjadeo_path_changed ()
1632 UIConfiguration::instance().set_xjadeo_binary (_custom_xjadeo_path.get_text());
1635 void xjadeo_browse_clicked ()
1637 Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN);
1638 dialog.set_filename (UIConfiguration::instance().get_xjadeo_binary());
1639 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1640 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1641 if (dialog.run () == Gtk::RESPONSE_OK) {
1642 const std::string& filename = dialog.get_filename();
1643 if (!filename.empty() && (
1645 Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) ||
1647 Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)
1649 UIConfiguration::instance().set_xjadeo_binary (filename);
1654 void parameter_changed (string const & p)
1656 if (p == "video-server-url") {
1657 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1658 } else if (p == "video-server-docroot") {
1659 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1660 } else if (p == "show-video-export-info") {
1661 bool const x = _rc_config->get_show_video_export_info();
1662 _show_video_export_info_button.set_active (x);
1663 } else if (p == "show-video-server-dialog") {
1664 bool const x = _rc_config->get_show_video_server_dialog();
1665 _show_video_server_dialog_button.set_active (x);
1666 } else if (p == "video-advanced-setup") {
1667 bool const x = _rc_config->get_video_advanced_setup();
1668 _video_advanced_setup_button.set_active(x);
1669 _video_server_docroot_entry.set_sensitive(x);
1670 _video_server_url_entry.set_sensitive(x);
1671 } else if (p == "xjadeo-binary") {
1672 _custom_xjadeo_path.set_text (UIConfiguration::instance().get_xjadeo_binary());
1676 void set_state_from_config ()
1678 parameter_changed ("video-server-url");
1679 parameter_changed ("video-server-docroot");
1680 parameter_changed ("video-monitor-setup-dialog");
1681 parameter_changed ("show-video-export-info");
1682 parameter_changed ("show-video-server-dialog");
1683 parameter_changed ("video-advanced-setup");
1684 parameter_changed ("xjadeo-binary");
1688 RCConfiguration* _rc_config;
1689 Entry _video_server_url_entry;
1690 Entry _video_server_docroot_entry;
1691 Entry _custom_xjadeo_path;
1692 CheckButton _show_video_export_info_button;
1693 CheckButton _show_video_server_dialog_button;
1694 CheckButton _video_advanced_setup_button;
1695 Button _xjadeo_browse_button;
1698 class ColumVisibilityOption : public Option
1701 ColumVisibilityOption (string id, string name, uint32_t n_col, sigc::slot<uint32_t> get, sigc::slot<bool, uint32_t> set)
1708 cb = (CheckButton**) malloc (sizeof (CheckButton*) * n_col);
1709 for (uint32_t i = 0; i < n_col; ++i) {
1710 CheckButton* col = manage (new CheckButton (string_compose (_("Column %1"), i + 1)));
1711 col->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ColumVisibilityOption::column_toggled), i));
1712 _hbox.pack_start (*col);
1715 parameter_changed (id);
1718 ~ColumVisibilityOption () {
1722 Gtk::Widget& tip_widget() { return _hbox; }
1724 void set_state_from_config ()
1726 uint32_t c = _get();
1727 for (uint32_t i = 0; i < _n_col; ++i) {
1728 bool en = (c & (1<<i)) ? true : false;
1729 if (cb[i]->get_active () != en) {
1730 cb[i]->set_active (en);
1735 void add_to_page (OptionEditorPage* p)
1737 _heading.add_to_page (p);
1738 add_widget_to_page (p, &_hbox);
1742 void column_toggled (int b) {
1743 uint32_t c = _get();
1745 if (cb[b]->get_active ()) {
1756 OptionEditorHeading _heading;
1760 sigc::slot<uint32_t> _get;
1761 sigc::slot<bool, uint32_t> _set;
1765 /** A class which allows control of visibility of some editor components usign
1766 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1767 * which has the correct members, but with null widget pointers. This
1768 * class allows the user to set visibility of the members, the details
1769 * of which are stored in a configuration variable which can be watched
1770 * by parts of the editor that actually contain the widgets whose visibility
1771 * is being controlled.
1774 class VisibilityOption : public Option
1777 /** @param name User-visible name for this group.
1778 * @param g `Dummy' VisibilityGroup (as described above).
1779 * @param get Method to get the value of the appropriate configuration variable.
1780 * @param set Method to set the value of the appropriate configuration variable.
1782 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1783 : Option (g->get_state_name(), name)
1785 , _visibility_group (g)
1789 /* Watch for changes made by the user to our members */
1790 _visibility_group->VisibilityChanged.connect_same_thread (
1791 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1795 void set_state_from_config ()
1797 /* Set our state from the current configuration */
1798 _visibility_group->set_state (_get ());
1801 void add_to_page (OptionEditorPage* p)
1803 _heading.add_to_page (p);
1804 add_widget_to_page (p, _visibility_group->list_view ());
1807 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1812 /* The user has changed something, so reflect this change
1813 in the RCConfiguration.
1815 _set (_visibility_group->get_state_value ());
1818 OptionEditorHeading _heading;
1819 VisibilityGroup* _visibility_group;
1820 sigc::slot<std::string> _get;
1821 sigc::slot<bool, std::string> _set;
1822 PBD::ScopedConnection _visibility_group_connection;
1826 class MidiPortOptions : public OptionEditorMiniPage, public sigc::trackable
1831 setup_midi_port_view (midi_output_view, false);
1832 setup_midi_port_view (midi_input_view, true);
1834 OptionEditorHeading* h = new OptionEditorHeading (_("MIDI Inputs"));
1835 h->add_to_page (this);
1837 Gtk::ScrolledWindow* scroller = manage (new Gtk::ScrolledWindow);
1838 scroller->add (midi_input_view);
1839 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1840 scroller->set_size_request (-1, 180);
1842 int n = table.property_n_rows();
1843 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1845 h = new OptionEditorHeading (_("MIDI Outputs"));
1846 h->add_to_page (this);
1848 scroller = manage (new Gtk::ScrolledWindow);
1849 scroller->add (midi_output_view);
1850 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1851 scroller->set_size_request (-1, 180);
1853 n = table.property_n_rows();
1854 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1856 midi_output_view.show ();
1857 midi_input_view.show ();
1859 table.signal_show().connect (sigc::mem_fun (*this, &MidiPortOptions::on_show));
1862 void parameter_changed (string const&) {}
1863 void set_state_from_config() {}
1868 AudioEngine::instance()->PortRegisteredOrUnregistered.connect (connections,
1869 invalidator (*this),
1870 boost::bind (&MidiPortOptions::refill, this),
1872 AudioEngine::instance()->MidiPortInfoChanged.connect (connections,
1873 invalidator (*this),
1874 boost::bind (&MidiPortOptions::refill, this),
1876 AudioEngine::instance()->MidiSelectionPortsChanged.connect (connections,
1877 invalidator (*this),
1878 boost::bind (&MidiPortOptions::refill, this),
1884 if (refill_midi_ports (true, midi_input_view)) {
1885 input_label.show ();
1887 input_label.hide ();
1889 if (refill_midi_ports (false, midi_output_view)) {
1890 output_label.show ();
1892 output_label.hide ();
1897 PBD::ScopedConnectionList connections;
1899 /* MIDI port management */
1900 struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord {
1902 MidiPortColumns () {
1911 Gtk::TreeModelColumn<std::string> pretty_name;
1912 Gtk::TreeModelColumn<bool> music_data;
1913 Gtk::TreeModelColumn<bool> control_data;
1914 Gtk::TreeModelColumn<bool> selection;
1915 Gtk::TreeModelColumn<std::string> name;
1916 Gtk::TreeModelColumn<std::string> filler;
1919 MidiPortColumns midi_port_columns;
1920 Gtk::TreeView midi_input_view;
1921 Gtk::TreeView midi_output_view;
1922 Gtk::Label input_label;
1923 Gtk::Label output_label;
1925 void setup_midi_port_view (Gtk::TreeView&, bool with_selection);
1926 bool refill_midi_ports (bool for_input, Gtk::TreeView&);
1927 void pretty_name_edit (std::string const & path, std::string const & new_text, Gtk::TreeView*);
1928 void midi_music_column_toggled (std::string const & path, Gtk::TreeView*);
1929 void midi_control_column_toggled (std::string const & path, Gtk::TreeView*);
1930 void midi_selection_column_toggled (std::string const & path, Gtk::TreeView*);
1934 MidiPortOptions::setup_midi_port_view (Gtk::TreeView& view, bool with_selection)
1936 int pretty_name_column;
1939 int selection_column;
1940 TreeViewColumn* col;
1943 pretty_name_column = view.append_column_editable (_("Name (click to edit)"), midi_port_columns.pretty_name) - 1;
1945 col = manage (new TreeViewColumn ("", midi_port_columns.music_data));
1946 col->set_alignment (ALIGN_CENTER);
1947 l = manage (new Label (_("Music Data")));
1948 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of music performance data."), PROGRAM_NAME));
1949 col->set_widget (*l);
1951 music_column = view.append_column (*col) - 1;
1953 col = manage (new TreeViewColumn ("", midi_port_columns.control_data));
1954 col->set_alignment (ALIGN_CENTER);
1955 l = manage (new Label (_("Control Data")));
1956 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of control data."), PROGRAM_NAME));
1957 col->set_widget (*l);
1959 control_column = view.append_column (*col) - 1;
1961 if (with_selection) {
1962 col = manage (new TreeViewColumn (_("Follow Selection"), midi_port_columns.selection));
1963 selection_column = view.append_column (*col) - 1;
1964 l = manage (new Label (_("Follow Selection")));
1965 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));
1966 col->set_widget (*l);
1970 /* filler column so that the last real column doesn't expand */
1971 view.append_column ("", midi_port_columns.filler);
1973 CellRendererText* pretty_name_cell = dynamic_cast<CellRendererText*> (view.get_column_cell_renderer (pretty_name_column));
1974 pretty_name_cell->property_editable() = true;
1975 pretty_name_cell->signal_edited().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::pretty_name_edit), &view));
1977 CellRendererToggle* toggle_cell;
1979 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (music_column));
1980 toggle_cell->property_activatable() = true;
1981 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_music_column_toggled), &view));
1983 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (control_column));
1984 toggle_cell->property_activatable() = true;
1985 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_control_column_toggled), &view));
1987 if (with_selection) {
1988 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (selection_column));
1989 toggle_cell->property_activatable() = true;
1990 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_selection_column_toggled), &view));
1993 view.get_selection()->set_mode (SELECTION_NONE);
1994 view.set_tooltip_column (4); /* port "real" name */
1995 view.get_column(0)->set_resizable (true);
1996 view.get_column(0)->set_expand (true);
2000 MidiPortOptions::refill_midi_ports (bool for_input, Gtk::TreeView& view)
2002 using namespace ARDOUR;
2004 std::vector<string> ports;
2006 AudioEngine::instance()->get_known_midi_ports (ports);
2008 if (ports.empty()) {
2013 Glib::RefPtr<ListStore> model = Gtk::ListStore::create (midi_port_columns);
2015 for (vector<string>::const_iterator s = ports.begin(); s != ports.end(); ++s) {
2017 if (AudioEngine::instance()->port_is_mine (*s)) {
2021 PortManager::MidiPortInformation mpi (AudioEngine::instance()->midi_port_information (*s));
2023 if (mpi.pretty_name.empty()) {
2024 /* vanished since get_known_midi_ports() */
2028 if (for_input != mpi.input) {
2032 TreeModel::Row row = *(model->append());
2034 row[midi_port_columns.pretty_name] = mpi.pretty_name;
2035 row[midi_port_columns.music_data] = mpi.properties & MidiPortMusic;
2036 row[midi_port_columns.control_data] = mpi.properties & MidiPortControl;
2037 row[midi_port_columns.selection] = mpi.properties & MidiPortSelection;
2038 row[midi_port_columns.name] = *s;
2041 view.set_model (model);
2047 MidiPortOptions::midi_music_column_toggled (string const & path, TreeView* view)
2049 TreeIter iter = view->get_model()->get_iter (path);
2055 bool new_value = ! bool ((*iter)[midi_port_columns.music_data]);
2057 /* don't reset model - wait for MidiPortInfoChanged signal */
2060 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2062 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2067 MidiPortOptions::midi_control_column_toggled (string const & path, TreeView* view)
2069 TreeIter iter = view->get_model()->get_iter (path);
2075 bool new_value = ! bool ((*iter)[midi_port_columns.control_data]);
2077 /* don't reset model - wait for MidiPortInfoChanged signal */
2080 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2082 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2087 MidiPortOptions::midi_selection_column_toggled (string const & path, TreeView* view)
2089 TreeIter iter = view->get_model()->get_iter (path);
2095 bool new_value = ! bool ((*iter)[midi_port_columns.selection]);
2097 /* don't reset model - wait for MidiSelectionPortsChanged signal */
2100 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2102 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2107 MidiPortOptions::pretty_name_edit (std::string const & path, string const & new_text, Gtk::TreeView* view)
2109 TreeIter iter = view->get_model()->get_iter (path);
2115 AudioEngine::instance()->set_midi_port_pretty_name ((*iter)[midi_port_columns.name], new_text);
2121 RCOptionEditor::RCOptionEditor ()
2122 : OptionEditorContainer (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
2123 , Tabbable (*this, _("Preferences")
2125 , false // detached by default (first start, no instant.xml)
2127 ) /* pack self-as-vbox into tabbable */
2128 , _rc_config (Config)
2129 , _mixer_strip_visibility ("mixer-element-visibility")
2131 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
2135 uint32_t hwcpus = hardware_concurrency ();
2139 add_option (_("General"), new OptionEditorHeading (_("DSP CPU Utilization")));
2141 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
2143 _("Signal processing uses"),
2144 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
2145 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
2148 procs->add (-1, _("all but one processor"));
2149 procs->add (0, _("all available processors"));
2151 for (uint32_t i = 1; i <= hwcpus; ++i) {
2152 procs->add (i, string_compose (P_("%1 processor", "%1 processors", i), i));
2155 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
2157 add_option (_("General"), procs);
2160 /* Image cache size */
2161 add_option (_("General"), new OptionEditorHeading (_("Memory Usage")));
2163 HSliderOption *sics = new HSliderOption ("waveform-cache-size",
2164 _("Waveform image cache size (megabytes)"),
2165 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
2166 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size),
2167 1, 1024, 10 /* 1 MB to 1GB in steps of 10MB */
2169 sics->scale().set_digits (0);
2170 Gtkmm2ext::UI::instance()->set_tip (
2172 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
2173 add_option (_("General"), sics);
2175 add_option (_("General"), new OptionEditorHeading (_("Engine")));
2177 add_option (_("General"),
2179 "try-autostart-engine",
2180 _("Try to auto-launch audio/midi engine"),
2181 sigc::mem_fun (*_rc_config, &RCConfiguration::get_try_autostart_engine),
2182 sigc::mem_fun (*_rc_config, &RCConfiguration::set_try_autostart_engine)
2185 add_option (_("General"), new OptionEditorHeading (_("Automation")));
2187 add_option (_("General"),
2188 new SpinOption<double> (
2189 "automation-thinning-factor",
2190 _("Thinning factor (larger value => less data)"),
2191 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
2192 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
2196 add_option (_("General"),
2197 new SpinOption<double> (
2198 "automation-interval-msecs",
2199 _("Automation sampling interval (milliseconds)"),
2200 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
2201 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
2205 add_option (_("General"), new OptionEditorHeading (_("Tempo")));
2207 bo = new BoolOption (
2208 "allow-non-quarter-pulse",
2209 _("Allow non quarter-note pulse"),
2210 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_allow_non_quarter_pulse),
2211 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_allow_non_quarter_pulse)
2213 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2214 string_compose (_("<b>When enabled</b> %1 will allow tempo to be expressed in divisions per minute\n"
2215 "<b>When disabled</b> %1 will only allow tempo to be expressed in quarter notes per minute"),
2217 add_option (_("General"), bo);
2219 if (!ARDOUR::Profile->get_mixbus()) {
2220 add_option (_("General"), new OptionEditorHeading (_("GUI Lock")));
2221 /* Lock GUI timeout */
2223 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2224 _("Lock timeout (seconds)"),
2225 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
2226 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds),
2229 slts->scale().set_digits (0);
2230 Gtkmm2ext::UI::instance()->set_tip (
2232 _("Lock GUI after this many idle seconds (zero to never lock)"));
2233 add_option (_("General"), slts);
2236 add_option (_("General/Session"), new OptionEditorHeading (S_("Options|Undo")));
2238 add_option (_("General/Session"), new UndoOptions (_rc_config));
2240 add_option (_("General/Session"),
2242 "verify-remove-last-capture",
2243 _("Verify removal of last capture"),
2244 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
2245 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
2248 add_option (_("General/Session"), new OptionEditorHeading (_("Session Management")));
2250 add_option (_("General/Session"),
2252 "periodic-safety-backups",
2253 _("Make periodic backups of the session file"),
2254 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
2255 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
2258 add_option (_("General/Session"),
2260 "only-copy-imported-files",
2261 _("Always copy imported files"),
2262 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
2263 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
2266 add_option (_("General/Session"), new DirectoryOption (
2267 X_("default-session-parent-dir"),
2268 _("Default folder for new sessions:"),
2269 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
2270 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
2273 add_option (_("General/Session"),
2274 new SpinOption<uint32_t> (
2275 "max-recent-sessions",
2276 _("Maximum number of recent sessions"),
2277 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
2278 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
2285 add_option (_("General/Translation"), new OptionEditorHeading (_("Internationalization")));
2287 bo = new BoolOption (
2288 "enable-translation",
2289 _("Use translations"),
2290 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2291 sigc::ptr_fun (ARDOUR::set_translations_enabled)
2294 bo->set_note (string_compose (_("These settings will only take effect after %1 is restarted (if available for your language preferences)."), PROGRAM_NAME));
2296 add_option (_("General/Translation"), bo);
2298 parameter_changed ("enable-translation");
2299 #endif // ENABLE_NLS
2304 add_option (_("Editor"), new OptionEditorHeading (_("General")));
2306 bo = new BoolOption (
2308 _("Prompt for new marker names"),
2309 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2310 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2312 add_option (_("Editor"), bo);
2313 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."
2314 "\n\nYou can always rename markers by right-clicking on them"));
2316 add_option (_("Editor"),
2318 "draggable-playhead",
2319 _("Allow dragging of playhead"),
2320 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2321 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2324 ComboOption<float>* dps = new ComboOption<float> (
2325 "draggable-playhead-speed",
2326 _("Playhead dragging speed (%)"),
2327 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead_speed),
2328 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead_speed)
2330 dps->add (0.05, _("5%"));
2331 dps->add (0.1, _("10%"));
2332 dps->add (0.25, _("25%"));
2333 dps->add (0.5, _("50%"));
2334 dps->add (1.0, _("100%"));
2335 add_option (_("Editor"), dps);
2337 ComboOption<float>* eet = new ComboOption<float> (
2338 "extra-ui-extents-time",
2339 _("Limit zooming & summary view to X minutes beyond session extents"),
2340 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_extra_ui_extents_time),
2341 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_extra_ui_extents_time)
2343 eet->add (1, _("1 minute"));
2344 eet->add (2, _("2 minutes"));
2345 eet->add (20, _("20 minutes"));
2346 eet->add (60, _("1 hour"));
2347 eet->add (60*2, _("2 hours"));
2348 eet->add (60*24, _("24 hours"));
2349 add_option (_("Editor"), eet);
2351 if (!Profile->get_mixbus()) {
2353 add_option (_("Editor"),
2355 "use-mouse-position-as-zoom-focus-on-scroll",
2356 _("Zoom to mouse position when zooming with scroll wheel"),
2357 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2358 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2362 add_option (_("Editor"),
2364 "use-time-rulers-to-zoom-with-vertical-drag",
2365 _("Zoom with vertical drag in rulers"),
2366 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag),
2367 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag)
2370 add_option (_("Editor"),
2372 "use-double-click-to-zoom-to-selection",
2373 _("Double click zooms to selection"),
2374 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection),
2375 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection)
2378 add_option (_("Editor"),
2380 "update-editor-during-summary-drag",
2381 _("Update editor window during drags of the summary"),
2382 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2383 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2386 add_option (_("Editor"),
2388 "autoscroll-editor",
2389 _("Auto-scroll editor window when dragging near its edges"),
2390 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2391 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2394 add_option (_("Editor"),
2395 new BoolComboOption (
2396 "show-region-gain-envelopes",
2397 _("Show gain envelopes in audio regions"),
2399 _("only in Draw and Internal Edit modes"),
2400 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2401 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2404 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2406 add_option (_("Editor"),
2408 "automation-follows-regions",
2409 _("Move relevant automation when audio regions are moved"),
2410 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2411 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2414 bo = new BoolOption (
2415 "new-automation-points-on-lane",
2416 _("Ignore Y-axis click position when adding new automation-points"),
2417 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_new_automation_points_on_lane),
2418 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_new_automation_points_on_lane)
2420 add_option (_("Editor"), bo);
2421 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2422 _("<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."));
2424 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2425 "default-fade-shape",
2426 _("Default fade shape"),
2427 sigc::mem_fun (*_rc_config,
2428 &RCConfiguration::get_default_fade_shape),
2429 sigc::mem_fun (*_rc_config,
2430 &RCConfiguration::set_default_fade_shape)
2433 fadeshape->add (FadeLinear,
2434 _("Linear (for highly correlated material)"));
2435 fadeshape->add (FadeConstantPower, _("Constant power"));
2436 fadeshape->add (FadeSymmetric, _("Symmetric"));
2437 fadeshape->add (FadeSlow, _("Slow"));
2438 fadeshape->add (FadeFast, _("Fast"));
2440 add_option (_("Editor"), fadeshape);
2442 ComboOption<RegionEquivalence> *eqv = new ComboOption<RegionEquivalence> (
2443 "region-equivalence",
2444 _("Regions in active edit groups are edited together"),
2445 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_equivalence),
2446 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_equivalence)
2449 eqv->add (Overlap, _("whenever they overlap in time"));
2450 eqv->add (Enclosed, _("if either encloses the other"));
2451 eqv->add (Exact, _("only if they have identical length, position and origin"));
2453 add_option (_("Editor"), eqv);
2455 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2457 _("Layering model"),
2458 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2459 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2462 lm->add (LaterHigher, _("later is higher"));
2463 lm->add (Manual, _("manual layering"));
2464 add_option (_("Editor"), lm);
2466 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2467 "region-selection-after-split",
2468 _("After splitting selected regions, select"),
2469 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2470 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2472 // TODO: decide which of these modes are really useful
2473 rsas->add(None, _("no regions"));
2474 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2475 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2476 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2477 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2478 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2479 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2480 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2482 add_option (_("Editor"), rsas);
2484 add_option (_("Editor/Snap"), new OptionEditorHeading (_("General Snap options:")));
2486 add_option (_("Editor/Snap"),
2487 new SpinOption<uint32_t> (
2489 _("Snap Threshold (pixels)"),
2490 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_threshold),
2491 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_threshold),
2496 add_option (_("Editor/Snap"),
2498 "show-snapped-cursor",
2499 _("Show \"snapped cursor\""),
2500 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_snapped_cursor),
2501 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_snapped_cursor)
2504 add_option (_("Editor/Snap"),
2506 "rubberbanding-snaps-to-grid",
2507 _("Snap rubberband selection to grid"),
2508 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2509 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2512 add_option (_("Editor/Snap"),
2514 "grid-follows-internal",
2515 _("Grid switches to alternate selection for Internal Edit tools"),
2516 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_grid_follows_internal),
2517 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_grid_follows_internal)
2520 add_option (_("Editor/Snap"),
2522 "rulers-follow-grid",
2523 _("Rulers automatically change to follow the Grid mode selection"),
2524 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rulers_follow_grid),
2525 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rulers_follow_grid)
2528 add_option (_("Editor/Snap"), new OptionEditorHeading (_("When \"Snap\" is enabled, snap to:")));
2531 add_option (_("Editor/Snap"),
2535 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_marks),
2536 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_marks)
2539 add_option (_("Editor/Snap"),
2541 "snap-to-region-sync",
2542 _("Region Sync Points"),
2543 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_region_sync),
2544 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_region_sync)
2547 add_option (_("Editor/Snap"),
2549 "snap-to-region-start",
2551 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_region_start),
2552 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_region_start)
2555 add_option (_("Editor/Snap"),
2557 "snap-to-region-end",
2559 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_region_end),
2560 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_region_end)
2563 add_option (_("Editor/Snap"),
2567 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_snap_to_grid),
2568 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_snap_to_grid)
2571 add_option (_("Editor/Modifiers"), new OptionEditorHeading (_("Keyboard Modifiers")));
2572 add_option (_("Editor/Modifiers"), new KeyboardOptions);
2573 add_option (_("Editor/Modifiers"), new OptionEditorBlank ());
2575 /* MIXER -- SOLO AND MUTE */
2577 add_option (_("Mixer"), new OptionEditorHeading (_("Solo")));
2579 _solo_control_is_listen_control = new BoolOption (
2580 "solo-control-is-listen-control",
2581 _("Solo controls are Listen controls"),
2582 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2583 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2586 add_option (_("Mixer"), _solo_control_is_listen_control);
2588 add_option (_("Mixer"),
2591 _("Exclusive solo"),
2592 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2593 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2596 add_option (_("Mixer"),
2599 _("Show solo muting"),
2600 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2601 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2604 add_option (_("Mixer"),
2606 "solo-mute-override",
2607 _("Soloing overrides muting"),
2608 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2609 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2612 add_option (_("Mixer"),
2615 _("Solo-in-place mute cut (dB)"),
2616 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2617 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2620 _listen_position = new ComboOption<ListenPosition> (
2622 _("Listen Position"),
2623 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2624 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2627 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2628 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2630 add_option (_("Mixer"), _listen_position);
2632 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2634 _("PFL signals come from"),
2635 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2636 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2639 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2640 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2642 add_option (_("Mixer"), pp);
2644 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2646 _("AFL signals come from"),
2647 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2648 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2651 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2652 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2654 add_option (_("Mixer"), pa);
2656 add_option (_("Mixer"), new OptionEditorHeading (_("Default Track / Bus Muting Options")));
2658 add_option (_("Mixer"),
2660 "mute-affects-pre-fader",
2661 _("Mute affects pre-fader sends"),
2662 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2663 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2666 add_option (_("Mixer"),
2668 "mute-affects-post-fader",
2669 _("Mute affects post-fader sends"),
2670 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2671 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2674 add_option (_("Mixer"),
2676 "mute-affects-control-outs",
2677 _("Mute affects control outputs"),
2678 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2679 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2682 add_option (_("Mixer"),
2684 "mute-affects-main-outs",
2685 _("Mute affects main outputs"),
2686 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2687 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2691 if (!ARDOUR::Profile->get_mixbus()) {
2692 add_option (_("Mixer"), new OptionEditorHeading (_("Send Routing")));
2693 add_option (_("Mixer"),
2695 "link-send-and-route-panner",
2696 _("Link panners of Aux and External Sends with main panner by default"),
2697 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2698 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2704 add_option (_("Signal Flow"), new OptionEditorHeading (_("Monitoring")));
2706 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2708 _("Record monitoring handled by"),
2709 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2710 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2713 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2714 mm->add (HardwareMonitoring, _("via Audio Driver"));
2717 string prog (PROGRAM_NAME);
2718 boost::algorithm::to_lower (prog);
2719 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2720 mm->add (ExternalMonitoring, _("audio hardware"));
2722 add_option (_("Signal Flow"), mm);
2724 bo = new BoolOption (
2725 "tape-machine-mode",
2726 _("Tape machine mode"),
2727 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2728 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2730 add_option (_("Signal Flow"), bo);
2731 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2732 string_compose (_("<b>When enabled</b> %1 will not monitor a track's input if the transport is stopped."),
2735 if (!Profile->get_mixbus()) {
2737 add_option (_("Signal Flow"), new OptionEditorHeading (_("Track and Bus Connections")));
2739 add_option (_("Signal Flow"),
2741 "auto-connect-standard-busses",
2742 _("Auto-connect master/monitor busses"),
2743 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2744 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2747 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2748 "input-auto-connect",
2749 _("Connect track inputs"),
2750 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2751 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2754 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2755 iac->add (ManualConnect, _("manually"));
2757 add_option (_("Signal Flow"), iac);
2759 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2760 "output-auto-connect",
2761 _("Connect track and bus outputs"),
2762 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2763 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2766 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2767 oac->add (AutoConnectMaster, _("automatically to master bus"));
2768 oac->add (ManualConnect, _("manually"));
2770 add_option (_("Signal Flow"), oac);
2772 bo = new BoolOption (
2774 _("Use 'Strict-I/O' for new tracks or busses"),
2775 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2776 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2779 add_option (_("Signal Flow"), bo);
2780 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2781 _("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."));
2788 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2790 add_option (_("Audio"), new BufferingOptions (_rc_config));
2792 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2794 add_option (_("Audio"),
2796 "denormal-protection",
2797 _("Use DC bias to protect against denormals"),
2798 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2799 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2802 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2804 _("Processor handling"),
2805 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2806 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2810 dm->add (DenormalNone, _("no processor handling"));
2812 FPU* fpu = FPU::instance();
2814 if (fpu->has_flush_to_zero()) {
2816 dm->add (DenormalFTZ, _("use FlushToZero"));
2817 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2818 _rc_config->set_denormal_model(DenormalNone);
2821 if (fpu->has_denormals_are_zero()) {
2823 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2824 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2825 _rc_config->set_denormal_model(DenormalNone);
2828 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2830 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2831 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2832 _rc_config->set_denormal_model(DenormalNone);
2836 dm->set_sensitive(false);
2839 add_option (_("Audio"), dm);
2841 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2843 add_option (_("Audio"),
2845 "auto-analyse-audio",
2846 _("Enable automatic analysis of audio"),
2847 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2848 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2851 add_option (_("Audio"),
2853 "replicate-missing-region-channels",
2854 _("Replicate missing region channels"),
2855 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2856 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2861 add_option (_("MIDI"), new OptionEditorHeading (_("Buffering")));
2863 add_option (_("MIDI"),
2864 new SpinOption<float> (
2866 _("MIDI read-ahead time (seconds)"),
2867 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2868 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2873 add_option (_("MIDI"), new OptionEditorHeading (_("Session")));
2875 add_option (_("MIDI"),
2876 new SpinOption<int32_t> (
2877 "initial-program-change",
2878 _("Initial program change"),
2879 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2880 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2884 add_option (_("MIDI"), new OptionEditorHeading (_("Audition")));
2886 add_option (_("MIDI"),
2889 _("Sound MIDI notes as they are selected in the editor"),
2890 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2891 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2894 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2895 "midi-audition-synth-uri",
2896 _("MIDI Audition Synth (LV2)"),
2897 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2898 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2901 audition_synth->add(X_(""), _("None"));
2902 PluginInfoList all_plugs;
2903 PluginManager& manager (PluginManager::instance());
2905 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2907 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2908 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2909 if (!(*i)->is_instrument()) continue;
2910 if ((*i)->type != ARDOUR::LV2) continue;
2911 if ((*i)->name.length() > 46) {
2912 audition_synth->add((*i)->unique_id, (*i)->name.substr (0, 44) + "...");
2914 audition_synth->add((*i)->unique_id, (*i)->name);
2919 add_option (_("MIDI"), audition_synth);
2923 add_option (_("Metronome"), new OptionEditorHeading (_("Metronome")));
2924 add_option (_("Metronome"), new ClickOptions (_rc_config));
2925 add_option (_("Metronome"), new OptionEditorHeading (_("Options")));
2927 bo = new BoolOption (
2928 "click-record-only",
2929 _("Enable metronome only while recording"),
2930 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_record_only),
2931 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_record_only)
2934 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2935 string_compose (_("<b>When enabled</b> the metronome will remain silent if %1 is <b>not recording</b>."), PROGRAM_NAME));
2936 add_option (_("Metronome"), bo);
2937 add_option (_("Metronome"), new OptionEditorBlank ());
2942 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2944 ComboOption<float>* mht = new ComboOption<float> (
2946 _("Peak hold time"),
2947 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
2948 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
2951 mht->add (MeterHoldOff, _("off"));
2952 mht->add (MeterHoldShort, _("short"));
2953 mht->add (MeterHoldMedium, _("medium"));
2954 mht->add (MeterHoldLong, _("long"));
2956 add_option (S_("Preferences|Metering"), mht);
2958 ComboOption<float>* mfo = new ComboOption<float> (
2961 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2962 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2965 mfo->add (METER_FALLOFF_OFF, _("off"));
2966 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2967 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2968 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2969 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2970 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2971 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
2973 add_option (S_("Preferences|Metering"), mfo);
2975 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2976 "meter-line-up-level",
2977 _("Meter line-up level; 0dBu"),
2978 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
2979 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
2982 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2983 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2984 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2985 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2987 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."));
2989 add_option (S_("Preferences|Metering"), mlu);
2991 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2992 "meter-line-up-din",
2993 _("IEC1/DIN Meter line-up level; 0dBu"),
2994 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
2995 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
2998 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2999 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3000 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3001 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3003 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
3005 add_option (S_("Preferences|Metering"), mld);
3007 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
3008 "meter-vu-standard",
3009 _("VU Meter standard"),
3010 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
3011 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
3014 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
3015 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
3016 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
3017 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
3019 add_option (S_("Preferences|Metering"), mvu);
3021 HSliderOption *mpks = new HSliderOption("meter-peak",
3022 _("Peak indicator threshold [dBFS]"),
3023 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
3024 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak),
3028 Gtkmm2ext::UI::instance()->set_tip (
3030 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
3032 add_option (S_("Preferences|Metering"), mpks);
3034 OptionEditorHeading* default_meter_head = new OptionEditorHeading (_("Default Meter Types"));
3035 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."));
3037 add_option (S_("Preferences|Metering"), default_meter_head);
3039 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3040 "meter-type-master",
3041 _("Default Meter Type for Master Bus"),
3042 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3043 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3045 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3046 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3047 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3048 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3049 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3050 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3051 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3052 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3054 add_option (S_("Preferences|Metering"), mtm);
3057 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3059 _("Default meter type for busses"),
3060 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3061 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3063 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3064 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3065 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3066 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3067 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3068 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3069 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3070 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3072 add_option (S_("Preferences|Metering"), mtb);
3074 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3076 _("Default meter type for tracks"),
3077 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3078 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3080 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3081 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3083 add_option (S_("Preferences|Metering"), mtt);
3085 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
3087 add_option (S_("Preferences|Metering"),
3089 "save-export-analysis-image",
3090 _("Save loudness analysis as image file"),
3091 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
3092 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
3095 /* TRANSPORT & Sync */
3097 add_option (_("Transport"), new OptionEditorHeading (_("General")));
3099 bo = new BoolOption (
3100 "stop-at-session-end",
3101 _("Stop at the end of the session"),
3102 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
3103 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
3105 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3106 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
3107 "when it reaches the current session end marker\n\n"
3108 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
3110 add_option (_("Transport"), bo);
3112 bo = new BoolOption (
3113 "latched-record-enable",
3114 _("Keep record-enable engaged on stop"),
3115 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
3116 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
3118 add_option (_("Transport"), bo);
3119 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3120 _("<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."));
3122 bo = new BoolOption (
3123 "disable-disarm-during-roll",
3124 _("Disable per-track record disarm while rolling"),
3125 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
3126 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
3128 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."));
3129 add_option (_("Transport"), bo);
3131 bo = new BoolOption (
3133 _("12dB gain reduction during fast-forward and fast-rewind"),
3134 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
3135 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
3137 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3138 _("<b>When enabled</b> this will reduce the unpleasant increase in perceived volume "
3139 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
3140 add_option (_("Transport"), bo);
3142 ComboOption<float>* psc = new ComboOption<float> (
3145 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
3146 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
3148 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
3149 (_("The amount of preroll to apply when <b>Play with Preroll</b> or <b>Record with Preroll</b>is initiated.\n\n"
3150 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
3151 psc->add (-4.0, _("4 Bars"));
3152 psc->add (-2.0, _("2 Bars"));
3153 psc->add (-1.0, _("1 Bar"));
3154 psc->add (0.0, _("0 (no pre-roll)"));
3155 psc->add (0.1, _("0.1 second"));
3156 psc->add (0.25, _("0.25 second"));
3157 psc->add (0.5, _("0.5 second"));
3158 psc->add (1.0, _("1.0 second"));
3159 psc->add (2.0, _("2.0 seconds"));
3160 add_option (_("Transport"), psc);
3163 add_option (_("Transport"), new OptionEditorHeading (_("Looping")));
3165 bo = new BoolOption (
3167 _("Play loop is a transport mode"),
3168 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
3169 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
3171 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3172 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
3173 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
3174 add_option (_("Transport"), bo);
3176 bo = new BoolOption (
3178 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
3179 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
3180 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
3182 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3183 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
3184 "preventing any need to do a transport locate at the end of the loop\n\n"
3185 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
3186 "which will often cause a small click or delay"), PROGRAM_NAME));
3187 add_option (_("Transport"), bo);
3189 add_option (_("Transport"), new OptionEditorHeading (_("Dropout (xrun) Handling")));
3190 bo = new BoolOption (
3191 "stop-recording-on-xrun",
3192 _("Stop recording when an xrun occurs"),
3193 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
3194 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
3196 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3197 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
3199 add_option (_("Transport"), bo);
3201 bo = new BoolOption (
3202 "create-xrun-marker",
3203 _("Create markers where xruns occur"),
3204 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
3205 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
3207 add_option (_("Transport"), bo);
3212 add_option (_("Sync"), new OptionEditorHeading (_("Transport Masters")));
3214 add_option (_("Sync"), new WidgetOption (X_("foo"), X_("Transport Masters"), _transport_masters_widget));
3216 _sync_framerate = new BoolOption (
3217 "timecode-sync-frame-rate",
3218 _("Match session video frame rate to external timecode"),
3219 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
3220 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
3222 Gtkmm2ext::UI::instance()->set_tip
3223 (_sync_framerate->tip_widget(),
3224 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
3225 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
3226 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
3227 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
3228 "timecode standard and the session standard."), PROGRAM_NAME));
3230 add_option (_("Sync"), _sync_framerate);
3232 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Generator")));
3234 add_option (_("Sync/LTC"),
3237 _("Enable LTC generator"),
3238 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
3239 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
3242 _ltc_send_continuously = new BoolOption (
3243 "ltc-send-continuously",
3244 _("Send LTC while stopped"),
3245 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
3246 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
3248 Gtkmm2ext::UI::instance()->set_tip
3249 (_ltc_send_continuously->tip_widget(),
3250 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
3251 add_option (_("Sync/LTC"), _ltc_send_continuously);
3253 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level [dBFS]"),
3254 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_output_volume),
3255 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_output_volume),
3259 Gtkmm2ext::UI::instance()->set_tip
3260 (_ltc_volume_slider->tip_widget(),
3261 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
3263 add_option (_("Sync/LTC"), _ltc_volume_slider);
3266 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Beat Clock (Mclk) Generator")));
3268 add_option (_("Sync/MIDI"),
3271 _("Enable Mclk generator"),
3272 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
3273 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
3276 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC) Generator")));
3278 add_option (_("Sync/MIDI"),
3281 _("Enable MTC Generator"),
3282 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
3283 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
3286 add_option (_("Sync/MIDI"),
3287 new SpinOption<int> (
3288 "mtc-qf-speed-tolerance",
3289 _("Percentage either side of normal transport speed to transmit MTC"),
3290 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
3291 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
3295 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Machine Control (MMC)")));
3297 add_option (_("Sync/MIDI"),
3300 _("Respond to MMC commands"),
3301 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
3302 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
3305 add_option (_("Sync/MIDI"),
3308 _("Send MMC commands"),
3309 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
3310 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
3313 add_option (_("Sync/MIDI"),
3314 new SpinOption<uint8_t> (
3315 "mmc-receive-device-id",
3316 _("Inbound MMC device ID"),
3317 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
3318 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
3322 add_option (_("Sync/MIDI"),
3323 new SpinOption<uint8_t> (
3324 "mmc-send-device-id",
3325 _("Outbound MMC device ID"),
3326 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
3327 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
3332 /* Control Surfaces */
3334 add_option (_("Control Surfaces"), new OptionEditorHeading (_("Control Surfaces")));
3335 add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
3338 add_option (_("MIDI Ports"), new OptionEditorHeading (_("MIDI Port Options")));
3340 add_option (_("MIDI Ports"),
3342 "midi-input-follows-selection",
3343 _("MIDI input follows MIDI track selection"),
3344 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
3345 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
3348 add_option (_("MIDI Ports"), new MidiPortOptions ());
3349 add_option (_("MIDI Ports"), new OptionEditorBlank ());
3353 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3354 add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
3355 add_option (_("Plugins"),
3356 new RcActionButton (_("Scan for Plugins"),
3357 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3361 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
3363 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3364 bo = new BoolOption (
3365 "show-plugin-scan-window",
3366 _("Always Display Plugin Scan Progress"),
3367 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
3368 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
3370 add_option (_("Plugins"), bo);
3371 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3372 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
3375 bo = new BoolOption (
3376 "plugins-stop-with-transport",
3377 _("Silence plugins when the transport is stopped"),
3378 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
3379 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
3381 add_option (_("Plugins"), bo);
3382 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3383 _("<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."));
3385 bo = new BoolOption (
3386 "new-plugins-active",
3387 _("Make new plugins active"),
3388 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
3389 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
3391 add_option (_("Plugins"), bo);
3392 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3393 _("<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"));
3395 #if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
3396 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
3398 add_option (_("Plugins/VST"),
3399 new RcActionButton (_("Scan for Plugins"),
3400 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3403 #if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
3404 bo = new BoolOption (
3406 _("Enable Mac VST support (requires restart or re-scan)"),
3407 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
3408 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
3410 add_option (_("Plugins/VST"), bo);
3413 bo = new BoolOption (
3414 "discover-vst-on-start",
3415 _("Scan for [new] VST Plugins on Application Start"),
3416 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
3417 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
3419 add_option (_("Plugins/VST"), bo);
3420 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3421 _("<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"));
3423 #ifdef WINDOWS_VST_SUPPORT
3424 // currently verbose logging is only implemented for Windows VST.
3425 bo = new BoolOption (
3426 "verbose-plugin-scan",
3427 _("Verbose Plugin Scan"),
3428 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
3429 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
3431 add_option (_("Plugins/VST"), bo);
3432 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3433 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
3436 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
3438 add_option (_("Plugins/VST"),
3439 new RcActionButton (_("Clear"),
3440 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
3443 add_option (_("Plugins/VST"),
3444 new RcActionButton (_("Clear"),
3445 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
3446 _("VST Blacklist:")));
3449 #ifdef LXVST_SUPPORT
3450 add_option (_("Plugins/VST"),
3451 new RcActionButton (_("Edit"),
3452 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
3453 _("Linux VST Path:")));
3455 add_option (_("Plugins/VST"),
3456 new RcConfigDisplay (
3457 "plugin-path-lxvst",
3459 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
3463 #ifdef WINDOWS_VST_SUPPORT
3464 add_option (_("Plugins/VST"),
3465 new RcActionButton (_("Edit"),
3466 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
3467 _("Windows VST Path:")));
3468 add_option (_("Plugins/VST"),
3469 new RcConfigDisplay (
3472 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
3476 #ifdef AUDIOUNIT_SUPPORT
3478 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
3480 add_option (_("Plugins/Audio Unit"),
3481 new RcActionButton (_("Scan for Plugins"),
3482 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3485 bo = new BoolOption (
3486 "discover-audio-units",
3487 _("Scan for [new] AudioUnit Plugins on Application Start"),
3488 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
3489 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
3491 add_option (_("Plugins/Audio Unit"), bo);
3492 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3493 _("<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."));
3495 add_option (_("Plugins/Audio Unit"),
3496 new RcActionButton (_("Clear"),
3497 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
3500 add_option (_("Plugins/Audio Unit"),
3501 new RcActionButton (_("Clear"),
3502 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
3503 _("AU Blacklist:")));
3506 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
3507 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
3508 add_option (_("Plugins"),
3510 "open-gui-after-adding-plugin",
3511 _("Automatically open the plugin GUI when adding a new plugin"),
3512 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
3513 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3516 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3517 add_option (_("Plugins"),
3519 "show-inline-display-by-default",
3520 _("Show Plugin Inline Display on Mixerstrip by default"),
3521 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3522 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3525 _plugin_prefer_inline = new BoolOption (
3526 "prefer-inline-over-gui",
3527 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3528 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3529 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3531 add_option (_("Plugins"), _plugin_prefer_inline);
3534 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3536 bo = new BoolOption (
3537 "ask-replace-instrument",
3538 _("Ask to replace existing instrument plugin"),
3539 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3540 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3542 add_option (_("Plugins"), bo);
3544 bo = new BoolOption (
3545 "ask-setup_instrument",
3546 _("Interactively configure instrument plugins on insert"),
3547 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3548 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3550 add_option (_("Plugins"), bo);
3551 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3552 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3555 add_option (_("Plugins"), new OptionEditorBlank ());
3558 #if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
3559 add_option (_("Appearance"), new OptionEditorHeading (_("Graphics Acceleration")));
3562 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3563 BoolOption* bgc = new BoolOption (
3564 "cairo-image-surface",
3565 _("Disable Graphics Hardware Acceleration (requires restart)"),
3566 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3567 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3570 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3571 _("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));
3572 add_option (_("Appearance"), bgc);
3575 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3576 BoolOption* bgo = new BoolOption (
3578 _("Possibly improve slow graphical performance (requires restart)"),
3579 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3580 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3583 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));
3584 add_option (_("Appearance"), bgo);
3586 add_option (_("Appearance"), new OptionEditorHeading (_("Graphical User Interface")));
3588 add_option (_("Appearance"),
3591 _("Highlight widgets on mouseover"),
3592 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3593 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3596 add_option (_("Appearance"),
3599 _("Show tooltips if mouse hovers over a control"),
3600 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3601 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3604 bo = new BoolOption (
3605 "super-rapid-clock-update",
3606 _("Update clocks at TC Frame rate"),
3607 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3608 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3610 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3611 _("<b>When enabled</b> clock displays are updated every Timecode Frame (fps).\n\n"
3612 "<b>When disabled</b> clock displays are updated only every 100ms."
3614 add_option (_("Appearance"), bo);
3616 add_option (_("Appearance"),
3619 _("Blink Rec-Arm buttons"),
3620 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_rec_arm),
3621 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_rec_arm)
3624 add_option (_("Appearance"),
3626 "blink-alert-indicators",
3627 _("Blink Alert Indicators"),
3628 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_alert_indicators),
3629 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_alert_indicators)
3634 /* font scaling does nothing with GDK/Quartz */
3635 add_option (_("Appearance"), new FontScalingOptions ());
3637 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("General")));
3638 add_option (_("Appearance/Editor"),
3640 "show-name-highlight",
3641 _("Use name highlight bars in region displays (requires a restart)"),
3642 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3643 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3646 add_option (_("Appearance/Editor"),
3648 "color-regions-using-track-color",
3649 _("Region color follows track color"),
3650 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_color_regions_using_track_color),
3651 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_color_regions_using_track_color)
3654 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Waveforms")));
3656 if (!Profile->get_mixbus()) {
3657 add_option (_("Appearance/Editor"),
3660 _("Show waveforms in regions"),
3661 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
3662 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
3666 add_option (_("Appearance/Editor"),
3668 "show-waveforms-while-recording",
3669 _("Show waveforms while recording"),
3670 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
3671 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
3674 add_option (_("Appearance/Editor"),
3676 "show-waveform-clipping",
3677 _("Show waveform clipping"),
3678 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveform_clipping),
3679 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveform_clipping)
3682 add_option (_("Appearance/Editor"), new ClipLevelOptions ());
3684 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
3686 _("Waveform scale"),
3687 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
3688 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
3691 wfs->add (Linear, _("linear"));
3692 wfs->add (Logarithmic, _("logarithmic"));
3694 add_option (_("Appearance/Editor"), wfs);
3696 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
3698 _("Waveform shape"),
3699 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
3700 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
3703 wfsh->add (Traditional, _("traditional"));
3704 wfsh->add (Rectified, _("rectified"));
3706 add_option (_("Appearance/Editor"), wfsh);
3708 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Editor Meters")));
3710 add_option (_("Appearance/Editor"),
3712 "show-track-meters",
3713 _("Show meters in track headers"),
3714 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3715 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3718 add_option (_("Appearance/Editor"),
3720 "editor-stereo-only-meters",
3721 _("Limit track header meters to stereo"),
3722 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3723 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3726 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("MIDI Regions")));
3728 add_option (_("Appearance/Editor"),
3730 "display-first-midi-bank-as-zero",
3731 _("Display first MIDI bank/program as 0"),
3732 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
3733 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
3736 add_option (_("Appearance/Editor"),
3738 "never-display-periodic-midi",
3739 _("Don't display periodic (MTC, MMC) SysEx messages in MIDI Regions"),
3740 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
3741 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
3745 add_option (_("Appearance/Editor"),
3747 "use-note-bars-for-velocity",
3748 _("Show velocity horizontally inside notes"),
3749 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_note_bars_for_velocity),
3750 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_note_bars_for_velocity)
3753 add_option (_("Appearance/Editor"),
3755 "use-note-color-for-velocity",
3756 _("Use colors to show note velocity"),
3757 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_note_color_for_velocity),
3758 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_note_color_for_velocity)
3761 add_option (_("Appearance/Editor"), new OptionEditorBlank ());
3763 /* The names of these controls must be the same as those given in MixerStrip
3764 for the actual widgets being controlled.
3766 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3767 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3768 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3769 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3770 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3771 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3772 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3774 add_option (_("Appearance/Mixer"),
3775 new VisibilityOption (
3777 &_mixer_strip_visibility,
3778 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3779 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3783 add_option (_("Appearance/Mixer"),
3785 "default-narrow_ms",
3786 _("Use narrow strips in the mixer for new strips by default"),
3787 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3788 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3791 add_option (_("Appearance/Mixer"), new OptionEditorBlank ());
3793 add_option (_("Appearance/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items")));
3795 add_option (_("Appearance/Toolbar"),
3797 "show-toolbar-recpunch",
3798 _("Display Record/Punch Options"),
3799 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_recpunch),
3800 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_recpunch)
3803 add_option (_("Appearance/Toolbar"),
3805 "show-toolbar-monitoring",
3806 _("Display Monitor Options"),
3807 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_monitoring),
3808 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_monitoring)
3811 add_option (_("Appearance/Toolbar"),
3813 "show-toolbar-selclock",
3814 _("Display Selection Clock"),
3815 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
3816 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
3819 if (!ARDOUR::Profile->get_small_screen()) {
3820 add_option (_("Appearance/Toolbar"),
3822 "show-secondary-clock",
3823 _("Display Secondary Clock"),
3824 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
3825 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
3829 add_option (_("Appearance/Toolbar"),
3831 "show-mini-timeline",
3832 _("Display Navigation Timeline"),
3833 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
3834 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
3837 add_option (_("Appearance/Toolbar"),
3839 "show-editor-meter",
3840 _("Display Master Level Meter"),
3841 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
3842 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
3845 add_option (_("Appearance/Toolbar"),
3846 new ColumVisibilityOption (
3847 "action-table-columns", _("Display Action-Buttons"), 4,
3848 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3849 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3852 add_option (_("Appearance/Toolbar"), new OptionEditorBlank ());
3855 /* and now the theme manager */
3857 add_option (_("Appearance/Theme"), new OptionEditorHeading (_("Theme")));
3859 add_option (_("Appearance/Theme"), new BoolOption (
3861 _("Draw \"flat\" buttons"),
3862 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_flat_buttons),
3863 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_flat_buttons)
3866 add_option (_("Appearance/Theme"), new BoolOption (
3868 _("Draw \"boxy\" buttons"),
3869 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_boxy_buttons),
3870 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_boxy_buttons)
3873 add_option (_("Appearance/Theme"), new BoolOption (
3875 _("LED meter style"),
3876 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3877 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3881 HSliderOption *gui_hs = new HSliderOption(
3882 "timeline-item-gradient-depth",
3883 _("Waveforms color gradient depth"),
3884 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_gradient_depth),
3885 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_gradient_depth),
3888 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3889 add_option (_("Appearance/Theme"), gui_hs);
3891 gui_hs = new HSliderOption(
3892 "timeline-item-gradient-depth",
3893 _("Timeline item gradient depth"),
3894 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_timeline_item_gradient_depth),
3895 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_timeline_item_gradient_depth),
3898 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3899 add_option (_("Appearance/Theme"), gui_hs);
3901 vector<string> icon_sets = ::get_icon_sets ();
3902 if (icon_sets.size() > 1) {
3903 ComboOption<std::string>* io = new ComboOption<std::string> (
3904 "icon-set", _("Icon Set"),
3905 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_icon_set),
3906 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_icon_set)
3908 for (vector<string>::const_iterator i = icon_sets.begin (); i != icon_sets.end (); ++i) {
3911 add_option (_("Appearance/Theme"), io);
3914 add_option (_("Appearance/Colors"), new OptionEditorHeading (_("Colors")));
3915 add_option (_("Appearance/Colors"), new ColorThemeManager);
3916 add_option (_("Appearance/Colors"), new OptionEditorBlank ());
3920 OptionEditorHeading* quirks_head = new OptionEditorHeading (_("Various Workarounds for Windowing Systems"));
3922 quirks_head->set_note (string_compose (_("Rules for closing, minimizing, maximizing, and stay-on-top can vary \
3923 with each version of your OS, and the preferences that you've set in your OS.\n\n\
3924 You can adjust the options, below, to change how %1's windows and dialogs behave.\n\n\
3925 These settings will only take effect after %1 is restarted.\n\
3928 add_option (_("Appearance/Quirks"), quirks_head);
3930 bo = new BoolOption (
3931 "use-wm-visibility",
3932 _("Use visibility information provided by your Window Manager/Desktop"),
3933 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3934 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3936 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3937 _("If you have trouble toggling between hidden Editor and Mixer windows, try changing this setting."));
3938 add_option (_("Appearance/Quirks"), bo);
3941 bo = new BoolOption (
3942 "all-floating-windows-are-dialogs",
3943 _("All floating windows are dialogs"),
3944 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_all_floating_windows_are_dialogs),
3945 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_all_floating_windows_are_dialogs)
3947 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3948 _("Mark all floating windows to be type \"Dialog\" rather than using \"Utility\" for some.\nThis may help with some window managers."));
3949 add_option (_("Appearance/Quirks"), bo);
3951 bo = new BoolOption (
3952 "transients-follow-front",
3953 _("Transient windows follow front window."),
3954 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_transients_follow_front),
3955 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_transients_follow_front)
3957 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3958 _("Make transient windows follow the front window when toggling between the editor and mixer."));
3959 add_option (_("Appearance/Quirks"), bo);
3962 if (!Profile->get_mixbus()) {
3963 bo = new BoolOption (
3964 "floating-monitor-section",
3965 _("Float detached monitor-section window"),
3966 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_floating_monitor_section),
3967 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_floating_monitor_section)
3969 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3970 _("When detaching the monitoring section, mark it as \"Utility\" window to stay in front."));
3971 add_option (_("Appearance/Quirks"), bo);
3974 add_option (_("Appearance/Quirks"), new OptionEditorBlank ());
3976 /* VIDEO Timeline */
3977 add_option (_("Video"), new OptionEditorHeading (_("Video Server")));
3978 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
3980 Widget::show_all ();
3982 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3983 parameter_changed ("send-ltc");
3984 parameter_changed ("sync-source");
3985 parameter_changed ("use-monitor-bus");
3986 parameter_changed ("open-gui-after-adding-plugin");
3988 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
3990 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
3991 (Gtk::StateType) here !!!
3993 Tabbable::set_state (*node, Stateful::loading_state_version);
3996 set_current_page (_("General"));
4000 RCOptionEditor::set_session (Session *s)
4002 SessionHandlePtr::set_session (s);
4003 _transport_masters_widget.set_session (s);
4007 RCOptionEditor::parameter_changed (string const & p)
4009 OptionEditor::parameter_changed (p);
4011 if (p == "use-monitor-bus") {
4012 bool const s = Config->get_use_monitor_bus ();
4014 /* we can't use this if we don't have a monitor bus */
4015 Config->set_solo_control_is_listen_control (false);
4017 _solo_control_is_listen_control->set_sensitive (s);
4018 _listen_position->set_sensitive (s);
4019 } else if (p == "sync-source") {
4020 boost::shared_ptr<TransportMaster> tm (TransportMasterManager::instance().current());
4021 if (boost::dynamic_pointer_cast<TimecodeTransportMaster> (tm)) {
4022 _sync_framerate->set_sensitive (true);
4024 _sync_framerate->set_sensitive (false);
4026 } else if (p == "send-ltc") {
4027 bool const s = Config->get_send_ltc ();
4028 _ltc_send_continuously->set_sensitive (s);
4029 _ltc_volume_slider->set_sensitive (s);
4030 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
4031 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
4032 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
4037 void RCOptionEditor::plugin_scan_refresh () {
4038 PluginManager::instance().refresh();
4041 void RCOptionEditor::clear_vst_cache () {
4042 PluginManager::instance().clear_vst_cache();
4045 void RCOptionEditor::clear_vst_blacklist () {
4046 PluginManager::instance().clear_vst_blacklist();
4049 void RCOptionEditor::clear_au_cache () {
4050 PluginManager::instance().clear_au_cache();
4053 void RCOptionEditor::clear_au_blacklist () {
4054 PluginManager::instance().clear_au_blacklist();
4057 void RCOptionEditor::edit_lxvst_path () {
4058 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
4059 PathsDialog *pd = new PathsDialog (
4060 *current_toplevel(), _("Set Linux VST Search Path"),
4061 _rc_config->get_plugin_path_lxvst(),
4062 PluginManager::instance().get_default_lxvst_path()
4064 ResponseType r = (ResponseType) pd->run ();
4066 if (r == RESPONSE_ACCEPT) {
4067 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
4069 MessageDialog msg (_("Re-scan Plugins now?"),
4070 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
4071 msg.set_default_response (Gtk::RESPONSE_YES);
4072 if (msg.run() == Gtk::RESPONSE_YES) {
4074 plugin_scan_refresh ();
4080 void RCOptionEditor::edit_vst_path () {
4081 PathsDialog *pd = new PathsDialog (
4082 *current_toplevel(), _("Set Windows VST Search Path"),
4083 _rc_config->get_plugin_path_vst(),
4084 PluginManager::instance().get_default_windows_vst_path()
4086 ResponseType r = (ResponseType) pd->run ();
4088 if (r == RESPONSE_ACCEPT) {
4089 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
4090 MessageDialog msg (_("Re-scan Plugins now?"),
4091 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
4092 msg.set_default_response (Gtk::RESPONSE_YES);
4093 if (msg.run() == Gtk::RESPONSE_YES) {
4095 plugin_scan_refresh ();
4102 RCOptionEditor::use_own_window (bool and_fill_it)
4104 bool new_window = !own_window ();
4106 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
4108 if (win && new_window) {
4109 win->set_name ("PreferencesWindow");
4110 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
4112 win->set_resizable (false);
4119 RCOptionEditor::get_state ()
4121 XMLNode* node = new XMLNode (X_("Preferences"));
4122 node->add_child_nocopy (Tabbable::get_state());