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/slider_controller.h>
38 #include <gtkmm2ext/gtk_ui.h>
39 #include <gtkmm2ext/paths_dialog.h>
40 #include <gtkmm2ext/window_title.h>
46 #include "ardour/audio_backend.h"
47 #include "ardour/audioengine.h"
48 #include "ardour/profile.h"
49 #include "ardour/dB.h"
50 #include "ardour/rc_configuration.h"
51 #include "ardour/control_protocol_manager.h"
52 #include "ardour/port_manager.h"
53 #include "ardour/plugin_manager.h"
54 #include "control_protocol/control_protocol.h"
56 #include "canvas/wave_view.h"
58 #include "ardour_dialog.h"
59 #include "ardour_ui.h"
60 #include "ardour_window.h"
61 #include "color_theme_manager.h"
62 #include "gui_thread.h"
64 #include "meter_patterns.h"
65 #include "midi_tracer.h"
66 #include "rc_option_editor.h"
69 #include "ui_config.h"
74 using namespace Gtkmm2ext;
76 using namespace ARDOUR;
77 using namespace ARDOUR_UI_UTILS;
79 class ClickOptions : public OptionEditorMiniPage
82 ClickOptions (RCConfiguration* c)
84 , _click_browse_button (_("Browse..."))
85 , _click_emphasis_browse_button (_("Browse..."))
87 // TODO get rid of GTK -> use OptionEditor Widgets
90 Label* l = manage (left_aligned_label (_("Emphasis on first beat")));
91 _use_emphasis_on_click_check_button.add (*l);
92 t->attach (_use_emphasis_on_click_check_button, 1, 3, 0, 1, FILL);
93 _use_emphasis_on_click_check_button.signal_toggled().connect (
94 sigc::mem_fun (*this, &ClickOptions::use_emphasis_on_click_toggled));
96 l = manage (left_aligned_label (_("Use built-in default sounds")));
97 _use_default_click_check_button.add (*l);
98 t->attach (_use_default_click_check_button, 1, 3, 1, 2, FILL);
99 _use_default_click_check_button.signal_toggled().connect (
100 sigc::mem_fun (*this, &ClickOptions::use_default_click_toggled));
102 l = manage (left_aligned_label (_("Audio file:")));
103 t->attach (*l, 1, 2, 2, 3, FILL);
104 t->attach (_click_path_entry, 2, 3, 2, 3, FILL);
105 _click_browse_button.signal_clicked ().connect (
106 sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
107 t->attach (_click_browse_button, 3, 4, 2, 3, FILL);
109 l = manage (left_aligned_label (_("Emphasis audio file:")));
110 t->attach (*l, 1, 2, 3, 4, FILL);
111 t->attach (_click_emphasis_path_entry, 2, 3, 3, 4, FILL);
112 _click_emphasis_browse_button.signal_clicked ().connect (
113 sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
114 t->attach (_click_emphasis_browse_button, 3, 4, 3, 4, FILL);
116 FaderOption* fo = new FaderOption (
119 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
120 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
123 fo->add_to_page (this);
124 fo->set_state_from_config ();
126 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
127 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
129 if (_rc_config->get_click_sound ().empty() &&
130 _rc_config->get_click_emphasis_sound().empty()) {
131 _use_default_click_check_button.set_active (true);
132 _use_emphasis_on_click_check_button.set_active (true);
135 _use_default_click_check_button.set_active (false);
136 _use_emphasis_on_click_check_button.set_active (false);
140 void parameter_changed (string const & p)
142 if (p == "click-sound") {
143 _click_path_entry.set_text (_rc_config->get_click_sound());
144 } else if (p == "click-emphasis-sound") {
145 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
146 } else if (p == "use-click-emphasis") {
147 bool x = _rc_config->get_use_click_emphasis ();
148 _use_emphasis_on_click_check_button.set_active (x);
152 void set_state_from_config ()
154 parameter_changed ("click-sound");
155 parameter_changed ("click-emphasis-sound");
156 parameter_changed ("use-click-emphasis");
161 void click_browse_clicked ()
163 SoundFileChooser sfdb (_("Choose Click"));
168 if (sfdb.run () == RESPONSE_OK) {
169 click_chosen (sfdb.get_filename());
173 void click_chosen (string const & path)
175 _click_path_entry.set_text (path);
176 _rc_config->set_click_sound (path);
179 void click_changed ()
181 click_chosen (_click_path_entry.get_text ());
184 void click_emphasis_browse_clicked ()
186 SoundFileChooser sfdb (_("Choose Click Emphasis"));
191 if (sfdb.run () == RESPONSE_OK) {
192 click_emphasis_chosen (sfdb.get_filename());
196 void click_emphasis_chosen (string const & path)
198 _click_emphasis_path_entry.set_text (path);
199 _rc_config->set_click_emphasis_sound (path);
202 void click_emphasis_changed ()
204 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
207 void use_default_click_toggled ()
209 if (_use_default_click_check_button.get_active ()) {
210 _rc_config->set_click_sound ("");
211 _rc_config->set_click_emphasis_sound ("");
212 _click_path_entry.set_sensitive (false);
213 _click_emphasis_path_entry.set_sensitive (false);
214 _click_browse_button.set_sensitive (false);
215 _click_emphasis_browse_button.set_sensitive (false);
217 _click_path_entry.set_sensitive (true);
218 _click_emphasis_path_entry.set_sensitive (true);
219 _click_browse_button.set_sensitive (true);
220 _click_emphasis_browse_button.set_sensitive (true);
224 void use_emphasis_on_click_toggled ()
226 if (_use_emphasis_on_click_check_button.get_active ()) {
227 _rc_config->set_use_click_emphasis(true);
229 _rc_config->set_use_click_emphasis(false);
233 RCConfiguration* _rc_config;
234 CheckButton _use_default_click_check_button;
235 CheckButton _use_emphasis_on_click_check_button;
236 Entry _click_path_entry;
237 Entry _click_emphasis_path_entry;
238 Button _click_browse_button;
239 Button _click_emphasis_browse_button;
242 class UndoOptions : public OptionEditorComponent
245 UndoOptions (RCConfiguration* c) :
247 _limit_undo_button (_("Limit undo history to")),
248 _save_undo_button (_("Save undo history of"))
250 // TODO get rid of GTK -> use OptionEditor SpinOption
251 _limit_undo_spin.set_range (0, 512);
252 _limit_undo_spin.set_increments (1, 10);
254 _save_undo_spin.set_range (0, 512);
255 _save_undo_spin.set_increments (1, 10);
257 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
258 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
259 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
260 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
263 void parameter_changed (string const & p)
265 if (p == "history-depth") {
266 int32_t const d = _rc_config->get_history_depth();
267 _limit_undo_button.set_active (d != 0);
268 _limit_undo_spin.set_sensitive (d != 0);
269 _limit_undo_spin.set_value (d);
270 } else if (p == "save-history") {
271 bool const x = _rc_config->get_save_history ();
272 _save_undo_button.set_active (x);
273 _save_undo_spin.set_sensitive (x);
274 } else if (p == "save-history-depth") {
275 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
279 void set_state_from_config ()
281 parameter_changed ("save-history");
282 parameter_changed ("history-depth");
283 parameter_changed ("save-history-depth");
286 void limit_undo_toggled ()
288 bool const x = _limit_undo_button.get_active ();
289 _limit_undo_spin.set_sensitive (x);
290 int32_t const n = x ? 16 : 0;
291 _limit_undo_spin.set_value (n);
292 _rc_config->set_history_depth (n);
295 void limit_undo_changed ()
297 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
300 void save_undo_toggled ()
302 bool const x = _save_undo_button.get_active ();
303 _rc_config->set_save_history (x);
306 void save_undo_changed ()
308 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
311 void add_to_page (OptionEditorPage* p)
313 int const n = p->table.property_n_rows();
314 Table* t = & p->table;
316 t->resize (n + 2, 3);
318 Label* l = manage (left_aligned_label (_("commands")));
319 HBox* box = manage (new HBox());
320 box->set_spacing (4);
321 box->pack_start (_limit_undo_spin, false, false);
322 box->pack_start (*l, true, true);
323 t->attach (_limit_undo_button, 1, 2, n, n +1, FILL);
324 t->attach (*box, 2, 3, n, n + 1, FILL | EXPAND);
326 l = manage (left_aligned_label (_("commands")));
327 box = manage (new HBox());
328 box->set_spacing (4);
329 box->pack_start (_save_undo_spin, false, false);
330 box->pack_start (*l, true, true);
331 t->attach (_save_undo_button, 1, 2, n + 1, n + 2, FILL);
332 t->attach (*box, 2, 3, n + 1, n + 2, FILL | EXPAND);
335 Gtk::Widget& tip_widget() {
336 return _limit_undo_button; // unused
340 RCConfiguration* _rc_config;
341 CheckButton _limit_undo_button;
342 SpinButton _limit_undo_spin;
343 CheckButton _save_undo_button;
344 SpinButton _save_undo_spin;
348 static const struct {
360 { "Key|Shift", GDK_SHIFT_MASK },
361 { "Command", GDK_MOD2_MASK },
362 { "Control", GDK_CONTROL_MASK },
363 { "Option", GDK_MOD1_MASK },
364 { "Command-Shift", GDK_MOD2_MASK|GDK_SHIFT_MASK },
365 { "Command-Option", GDK_MOD2_MASK|GDK_MOD1_MASK },
366 { "Command-Control", GDK_MOD2_MASK|GDK_CONTROL_MASK },
367 { "Command-Option-Control", GDK_MOD2_MASK|GDK_MOD1_MASK|GDK_CONTROL_MASK },
368 { "Option-Control", GDK_MOD1_MASK|GDK_CONTROL_MASK },
369 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
370 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
371 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_MOD2_MASK },
374 { "Key|Shift", GDK_SHIFT_MASK },
375 { "Control", GDK_CONTROL_MASK },
376 { "Alt", GDK_MOD1_MASK },
377 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
378 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
379 { "Control-Windows", GDK_CONTROL_MASK|GDK_MOD4_MASK },
380 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
381 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
382 { "Alt-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
383 { "Alt-Shift-Windows", GDK_MOD1_MASK|GDK_SHIFT_MASK|GDK_MOD4_MASK },
384 { "Mod2", GDK_MOD2_MASK },
385 { "Mod3", GDK_MOD3_MASK },
386 { "Windows", GDK_MOD4_MASK },
387 { "Mod5", GDK_MOD5_MASK },
393 class KeyboardOptions : public OptionEditorMiniPage
397 : _delete_button_adjustment (3, 1, 12)
398 , _delete_button_spin (_delete_button_adjustment)
399 , _edit_button_adjustment (3, 1, 5)
400 , _edit_button_spin (_edit_button_adjustment)
401 , _insert_note_button_adjustment (3, 1, 5)
402 , _insert_note_button_spin (_insert_note_button_adjustment)
404 // TODO get rid of GTK -> use OptionEditor Widgets
406 const std::string restart_msg = _("\nChanges to this setting will only persist after your project has been saved.");
407 /* internationalize and prepare for use with combos */
410 for (int i = 0; modifiers[i].name; ++i) {
411 dumb.push_back (S_(modifiers[i].name));
414 set_popdown_strings (_edit_modifier_combo, dumb);
415 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
416 Gtkmm2ext::UI::instance()->set_tip (_edit_modifier_combo,
417 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
424 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
425 l->set_name ("OptionsLabel");
429 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
430 strs.push_back (bf->first);
433 set_popdown_strings (_keyboard_layout_selector, strs);
434 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
435 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
437 t->attach (*l, col + 1, col + 2, row, row + 1, FILL, FILL);
438 t->attach (_keyboard_layout_selector, col + 2, col + 3, row, row + 1, FILL | EXPAND, FILL);
443 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Clicking:"))));
444 l->set_name ("OptionEditorHeading");
445 l->set_use_markup (true);
446 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
451 l = manage (left_aligned_label (_("Edit using:")));
452 l->set_name ("OptionsLabel");
454 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
455 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
457 l = manage (new Label (_("+ button")));
458 l->set_name ("OptionsLabel");
460 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
461 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, SHRINK , FILL);
463 _edit_button_spin.set_name ("OptionsEntry");
464 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
469 set_popdown_strings (_delete_modifier_combo, dumb);
470 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
471 Gtkmm2ext::UI::instance()->set_tip (_delete_modifier_combo,
472 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
474 l = manage (left_aligned_label (_("Delete using:")));
475 l->set_name ("OptionsLabel");
477 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
478 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
480 l = manage (new Label (_("+ button")));
481 l->set_name ("OptionsLabel");
483 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
484 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, SHRINK, FILL);
486 _delete_button_spin.set_name ("OptionsEntry");
487 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
492 set_popdown_strings (_insert_note_modifier_combo, dumb);
493 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
494 Gtkmm2ext::UI::instance()->set_tip (_insert_note_modifier_combo,
495 (string_compose (_("<b>Recommended Setting: %1 + button 1 (left mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
497 l = manage (left_aligned_label (_("Insert note using:")));
498 l->set_name ("OptionsLabel");
500 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
501 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
503 l = manage (new Label (_("+ button")));
504 l->set_name ("OptionsLabel");
506 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
507 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, SHRINK, FILL);
509 _insert_note_button_spin.set_name ("OptionsEntry");
510 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
514 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Beginning a Drag:"))));
515 l->set_name ("OptionEditorHeading");
516 l->set_use_markup (true);
517 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
523 set_popdown_strings (_copy_modifier_combo, dumb);
524 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
525 Gtkmm2ext::UI::instance()->set_tip (_copy_modifier_combo,
526 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
528 Keyboard::secondary_modifier_name (),
530 Keyboard::primary_modifier_name (),
534 l = manage (left_aligned_label (_("Copy items using:")));
535 l->set_name ("OptionsLabel");
537 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
538 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
543 /* constraint modifier */
544 set_popdown_strings (_constraint_modifier_combo, dumb);
545 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
546 Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo,
547 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
549 Keyboard::primary_modifier_name (),
551 Keyboard::tertiary_modifier_name (),
555 l = manage (left_aligned_label (_("Constrain drag using:")));
556 l->set_name ("OptionsLabel");
558 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
559 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
565 set_popdown_strings (_push_points_combo, dumb);
566 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
568 std::string mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
569 Gtkmm2ext::UI::instance()->set_tip (_push_points_combo,
570 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
572 l = manage (left_aligned_label (_("Push points using:")));
573 l->set_name ("OptionsLabel");
575 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
576 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
580 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Beginning a Trim:"))));
581 l->set_name ("OptionEditorHeading");
582 l->set_use_markup (true);
583 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
589 set_popdown_strings (_trim_contents_combo, dumb);
590 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
591 Gtkmm2ext::UI::instance()->set_tip (_trim_contents_combo,
592 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
594 l = manage (left_aligned_label (_("Trim contents using:")));
595 l->set_name ("OptionsLabel");
597 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
598 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
604 set_popdown_strings (_trim_anchored_combo, dumb);
605 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
607 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::tertiary_modifier_name ());
608 Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo,
609 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
611 l = manage (left_aligned_label (_("Anchored trim using:")));
612 l->set_name ("OptionsLabel");
614 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
616 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
621 /* jump trim disabled for now
622 set_popdown_strings (_trim_jump_combo, dumb);
623 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
625 l = manage (left_aligned_label (_("Jump after trim using:")));
626 l->set_name ("OptionsLabel");
628 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
630 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
636 /* note resize relative */
637 set_popdown_strings (_note_size_relative_combo, dumb);
638 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
639 Gtkmm2ext::UI::instance()->set_tip (_note_size_relative_combo,
640 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg))); // XXX 2ndary
642 l = manage (left_aligned_label (_("Resize notes relatively using:")));
643 l->set_name ("OptionsLabel");
645 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
647 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
651 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Dragging:"))));
652 l->set_name ("OptionEditorHeading");
653 l->set_use_markup (true);
654 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
660 set_popdown_strings (_snap_modifier_combo, dumb);
661 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
663 mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ());
665 mod_str = Keyboard::secondary_modifier_name();
667 Gtkmm2ext::UI::instance()->set_tip (_snap_modifier_combo,
668 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
670 l = manage (left_aligned_label (_("Ignore snap using:")));
671 l->set_name ("OptionsLabel");
673 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
674 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
680 set_popdown_strings (_snap_delta_combo, dumb);
681 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
683 mod_str = Keyboard::level4_modifier_name ();
685 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::level4_modifier_name ());
687 Gtkmm2ext::UI::instance()->set_tip (_snap_delta_combo,
688 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
690 l = manage (left_aligned_label (_("Snap relatively using:")));
691 l->set_name ("OptionsLabel");
693 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
694 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
698 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Trimming:"))));
699 l->set_name ("OptionEditorHeading");
700 l->set_use_markup (true);
701 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
707 set_popdown_strings (_trim_overlap_combo, dumb);
708 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
710 Gtkmm2ext::UI::instance()->set_tip (_trim_overlap_combo,
711 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
713 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
714 l->set_name ("OptionsLabel");
716 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
717 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
721 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Dragging Control Points:"))));
722 l->set_name ("OptionEditorHeading");
723 l->set_use_markup (true);
724 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
730 set_popdown_strings (_fine_adjust_combo, dumb);
731 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
733 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::secondary_modifier_name ()); // XXX just 2ndary ?!
734 Gtkmm2ext::UI::instance()->set_tip (_fine_adjust_combo,
735 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
737 l = manage (left_aligned_label (_("Fine adjust using:")));
738 l->set_name ("OptionsLabel");
740 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
741 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
743 OptionEditorHeading* h = new OptionEditorHeading (_("Reset"));
744 h->add_to_page (this);
746 RcActionButton* rb = new RcActionButton (_("Reset to recommended defaults"),
747 sigc::mem_fun (*this, &KeyboardOptions::reset_to_defaults));
748 rb->add_to_page (this);
750 set_state_from_config ();
753 void parameter_changed (string const &)
755 /* XXX: these aren't really config options... */
758 void set_state_from_config ()
760 _delete_button_adjustment.set_value (Keyboard::delete_button());
761 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
762 _edit_button_adjustment.set_value (Keyboard::edit_button());
764 for (int x = 0; modifiers[x].name; ++x) {
765 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
766 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
768 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
769 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
771 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
772 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
774 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
775 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
777 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
778 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
780 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
781 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
783 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
784 _push_points_combo.set_active_text (S_(modifiers[x].name));
786 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
787 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
789 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
790 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
793 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
794 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
797 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
798 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
800 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
801 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
803 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
804 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
806 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
807 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
812 void add_to_page (OptionEditorPage* p)
814 int const n = p->table.property_n_rows();
815 p->table.resize (n + 1, 3);
816 p->table.attach (box, 1, 3, n, n + 1, FILL | EXPAND, SHRINK, 0, 0);
821 void bindings_changed ()
823 string const txt = _keyboard_layout_selector.get_active_text();
825 /* XXX: config...? for all this keyboard stuff */
827 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
828 if (txt == i->first) {
829 if (Keyboard::load_keybindings (i->second)) {
830 Keyboard::save_keybindings ();
836 void edit_modifier_chosen ()
838 string const txt = _edit_modifier_combo.get_active_text();
840 for (int i = 0; modifiers[i].name; ++i) {
841 if (txt == S_(modifiers[i].name)) {
842 Keyboard::set_edit_modifier (modifiers[i].modifier);
848 void delete_modifier_chosen ()
850 string const txt = _delete_modifier_combo.get_active_text();
852 for (int i = 0; modifiers[i].name; ++i) {
853 if (txt == S_(modifiers[i].name)) {
854 Keyboard::set_delete_modifier (modifiers[i].modifier);
860 void copy_modifier_chosen ()
862 string const txt = _copy_modifier_combo.get_active_text();
864 for (int i = 0; modifiers[i].name; ++i) {
865 if (txt == S_(modifiers[i].name)) {
866 Keyboard::set_copy_modifier (modifiers[i].modifier);
872 void insert_note_modifier_chosen ()
874 string const txt = _insert_note_modifier_combo.get_active_text();
876 for (int i = 0; modifiers[i].name; ++i) {
877 if (txt == S_(modifiers[i].name)) {
878 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
884 void snap_modifier_chosen ()
886 string const txt = _snap_modifier_combo.get_active_text();
888 for (int i = 0; modifiers[i].name; ++i) {
889 if (txt == S_(modifiers[i].name)) {
890 Keyboard::set_snap_modifier (modifiers[i].modifier);
896 void snap_delta_modifier_chosen ()
898 string const txt = _snap_delta_combo.get_active_text();
900 for (int i = 0; modifiers[i].name; ++i) {
901 if (txt == S_(modifiers[i].name)) {
902 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
908 void constraint_modifier_chosen ()
910 string const txt = _constraint_modifier_combo.get_active_text();
912 for (int i = 0; modifiers[i].name; ++i) {
913 if (txt == S_(modifiers[i].name)) {
914 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
920 void trim_contents_modifier_chosen ()
922 string const txt = _trim_contents_combo.get_active_text();
924 for (int i = 0; modifiers[i].name; ++i) {
925 if (txt == S_(modifiers[i].name)) {
926 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
932 void trim_overlap_modifier_chosen ()
934 string const txt = _trim_overlap_combo.get_active_text();
936 for (int i = 0; modifiers[i].name; ++i) {
937 if (txt == S_(modifiers[i].name)) {
938 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
944 void trim_anchored_modifier_chosen ()
946 string const txt = _trim_anchored_combo.get_active_text();
948 for (int i = 0; modifiers[i].name; ++i) {
949 if (txt == S_(modifiers[i].name)) {
950 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
956 void fine_adjust_modifier_chosen ()
958 string const txt = _fine_adjust_combo.get_active_text();
960 for (int i = 0; modifiers[i].name; ++i) {
961 if (txt == S_(modifiers[i].name)) {
962 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
968 void push_points_modifier_chosen ()
970 string const txt = _push_points_combo.get_active_text();
972 for (int i = 0; modifiers[i].name; ++i) {
973 if (txt == S_(modifiers[i].name)) {
974 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
980 void note_size_relative_modifier_chosen ()
982 string const txt = _note_size_relative_combo.get_active_text();
984 for (int i = 0; modifiers[i].name; ++i) {
985 if (txt == S_(modifiers[i].name)) {
986 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
992 void delete_button_changed ()
994 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
997 void edit_button_changed ()
999 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
1002 void insert_note_button_changed ()
1004 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
1007 void reset_to_defaults ()
1010 Keyboard::set_edit_modifier (Keyboard::PrimaryModifier);
1011 Keyboard::set_edit_button (3);
1012 Keyboard::set_delete_modifier (Keyboard::TertiaryModifier);
1013 Keyboard::set_delete_button (3);
1014 Keyboard::set_insert_note_modifier (Keyboard::PrimaryModifier);
1015 Keyboard::set_insert_note_button (1);
1017 /* when beginning a drag */
1019 Keyboard::set_copy_modifier (Keyboard::SecondaryModifier);
1021 Keyboard::set_copy_modifier (Keyboard::PrimaryModifier);
1025 ArdourKeyboard::set_constraint_modifier (Keyboard::PrimaryModifier);
1027 ArdourKeyboard::set_constraint_modifier (Keyboard::TertiaryModifier);
1029 ArdourKeyboard::set_push_points_modifier (Keyboard::PrimaryModifier | Keyboard::Level4Modifier);
1031 /* when beginning a trim */
1032 ArdourKeyboard::set_trim_contents_modifier (Keyboard::PrimaryModifier);
1033 ArdourKeyboard::set_trim_anchored_modifier (Keyboard::PrimaryModifier | Keyboard::TertiaryModifier);
1034 ArdourKeyboard::set_note_size_relative_modifier (Keyboard::TertiaryModifier); // XXX better: 2ndary
1036 /* while dragging */
1038 Keyboard::set_snap_modifier (Keyboard::TertiaryModifier);
1040 Keyboard::set_snap_modifier (Keyboard::SecondaryModifier);
1043 Keyboard::set_snap_delta_modifier (Keyboard::Level4Modifier);
1045 Keyboard::set_snap_delta_modifier (Keyboard::SecondaryModifier | Keyboard::Level4Modifier);
1048 /* while trimming */
1049 ArdourKeyboard::set_trim_overlap_modifier (Keyboard::TertiaryModifier);
1051 /* while dragging ctrl points */
1052 ArdourKeyboard::set_fine_adjust_modifier (/*Keyboard::PrimaryModifier | */Keyboard::SecondaryModifier); // XXX
1054 set_state_from_config ();
1057 ComboBoxText _keyboard_layout_selector;
1058 ComboBoxText _edit_modifier_combo;
1059 ComboBoxText _delete_modifier_combo;
1060 ComboBoxText _copy_modifier_combo;
1061 ComboBoxText _insert_note_modifier_combo;
1062 ComboBoxText _snap_modifier_combo;
1063 ComboBoxText _snap_delta_combo;
1064 ComboBoxText _constraint_modifier_combo;
1065 ComboBoxText _trim_contents_combo;
1066 ComboBoxText _trim_overlap_combo;
1067 ComboBoxText _trim_anchored_combo;
1068 ComboBoxText _trim_jump_combo;
1069 ComboBoxText _fine_adjust_combo;
1070 ComboBoxText _push_points_combo;
1071 ComboBoxText _note_size_relative_combo;
1072 Adjustment _delete_button_adjustment;
1073 SpinButton _delete_button_spin;
1074 Adjustment _edit_button_adjustment;
1075 SpinButton _edit_button_spin;
1076 Adjustment _insert_note_button_adjustment;
1077 SpinButton _insert_note_button_spin;
1081 class FontScalingOptions : public HSliderOption
1084 FontScalingOptions ()
1085 : HSliderOption ("font-scale", _("GUI and Font scaling"),
1086 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_font_scale),
1087 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_font_scale),
1091 const std::string dflt = _("100%");
1092 const std::string empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
1094 _hscale.set_name("FontScaleSlider");
1095 _hscale.set_draw_value(false);
1096 _hscale.add_mark(50, Gtk::POS_TOP, empty);
1097 _hscale.add_mark(60, Gtk::POS_TOP, empty);
1098 _hscale.add_mark(70, Gtk::POS_TOP, empty);
1099 _hscale.add_mark(80, Gtk::POS_TOP, empty);
1100 _hscale.add_mark(90, Gtk::POS_TOP, empty);
1101 _hscale.add_mark(100, Gtk::POS_TOP, dflt);
1102 _hscale.add_mark(125, Gtk::POS_TOP, empty);
1103 _hscale.add_mark(150, Gtk::POS_TOP, empty);
1104 _hscale.add_mark(175, Gtk::POS_TOP, empty);
1105 _hscale.add_mark(200, Gtk::POS_TOP, empty);
1106 _hscale.add_mark(250, Gtk::POS_TOP, empty);
1108 set_note (_("Adjusting the scale requires an application restart to re-layout."));
1113 HSliderOption::changed ();
1114 /* XXX: should be triggered from the parameter changed signal */
1115 UIConfiguration::instance().reset_dpi ();
1119 class VstTimeOutSliderOption : public HSliderOption
1122 VstTimeOutSliderOption (RCConfiguration* c)
1123 : HSliderOption ("vst-scan-timeout", _("Scan Time Out"),
1124 sigc::mem_fun (*c, &RCConfiguration::get_vst_scan_timeout),
1125 sigc::mem_fun (*c, &RCConfiguration::set_vst_scan_timeout),
1128 _label.set_alignment (1.0, 0.5); // match buttons below
1129 _hscale.set_digits (0);
1130 _hscale.set_draw_value(false);
1131 _hscale.add_mark( 0, Gtk::POS_TOP, _("\u221e")); // infinity
1132 _hscale.add_mark( 300, Gtk::POS_TOP, _("30 sec"));
1133 _hscale.add_mark( 600, Gtk::POS_TOP, _("1 min"));
1134 _hscale.add_mark(1200, Gtk::POS_TOP, _("2 mins"));
1135 _hscale.add_mark(1800, Gtk::POS_TOP, _("3 mins"));
1136 _hscale.add_mark(2400, Gtk::POS_TOP, _("4 mins"));
1137 _hscale.add_mark(3000, Gtk::POS_TOP, _("5 mins"));
1139 Gtkmm2ext::UI::instance()->set_tip(_hscale,
1140 _("Specify the default timeout for plugin instantiation. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1144 class ClipLevelOptions : public OptionEditorComponent
1148 : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1149 , _clip_level_slider (_clip_level_adjustment)
1150 , _label (_("Waveform Clip Level (dBFS):"))
1152 _label.set_name ("OptionsLabel");
1154 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ());
1156 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1158 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1161 void parameter_changed (string const & p)
1163 if (p == "waveform-clip-level") {
1164 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level());
1166 if (p == "show-waveform-clipping") {
1167 _clip_level_slider.set_sensitive (UIConfiguration::instance().get_show_waveform_clipping ());
1171 void set_state_from_config ()
1173 parameter_changed ("waveform-clip-level");
1174 parameter_changed ("show-waveform-clipping");
1177 void add_to_page (OptionEditorPage* p) {
1178 add_widgets_to_page (p, &_label, &_clip_level_slider);
1181 Gtk::Widget& tip_widget() {
1182 return _clip_level_slider;
1187 void clip_level_changed ()
1189 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1190 /* XXX: should be triggered from the parameter changed signal */
1191 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1194 Adjustment _clip_level_adjustment;
1195 HScale _clip_level_slider;
1199 class BufferingOptions : public OptionEditorComponent
1202 BufferingOptions (RCConfiguration* c)
1204 , _label (_("Preset:"))
1205 , _playback ("playback-buffer-seconds", _("Playback (seconds of buffering)"),
1206 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_playback_buffer_seconds),
1207 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_playback_buffer_seconds),
1209 , _capture ("capture-buffer-seconds", _("Recording (seconds of buffering)"),
1210 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_capture_buffer_seconds),
1211 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_capture_buffer_seconds),
1214 // TODO use ComboOption
1215 vector<string> presets;
1217 /* these must match the order of the enums for BufferingPreset */
1218 presets.push_back (_("Small sessions (4-16 tracks)"));
1219 presets.push_back (_("Medium sessions (16-64 tracks)"));
1220 presets.push_back (_("Large sessions (64+ tracks)"));
1221 presets.push_back (_("Custom (set by sliders below)"));
1223 set_popdown_strings (_buffering_presets_combo, presets);
1224 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1226 _label.set_name ("OptionsLabel");
1227 _label.set_alignment (0, 0.5);
1231 add_to_page (OptionEditorPage* p)
1233 add_widgets_to_page (p, &_label, &_buffering_presets_combo);
1234 _playback.add_to_page (p);
1235 _capture.add_to_page (p);
1238 void parameter_changed (string const & p)
1240 if (p == "buffering-preset") {
1241 switch (_rc_config->get_buffering_preset()) {
1243 _playback.set_sensitive (false);
1244 _capture.set_sensitive (false);
1245 _buffering_presets_combo.set_active (0);
1248 _playback.set_sensitive (false);
1249 _capture.set_sensitive (false);
1250 _buffering_presets_combo.set_active (1);
1253 _playback.set_sensitive (false);
1254 _capture.set_sensitive (false);
1255 _buffering_presets_combo.set_active (2);
1258 _playback.set_sensitive (true);
1259 _capture.set_sensitive (true);
1260 _buffering_presets_combo.set_active (3);
1264 _playback.parameter_changed (p);
1265 _capture.parameter_changed (p);
1268 void set_state_from_config ()
1270 parameter_changed ("buffering-preset");
1271 _playback.set_state_from_config();
1272 _capture.set_state_from_config();
1275 Gtk::Widget& tip_widget() { return _buffering_presets_combo; }
1279 void preset_changed ()
1281 int index = _buffering_presets_combo.get_active_row_number ();
1287 _rc_config->set_buffering_preset (Small);
1290 _rc_config->set_buffering_preset (Medium);
1293 _rc_config->set_buffering_preset (Large);
1296 _rc_config->set_buffering_preset (Custom);
1299 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1304 RCConfiguration* _rc_config;
1306 HSliderOption _playback;
1307 HSliderOption _capture;
1308 ComboBoxText _buffering_presets_combo;
1311 class ControlSurfacesOptions : public OptionEditorMiniPage
1314 ControlSurfacesOptions ()
1315 : _ignore_view_change (0)
1317 _store = ListStore::create (_model);
1318 _view.set_model (_store);
1319 _view.append_column (_("Control Surface Protocol"), _model.name);
1320 _view.get_column(0)->set_resizable (true);
1321 _view.get_column(0)->set_expand (true);
1322 _view.append_column_editable (_("Enable"), _model.enabled);
1324 Gtk::HBox* edit_box = manage (new Gtk::HBox);
1325 edit_box->set_spacing(3);
1328 Label* label = manage (new Label);
1329 label->set_text (_("Edit the settings for selected protocol (it must be ENABLED first):"));
1330 edit_box->pack_start (*label, false, false);
1333 edit_button = manage (new Button(_("Show Protocol Settings")));
1334 edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
1335 edit_box->pack_start (*edit_button, true, true);
1336 edit_button->set_sensitive (false);
1337 edit_button->show ();
1339 int const n = table.property_n_rows();
1340 table.resize (n + 2, 3);
1341 table.attach (_view, 0, 3, n, n + 1);
1342 table.attach (*edit_box, 0, 3, n + 1, n + 2);
1344 ControlProtocolManager& m = ControlProtocolManager::instance ();
1345 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1346 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1348 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1349 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1350 _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
1353 void parameter_changed (std::string const &)
1358 void set_state_from_config ()
1362 ControlProtocolManager& m = ControlProtocolManager::instance ();
1363 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1365 if (!(*i)->mandatory) {
1366 TreeModel::Row r = *_store->append ();
1367 r[_model.name] = (*i)->name;
1368 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1369 r[_model.protocol_info] = *i;
1376 void protocol_status_changed (ControlProtocolInfo* cpi) {
1378 TreeModel::Children rows = _store->children();
1380 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1381 string n = ((*x)[_model.name]);
1383 if ((*x)[_model.protocol_info] == cpi) {
1384 _ignore_view_change++;
1385 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1386 _ignore_view_change--;
1392 void selection_changed ()
1394 //enable the Edit button when a row is selected for editing
1395 TreeModel::Row row = *(_view.get_selection()->get_selected());
1396 if (row && row[_model.enabled])
1397 edit_button->set_sensitive (true);
1399 edit_button->set_sensitive (false);
1402 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1404 TreeModel::Row r = *i;
1406 if (_ignore_view_change) {
1410 ControlProtocolInfo* cpi = r[_model.protocol_info];
1415 bool const was_enabled = (cpi->protocol != 0);
1416 bool const is_enabled = r[_model.enabled];
1419 if (was_enabled != is_enabled) {
1422 ControlProtocolManager::instance().activate (*cpi);
1424 ControlProtocolManager::instance().deactivate (*cpi);
1428 selection_changed ();
1431 void edit_btn_clicked ()
1434 ControlProtocolInfo* cpi;
1437 row = *(_view.get_selection()->get_selected());
1438 if (!row[_model.enabled]) {
1441 cpi = row[_model.protocol_info];
1442 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1445 Box* box = (Box*) cpi->protocol->get_gui ();
1449 if (box->get_parent()) {
1450 static_cast<ArdourWindow*>(box->get_parent())->present();
1453 WindowTitle title (Glib::get_application_name());
1454 title += row[_model.name];
1455 title += _("Configuration");
1456 /* once created, the window is managed by the surface itself (as ->get_parent())
1457 * Surface's tear_down_gui() is called on session close, when de-activating
1458 * or re-initializing a surface.
1459 * tear_down_gui() hides an deletes the Window if it exists.
1461 ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
1462 win->set_title ("Control Protocol Options");
1468 void edit_clicked (GdkEventButton* ev)
1470 if (ev->type != GDK_2BUTTON_PRESS) {
1477 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1481 ControlSurfacesModelColumns ()
1485 add (protocol_info);
1488 TreeModelColumn<string> name;
1489 TreeModelColumn<bool> enabled;
1490 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1493 Glib::RefPtr<ListStore> _store;
1494 ControlSurfacesModelColumns _model;
1496 PBD::ScopedConnection protocol_status_connection;
1497 uint32_t _ignore_view_change;
1498 Gtk::Button* edit_button;
1501 class VideoTimelineOptions : public OptionEditorMiniPage
1504 VideoTimelineOptions (RCConfiguration* c)
1506 , _show_video_export_info_button (_("Show Video Export Info before export"))
1507 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1508 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1509 , _xjadeo_browse_button (_("Browse..."))
1512 int n = table.property_n_rows();
1514 t->attach (_show_video_export_info_button, 1, 4, n, n + 1);
1515 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1516 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1517 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1520 t->attach (_show_video_server_dialog_button, 1, 4, n, n + 1);
1521 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1522 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1523 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1526 t->attach (_video_advanced_setup_button, 1, 4, n, n + 1, FILL);
1527 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1528 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1529 _("<b>When enabled</b> you can speficify a custom video-server URL and docroot. - Do not enable this option unless you know what you are doing."));
1532 Label* l = manage (new Label (_("Video Server URL:")));
1533 l->set_alignment (0, 0.5);
1534 t->attach (*l, 1, 2, n, n + 1, FILL);
1535 t->attach (_video_server_url_entry, 2, 4, n, n + 1, FILL);
1536 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1537 _("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"));
1540 l = manage (new Label (_("Video Folder:")));
1541 l->set_alignment (0, 0.5);
1542 t->attach (*l, 1, 2, n, n + 1, FILL);
1543 t->attach (_video_server_docroot_entry, 2, 4, n, n + 1);
1544 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1545 _("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 unvailable. It is used for the local video-monitor and file-browsing when opening/adding a video file."));
1548 l = manage (new Label (""));
1549 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1552 l = manage (new Label (string_compose ("<b>%1</b>", _("Video Monitor"))));
1553 l->set_use_markup (true);
1554 l->set_alignment (0, 0.5);
1555 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1558 l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"),
1561 #elif defined PLATFORM_WINDOWS
1567 l->set_alignment (0, 0.5);
1568 t->attach (*l, 1, 4, n, n + 1, FILL);
1571 t->attach (_custom_xjadeo_path, 2, 3, n, n + 1, EXPAND|FILL);
1572 Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart."));
1573 t->attach (_xjadeo_browse_button, 3, 4, n, n + 1, FILL);
1575 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1576 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1577 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1578 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1579 _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed));
1580 _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked));
1582 // xjadeo-path is a UIConfig parameter
1583 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &VideoTimelineOptions::parameter_changed));
1586 void server_url_changed ()
1588 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1591 void server_docroot_changed ()
1593 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1596 void show_video_export_info_toggled ()
1598 bool const x = _show_video_export_info_button.get_active ();
1599 _rc_config->set_show_video_export_info (x);
1602 void show_video_server_dialog_toggled ()
1604 bool const x = _show_video_server_dialog_button.get_active ();
1605 _rc_config->set_show_video_server_dialog (x);
1608 void video_advanced_setup_toggled ()
1610 bool const x = _video_advanced_setup_button.get_active ();
1611 _rc_config->set_video_advanced_setup(x);
1614 void custom_xjadeo_path_changed ()
1616 UIConfiguration::instance().set_xjadeo_binary (_custom_xjadeo_path.get_text());
1619 void xjadeo_browse_clicked ()
1621 Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN);
1622 dialog.set_filename (UIConfiguration::instance().get_xjadeo_binary());
1623 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1624 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1625 if (dialog.run () == Gtk::RESPONSE_OK) {
1626 const std::string& filename = dialog.get_filename();
1627 if (!filename.empty() && (
1629 Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) ||
1631 Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)
1633 UIConfiguration::instance().set_xjadeo_binary (filename);
1638 void parameter_changed (string const & p)
1640 if (p == "video-server-url") {
1641 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1642 } else if (p == "video-server-docroot") {
1643 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1644 } else if (p == "show-video-export-info") {
1645 bool const x = _rc_config->get_show_video_export_info();
1646 _show_video_export_info_button.set_active (x);
1647 } else if (p == "show-video-server-dialog") {
1648 bool const x = _rc_config->get_show_video_server_dialog();
1649 _show_video_server_dialog_button.set_active (x);
1650 } else if (p == "video-advanced-setup") {
1651 bool const x = _rc_config->get_video_advanced_setup();
1652 _video_advanced_setup_button.set_active(x);
1653 _video_server_docroot_entry.set_sensitive(x);
1654 _video_server_url_entry.set_sensitive(x);
1655 } else if (p == "xjadeo-binary") {
1656 _custom_xjadeo_path.set_text (UIConfiguration::instance().get_xjadeo_binary());
1660 void set_state_from_config ()
1662 parameter_changed ("video-server-url");
1663 parameter_changed ("video-server-docroot");
1664 parameter_changed ("video-monitor-setup-dialog");
1665 parameter_changed ("show-video-export-info");
1666 parameter_changed ("show-video-server-dialog");
1667 parameter_changed ("video-advanced-setup");
1668 parameter_changed ("xjadeo-binary");
1672 RCConfiguration* _rc_config;
1673 Entry _video_server_url_entry;
1674 Entry _video_server_docroot_entry;
1675 Entry _custom_xjadeo_path;
1676 CheckButton _show_video_export_info_button;
1677 CheckButton _show_video_server_dialog_button;
1678 CheckButton _video_advanced_setup_button;
1679 Button _xjadeo_browse_button;
1682 class ColumVisibilityOption : public Option
1685 ColumVisibilityOption (string id, string name, uint32_t n_col, sigc::slot<uint32_t> get, sigc::slot<bool, uint32_t> set)
1692 cb = (CheckButton**) malloc (sizeof (CheckButton*) * n_col);
1693 for (uint32_t i = 0; i < n_col; ++i) {
1694 CheckButton* col = manage (new CheckButton (string_compose (_("Column %1"), i + 1)));
1695 col->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ColumVisibilityOption::column_toggled), i));
1696 _hbox.pack_start (*col);
1699 parameter_changed (id);
1702 ~ColumVisibilityOption () {
1706 Gtk::Widget& tip_widget() { return _hbox; }
1708 void set_state_from_config ()
1710 uint32_t c = _get();
1711 for (uint32_t i = 0; i < _n_col; ++i) {
1712 bool en = (c & (1<<i)) ? true : false;
1713 if (cb[i]->get_active () != en) {
1714 cb[i]->set_active (en);
1719 void add_to_page (OptionEditorPage* p)
1721 _heading.add_to_page (p);
1722 add_widget_to_page (p, &_hbox);
1726 void column_toggled (int b) {
1727 uint32_t c = _get();
1729 if (cb[b]->get_active ()) {
1740 OptionEditorHeading _heading;
1744 sigc::slot<uint32_t> _get;
1745 sigc::slot<bool, uint32_t> _set;
1749 /** A class which allows control of visibility of some editor components usign
1750 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1751 * which has the correct members, but with null widget pointers. This
1752 * class allows the user to set visibility of the members, the details
1753 * of which are stored in a configuration variable which can be watched
1754 * by parts of the editor that actually contain the widgets whose visibility
1755 * is being controlled.
1758 class VisibilityOption : public Option
1761 /** @param name User-visible name for this group.
1762 * @param g `Dummy' VisibilityGroup (as described above).
1763 * @param get Method to get the value of the appropriate configuration variable.
1764 * @param set Method to set the value of the appropriate configuration variable.
1766 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1767 : Option (g->get_state_name(), name)
1769 , _visibility_group (g)
1773 /* Watch for changes made by the user to our members */
1774 _visibility_group->VisibilityChanged.connect_same_thread (
1775 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1779 void set_state_from_config ()
1781 /* Set our state from the current configuration */
1782 _visibility_group->set_state (_get ());
1785 void add_to_page (OptionEditorPage* p)
1787 _heading.add_to_page (p);
1788 add_widget_to_page (p, _visibility_group->list_view ());
1791 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1796 /* The user has changed something, so reflect this change
1797 in the RCConfiguration.
1799 _set (_visibility_group->get_state_value ());
1802 OptionEditorHeading _heading;
1803 VisibilityGroup* _visibility_group;
1804 sigc::slot<std::string> _get;
1805 sigc::slot<bool, std::string> _set;
1806 PBD::ScopedConnection _visibility_group_connection;
1810 class MidiPortOptions : public OptionEditorMiniPage, public sigc::trackable
1815 setup_midi_port_view (midi_output_view, false);
1816 setup_midi_port_view (midi_input_view, true);
1818 OptionEditorHeading* h = new OptionEditorHeading (_("MIDI Inputs"));
1819 h->add_to_page (this);
1821 Gtk::ScrolledWindow* scroller = manage (new Gtk::ScrolledWindow);
1822 scroller->add (midi_input_view);
1823 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1824 scroller->set_size_request (-1, 180);
1826 int n = table.property_n_rows();
1827 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1829 h = new OptionEditorHeading (_("MIDI Outputs"));
1830 h->add_to_page (this);
1832 scroller = manage (new Gtk::ScrolledWindow);
1833 scroller->add (midi_output_view);
1834 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1835 scroller->set_size_request (-1, 180);
1837 n = table.property_n_rows();
1838 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1840 midi_output_view.show ();
1841 midi_input_view.show ();
1843 table.signal_show().connect (sigc::mem_fun (*this, &MidiPortOptions::on_show));
1846 void parameter_changed (string const&) {}
1847 void set_state_from_config() {}
1852 AudioEngine::instance()->PortRegisteredOrUnregistered.connect (connections,
1853 invalidator (*this),
1854 boost::bind (&MidiPortOptions::refill, this),
1856 AudioEngine::instance()->MidiPortInfoChanged.connect (connections,
1857 invalidator (*this),
1858 boost::bind (&MidiPortOptions::refill, this),
1860 AudioEngine::instance()->MidiSelectionPortsChanged.connect (connections,
1861 invalidator (*this),
1862 boost::bind (&MidiPortOptions::refill, this),
1868 if (refill_midi_ports (true, midi_input_view)) {
1869 input_label.show ();
1871 input_label.hide ();
1873 if (refill_midi_ports (false, midi_output_view)) {
1874 output_label.show ();
1876 output_label.hide ();
1881 PBD::ScopedConnectionList connections;
1883 /* MIDI port management */
1884 struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord {
1886 MidiPortColumns () {
1895 Gtk::TreeModelColumn<std::string> pretty_name;
1896 Gtk::TreeModelColumn<bool> music_data;
1897 Gtk::TreeModelColumn<bool> control_data;
1898 Gtk::TreeModelColumn<bool> selection;
1899 Gtk::TreeModelColumn<std::string> name;
1900 Gtk::TreeModelColumn<std::string> filler;
1903 MidiPortColumns midi_port_columns;
1904 Gtk::TreeView midi_input_view;
1905 Gtk::TreeView midi_output_view;
1906 Gtk::Label input_label;
1907 Gtk::Label output_label;
1909 void setup_midi_port_view (Gtk::TreeView&, bool with_selection);
1910 bool refill_midi_ports (bool for_input, Gtk::TreeView&);
1911 void pretty_name_edit (std::string const & path, std::string const & new_text, Gtk::TreeView*);
1912 void midi_music_column_toggled (std::string const & path, Gtk::TreeView*);
1913 void midi_control_column_toggled (std::string const & path, Gtk::TreeView*);
1914 void midi_selection_column_toggled (std::string const & path, Gtk::TreeView*);
1918 MidiPortOptions::setup_midi_port_view (Gtk::TreeView& view, bool with_selection)
1920 int pretty_name_column;
1923 int selection_column;
1924 TreeViewColumn* col;
1927 pretty_name_column = view.append_column_editable (_("Name (click to edit)"), midi_port_columns.pretty_name) - 1;
1929 col = manage (new TreeViewColumn ("", midi_port_columns.music_data));
1930 col->set_alignment (ALIGN_CENTER);
1931 l = manage (new Label (_("Music Data")));
1932 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of music performance data."), PROGRAM_NAME));
1933 col->set_widget (*l);
1935 music_column = view.append_column (*col) - 1;
1937 col = manage (new TreeViewColumn ("", midi_port_columns.control_data));
1938 col->set_alignment (ALIGN_CENTER);
1939 l = manage (new Label (_("Control Data")));
1940 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of control data."), PROGRAM_NAME));
1941 col->set_widget (*l);
1943 control_column = view.append_column (*col) - 1;
1945 if (with_selection) {
1946 col = manage (new TreeViewColumn (_("Follow Selection"), midi_port_columns.selection));
1947 selection_column = view.append_column (*col) - 1;
1948 l = manage (new Label (_("Follow Selection")));
1949 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));
1950 col->set_widget (*l);
1954 /* filler column so that the last real column doesn't expand */
1955 view.append_column ("", midi_port_columns.filler);
1957 CellRendererText* pretty_name_cell = dynamic_cast<CellRendererText*> (view.get_column_cell_renderer (pretty_name_column));
1958 pretty_name_cell->property_editable() = true;
1959 pretty_name_cell->signal_edited().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::pretty_name_edit), &view));
1961 CellRendererToggle* toggle_cell;
1963 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (music_column));
1964 toggle_cell->property_activatable() = true;
1965 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_music_column_toggled), &view));
1967 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (control_column));
1968 toggle_cell->property_activatable() = true;
1969 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_control_column_toggled), &view));
1971 if (with_selection) {
1972 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (selection_column));
1973 toggle_cell->property_activatable() = true;
1974 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_selection_column_toggled), &view));
1977 view.get_selection()->set_mode (SELECTION_NONE);
1978 view.set_tooltip_column (4); /* port "real" name */
1979 view.get_column(0)->set_resizable (true);
1980 view.get_column(0)->set_expand (true);
1984 MidiPortOptions::refill_midi_ports (bool for_input, Gtk::TreeView& view)
1986 using namespace ARDOUR;
1988 std::vector<string> ports;
1990 AudioEngine::instance()->get_known_midi_ports (ports);
1992 if (ports.empty()) {
1997 Glib::RefPtr<ListStore> model = Gtk::ListStore::create (midi_port_columns);
1999 for (vector<string>::const_iterator s = ports.begin(); s != ports.end(); ++s) {
2001 if (AudioEngine::instance()->port_is_mine (*s)) {
2005 PortManager::MidiPortInformation mpi (AudioEngine::instance()->midi_port_information (*s));
2007 if (mpi.pretty_name.empty()) {
2008 /* vanished since get_known_midi_ports() */
2012 if (for_input != mpi.input) {
2016 TreeModel::Row row = *(model->append());
2018 row[midi_port_columns.pretty_name] = mpi.pretty_name;
2019 row[midi_port_columns.music_data] = mpi.properties & MidiPortMusic;
2020 row[midi_port_columns.control_data] = mpi.properties & MidiPortControl;
2021 row[midi_port_columns.selection] = mpi.properties & MidiPortSelection;
2022 row[midi_port_columns.name] = *s;
2025 view.set_model (model);
2031 MidiPortOptions::midi_music_column_toggled (string const & path, TreeView* view)
2033 TreeIter iter = view->get_model()->get_iter (path);
2039 bool new_value = ! bool ((*iter)[midi_port_columns.music_data]);
2041 /* don't reset model - wait for MidiPortInfoChanged signal */
2044 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2046 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2051 MidiPortOptions::midi_control_column_toggled (string const & path, TreeView* view)
2053 TreeIter iter = view->get_model()->get_iter (path);
2059 bool new_value = ! bool ((*iter)[midi_port_columns.control_data]);
2061 /* don't reset model - wait for MidiPortInfoChanged signal */
2064 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2066 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2071 MidiPortOptions::midi_selection_column_toggled (string const & path, TreeView* view)
2073 TreeIter iter = view->get_model()->get_iter (path);
2079 bool new_value = ! bool ((*iter)[midi_port_columns.selection]);
2081 /* don't reset model - wait for MidiSelectionPortsChanged signal */
2084 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2086 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2091 MidiPortOptions::pretty_name_edit (std::string const & path, string const & new_text, Gtk::TreeView* view)
2093 TreeIter iter = view->get_model()->get_iter (path);
2099 boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
2101 ARDOUR::PortEngine::PortHandle ph = backend->get_port_by_name ((*iter)[midi_port_columns.name]);
2103 backend->set_port_property (ph, "http://jackaudio.org/metadata/pretty-name", new_text, "");
2104 (*iter)[midi_port_columns.pretty_name] = new_text;
2112 RCOptionEditor::RCOptionEditor ()
2113 : OptionEditorContainer (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
2114 , Tabbable (*this, _("Preferences")) /* pack self-as-vbox into tabbable */
2115 , _rc_config (Config)
2116 , _mixer_strip_visibility ("mixer-element-visibility")
2118 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
2122 uint32_t hwcpus = hardware_concurrency ();
2124 BoolComboOption* bco;
2127 add_option (_("General"), new OptionEditorHeading (_("DSP CPU Utilization")));
2129 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
2131 _("Signal processing uses"),
2132 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
2133 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
2136 procs->add (-1, _("all but one processor"));
2137 procs->add (0, _("all available processors"));
2139 for (uint32_t i = 1; i <= hwcpus; ++i) {
2140 procs->add (i, string_compose (P_("%1 processor", "%1 processors", i), i));
2143 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
2145 add_option (_("General"), procs);
2148 /* Image cache size */
2149 add_option (_("General"), new OptionEditorHeading (_("Memory Usage")));
2151 HSliderOption *sics = new HSliderOption ("waveform-cache-size",
2152 _("Waveform image cache size (megabytes)"),
2153 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
2154 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size),
2155 1, 1024, 10 /* 1 MB to 1GB in steps of 10MB */
2157 sics->scale().set_digits (0);
2158 Gtkmm2ext::UI::instance()->set_tip (
2160 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
2161 add_option (_("General"), sics);
2163 add_option (_("General"), new OptionEditorHeading (S_("Options|Undo")));
2165 add_option (_("General"), new UndoOptions (_rc_config));
2167 add_option (_("General"),
2169 "verify-remove-last-capture",
2170 _("Verify removal of last capture"),
2171 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
2172 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
2175 add_option (_("General"), new OptionEditorHeading (_("Session Management")));
2177 add_option (_("General"),
2179 "periodic-safety-backups",
2180 _("Make periodic backups of the session file"),
2181 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
2182 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
2185 add_option (_("General"),
2187 "only-copy-imported-files",
2188 _("Always copy imported files"),
2189 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
2190 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
2193 add_option (_("General"), new DirectoryOption (
2194 X_("default-session-parent-dir"),
2195 _("Default folder for new sessions:"),
2196 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
2197 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
2200 add_option (_("General"),
2201 new SpinOption<uint32_t> (
2202 "max-recent-sessions",
2203 _("Maximum number of recent sessions"),
2204 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
2205 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
2209 add_option (_("General"), new OptionEditorHeading (_("Automation")));
2211 add_option (_("General"),
2212 new SpinOption<double> (
2213 "automation-thinning-factor",
2214 _("Thinning factor (larger value => less data)"),
2215 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
2216 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
2220 add_option (_("General"),
2221 new SpinOption<double> (
2222 "automation-interval-msecs",
2223 _("Automation sampling interval (milliseconds)"),
2224 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
2225 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
2229 add_option (_("General"), new OptionEditorHeading (_("Tempo")));
2232 tsf = new BoolOption (
2233 "allow-non-quarter-pulse",
2234 _("Allow non quarter-note pulse"),
2235 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_allow_non_quarter_pulse),
2236 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_allow_non_quarter_pulse)
2238 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2239 string_compose (_("<b>When enabled</b> %1 will allow tempo to be expressed in divisions per minute\n"
2240 "<b>When disabled</b> %1 will only allow tempo to be expressed in quarter notes per minute"),
2242 add_option (_("General"), tsf);
2244 if (!ARDOUR::Profile->get_mixbus()) {
2245 add_option (_("General"), new OptionEditorHeading (_("GUI Lock")));
2246 /* Lock GUI timeout */
2248 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2249 _("Lock timeout (seconds)"),
2250 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
2251 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds),
2254 slts->scale().set_digits (0);
2255 Gtkmm2ext::UI::instance()->set_tip (
2257 _("Lock GUI after this many idle seconds (zero to never lock)"));
2258 add_option (_("General"), slts);
2263 add_option (_("General/Translation"), new OptionEditorHeading (_("Internationalization")));
2265 bo = new BoolOption (
2266 "enable-translation",
2267 _("Use translations"),
2268 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2269 sigc::ptr_fun (ARDOUR::set_translations_enabled)
2272 bo->set_note (string_compose (_("These settings will only take effect after %1 is restarted (if available for your language preferences)."), PROGRAM_NAME));
2274 add_option (_("General/Translation"), bo);
2276 _l10n = new ComboOption<ARDOUR::LocaleMode> (
2279 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_locale_mode),
2280 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_locale_mode)
2283 _l10n->add (ARDOUR::SET_LC_ALL, _("Set complete locale"));
2284 _l10n->add (ARDOUR::SET_LC_MESSAGES, _("Enable only message translation"));
2285 _l10n->add (ARDOUR::SET_LC_MESSAGES_AND_LC_NUMERIC, _("Translate messages and format numeric format"));
2286 _l10n->set_note (_("This setting is provided for plugin compatibility. e.g. some plugins on some systems expect the decimal point to be a dot."));
2288 add_option (_("General/Translation"), _l10n);
2289 parameter_changed ("enable-translation");
2290 #endif // ENABLE_NLS
2295 add_option (_("Editor"), new OptionEditorHeading (_("General")));
2297 add_option (_("Editor"),
2299 "rubberbanding-snaps-to-grid",
2300 _("Snap rubberband to grid"),
2301 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2302 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2305 bo = new BoolOption (
2307 _("Prompt for a new marker name"),
2308 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2309 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2311 add_option (_("Editor"), bo);
2312 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."
2313 "\n\nYou can always rename markers by right-clicking on them"));
2315 add_option (_("Editor"),
2317 "draggable-playhead",
2318 _("Allow dragging of playhead"),
2319 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2320 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2323 if (!Profile->get_mixbus()) {
2325 add_option (_("Editor"),
2327 "use-mouse-position-as-zoom-focus-on-scroll",
2328 _("Zoom to mouse position when zooming with scroll wheel"),
2329 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2330 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2334 add_option (_("Editor"),
2336 "use-time-rulers-to-zoom-with-vertical-drag",
2337 _("Zoom with vertical drag in rulers"),
2338 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag),
2339 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag)
2342 add_option (_("Editor"),
2344 "use-double-click-to-zoom-to-selection",
2345 _("Double click zooms to selection"),
2346 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection),
2347 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection)
2350 add_option (_("Editor"),
2352 "update-editor-during-summary-drag",
2353 _("Update editor window during drags of the summary"),
2354 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2355 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2358 add_option (_("Editor"),
2360 "autoscroll-editor",
2361 _("Auto-scroll editor window when dragging near its edges"),
2362 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2363 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2366 add_option (_("Editor"),
2367 new BoolComboOption (
2368 "show-region-gain-envelopes",
2369 _("Show gain envelopes in audio regions"),
2371 _("only in Draw and Internal Edit modes"),
2372 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2373 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2376 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2378 add_option (_("Editor"),
2380 "automation-follows-regions",
2381 _("Move relevant automation when audio regions are moved"),
2382 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2383 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2386 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2387 "default-fade-shape",
2388 _("Default fade shape"),
2389 sigc::mem_fun (*_rc_config,
2390 &RCConfiguration::get_default_fade_shape),
2391 sigc::mem_fun (*_rc_config,
2392 &RCConfiguration::set_default_fade_shape)
2395 fadeshape->add (FadeLinear,
2396 _("Linear (for highly correlated material)"));
2397 fadeshape->add (FadeConstantPower, _("Constant power"));
2398 fadeshape->add (FadeSymmetric, _("Symmetric"));
2399 fadeshape->add (FadeSlow, _("Slow"));
2400 fadeshape->add (FadeFast, _("Fast"));
2402 add_option (_("Editor"), fadeshape);
2404 bco = new BoolComboOption (
2405 "use-overlap-equivalency",
2406 _("Regions in edit groups are edited together"),
2407 _("whenever they overlap in time"),
2408 _("only if they have identical length and position"),
2409 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2410 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2413 add_option (_("Editor"), bco);
2415 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2417 _("Layering model"),
2418 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2419 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2422 lm->add (LaterHigher, _("later is higher"));
2423 lm->add (Manual, _("manual layering"));
2424 add_option (_("Editor"), lm);
2426 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2427 "region-selection-after-split",
2428 _("After splitting selected regions, select"),
2429 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2430 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2432 // TODO: decide which of these modes are really useful
2433 rsas->add(None, _("no regions"));
2434 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2435 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2436 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2437 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2438 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2439 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2440 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2442 add_option (_("Editor"), rsas);
2444 add_option (_("Editor/Modifiers"), new OptionEditorHeading (_("Keyboard Modifiers")));
2445 add_option (_("Editor/Modifiers"), new KeyboardOptions);
2446 add_option (_("Editor/Modifiers"), new OptionEditorBlank ());
2448 /* MIXER -- SOLO AND MUTE */
2450 add_option (_("Mixer"), new OptionEditorHeading (_("Solo")));
2452 _solo_control_is_listen_control = new BoolOption (
2453 "solo-control-is-listen-control",
2454 _("Solo controls are Listen controls"),
2455 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2456 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2459 add_option (_("Mixer"), _solo_control_is_listen_control);
2461 add_option (_("Mixer"),
2464 _("Exclusive solo"),
2465 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2466 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2469 add_option (_("Mixer"),
2472 _("Show solo muting"),
2473 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2474 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2477 add_option (_("Mixer"),
2479 "solo-mute-override",
2480 _("Soloing overrides muting"),
2481 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2482 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2485 add_option (_("Mixer"),
2488 _("Solo-in-place mute cut (dB)"),
2489 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2490 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2493 _listen_position = new ComboOption<ListenPosition> (
2495 _("Listen Position"),
2496 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2497 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2500 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2501 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2503 add_option (_("Mixer"), _listen_position);
2505 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2507 _("PFL signals come from"),
2508 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2509 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2512 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2513 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2515 add_option (_("Mixer"), pp);
2517 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2519 _("AFL signals come from"),
2520 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2521 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2524 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2525 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2527 add_option (_("Mixer"), pa);
2529 add_option (_("Mixer"), new OptionEditorHeading (_("Default track / bus muting options")));
2531 add_option (_("Mixer"),
2533 "mute-affects-pre-fader",
2534 _("Mute affects pre-fader sends"),
2535 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2536 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2539 add_option (_("Mixer"),
2541 "mute-affects-post-fader",
2542 _("Mute affects post-fader sends"),
2543 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2544 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2547 add_option (_("Mixer"),
2549 "mute-affects-control-outs",
2550 _("Mute affects control outputs"),
2551 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2552 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2555 add_option (_("Mixer"),
2557 "mute-affects-main-outs",
2558 _("Mute affects main outputs"),
2559 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2560 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2564 if (!ARDOUR::Profile->get_mixbus()) {
2565 add_option (_("Mixer"), new OptionEditorHeading (_("Send Routing")));
2566 add_option (_("Mixer"),
2568 "link-send-and-route-panner",
2569 _("Link panners of Aux and External Sends with main panner by default"),
2570 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2571 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2577 add_option (_("Signal Flow"), new OptionEditorHeading (_("Monitoring")));
2579 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2581 _("Record monitoring handled by"),
2582 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2583 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2586 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2587 mm->add (HardwareMonitoring, _("via Audio Driver"));
2590 string prog (PROGRAM_NAME);
2591 boost::algorithm::to_lower (prog);
2592 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2593 mm->add (ExternalMonitoring, _("audio hardware"));
2595 add_option (_("Signal Flow"), mm);
2597 add_option (_("Signal Flow"),
2599 "tape-machine-mode",
2600 _("Tape machine mode"),
2601 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2602 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2605 if (!Profile->get_mixbus()) {
2607 add_option (_("Signal Flow"), new OptionEditorHeading (_("Track and Bus Connections")));
2609 add_option (_("Signal Flow"),
2611 "auto-connect-standard-busses",
2612 _("Auto-connect master/monitor busses"),
2613 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2614 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2617 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2618 "input-auto-connect",
2619 _("Connect track inputs"),
2620 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2621 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2624 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2625 iac->add (ManualConnect, _("manually"));
2627 add_option (_("Signal Flow"), iac);
2629 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2630 "output-auto-connect",
2631 _("Connect track and bus outputs"),
2632 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2633 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2636 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2637 oac->add (AutoConnectMaster, _("automatically to master bus"));
2638 oac->add (ManualConnect, _("manually"));
2640 add_option (_("Signal Flow"), oac);
2642 bo = new BoolOption (
2644 _("Use 'Strict-I/O' for new tracks or Busses"),
2645 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2646 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2649 add_option (_("Signal Flow"), bo);
2650 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2651 _("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."));
2658 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2660 add_option (_("Audio"), new BufferingOptions (_rc_config));
2662 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2664 add_option (_("Audio"),
2666 "denormal-protection",
2667 _("Use DC bias to protect against denormals"),
2668 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2669 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2672 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2674 _("Processor handling"),
2675 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2676 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2680 dm->add (DenormalNone, _("no processor handling"));
2682 FPU* fpu = FPU::instance();
2684 if (fpu->has_flush_to_zero()) {
2686 dm->add (DenormalFTZ, _("use FlushToZero"));
2687 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2688 _rc_config->set_denormal_model(DenormalNone);
2691 if (fpu->has_denormals_are_zero()) {
2693 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2694 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2695 _rc_config->set_denormal_model(DenormalNone);
2698 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2700 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2701 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2702 _rc_config->set_denormal_model(DenormalNone);
2706 dm->set_sensitive(false);
2709 add_option (_("Audio"), dm);
2711 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2713 add_option (_("Audio"),
2715 "auto-analyse-audio",
2716 _("Enable automatic analysis of audio"),
2717 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2718 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2721 add_option (_("Audio"),
2723 "replicate-missing-region-channels",
2724 _("Replicate missing region channels"),
2725 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2726 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2731 add_option (_("MIDI"), new OptionEditorHeading (_("Buffering")));
2733 add_option (_("MIDI"),
2734 new SpinOption<float> (
2736 _("MIDI read-ahead time (seconds)"),
2737 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2738 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2743 add_option (_("MIDI"), new OptionEditorHeading (_("Session")));
2745 add_option (_("MIDI"),
2746 new SpinOption<int32_t> (
2747 "initial-program-change",
2748 _("Initial program change"),
2749 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2750 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2754 add_option (_("MIDI"), new OptionEditorHeading (_("Audition")));
2756 add_option (_("MIDI"),
2759 _("Sound MIDI notes as they are selected in the editor"),
2760 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2761 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2764 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2765 "midi-audition-synth-uri",
2766 _("MIDI Audition Synth (LV2)"),
2767 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2768 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2771 audition_synth->add(X_(""), _("None"));
2772 PluginInfoList all_plugs;
2773 PluginManager& manager (PluginManager::instance());
2775 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2777 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2778 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2779 if (!(*i)->is_instrument()) continue;
2780 if ((*i)->type != ARDOUR::LV2) continue;
2781 if ((*i)->name.length() > 46) {
2782 audition_synth->add((*i)->unique_id, (*i)->name.substr (0, 44) + "...");
2784 audition_synth->add((*i)->unique_id, (*i)->name);
2789 add_option (_("MIDI"), audition_synth);
2793 add_option (_("Metronome"), new OptionEditorHeading (_("Metronome")));
2794 add_option (_("Metronome"), new ClickOptions (_rc_config));
2798 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2800 ComboOption<float>* mht = new ComboOption<float> (
2802 _("Peak hold time"),
2803 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
2804 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
2807 mht->add (MeterHoldOff, _("off"));
2808 mht->add (MeterHoldShort, _("short"));
2809 mht->add (MeterHoldMedium, _("medium"));
2810 mht->add (MeterHoldLong, _("long"));
2812 add_option (S_("Preferences|Metering"), mht);
2814 ComboOption<float>* mfo = new ComboOption<float> (
2817 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2818 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2821 mfo->add (METER_FALLOFF_OFF, _("off"));
2822 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2823 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2824 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2825 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2826 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2827 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
2829 add_option (S_("Preferences|Metering"), mfo);
2831 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2832 "meter-line-up-level",
2833 _("Meter line-up level; 0dBu"),
2834 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
2835 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
2838 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2839 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2840 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2841 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2843 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."));
2845 add_option (S_("Preferences|Metering"), mlu);
2847 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2848 "meter-line-up-din",
2849 _("IEC1/DIN Meter line-up level; 0dBu"),
2850 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
2851 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
2854 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2855 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2856 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2857 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2859 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2861 add_option (S_("Preferences|Metering"), mld);
2863 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2864 "meter-vu-standard",
2865 _("VU Meter standard"),
2866 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
2867 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
2870 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2871 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2872 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2873 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2875 add_option (S_("Preferences|Metering"), mvu);
2877 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
2878 "meter-type-master",
2879 _("Default Meter Type for Master Bus"),
2880 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
2881 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
2883 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2884 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2885 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2886 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2887 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2888 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2889 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2890 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
2892 add_option (S_("Preferences|Metering"), mtm);
2895 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
2897 _("Default Meter Type for Busses"),
2898 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
2899 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
2901 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2902 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2903 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2904 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2905 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2906 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2907 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2908 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
2910 add_option (S_("Preferences|Metering"), mtb);
2912 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
2914 _("Default Meter Type for Tracks"),
2915 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
2916 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
2918 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2919 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
2921 add_option (S_("Preferences|Metering"), mtt);
2923 HSliderOption *mpks = new HSliderOption("meter-peak",
2924 _("Peak threshold [dBFS]"),
2925 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
2926 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak),
2930 Gtkmm2ext::UI::instance()->set_tip (
2932 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
2934 add_option (S_("Preferences|Metering"), mpks);
2936 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
2938 add_option (S_("Preferences|Metering"),
2940 "save-export-analysis-image",
2941 _("Save loudness analysis as image file"),
2942 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
2943 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
2946 /* TRANSPORT & Sync */
2948 add_option (_("Transport"), new OptionEditorHeading (_("General")));
2950 tsf = new BoolOption (
2951 "stop-at-session-end",
2952 _("Stop at the end of the session"),
2953 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
2954 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
2956 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2957 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
2958 "when it reaches the current session end marker\n\n"
2959 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
2961 add_option (_("Transport"), tsf);
2963 tsf = new BoolOption (
2964 "latched-record-enable",
2965 _("Keep record-enable engaged on stop"),
2966 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
2967 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
2969 add_option (_("Transport"), tsf);
2971 tsf = new BoolOption (
2972 "disable-disarm-during-roll",
2973 _("Disable per-track record disarm while rolling"),
2974 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
2975 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
2977 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("<b>When enabled</b> this will prevent you from accidentally stopping specific tracks recording during a take"));
2978 add_option (_("Transport"), tsf);
2980 tsf = new BoolOption (
2982 _("12dB gain reduction during fast-forward and fast-rewind"),
2983 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
2984 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2986 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2987 _("<b>When enabled</b> rhis will reduce the unpleasant increase in perceived volume "
2988 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2989 add_option (_("Transport"), tsf);
2991 ComboOption<float>* psc = new ComboOption<float> (
2994 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
2995 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
2997 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
2998 (_("The amount of preroll (in seconds) to apply when <b>Play with Preroll</b> is initiated.\n\n"
2999 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
3000 psc->add (0.0, _("0 (no pre-roll)"));
3001 psc->add (0.1, _("0.1 second"));
3002 psc->add (0.25, _("0.25 second"));
3003 psc->add (0.5, _("0.5 second"));
3004 psc->add (1.0, _("1.0 second"));
3005 psc->add (2.0, _("2.0 seconds"));
3006 add_option (_("Transport"), psc);
3009 add_option (_("Transport"), new OptionEditorHeading (_("Looping")));
3011 tsf = new BoolOption (
3013 _("Play loop is a transport mode"),
3014 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
3015 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
3017 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
3018 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
3019 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
3020 add_option (_("Transport"), tsf);
3022 tsf = new BoolOption (
3024 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
3025 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
3026 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
3028 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
3029 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
3030 "preventing any need to do a transport locate at the end of the loop\n\n"
3031 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
3032 "which will often cause a small click or delay"), PROGRAM_NAME));
3033 add_option (_("Transport"), tsf);
3035 add_option (_("Transport"), new OptionEditorHeading (_("Dropout (xrun) Handling")));
3036 tsf = new BoolOption (
3037 "stop-recording-on-xrun",
3038 _("Stop recording when an xrun occurs"),
3039 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
3040 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
3042 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
3043 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
3045 add_option (_("Transport"), tsf);
3047 tsf = new BoolOption (
3048 "create-xrun-marker",
3049 _("Create markers where xruns occur"),
3050 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
3051 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
3053 add_option (_("Transport"), tsf);
3058 add_option (_("Sync"), new OptionEditorHeading (_("External Syncronization")));
3060 _sync_source = new ComboOption<SyncSource> (
3062 _("External timecode source"),
3063 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
3064 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
3067 add_option (_("Sync"), _sync_source);
3069 _sync_framerate = new BoolOption (
3070 "timecode-sync-frame-rate",
3071 _("Match session video frame rate to external timecode"),
3072 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
3073 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
3075 Gtkmm2ext::UI::instance()->set_tip
3076 (_sync_framerate->tip_widget(),
3077 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
3078 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
3079 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
3080 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
3081 "timecode standard and the session standard."), PROGRAM_NAME));
3083 add_option (_("Sync"), _sync_framerate);
3085 _sync_genlock = new BoolOption (
3086 "timecode-source-is-synced",
3087 _("Sync-lock timecode to clock (disable drift compensation)"),
3088 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
3089 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
3091 Gtkmm2ext::UI::instance()->set_tip
3092 (_sync_genlock->tip_widget(),
3093 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
3094 "Sync Lock indicates that the selected external timecode source shares clock-sync "
3095 "(Black & Burst, Wordclock, etc) with the audio interface. "
3096 "This option disables drift compensation. The transport speed is fixed at 1.0. "
3097 "Vari-speed LTC will be ignored and cause drift."
3099 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
3100 "timecode sources shares clock sync."
3104 add_option (_("Sync"), _sync_genlock);
3106 _sync_source_2997 = new BoolOption (
3107 "timecode-source-2997",
3108 _("Lock to 29.9700 fps instead of 30000/1001"),
3109 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
3110 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
3112 Gtkmm2ext::UI::instance()->set_tip
3113 (_sync_source_2997->tip_widget(),
3114 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
3115 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
3116 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
3117 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
3118 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
3119 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
3122 add_option (_("Sync"), _sync_source_2997);
3124 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Reader")));
3126 _ltc_port = new ComboStringOption (
3128 _("LTC incoming port"),
3129 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
3130 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
3133 vector<string> physical_inputs;
3134 physical_inputs.push_back (_("None"));
3135 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
3136 _ltc_port->set_popdown_strings (physical_inputs);
3138 populate_sync_options ();
3139 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
3141 add_option (_("Sync/LTC"), _ltc_port);
3143 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Generator")));
3145 add_option (_("Sync/LTC"),
3148 _("Enable LTC generator"),
3149 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
3150 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
3153 _ltc_send_continuously = new BoolOption (
3154 "ltc-send-continuously",
3155 _("Send LTC while stopped"),
3156 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
3157 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
3159 Gtkmm2ext::UI::instance()->set_tip
3160 (_ltc_send_continuously->tip_widget(),
3161 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
3162 add_option (_("Sync/LTC"), _ltc_send_continuously);
3164 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level [dBFS]"),
3165 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_output_volume),
3166 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_output_volume),
3170 Gtkmm2ext::UI::instance()->set_tip
3171 (_ltc_volume_slider->tip_widget(),
3172 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
3174 add_option (_("Sync/LTC"), _ltc_volume_slider);
3177 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Beat Clock (Mclk) Generator")));
3179 add_option (_("Sync/MIDI"),
3182 _("Enable Mclk generator"),
3183 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
3184 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
3187 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC) Generator")));
3189 add_option (_("Sync/MIDI"),
3192 _("Enable MTC Generator"),
3193 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
3194 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
3197 add_option (_("Sync/MIDI"),
3198 new SpinOption<int> (
3199 "mtc-qf-speed-tolerance",
3200 _("Percentage either side of normal transport speed to transmit MTC"),
3201 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
3202 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
3206 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Machine Control (MMC)")));
3208 add_option (_("Sync/MIDI"),
3211 _("Respond to MMC commands"),
3212 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
3213 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
3216 add_option (_("Sync/MIDI"),
3219 _("Send MMC commands"),
3220 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
3221 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
3224 add_option (_("Sync/MIDI"),
3225 new SpinOption<uint8_t> (
3226 "mmc-receive-device-id",
3227 _("Inbound MMC device ID"),
3228 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
3229 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
3233 add_option (_("Sync/MIDI"),
3234 new SpinOption<uint8_t> (
3235 "mmc-send-device-id",
3236 _("Outbound MMC device ID"),
3237 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
3238 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
3243 /* Control Surfaces */
3245 add_option (_("Control Surfaces"), new OptionEditorHeading (_("Control Surfaces")));
3246 add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
3249 add_option (_("MIDI Ports"), new OptionEditorHeading (_("MIDI Port Options")));
3251 add_option (_("MIDI Ports"),
3253 "get-midi-input-follows-selection",
3254 _("MIDI input follows MIDI track selection"),
3255 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
3256 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
3259 add_option (_("MIDI Ports"), new MidiPortOptions ());
3260 add_option (_("MIDI Ports"), new OptionEditorBlank ());
3264 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3265 add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
3266 add_option (_("Plugins"),
3267 new RcActionButton (_("Scan for Plugins"),
3268 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3272 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
3274 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3275 bo = new BoolOption (
3276 "show-plugin-scan-window",
3277 _("Always Display Plugin Scan Progress"),
3278 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
3279 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
3281 add_option (_("Plugins"), bo);
3282 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3283 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
3286 bo = new BoolOption (
3287 "plugins-stop-with-transport",
3288 _("Silence plugins when the transport is stopped"),
3289 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
3290 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
3292 add_option (_("Plugins"), bo);
3293 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3294 _("<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."));
3296 bo = new BoolOption (
3297 "new-plugins-active",
3298 _("Make new plugins active"),
3299 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
3300 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
3302 add_option (_("Plugins"), bo);
3303 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3304 _("<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"));
3306 #if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
3307 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
3309 add_option (_("Plugins/VST"),
3310 new RcActionButton (_("Scan for Plugins"),
3311 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3314 #if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
3315 bo = new BoolOption (
3317 _("Enable Mac VST support (requires restart or re-scan)"),
3318 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
3319 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
3321 add_option (_("Plugins/VST"), bo);
3324 bo = new BoolOption (
3325 "discover-vst-on-start",
3326 _("Scan for [new] VST Plugins on Application Start"),
3327 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
3328 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
3330 add_option (_("Plugins/VST"), bo);
3331 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3332 _("<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"));
3334 #ifdef WINDOWS_VST_SUPPORT
3335 // currently verbose logging is only implemented for Windows VST.
3336 bo = new BoolOption (
3337 "verbose-plugin-scan",
3338 _("Verbose Plugin Scan"),
3339 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
3340 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
3342 add_option (_("Plugins/VST"), bo);
3343 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3344 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
3347 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
3349 add_option (_("Plugins/VST"),
3350 new RcActionButton (_("Clear"),
3351 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
3354 add_option (_("Plugins/VST"),
3355 new RcActionButton (_("Clear"),
3356 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
3357 _("VST Blacklist:")));
3360 #ifdef LXVST_SUPPORT
3361 add_option (_("Plugins/VST"),
3362 new RcActionButton (_("Edit"),
3363 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
3364 _("Linux VST Path:")));
3366 add_option (_("Plugins/VST"),
3367 new RcConfigDisplay (
3368 "plugin-path-lxvst",
3370 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
3374 #ifdef WINDOWS_VST_SUPPORT
3375 add_option (_("Plugins/VST"),
3376 new RcActionButton (_("Edit"),
3377 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
3378 _("Windows VST Path:")));
3379 add_option (_("Plugins/VST"),
3380 new RcConfigDisplay (
3383 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
3387 #ifdef AUDIOUNIT_SUPPORT
3389 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
3391 add_option (_("Plugins/Audio Unit"),
3392 new RcActionButton (_("Scan for Plugins"),
3393 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3396 bo = new BoolOption (
3397 "discover-audio-units",
3398 _("Scan for [new] AudioUnit Plugins on Application Start"),
3399 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
3400 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
3402 add_option (_("Plugins/Audio Unit"), bo);
3403 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3404 _("<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."));
3406 add_option (_("Plugins/Audio Unit"),
3407 new RcActionButton (_("Clear"),
3408 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
3411 add_option (_("Plugins/Audio Unit"),
3412 new RcActionButton (_("Clear"),
3413 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
3414 _("AU Blacklist:")));
3417 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
3418 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
3419 add_option (_("Plugins"),
3421 "open-gui-after-adding-plugin",
3422 _("Automatically open the plugin GUI when adding a new plugin"),
3423 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
3424 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3427 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3428 add_option (_("Plugins"),
3430 "show-inline-display-by-default",
3431 _("Show Plugin Inline Display on Mixerstrip by default"),
3432 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3433 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3436 _plugin_prefer_inline = new BoolOption (
3437 "prefer-inline-over-gui",
3438 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3439 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3440 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3442 add_option (_("Plugins"), _plugin_prefer_inline);
3445 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3447 bo = new BoolOption (
3448 "ask-replace-instrument",
3449 _("Ask to replace existing instrument plugin"),
3450 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3451 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3453 add_option (_("Plugins"), bo);
3455 bo = new BoolOption (
3456 "ask-setup_instrument",
3457 _("Interactively configure instrument plugins on insert"),
3458 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3459 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3461 add_option (_("Plugins"), bo);
3462 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3463 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3466 add_option (_("Plugins"), new OptionEditorBlank ());
3469 #if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
3470 add_option (_("Appearance"), new OptionEditorHeading (_("Graphics Acceleration")));
3473 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3474 BoolOption* bgc = new BoolOption (
3475 "cairo-image-surface",
3476 _("Disable Graphics Hardware Acceleration (requires restart)"),
3477 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3478 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3481 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3482 _("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));
3483 add_option (_("Appearance"), bgc);
3486 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3487 BoolOption* bgo = new BoolOption (
3489 _("Possibly improve slow graphical performance (requires restart)"),
3490 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3491 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3494 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));
3495 add_option (_("Appearance"), bgo);
3497 add_option (_("Appearance"), new OptionEditorHeading (_("Graphical User Interface")));
3499 add_option (_("Appearance"),
3502 _("Highlight widgets on mouseover"),
3503 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3504 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3507 add_option (_("Appearance"),
3510 _("Show tooltips if mouse hovers over a control"),
3511 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3512 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3515 bo = new BoolOption (
3516 "super-rapid-clock-update",
3517 _("Update clocks at TC Frame rate"),
3518 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3519 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3521 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3522 _("<b>When enabled</b> clock displays are updated every Timecode Frame (fps).\n\n"
3523 "<b>When disabled</b> clock displays are updated only every 100ms."
3525 add_option (_("Appearance"), bo);
3527 add_option (_("Appearance"),
3530 _("Blink Rec-Arm buttons"),
3531 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_rec_arm),
3532 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_rec_arm)
3537 /* font scaling does nothing with GDK/Quartz */
3538 add_option (_("Appearance"), new FontScalingOptions ());
3540 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("General")));
3541 add_option (_("Appearance/Editor"),
3543 "show-name-highlight",
3544 _("Use name highlight bars in region displays (requires a restart)"),
3545 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3546 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3549 add_option (_("Appearance/Editor"),
3551 "color-regions-using-track-color",
3552 _("Region color follows track color"),
3553 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_color_regions_using_track_color),
3554 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_color_regions_using_track_color)
3557 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Waveforms")));
3559 if (!Profile->get_mixbus()) {
3560 add_option (_("Appearance/Editor"),
3563 _("Show waveforms in regions"),
3564 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
3565 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
3569 add_option (_("Appearance/Editor"),
3571 "show-waveforms-while-recording",
3572 _("Show waveforms while recording"),
3573 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
3574 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
3577 add_option (_("Appearance/Editor"),
3579 "show-waveform-clipping",
3580 _("Show waveform clipping"),
3581 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveform_clipping),
3582 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveform_clipping)
3585 add_option (_("Appearance/Editor"), new ClipLevelOptions ());
3587 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
3589 _("Waveform scale"),
3590 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
3591 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
3594 wfs->add (Linear, _("linear"));
3595 wfs->add (Logarithmic, _("logarithmic"));
3597 add_option (_("Appearance/Editor"), wfs);
3599 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
3601 _("Waveform shape"),
3602 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
3603 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
3606 wfsh->add (Traditional, _("traditional"));
3607 wfsh->add (Rectified, _("rectified"));
3609 add_option (_("Appearance/Editor"), wfsh);
3611 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Editor Meters")));
3613 add_option (_("Appearance/Editor"),
3615 "show-track-meters",
3616 _("Show meters in track headers"),
3617 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3618 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3621 add_option (_("Appearance/Editor"),
3623 "editor-stereo-only-meters",
3624 _("Limit track header meters to stereo"),
3625 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3626 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3629 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("MIDI Regions")));
3631 add_option (_("Appearance/Editor"),
3633 "display-first-midi-bank-as-zero",
3634 _("Display first MIDI bank/program as 0"),
3635 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
3636 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
3639 add_option (_("Appearance/Editor"),
3641 "never-display-periodic-midi",
3642 _("Don't display periodic (MTC, MMC) SysEx messages in MIDI Regions"),
3643 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
3644 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
3647 add_option (_("Appearance/Editor"), new OptionEditorBlank ());
3649 /* The names of these controls must be the same as those given in MixerStrip
3650 for the actual widgets being controlled.
3652 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3653 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3654 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3655 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3656 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3657 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3658 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3660 add_option (_("Appearance/Mixer"),
3661 new VisibilityOption (
3663 &_mixer_strip_visibility,
3664 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3665 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3669 add_option (_("Appearance/Mixer"),
3671 "default-narrow_ms",
3672 _("Use narrow strips in the mixer by default"),
3673 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3674 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3677 add_option (_("Appearance/Mixer"), new OptionEditorBlank ());
3679 add_option (_("Appearance/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items")));
3681 add_option (_("Appearance/Toolbar"),
3683 "show-toolbar-selclock",
3684 _("Display Selection Clock"),
3685 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
3686 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
3689 if (!ARDOUR::Profile->get_small_screen()) {
3690 add_option (_("Appearance/Toolbar"),
3692 "show-secondary-clock",
3693 _("Display Secondary Clock"),
3694 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
3695 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
3699 add_option (_("Appearance/Toolbar"),
3701 "show-mini-timeline",
3702 _("Display Navigation Timeline"),
3703 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
3704 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
3707 add_option (_("Appearance/Toolbar"),
3709 "show-editor-meter",
3710 _("Display Master Level Meter"),
3711 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
3712 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
3715 add_option (_("Appearance/Toolbar"),
3716 new ColumVisibilityOption (
3717 "action-table-columns", _("Lua Action Script Button Visibility"), 4,
3718 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3719 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3722 add_option (_("Appearance/Toolbar"), new OptionEditorBlank ());
3725 OptionEditorHeading* quirks_head = new OptionEditorHeading (_("Various Workarounds for Windowing Systems"));
3727 quirks_head->set_note (string_compose (_("These settings will only take effect after %1 is restarted."), PROGRAM_NAME));
3729 /* and now the theme manager */
3731 add_option (_("Appearance/Theme"), new OptionEditorHeading (_("Theme")));
3733 add_option (_("Appearance/Theme"), new BoolOption (
3735 _("Draw \"flat\" buttons"),
3736 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_flat_buttons),
3737 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_flat_buttons)
3740 add_option (_("Appearance/Theme"), new BoolOption (
3742 _("LED meter style"),
3743 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3744 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3748 HSliderOption *gui_hs = new HSliderOption(
3749 "timeline-item-gradient-depth",
3750 _("Waveforms color gradient depth"),
3751 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_gradient_depth),
3752 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_gradient_depth),
3755 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3756 add_option (_("Appearance/Theme"), gui_hs);
3758 gui_hs = new HSliderOption(
3759 "timeline-item-gradient-depth",
3760 _("Timeline item gradient depth"),
3761 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_timeline_item_gradient_depth),
3762 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_timeline_item_gradient_depth),
3765 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3766 add_option (_("Appearance/Theme"), gui_hs);
3768 vector<string> icon_sets = ::get_icon_sets ();
3769 if (icon_sets.size() > 1) {
3770 ComboOption<std::string>* io = new ComboOption<std::string> (
3771 "icon-set", _("Icon Set"),
3772 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_icon_set),
3773 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_icon_set)
3775 for (vector<string>::const_iterator i = icon_sets.begin (); i != icon_sets.end (); ++i) {
3778 add_option (_("Appearance/Theme"), io);
3781 add_option (_("Appearance/Colors"), new OptionEditorHeading (_("Colors")));
3782 add_option (_("Appearance/Colors"), new ColorThemeManager);
3783 add_option (_("Appearance/Colors"), new OptionEditorBlank ());
3787 add_option (_("Appearance/Quirks"), quirks_head);
3789 add_option (_("Appearance/Quirks"),
3791 "use-wm-visibility",
3792 _("Use Window Manager/Desktop visibility information"),
3793 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3794 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3798 bo = new BoolOption (
3799 "all-floating-windows-are-dialogs",
3800 _("All floating windows are dialogs"),
3801 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_all_floating_windows_are_dialogs),
3802 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_all_floating_windows_are_dialogs)
3804 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3805 _("Mark all floating windows to be type \"Dialog\" rather than using \"Utility\" for some.\nThis may help with some window managers."));
3806 add_option (_("Appearance/Quirks"), bo);
3808 bo = new BoolOption (
3809 "transients-follow-front",
3810 _("Transient windows follow front window."),
3811 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_transients_follow_front),
3812 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_transients_follow_front)
3814 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3815 _("Make transient windows follow the front window when toggling between the editor and mixer."));
3816 add_option (_("Appearance/Quirks"), bo);
3819 if (!Profile->get_mixbus()) {
3820 bo = new BoolOption (
3821 "floating-monitor-section",
3822 _("Float detached monitor-section window"),
3823 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_floating_monitor_section),
3824 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_floating_monitor_section)
3826 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3827 _("When detaching the monitoring section, mark it as \"Utility\" window to stay in front."));
3828 add_option (_("Appearance/Quirks"), bo);
3831 add_option (_("Appearance/Quirks"), new OptionEditorBlank ());
3833 /* VIDEO Timeline */
3834 add_option (_("Video"), new OptionEditorHeading (_("Video Server")));
3835 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
3837 Widget::show_all ();
3839 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3840 parameter_changed ("send-ltc");
3841 parameter_changed ("sync-source");
3842 parameter_changed ("use-monitor-bus");
3843 parameter_changed ("open-gui-after-adding-plugin");
3845 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
3847 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
3848 (Gtk::StateType) here !!!
3850 Tabbable::set_state (*node, Stateful::loading_state_version);
3853 set_current_page (_("General"));
3857 RCOptionEditor::parameter_changed (string const & p)
3859 OptionEditor::parameter_changed (p);
3861 if (p == "use-monitor-bus") {
3862 bool const s = Config->get_use_monitor_bus ();
3864 /* we can't use this if we don't have a monitor bus */
3865 Config->set_solo_control_is_listen_control (false);
3867 _solo_control_is_listen_control->set_sensitive (s);
3868 _listen_position->set_sensitive (s);
3869 } else if (p == "sync-source") {
3870 _sync_source->set_sensitive (true);
3872 _sync_source->set_sensitive (!_session->config.get_external_sync());
3874 switch(Config->get_sync_source()) {
3877 _sync_genlock->set_sensitive (true);
3878 _sync_framerate->set_sensitive (true);
3879 _sync_source_2997->set_sensitive (true);
3882 _sync_genlock->set_sensitive (false);
3883 _sync_framerate->set_sensitive (false);
3884 _sync_source_2997->set_sensitive (false);
3887 } else if (p == "send-ltc") {
3888 bool const s = Config->get_send_ltc ();
3889 _ltc_send_continuously->set_sensitive (s);
3890 _ltc_volume_slider->set_sensitive (s);
3891 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
3892 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3893 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
3896 } else if (p == "enable-translation") {
3897 _l10n->set_sensitive (ARDOUR::translations_are_enabled ());
3902 void RCOptionEditor::plugin_scan_refresh () {
3903 PluginManager::instance().refresh();
3906 void RCOptionEditor::clear_vst_cache () {
3907 PluginManager::instance().clear_vst_cache();
3910 void RCOptionEditor::clear_vst_blacklist () {
3911 PluginManager::instance().clear_vst_blacklist();
3914 void RCOptionEditor::clear_au_cache () {
3915 PluginManager::instance().clear_au_cache();
3918 void RCOptionEditor::clear_au_blacklist () {
3919 PluginManager::instance().clear_au_blacklist();
3922 void RCOptionEditor::edit_lxvst_path () {
3923 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
3924 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3925 *current_toplevel(), _("Set Linux VST Search Path"),
3926 _rc_config->get_plugin_path_lxvst(),
3927 PluginManager::instance().get_default_lxvst_path()
3929 ResponseType r = (ResponseType) pd->run ();
3931 if (r == RESPONSE_ACCEPT) {
3932 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
3937 void RCOptionEditor::edit_vst_path () {
3938 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3939 *current_toplevel(), _("Set Windows VST Search Path"),
3940 _rc_config->get_plugin_path_vst(),
3941 PluginManager::instance().get_default_windows_vst_path()
3943 ResponseType r = (ResponseType) pd->run ();
3945 if (r == RESPONSE_ACCEPT) {
3946 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
3953 RCOptionEditor::populate_sync_options ()
3955 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3957 _sync_source->clear ();
3959 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3960 _sync_source->add (*i, sync_source_to_string (*i));
3963 if (sync_opts.empty()) {
3964 _sync_source->set_sensitive(false);
3966 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3967 _rc_config->set_sync_source(sync_opts.front());
3971 parameter_changed ("sync-source");
3975 RCOptionEditor::use_own_window (bool and_fill_it)
3977 bool new_window = !own_window ();
3979 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
3981 if (win && new_window) {
3982 win->set_name ("PreferencesWindow");
3983 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
3990 RCOptionEditor::get_state ()
3992 XMLNode* node = new XMLNode (X_("Preferences"));
3993 node->add_child_nocopy (Tabbable::get_state());