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")));
2231 bo = new BoolOption (
2232 "allow-non-quarter-pulse",
2233 _("Allow non quarter-note pulse"),
2234 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_allow_non_quarter_pulse),
2235 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_allow_non_quarter_pulse)
2237 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2238 string_compose (_("<b>When enabled</b> %1 will allow tempo to be expressed in divisions per minute\n"
2239 "<b>When disabled</b> %1 will only allow tempo to be expressed in quarter notes per minute"),
2241 add_option (_("General"), bo);
2243 if (!ARDOUR::Profile->get_mixbus()) {
2244 add_option (_("General"), new OptionEditorHeading (_("GUI Lock")));
2245 /* Lock GUI timeout */
2247 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2248 _("Lock timeout (seconds)"),
2249 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
2250 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds),
2253 slts->scale().set_digits (0);
2254 Gtkmm2ext::UI::instance()->set_tip (
2256 _("Lock GUI after this many idle seconds (zero to never lock)"));
2257 add_option (_("General"), slts);
2262 add_option (_("General/Translation"), new OptionEditorHeading (_("Internationalization")));
2264 bo = new BoolOption (
2265 "enable-translation",
2266 _("Use translations"),
2267 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2268 sigc::ptr_fun (ARDOUR::set_translations_enabled)
2271 bo->set_note (string_compose (_("These settings will only take effect after %1 is restarted (if available for your language preferences)."), PROGRAM_NAME));
2273 add_option (_("General/Translation"), bo);
2275 _l10n = new ComboOption<ARDOUR::LocaleMode> (
2278 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_locale_mode),
2279 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_locale_mode)
2282 _l10n->add (ARDOUR::SET_LC_ALL, _("Set complete locale"));
2283 _l10n->add (ARDOUR::SET_LC_MESSAGES, _("Enable only message translation"));
2284 _l10n->add (ARDOUR::SET_LC_MESSAGES_AND_LC_NUMERIC, _("Translate messages and format numeric format"));
2285 _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."));
2287 add_option (_("General/Translation"), _l10n);
2288 parameter_changed ("enable-translation");
2289 #endif // ENABLE_NLS
2294 add_option (_("Editor"), new OptionEditorHeading (_("General")));
2296 add_option (_("Editor"),
2298 "rubberbanding-snaps-to-grid",
2299 _("Snap rubberband to grid"),
2300 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2301 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2304 bo = new BoolOption (
2306 _("Prompt for new marker names"),
2307 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2308 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2310 add_option (_("Editor"), bo);
2311 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."
2312 "\n\nYou can always rename markers by right-clicking on them"));
2314 add_option (_("Editor"),
2316 "draggable-playhead",
2317 _("Allow dragging of playhead"),
2318 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2319 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2322 if (!Profile->get_mixbus()) {
2324 add_option (_("Editor"),
2326 "use-mouse-position-as-zoom-focus-on-scroll",
2327 _("Zoom to mouse position when zooming with scroll wheel"),
2328 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2329 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2333 add_option (_("Editor"),
2335 "use-time-rulers-to-zoom-with-vertical-drag",
2336 _("Zoom with vertical drag in rulers"),
2337 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag),
2338 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag)
2341 add_option (_("Editor"),
2343 "use-double-click-to-zoom-to-selection",
2344 _("Double click zooms to selection"),
2345 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection),
2346 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection)
2349 add_option (_("Editor"),
2351 "update-editor-during-summary-drag",
2352 _("Update editor window during drags of the summary"),
2353 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2354 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2357 add_option (_("Editor"),
2359 "autoscroll-editor",
2360 _("Auto-scroll editor window when dragging near its edges"),
2361 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2362 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2365 add_option (_("Editor"),
2366 new BoolComboOption (
2367 "show-region-gain-envelopes",
2368 _("Show gain envelopes in audio regions"),
2370 _("only in Draw and Internal Edit modes"),
2371 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2372 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2375 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2377 add_option (_("Editor"),
2379 "automation-follows-regions",
2380 _("Move relevant automation when audio regions are moved"),
2381 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2382 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2385 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2386 "default-fade-shape",
2387 _("Default fade shape"),
2388 sigc::mem_fun (*_rc_config,
2389 &RCConfiguration::get_default_fade_shape),
2390 sigc::mem_fun (*_rc_config,
2391 &RCConfiguration::set_default_fade_shape)
2394 fadeshape->add (FadeLinear,
2395 _("Linear (for highly correlated material)"));
2396 fadeshape->add (FadeConstantPower, _("Constant power"));
2397 fadeshape->add (FadeSymmetric, _("Symmetric"));
2398 fadeshape->add (FadeSlow, _("Slow"));
2399 fadeshape->add (FadeFast, _("Fast"));
2401 add_option (_("Editor"), fadeshape);
2403 bco = new BoolComboOption (
2404 "use-overlap-equivalency",
2405 _("Regions in edit groups are edited together"),
2406 _("whenever they overlap in time"),
2407 _("only if they have identical length and position"),
2408 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2409 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2412 add_option (_("Editor"), bco);
2414 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2416 _("Layering model"),
2417 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2418 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2421 lm->add (LaterHigher, _("later is higher"));
2422 lm->add (Manual, _("manual layering"));
2423 add_option (_("Editor"), lm);
2425 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2426 "region-selection-after-split",
2427 _("After splitting selected regions, select"),
2428 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2429 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2431 // TODO: decide which of these modes are really useful
2432 rsas->add(None, _("no regions"));
2433 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2434 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2435 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2436 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2437 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2438 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2439 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2441 add_option (_("Editor"), rsas);
2443 add_option (_("Editor/Modifiers"), new OptionEditorHeading (_("Keyboard Modifiers")));
2444 add_option (_("Editor/Modifiers"), new KeyboardOptions);
2445 add_option (_("Editor/Modifiers"), new OptionEditorBlank ());
2447 /* MIXER -- SOLO AND MUTE */
2449 add_option (_("Mixer"), new OptionEditorHeading (_("Solo")));
2451 _solo_control_is_listen_control = new BoolOption (
2452 "solo-control-is-listen-control",
2453 _("Solo controls are Listen controls"),
2454 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2455 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2458 add_option (_("Mixer"), _solo_control_is_listen_control);
2460 add_option (_("Mixer"),
2463 _("Exclusive solo"),
2464 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2465 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2468 add_option (_("Mixer"),
2471 _("Show solo muting"),
2472 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2473 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2476 add_option (_("Mixer"),
2478 "solo-mute-override",
2479 _("Soloing overrides muting"),
2480 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2481 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2484 add_option (_("Mixer"),
2487 _("Solo-in-place mute cut (dB)"),
2488 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2489 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2492 _listen_position = new ComboOption<ListenPosition> (
2494 _("Listen Position"),
2495 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2496 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2499 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2500 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2502 add_option (_("Mixer"), _listen_position);
2504 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2506 _("PFL signals come from"),
2507 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2508 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2511 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2512 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2514 add_option (_("Mixer"), pp);
2516 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2518 _("AFL signals come from"),
2519 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2520 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2523 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2524 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2526 add_option (_("Mixer"), pa);
2528 add_option (_("Mixer"), new OptionEditorHeading (_("Default track / bus muting options")));
2530 add_option (_("Mixer"),
2532 "mute-affects-pre-fader",
2533 _("Mute affects pre-fader sends"),
2534 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2535 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2538 add_option (_("Mixer"),
2540 "mute-affects-post-fader",
2541 _("Mute affects post-fader sends"),
2542 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2543 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2546 add_option (_("Mixer"),
2548 "mute-affects-control-outs",
2549 _("Mute affects control outputs"),
2550 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2551 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2554 add_option (_("Mixer"),
2556 "mute-affects-main-outs",
2557 _("Mute affects main outputs"),
2558 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2559 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2563 if (!ARDOUR::Profile->get_mixbus()) {
2564 add_option (_("Mixer"), new OptionEditorHeading (_("Send Routing")));
2565 add_option (_("Mixer"),
2567 "link-send-and-route-panner",
2568 _("Link panners of Aux and External Sends with main panner by default"),
2569 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2570 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2576 add_option (_("Signal Flow"), new OptionEditorHeading (_("Monitoring")));
2578 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2580 _("Record monitoring handled by"),
2581 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2582 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2585 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2586 mm->add (HardwareMonitoring, _("via Audio Driver"));
2589 string prog (PROGRAM_NAME);
2590 boost::algorithm::to_lower (prog);
2591 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2592 mm->add (ExternalMonitoring, _("audio hardware"));
2594 add_option (_("Signal Flow"), mm);
2596 bo = new BoolOption (
2597 "tape-machine-mode",
2598 _("Tape machine mode"),
2599 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2600 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2602 add_option (_("Signal Flow"), bo);
2603 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2604 string_compose (_("<b>When enabled</b> %1 will not monitor a track's input if the transport is stopped."),
2607 if (!Profile->get_mixbus()) {
2609 add_option (_("Signal Flow"), new OptionEditorHeading (_("Track and Bus Connections")));
2611 add_option (_("Signal Flow"),
2613 "auto-connect-standard-busses",
2614 _("Auto-connect master/monitor busses"),
2615 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2616 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2619 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2620 "input-auto-connect",
2621 _("Connect track inputs"),
2622 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2623 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2626 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2627 iac->add (ManualConnect, _("manually"));
2629 add_option (_("Signal Flow"), iac);
2631 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2632 "output-auto-connect",
2633 _("Connect track and bus outputs"),
2634 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2635 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2638 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2639 oac->add (AutoConnectMaster, _("automatically to master bus"));
2640 oac->add (ManualConnect, _("manually"));
2642 add_option (_("Signal Flow"), oac);
2644 bo = new BoolOption (
2646 _("Use 'Strict-I/O' for new tracks or Busses"),
2647 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2648 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2651 add_option (_("Signal Flow"), bo);
2652 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2653 _("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."));
2660 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2662 add_option (_("Audio"), new BufferingOptions (_rc_config));
2664 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2666 add_option (_("Audio"),
2668 "denormal-protection",
2669 _("Use DC bias to protect against denormals"),
2670 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2671 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2674 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2676 _("Processor handling"),
2677 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2678 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2682 dm->add (DenormalNone, _("no processor handling"));
2684 FPU* fpu = FPU::instance();
2686 if (fpu->has_flush_to_zero()) {
2688 dm->add (DenormalFTZ, _("use FlushToZero"));
2689 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2690 _rc_config->set_denormal_model(DenormalNone);
2693 if (fpu->has_denormals_are_zero()) {
2695 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2696 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2697 _rc_config->set_denormal_model(DenormalNone);
2700 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2702 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2703 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2704 _rc_config->set_denormal_model(DenormalNone);
2708 dm->set_sensitive(false);
2711 add_option (_("Audio"), dm);
2713 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2715 add_option (_("Audio"),
2717 "auto-analyse-audio",
2718 _("Enable automatic analysis of audio"),
2719 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2720 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2723 add_option (_("Audio"),
2725 "replicate-missing-region-channels",
2726 _("Replicate missing region channels"),
2727 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2728 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2733 add_option (_("MIDI"), new OptionEditorHeading (_("Buffering")));
2735 add_option (_("MIDI"),
2736 new SpinOption<float> (
2738 _("MIDI read-ahead time (seconds)"),
2739 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2740 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2745 add_option (_("MIDI"), new OptionEditorHeading (_("Session")));
2747 add_option (_("MIDI"),
2748 new SpinOption<int32_t> (
2749 "initial-program-change",
2750 _("Initial program change"),
2751 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2752 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2756 add_option (_("MIDI"), new OptionEditorHeading (_("Audition")));
2758 add_option (_("MIDI"),
2761 _("Sound MIDI notes as they are selected in the editor"),
2762 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2763 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2766 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2767 "midi-audition-synth-uri",
2768 _("MIDI Audition Synth (LV2)"),
2769 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2770 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2773 audition_synth->add(X_(""), _("None"));
2774 PluginInfoList all_plugs;
2775 PluginManager& manager (PluginManager::instance());
2777 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2779 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2780 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2781 if (!(*i)->is_instrument()) continue;
2782 if ((*i)->type != ARDOUR::LV2) continue;
2783 if ((*i)->name.length() > 46) {
2784 audition_synth->add((*i)->unique_id, (*i)->name.substr (0, 44) + "...");
2786 audition_synth->add((*i)->unique_id, (*i)->name);
2791 add_option (_("MIDI"), audition_synth);
2795 add_option (_("Metronome"), new OptionEditorHeading (_("Metronome")));
2796 add_option (_("Metronome"), new ClickOptions (_rc_config));
2800 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2802 ComboOption<float>* mht = new ComboOption<float> (
2804 _("Peak hold time"),
2805 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
2806 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
2809 mht->add (MeterHoldOff, _("off"));
2810 mht->add (MeterHoldShort, _("short"));
2811 mht->add (MeterHoldMedium, _("medium"));
2812 mht->add (MeterHoldLong, _("long"));
2814 add_option (S_("Preferences|Metering"), mht);
2816 ComboOption<float>* mfo = new ComboOption<float> (
2819 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2820 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2823 mfo->add (METER_FALLOFF_OFF, _("off"));
2824 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2825 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2826 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2827 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2828 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2829 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
2831 add_option (S_("Preferences|Metering"), mfo);
2833 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2834 "meter-line-up-level",
2835 _("Meter line-up level; 0dBu"),
2836 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
2837 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
2840 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2841 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2842 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2843 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2845 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."));
2847 add_option (S_("Preferences|Metering"), mlu);
2849 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2850 "meter-line-up-din",
2851 _("IEC1/DIN Meter line-up level; 0dBu"),
2852 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
2853 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
2856 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2857 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2858 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2859 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2861 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2863 add_option (S_("Preferences|Metering"), mld);
2865 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2866 "meter-vu-standard",
2867 _("VU Meter standard"),
2868 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
2869 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
2872 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2873 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2874 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2875 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2877 add_option (S_("Preferences|Metering"), mvu);
2879 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
2880 "meter-type-master",
2881 _("Default Meter Type for Master Bus"),
2882 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
2883 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
2885 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2886 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2887 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2888 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2889 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2890 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2891 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2892 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
2894 add_option (S_("Preferences|Metering"), mtm);
2897 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
2899 _("Default Meter Type for Busses"),
2900 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
2901 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
2903 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2904 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2905 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2906 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2907 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2908 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2909 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2910 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
2912 add_option (S_("Preferences|Metering"), mtb);
2914 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
2916 _("Default Meter Type for Tracks"),
2917 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
2918 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
2920 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2921 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
2923 add_option (S_("Preferences|Metering"), mtt);
2925 HSliderOption *mpks = new HSliderOption("meter-peak",
2926 _("Peak threshold [dBFS]"),
2927 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
2928 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak),
2932 Gtkmm2ext::UI::instance()->set_tip (
2934 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
2936 add_option (S_("Preferences|Metering"), mpks);
2938 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
2940 add_option (S_("Preferences|Metering"),
2942 "save-export-analysis-image",
2943 _("Save loudness analysis as image file"),
2944 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
2945 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
2948 /* TRANSPORT & Sync */
2950 add_option (_("Transport"), new OptionEditorHeading (_("General")));
2952 bo = new BoolOption (
2953 "stop-at-session-end",
2954 _("Stop at the end of the session"),
2955 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
2956 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
2958 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2959 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
2960 "when it reaches the current session end marker\n\n"
2961 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
2963 add_option (_("Transport"), bo);
2965 bo = new BoolOption (
2966 "latched-record-enable",
2967 _("Keep record-enable engaged on stop"),
2968 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
2969 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
2971 add_option (_("Transport"), bo);
2972 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2973 _("<b>When enabled</b> master record will remain engaged when the transport transitions to stop.\n<b>When disabled</b> master record will be disabled when the transport transitions to stop."));
2975 bo = new BoolOption (
2976 "disable-disarm-during-roll",
2977 _("Disable per-track record disarm while rolling"),
2978 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
2979 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
2981 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(), _("<b>When enabled</b> this will prevent you from accidentally stopping specific tracks recording during a take."));
2982 add_option (_("Transport"), bo);
2984 bo = new BoolOption (
2986 _("12dB gain reduction during fast-forward and fast-rewind"),
2987 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
2988 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2990 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2991 _("<b>When enabled</b> rhis will reduce the unpleasant increase in perceived volume "
2992 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2993 add_option (_("Transport"), bo);
2995 ComboOption<float>* psc = new ComboOption<float> (
2998 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
2999 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
3001 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
3002 (_("The amount of preroll to apply when <b>Play with Preroll</b> or <b>Record with Preroll</b>is initiated.\n\n"
3003 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
3004 psc->add (-4.0, _("4 Bars"));
3005 psc->add (-2.0, _("2 Bars"));
3006 psc->add (-1.0, _("1 Bar"));
3007 psc->add (0.0, _("0 (no pre-roll)"));
3008 psc->add (0.1, _("0.1 second"));
3009 psc->add (0.25, _("0.25 second"));
3010 psc->add (0.5, _("0.5 second"));
3011 psc->add (1.0, _("1.0 second"));
3012 psc->add (2.0, _("2.0 seconds"));
3013 add_option (_("Transport"), psc);
3016 add_option (_("Transport"), new OptionEditorHeading (_("Looping")));
3018 bo = new BoolOption (
3020 _("Play loop is a transport mode"),
3021 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
3022 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
3024 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3025 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
3026 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
3027 add_option (_("Transport"), bo);
3029 bo = new BoolOption (
3031 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
3032 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
3033 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
3035 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3036 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
3037 "preventing any need to do a transport locate at the end of the loop\n\n"
3038 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
3039 "which will often cause a small click or delay"), PROGRAM_NAME));
3040 add_option (_("Transport"), bo);
3042 add_option (_("Transport"), new OptionEditorHeading (_("Dropout (xrun) Handling")));
3043 bo = new BoolOption (
3044 "stop-recording-on-xrun",
3045 _("Stop recording when an xrun occurs"),
3046 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
3047 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
3049 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3050 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
3052 add_option (_("Transport"), bo);
3054 bo = new BoolOption (
3055 "create-xrun-marker",
3056 _("Create markers where xruns occur"),
3057 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
3058 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
3060 add_option (_("Transport"), bo);
3065 add_option (_("Sync"), new OptionEditorHeading (_("External Syncronization")));
3067 _sync_source = new ComboOption<SyncSource> (
3069 _("External timecode source"),
3070 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
3071 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
3074 add_option (_("Sync"), _sync_source);
3076 _sync_framerate = new BoolOption (
3077 "timecode-sync-frame-rate",
3078 _("Match session video frame rate to external timecode"),
3079 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
3080 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
3082 Gtkmm2ext::UI::instance()->set_tip
3083 (_sync_framerate->tip_widget(),
3084 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
3085 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
3086 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
3087 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
3088 "timecode standard and the session standard."), PROGRAM_NAME));
3090 add_option (_("Sync"), _sync_framerate);
3092 _sync_genlock = new BoolOption (
3093 "timecode-source-is-synced",
3094 _("Sync-lock timecode to clock (disable drift compensation)"),
3095 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
3096 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
3098 Gtkmm2ext::UI::instance()->set_tip
3099 (_sync_genlock->tip_widget(),
3100 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
3101 "Sync Lock indicates that the selected external timecode source shares clock-sync "
3102 "(Black & Burst, Wordclock, etc) with the audio interface. "
3103 "This option disables drift compensation. The transport speed is fixed at 1.0. "
3104 "Vari-speed LTC will be ignored and cause drift."
3106 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
3107 "timecode sources shares clock sync."
3111 add_option (_("Sync"), _sync_genlock);
3113 _sync_source_2997 = new BoolOption (
3114 "timecode-source-2997",
3115 _("Lock to 29.9700 fps instead of 30000/1001"),
3116 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
3117 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
3119 Gtkmm2ext::UI::instance()->set_tip
3120 (_sync_source_2997->tip_widget(),
3121 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
3122 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
3123 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
3124 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
3125 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
3126 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
3129 add_option (_("Sync"), _sync_source_2997);
3131 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Reader")));
3133 _ltc_port = new ComboStringOption (
3135 _("LTC incoming port"),
3136 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
3137 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
3140 vector<string> physical_inputs;
3141 physical_inputs.push_back (_("None"));
3142 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
3143 _ltc_port->set_popdown_strings (physical_inputs);
3145 populate_sync_options ();
3146 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
3148 add_option (_("Sync/LTC"), _ltc_port);
3150 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Generator")));
3152 add_option (_("Sync/LTC"),
3155 _("Enable LTC generator"),
3156 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
3157 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
3160 _ltc_send_continuously = new BoolOption (
3161 "ltc-send-continuously",
3162 _("Send LTC while stopped"),
3163 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
3164 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
3166 Gtkmm2ext::UI::instance()->set_tip
3167 (_ltc_send_continuously->tip_widget(),
3168 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
3169 add_option (_("Sync/LTC"), _ltc_send_continuously);
3171 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level [dBFS]"),
3172 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_output_volume),
3173 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_output_volume),
3177 Gtkmm2ext::UI::instance()->set_tip
3178 (_ltc_volume_slider->tip_widget(),
3179 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
3181 add_option (_("Sync/LTC"), _ltc_volume_slider);
3184 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Beat Clock (Mclk) Generator")));
3186 add_option (_("Sync/MIDI"),
3189 _("Enable Mclk generator"),
3190 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
3191 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
3194 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC) Generator")));
3196 add_option (_("Sync/MIDI"),
3199 _("Enable MTC Generator"),
3200 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
3201 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
3204 add_option (_("Sync/MIDI"),
3205 new SpinOption<int> (
3206 "mtc-qf-speed-tolerance",
3207 _("Percentage either side of normal transport speed to transmit MTC"),
3208 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
3209 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
3213 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Machine Control (MMC)")));
3215 add_option (_("Sync/MIDI"),
3218 _("Respond to MMC commands"),
3219 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
3220 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
3223 add_option (_("Sync/MIDI"),
3226 _("Send MMC commands"),
3227 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
3228 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
3231 add_option (_("Sync/MIDI"),
3232 new SpinOption<uint8_t> (
3233 "mmc-receive-device-id",
3234 _("Inbound MMC device ID"),
3235 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
3236 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
3240 add_option (_("Sync/MIDI"),
3241 new SpinOption<uint8_t> (
3242 "mmc-send-device-id",
3243 _("Outbound MMC device ID"),
3244 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
3245 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
3250 /* Control Surfaces */
3252 add_option (_("Control Surfaces"), new OptionEditorHeading (_("Control Surfaces")));
3253 add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
3256 add_option (_("MIDI Ports"), new OptionEditorHeading (_("MIDI Port Options")));
3258 add_option (_("MIDI Ports"),
3260 "get-midi-input-follows-selection",
3261 _("MIDI input follows MIDI track selection"),
3262 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
3263 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
3266 add_option (_("MIDI Ports"), new MidiPortOptions ());
3267 add_option (_("MIDI Ports"), new OptionEditorBlank ());
3271 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3272 add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
3273 add_option (_("Plugins"),
3274 new RcActionButton (_("Scan for Plugins"),
3275 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3279 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
3281 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3282 bo = new BoolOption (
3283 "show-plugin-scan-window",
3284 _("Always Display Plugin Scan Progress"),
3285 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
3286 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
3288 add_option (_("Plugins"), bo);
3289 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3290 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
3293 bo = new BoolOption (
3294 "plugins-stop-with-transport",
3295 _("Silence plugins when the transport is stopped"),
3296 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
3297 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
3299 add_option (_("Plugins"), bo);
3300 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3301 _("<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."));
3303 bo = new BoolOption (
3304 "new-plugins-active",
3305 _("Make new plugins active"),
3306 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
3307 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
3309 add_option (_("Plugins"), bo);
3310 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3311 _("<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"));
3313 #if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
3314 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
3316 add_option (_("Plugins/VST"),
3317 new RcActionButton (_("Scan for Plugins"),
3318 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3321 #if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
3322 bo = new BoolOption (
3324 _("Enable Mac VST support (requires restart or re-scan)"),
3325 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
3326 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
3328 add_option (_("Plugins/VST"), bo);
3331 bo = new BoolOption (
3332 "discover-vst-on-start",
3333 _("Scan for [new] VST Plugins on Application Start"),
3334 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
3335 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
3337 add_option (_("Plugins/VST"), bo);
3338 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3339 _("<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"));
3341 #ifdef WINDOWS_VST_SUPPORT
3342 // currently verbose logging is only implemented for Windows VST.
3343 bo = new BoolOption (
3344 "verbose-plugin-scan",
3345 _("Verbose Plugin Scan"),
3346 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
3347 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
3349 add_option (_("Plugins/VST"), bo);
3350 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3351 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
3354 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
3356 add_option (_("Plugins/VST"),
3357 new RcActionButton (_("Clear"),
3358 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
3361 add_option (_("Plugins/VST"),
3362 new RcActionButton (_("Clear"),
3363 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
3364 _("VST Blacklist:")));
3367 #ifdef LXVST_SUPPORT
3368 add_option (_("Plugins/VST"),
3369 new RcActionButton (_("Edit"),
3370 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
3371 _("Linux VST Path:")));
3373 add_option (_("Plugins/VST"),
3374 new RcConfigDisplay (
3375 "plugin-path-lxvst",
3377 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
3381 #ifdef WINDOWS_VST_SUPPORT
3382 add_option (_("Plugins/VST"),
3383 new RcActionButton (_("Edit"),
3384 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
3385 _("Windows VST Path:")));
3386 add_option (_("Plugins/VST"),
3387 new RcConfigDisplay (
3390 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
3394 #ifdef AUDIOUNIT_SUPPORT
3396 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
3398 add_option (_("Plugins/Audio Unit"),
3399 new RcActionButton (_("Scan for Plugins"),
3400 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3403 bo = new BoolOption (
3404 "discover-audio-units",
3405 _("Scan for [new] AudioUnit Plugins on Application Start"),
3406 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
3407 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
3409 add_option (_("Plugins/Audio Unit"), bo);
3410 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3411 _("<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."));
3413 add_option (_("Plugins/Audio Unit"),
3414 new RcActionButton (_("Clear"),
3415 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
3418 add_option (_("Plugins/Audio Unit"),
3419 new RcActionButton (_("Clear"),
3420 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
3421 _("AU Blacklist:")));
3424 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
3425 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
3426 add_option (_("Plugins"),
3428 "open-gui-after-adding-plugin",
3429 _("Automatically open the plugin GUI when adding a new plugin"),
3430 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
3431 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3434 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3435 add_option (_("Plugins"),
3437 "show-inline-display-by-default",
3438 _("Show Plugin Inline Display on Mixerstrip by default"),
3439 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3440 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3443 _plugin_prefer_inline = new BoolOption (
3444 "prefer-inline-over-gui",
3445 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3446 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3447 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3449 add_option (_("Plugins"), _plugin_prefer_inline);
3452 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3454 bo = new BoolOption (
3455 "ask-replace-instrument",
3456 _("Ask to replace existing instrument plugin"),
3457 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3458 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3460 add_option (_("Plugins"), bo);
3462 bo = new BoolOption (
3463 "ask-setup_instrument",
3464 _("Interactively configure instrument plugins on insert"),
3465 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3466 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3468 add_option (_("Plugins"), bo);
3469 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3470 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3473 add_option (_("Plugins"), new OptionEditorBlank ());
3476 #if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
3477 add_option (_("Appearance"), new OptionEditorHeading (_("Graphics Acceleration")));
3480 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3481 BoolOption* bgc = new BoolOption (
3482 "cairo-image-surface",
3483 _("Disable Graphics Hardware Acceleration (requires restart)"),
3484 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3485 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3488 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3489 _("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));
3490 add_option (_("Appearance"), bgc);
3493 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3494 BoolOption* bgo = new BoolOption (
3496 _("Possibly improve slow graphical performance (requires restart)"),
3497 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3498 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3501 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));
3502 add_option (_("Appearance"), bgo);
3504 add_option (_("Appearance"), new OptionEditorHeading (_("Graphical User Interface")));
3506 add_option (_("Appearance"),
3509 _("Highlight widgets on mouseover"),
3510 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3511 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3514 add_option (_("Appearance"),
3517 _("Show tooltips if mouse hovers over a control"),
3518 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3519 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3522 bo = new BoolOption (
3523 "super-rapid-clock-update",
3524 _("Update clocks at TC Frame rate"),
3525 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3526 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3528 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3529 _("<b>When enabled</b> clock displays are updated every Timecode Frame (fps).\n\n"
3530 "<b>When disabled</b> clock displays are updated only every 100ms."
3532 add_option (_("Appearance"), bo);
3534 add_option (_("Appearance"),
3537 _("Blink Rec-Arm buttons"),
3538 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_rec_arm),
3539 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_rec_arm)
3544 /* font scaling does nothing with GDK/Quartz */
3545 add_option (_("Appearance"), new FontScalingOptions ());
3547 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("General")));
3548 add_option (_("Appearance/Editor"),
3550 "show-name-highlight",
3551 _("Use name highlight bars in region displays (requires a restart)"),
3552 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3553 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3556 add_option (_("Appearance/Editor"),
3558 "color-regions-using-track-color",
3559 _("Region color follows track color"),
3560 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_color_regions_using_track_color),
3561 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_color_regions_using_track_color)
3564 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Waveforms")));
3566 if (!Profile->get_mixbus()) {
3567 add_option (_("Appearance/Editor"),
3570 _("Show waveforms in regions"),
3571 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
3572 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
3576 add_option (_("Appearance/Editor"),
3578 "show-waveforms-while-recording",
3579 _("Show waveforms while recording"),
3580 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
3581 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
3584 add_option (_("Appearance/Editor"),
3586 "show-waveform-clipping",
3587 _("Show waveform clipping"),
3588 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveform_clipping),
3589 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveform_clipping)
3592 add_option (_("Appearance/Editor"), new ClipLevelOptions ());
3594 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
3596 _("Waveform scale"),
3597 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
3598 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
3601 wfs->add (Linear, _("linear"));
3602 wfs->add (Logarithmic, _("logarithmic"));
3604 add_option (_("Appearance/Editor"), wfs);
3606 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
3608 _("Waveform shape"),
3609 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
3610 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
3613 wfsh->add (Traditional, _("traditional"));
3614 wfsh->add (Rectified, _("rectified"));
3616 add_option (_("Appearance/Editor"), wfsh);
3618 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Editor Meters")));
3620 add_option (_("Appearance/Editor"),
3622 "show-track-meters",
3623 _("Show meters in track headers"),
3624 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3625 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3628 add_option (_("Appearance/Editor"),
3630 "editor-stereo-only-meters",
3631 _("Limit track header meters to stereo"),
3632 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3633 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3636 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("MIDI Regions")));
3638 add_option (_("Appearance/Editor"),
3640 "display-first-midi-bank-as-zero",
3641 _("Display first MIDI bank/program as 0"),
3642 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
3643 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
3646 add_option (_("Appearance/Editor"),
3648 "never-display-periodic-midi",
3649 _("Don't display periodic (MTC, MMC) SysEx messages in MIDI Regions"),
3650 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
3651 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
3654 add_option (_("Appearance/Editor"), new OptionEditorBlank ());
3656 /* The names of these controls must be the same as those given in MixerStrip
3657 for the actual widgets being controlled.
3659 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3660 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3661 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3662 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3663 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3664 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3665 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3667 add_option (_("Appearance/Mixer"),
3668 new VisibilityOption (
3670 &_mixer_strip_visibility,
3671 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3672 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3676 add_option (_("Appearance/Mixer"),
3678 "default-narrow_ms",
3679 _("Use narrow strips in the mixer by default"),
3680 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3681 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3684 add_option (_("Appearance/Mixer"), new OptionEditorBlank ());
3686 add_option (_("Appearance/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items")));
3688 add_option (_("Appearance/Toolbar"),
3690 "show-toolbar-recpunch",
3691 _("Display Record/Punch Options"),
3692 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_recpunch),
3693 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_recpunch)
3696 add_option (_("Appearance/Toolbar"),
3698 "show-toolbar-monitoring",
3699 _("Display Monitor Options"),
3700 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_monitoring),
3701 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_monitoring)
3704 add_option (_("Appearance/Toolbar"),
3706 "show-toolbar-selclock",
3707 _("Display Selection Clock"),
3708 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
3709 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
3712 if (!ARDOUR::Profile->get_small_screen()) {
3713 add_option (_("Appearance/Toolbar"),
3715 "show-secondary-clock",
3716 _("Display Secondary Clock"),
3717 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
3718 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
3722 add_option (_("Appearance/Toolbar"),
3724 "show-mini-timeline",
3725 _("Display Navigation Timeline"),
3726 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
3727 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
3730 add_option (_("Appearance/Toolbar"),
3732 "show-editor-meter",
3733 _("Display Master Level Meter"),
3734 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
3735 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
3738 add_option (_("Appearance/Toolbar"),
3739 new ColumVisibilityOption (
3740 "action-table-columns", _("Lua Action Script Button Visibility"), 4,
3741 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3742 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3745 add_option (_("Appearance/Toolbar"), new OptionEditorBlank ());
3748 OptionEditorHeading* quirks_head = new OptionEditorHeading (_("Various Workarounds for Windowing Systems"));
3750 quirks_head->set_note (string_compose (_("Rules for closing, minimizing, maximizing, and stay-on-top can vary\n\
3751 with each version of your OS, and the preferences that you've set in your OS.\n\n\
3752 You can adjust the options, below, to change how %1's windows and dialogs behave.\n\n\
3753 These settings will only take effect after %1 is restarted.\n\
3756 /* and now the theme manager */
3758 add_option (_("Appearance/Theme"), new OptionEditorHeading (_("Theme")));
3760 add_option (_("Appearance/Theme"), new BoolOption (
3762 _("Draw \"flat\" buttons"),
3763 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_flat_buttons),
3764 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_flat_buttons)
3767 add_option (_("Appearance/Theme"), new BoolOption (
3769 _("LED meter style"),
3770 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3771 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3775 HSliderOption *gui_hs = new HSliderOption(
3776 "timeline-item-gradient-depth",
3777 _("Waveforms color gradient depth"),
3778 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_gradient_depth),
3779 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_gradient_depth),
3782 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3783 add_option (_("Appearance/Theme"), gui_hs);
3785 gui_hs = new HSliderOption(
3786 "timeline-item-gradient-depth",
3787 _("Timeline item gradient depth"),
3788 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_timeline_item_gradient_depth),
3789 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_timeline_item_gradient_depth),
3792 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3793 add_option (_("Appearance/Theme"), gui_hs);
3795 vector<string> icon_sets = ::get_icon_sets ();
3796 if (icon_sets.size() > 1) {
3797 ComboOption<std::string>* io = new ComboOption<std::string> (
3798 "icon-set", _("Icon Set"),
3799 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_icon_set),
3800 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_icon_set)
3802 for (vector<string>::const_iterator i = icon_sets.begin (); i != icon_sets.end (); ++i) {
3805 add_option (_("Appearance/Theme"), io);
3808 add_option (_("Appearance/Colors"), new OptionEditorHeading (_("Colors")));
3809 add_option (_("Appearance/Colors"), new ColorThemeManager);
3810 add_option (_("Appearance/Colors"), new OptionEditorBlank ());
3814 add_option (_("Appearance/Quirks"), quirks_head);
3816 bo = new BoolOption (
3817 "use-wm-visibility",
3818 _("Use visibility information provided by your Window Manager/Desktop"),
3819 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3820 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3822 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3823 _("If you have trouble toggling between hidden Editor and Mixer windows, try changing this setting."));
3824 add_option (_("Appearance/Quirks"), bo);
3827 bo = new BoolOption (
3828 "all-floating-windows-are-dialogs",
3829 _("All floating windows are dialogs"),
3830 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_all_floating_windows_are_dialogs),
3831 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_all_floating_windows_are_dialogs)
3833 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3834 _("Mark all floating windows to be type \"Dialog\" rather than using \"Utility\" for some.\nThis may help with some window managers."));
3835 add_option (_("Appearance/Quirks"), bo);
3837 bo = new BoolOption (
3838 "transients-follow-front",
3839 _("Transient windows follow front window."),
3840 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_transients_follow_front),
3841 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_transients_follow_front)
3843 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3844 _("Make transient windows follow the front window when toggling between the editor and mixer."));
3845 add_option (_("Appearance/Quirks"), bo);
3848 if (!Profile->get_mixbus()) {
3849 bo = new BoolOption (
3850 "floating-monitor-section",
3851 _("Float detached monitor-section window"),
3852 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_floating_monitor_section),
3853 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_floating_monitor_section)
3855 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3856 _("When detaching the monitoring section, mark it as \"Utility\" window to stay in front."));
3857 add_option (_("Appearance/Quirks"), bo);
3860 add_option (_("Appearance/Quirks"), new OptionEditorBlank ());
3862 /* VIDEO Timeline */
3863 add_option (_("Video"), new OptionEditorHeading (_("Video Server")));
3864 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
3866 Widget::show_all ();
3868 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3869 parameter_changed ("send-ltc");
3870 parameter_changed ("sync-source");
3871 parameter_changed ("use-monitor-bus");
3872 parameter_changed ("open-gui-after-adding-plugin");
3874 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
3876 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
3877 (Gtk::StateType) here !!!
3879 Tabbable::set_state (*node, Stateful::loading_state_version);
3882 set_current_page (_("General"));
3886 RCOptionEditor::parameter_changed (string const & p)
3888 OptionEditor::parameter_changed (p);
3890 if (p == "use-monitor-bus") {
3891 bool const s = Config->get_use_monitor_bus ();
3893 /* we can't use this if we don't have a monitor bus */
3894 Config->set_solo_control_is_listen_control (false);
3896 _solo_control_is_listen_control->set_sensitive (s);
3897 _listen_position->set_sensitive (s);
3898 } else if (p == "sync-source") {
3899 _sync_source->set_sensitive (true);
3901 _sync_source->set_sensitive (!_session->config.get_external_sync());
3903 switch(Config->get_sync_source()) {
3906 _sync_genlock->set_sensitive (true);
3907 _sync_framerate->set_sensitive (true);
3908 _sync_source_2997->set_sensitive (true);
3911 _sync_genlock->set_sensitive (false);
3912 _sync_framerate->set_sensitive (false);
3913 _sync_source_2997->set_sensitive (false);
3916 } else if (p == "send-ltc") {
3917 bool const s = Config->get_send_ltc ();
3918 _ltc_send_continuously->set_sensitive (s);
3919 _ltc_volume_slider->set_sensitive (s);
3920 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
3921 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3922 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
3925 } else if (p == "enable-translation") {
3926 _l10n->set_sensitive (ARDOUR::translations_are_enabled ());
3931 void RCOptionEditor::plugin_scan_refresh () {
3932 PluginManager::instance().refresh();
3935 void RCOptionEditor::clear_vst_cache () {
3936 PluginManager::instance().clear_vst_cache();
3939 void RCOptionEditor::clear_vst_blacklist () {
3940 PluginManager::instance().clear_vst_blacklist();
3943 void RCOptionEditor::clear_au_cache () {
3944 PluginManager::instance().clear_au_cache();
3947 void RCOptionEditor::clear_au_blacklist () {
3948 PluginManager::instance().clear_au_blacklist();
3951 void RCOptionEditor::edit_lxvst_path () {
3952 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
3953 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3954 *current_toplevel(), _("Set Linux VST Search Path"),
3955 _rc_config->get_plugin_path_lxvst(),
3956 PluginManager::instance().get_default_lxvst_path()
3958 ResponseType r = (ResponseType) pd->run ();
3960 if (r == RESPONSE_ACCEPT) {
3961 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
3966 void RCOptionEditor::edit_vst_path () {
3967 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3968 *current_toplevel(), _("Set Windows VST Search Path"),
3969 _rc_config->get_plugin_path_vst(),
3970 PluginManager::instance().get_default_windows_vst_path()
3972 ResponseType r = (ResponseType) pd->run ();
3974 if (r == RESPONSE_ACCEPT) {
3975 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
3982 RCOptionEditor::populate_sync_options ()
3984 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3986 _sync_source->clear ();
3988 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3989 _sync_source->add (*i, sync_source_to_string (*i));
3992 if (sync_opts.empty()) {
3993 _sync_source->set_sensitive(false);
3995 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3996 _rc_config->set_sync_source(sync_opts.front());
4000 parameter_changed ("sync-source");
4004 RCOptionEditor::use_own_window (bool and_fill_it)
4006 bool new_window = !own_window ();
4008 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
4010 if (win && new_window) {
4011 win->set_name ("PreferencesWindow");
4012 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
4014 win->set_resizable (false);
4021 RCOptionEditor::get_state ()
4023 XMLNode* node = new XMLNode (X_("Preferences"));
4024 node->add_child_nocopy (Tabbable::get_state());