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 add_option (_("General"), new OptionEditorHeading (S_("Options|Undo")));
2150 add_option (_("General"), new UndoOptions (_rc_config));
2152 add_option (_("General"),
2154 "verify-remove-last-capture",
2155 _("Verify removal of last capture"),
2156 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
2157 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
2160 add_option (_("General"), new OptionEditorHeading (_("Session Management")));
2162 add_option (_("General"),
2164 "periodic-safety-backups",
2165 _("Make periodic backups of the session file"),
2166 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
2167 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
2170 add_option (_("General"),
2172 "only-copy-imported-files",
2173 _("Always copy imported files"),
2174 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
2175 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
2178 add_option (_("General"), new DirectoryOption (
2179 X_("default-session-parent-dir"),
2180 _("Default folder for new sessions:"),
2181 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
2182 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
2185 add_option (_("General"),
2186 new SpinOption<uint32_t> (
2187 "max-recent-sessions",
2188 _("Maximum number of recent sessions"),
2189 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
2190 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
2194 add_option (_("General"), new OptionEditorHeading (_("Automation")));
2196 add_option (_("General"),
2197 new SpinOption<double> (
2198 "automation-thinning-factor",
2199 _("Thinning factor (larger value => less data)"),
2200 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
2201 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
2205 add_option (_("General"),
2206 new SpinOption<double> (
2207 "automation-interval-msecs",
2208 _("Automation sampling interval (milliseconds)"),
2209 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
2210 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
2214 add_option (_("General"), new OptionEditorHeading (_("Tempo")));
2218 tsf = new BoolOption (
2219 "allow-non-quarter-pulse",
2220 _("Allow non quarter-note pulse"),
2221 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_allow_non_quarter_pulse),
2222 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_allow_non_quarter_pulse)
2224 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2225 string_compose (_("<b>When enabled</b> %1 will allow tempo to be expressed in divisions per minute\n"
2226 "<b>When disabled</b> %1 will only allow tempo to be expressed in quarter notes per minute"),
2228 add_option (_("General"), tsf);
2232 add_option (_("General/Translation"), new OptionEditorHeading (_("Internationalization")));
2234 bo = new BoolOption (
2235 "enable-translation",
2236 _("Use translations"),
2237 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2238 sigc::ptr_fun (ARDOUR::set_translations_enabled)
2241 bo->set_note (string_compose (_("These settings will only take effect after %1 is restarted (if available for your language preferences)."), PROGRAM_NAME));
2243 add_option (_("General/Translation"), bo);
2245 _l10n = new ComboOption<ARDOUR::LocaleMode> (
2248 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_locale_mode),
2249 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_locale_mode)
2252 _l10n->add (ARDOUR::SET_LC_ALL, _("Set complete locale"));
2253 _l10n->add (ARDOUR::SET_LC_MESSAGES, _("Enable only message translation"));
2254 _l10n->add (ARDOUR::SET_LC_MESSAGES_AND_LC_NUMERIC, _("Translate messages and format numeric format"));
2255 _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."));
2257 add_option (_("General/Translation"), _l10n);
2258 parameter_changed ("enable-translation");
2259 #endif // ENABLE_NLS
2264 add_option (_("Editor"), new OptionEditorHeading (_("General")));
2266 add_option (_("Editor"),
2268 "rubberbanding-snaps-to-grid",
2269 _("Snap rubberband to grid"),
2270 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2271 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2274 bo = new BoolOption (
2276 _("Prompt for a new marker name"),
2277 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2278 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2280 add_option (_("Editor"), bo);
2281 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."
2282 "\n\nYou can always rename markers by right-clicking on them"));
2284 add_option (_("Editor"),
2286 "draggable-playhead",
2287 _("Allow dragging of playhead"),
2288 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2289 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2292 if (!Profile->get_mixbus()) {
2294 add_option (_("Editor"),
2296 "use-mouse-position-as-zoom-focus-on-scroll",
2297 _("Zoom to mouse position when zooming with scroll wheel"),
2298 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2299 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2303 add_option (_("Editor"),
2305 "use-time-rulers-to-zoom-with-vertical-drag",
2306 _("Zoom with vertical drag in rulers"),
2307 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag),
2308 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag)
2311 add_option (_("Editor"),
2313 "use-double-click-to-zoom-to-selection",
2314 _("Double click zooms to selection"),
2315 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection),
2316 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection)
2319 add_option (_("Editor"),
2321 "update-editor-during-summary-drag",
2322 _("Update editor window during drags of the summary"),
2323 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2324 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2327 add_option (_("Editor"),
2329 "autoscroll-editor",
2330 _("Auto-scroll editor window when dragging near its edges"),
2331 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2332 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2335 add_option (_("Editor"),
2336 new BoolComboOption (
2337 "show-region-gain-envelopes",
2338 _("Show gain envelopes in audio regions"),
2340 _("only in Draw and Internal Edit modes"),
2341 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2342 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2345 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2347 add_option (_("Editor"),
2349 "automation-follows-regions",
2350 _("Move relevant automation when audio regions are moved"),
2351 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2352 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2355 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2356 "default-fade-shape",
2357 _("Default fade shape"),
2358 sigc::mem_fun (*_rc_config,
2359 &RCConfiguration::get_default_fade_shape),
2360 sigc::mem_fun (*_rc_config,
2361 &RCConfiguration::set_default_fade_shape)
2364 fadeshape->add (FadeLinear,
2365 _("Linear (for highly correlated material)"));
2366 fadeshape->add (FadeConstantPower, _("Constant power"));
2367 fadeshape->add (FadeSymmetric, _("Symmetric"));
2368 fadeshape->add (FadeSlow, _("Slow"));
2369 fadeshape->add (FadeFast, _("Fast"));
2371 add_option (_("Editor"), fadeshape);
2373 bco = new BoolComboOption (
2374 "use-overlap-equivalency",
2375 _("Regions in edit groups are edited together"),
2376 _("whenever they overlap in time"),
2377 _("only if they have identical length and position"),
2378 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2379 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2382 add_option (_("Editor"), bco);
2384 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2386 _("Layering model"),
2387 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2388 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2391 lm->add (LaterHigher, _("later is higher"));
2392 lm->add (Manual, _("manual layering"));
2393 add_option (_("Editor"), lm);
2395 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2396 "region-selection-after-split",
2397 _("After splitting selected regions, select"),
2398 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2399 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2401 // TODO: decide which of these modes are really useful
2402 rsas->add(None, _("no regions"));
2403 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2404 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2405 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2406 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2407 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2408 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2409 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2411 add_option (_("Editor"), rsas);
2413 add_option (_("Editor/Modifiers"), new OptionEditorHeading (_("Keyboard Modifiers")));
2414 add_option (_("Editor/Modifiers"), new KeyboardOptions);
2415 add_option (_("Editor/Modifiers"), new OptionEditorBlank ());
2417 /* MIXER -- SOLO AND MUTE */
2419 add_option (_("Mixer"), new OptionEditorHeading (_("Solo")));
2421 _solo_control_is_listen_control = new BoolOption (
2422 "solo-control-is-listen-control",
2423 _("Solo controls are Listen controls"),
2424 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2425 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2428 add_option (_("Mixer"), _solo_control_is_listen_control);
2430 add_option (_("Mixer"),
2433 _("Exclusive solo"),
2434 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2435 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2438 add_option (_("Mixer"),
2441 _("Show solo muting"),
2442 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2443 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2446 add_option (_("Mixer"),
2448 "solo-mute-override",
2449 _("Soloing overrides muting"),
2450 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2451 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2454 add_option (_("Mixer"),
2457 _("Solo-in-place mute cut (dB)"),
2458 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2459 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2462 _listen_position = new ComboOption<ListenPosition> (
2464 _("Listen Position"),
2465 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2466 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2469 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2470 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2472 add_option (_("Mixer"), _listen_position);
2474 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2476 _("PFL signals come from"),
2477 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2478 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2481 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2482 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2484 add_option (_("Mixer"), pp);
2486 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2488 _("AFL signals come from"),
2489 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2490 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2493 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2494 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2496 add_option (_("Mixer"), pa);
2498 add_option (_("Mixer"), new OptionEditorHeading (_("Default track / bus muting options")));
2500 add_option (_("Mixer"),
2502 "mute-affects-pre-fader",
2503 _("Mute affects pre-fader sends"),
2504 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2505 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2508 add_option (_("Mixer"),
2510 "mute-affects-post-fader",
2511 _("Mute affects post-fader sends"),
2512 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2513 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2516 add_option (_("Mixer"),
2518 "mute-affects-control-outs",
2519 _("Mute affects control outputs"),
2520 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2521 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2524 add_option (_("Mixer"),
2526 "mute-affects-main-outs",
2527 _("Mute affects main outputs"),
2528 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2529 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2533 if (!ARDOUR::Profile->get_mixbus()) {
2534 add_option (_("Mixer"), new OptionEditorHeading (_("Send Routing")));
2535 add_option (_("Mixer"),
2537 "link-send-and-route-panner",
2538 _("Link panners of Aux and External Sends with main panner by default"),
2539 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2540 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2546 add_option (_("Signal Flow"), new OptionEditorHeading (_("Monitoring")));
2548 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2550 _("Record monitoring handled by"),
2551 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2552 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2555 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2556 mm->add (HardwareMonitoring, _("via Audio Driver"));
2559 string prog (PROGRAM_NAME);
2560 boost::algorithm::to_lower (prog);
2561 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2562 mm->add (ExternalMonitoring, _("audio hardware"));
2564 add_option (_("Signal Flow"), mm);
2566 add_option (_("Signal Flow"),
2568 "tape-machine-mode",
2569 _("Tape machine mode"),
2570 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2571 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2574 if (!Profile->get_mixbus()) {
2576 add_option (_("Signal Flow"), new OptionEditorHeading (_("Track and Bus Connections")));
2578 add_option (_("Signal Flow"),
2580 "auto-connect-standard-busses",
2581 _("Auto-connect master/monitor busses"),
2582 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2583 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2586 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2587 "input-auto-connect",
2588 _("Connect track inputs"),
2589 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2590 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2593 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2594 iac->add (ManualConnect, _("manually"));
2596 add_option (_("Signal Flow"), iac);
2598 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2599 "output-auto-connect",
2600 _("Connect track and bus outputs"),
2601 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2602 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2605 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2606 oac->add (AutoConnectMaster, _("automatically to master bus"));
2607 oac->add (ManualConnect, _("manually"));
2609 add_option (_("Signal Flow"), oac);
2611 bo = new BoolOption (
2613 _("Use 'Strict-I/O' for new tracks or Busses"),
2614 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2615 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2618 add_option (_("Signal Flow"), bo);
2619 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2620 _("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."));
2627 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2629 add_option (_("Audio"), new BufferingOptions (_rc_config));
2631 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2633 add_option (_("Audio"),
2635 "denormal-protection",
2636 _("Use DC bias to protect against denormals"),
2637 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2638 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2641 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2643 _("Processor handling"),
2644 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2645 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2649 dm->add (DenormalNone, _("no processor handling"));
2651 FPU* fpu = FPU::instance();
2653 if (fpu->has_flush_to_zero()) {
2655 dm->add (DenormalFTZ, _("use FlushToZero"));
2656 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2657 _rc_config->set_denormal_model(DenormalNone);
2660 if (fpu->has_denormals_are_zero()) {
2662 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2663 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2664 _rc_config->set_denormal_model(DenormalNone);
2667 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2669 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2670 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2671 _rc_config->set_denormal_model(DenormalNone);
2675 dm->set_sensitive(false);
2678 add_option (_("Audio"), dm);
2680 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2682 add_option (_("Audio"),
2684 "auto-analyse-audio",
2685 _("Enable automatic analysis of audio"),
2686 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2687 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2690 add_option (_("Audio"),
2692 "replicate-missing-region-channels",
2693 _("Replicate missing region channels"),
2694 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2695 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2700 add_option (_("MIDI"), new OptionEditorHeading (_("Buffering")));
2702 add_option (_("MIDI"),
2703 new SpinOption<float> (
2705 _("MIDI read-ahead time (seconds)"),
2706 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2707 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2712 add_option (_("MIDI"), new OptionEditorHeading (_("Session")));
2714 add_option (_("MIDI"),
2715 new SpinOption<int32_t> (
2716 "initial-program-change",
2717 _("Initial program change"),
2718 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2719 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2723 add_option (_("MIDI"), new OptionEditorHeading (_("Display")));
2725 add_option (_("MIDI"),
2727 "display-first-midi-bank-as-zero",
2728 _("Display first MIDI bank/program as 0"),
2729 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2730 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2733 add_option (_("MIDI"),
2735 "never-display-periodic-midi",
2736 _("Don't display periodic (MTC, MMC) SysEx messages in MIDI Regions"),
2737 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
2738 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
2741 add_option (_("MIDI"), new OptionEditorHeading (_("Audition")));
2743 add_option (_("MIDI"),
2746 _("Sound MIDI notes as they are selected in the editor"),
2747 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2748 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2751 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2752 "midi-audition-synth-uri",
2753 _("MIDI Audition Synth (LV2)"),
2754 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2755 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2758 audition_synth->add(X_(""), _("None"));
2759 PluginInfoList all_plugs;
2760 PluginManager& manager (PluginManager::instance());
2762 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2764 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2765 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2766 if (!(*i)->is_instrument()) continue;
2767 if ((*i)->type != ARDOUR::LV2) continue;
2768 if ((*i)->name.length() > 46) {
2769 audition_synth->add((*i)->unique_id, (*i)->name.substr (0, 44) + "...");
2771 audition_synth->add((*i)->unique_id, (*i)->name);
2776 add_option (_("MIDI"), audition_synth);
2780 add_option (_("Metronome"), new OptionEditorHeading (_("Metronome")));
2781 add_option (_("Metronome"), new ClickOptions (_rc_config));
2785 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2787 ComboOption<float>* mht = new ComboOption<float> (
2789 _("Peak hold time"),
2790 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
2791 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
2794 mht->add (MeterHoldOff, _("off"));
2795 mht->add (MeterHoldShort, _("short"));
2796 mht->add (MeterHoldMedium, _("medium"));
2797 mht->add (MeterHoldLong, _("long"));
2799 add_option (S_("Preferences|Metering"), mht);
2801 ComboOption<float>* mfo = new ComboOption<float> (
2804 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2805 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2808 mfo->add (METER_FALLOFF_OFF, _("off"));
2809 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2810 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2811 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2812 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2813 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2814 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
2816 add_option (S_("Preferences|Metering"), mfo);
2818 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2819 "meter-line-up-level",
2820 _("Meter line-up level; 0dBu"),
2821 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
2822 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
2825 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2826 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2827 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2828 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2830 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."));
2832 add_option (S_("Preferences|Metering"), mlu);
2834 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2835 "meter-line-up-din",
2836 _("IEC1/DIN Meter line-up level; 0dBu"),
2837 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
2838 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
2841 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2842 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2843 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2844 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2846 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2848 add_option (S_("Preferences|Metering"), mld);
2850 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2851 "meter-vu-standard",
2852 _("VU Meter standard"),
2853 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
2854 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
2857 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2858 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2859 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2860 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2862 add_option (S_("Preferences|Metering"), mvu);
2864 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
2865 "meter-type-master",
2866 _("Default Meter Type for Master Bus"),
2867 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
2868 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
2870 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2871 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2872 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2873 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2874 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2875 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2876 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2877 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
2879 add_option (S_("Preferences|Metering"), mtm);
2882 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
2884 _("Default Meter Type for Busses"),
2885 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
2886 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
2888 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2889 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2890 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2891 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2892 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2893 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2894 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2895 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
2897 add_option (S_("Preferences|Metering"), mtb);
2899 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
2901 _("Default Meter Type for Tracks"),
2902 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
2903 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
2905 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2906 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
2908 add_option (S_("Preferences|Metering"), mtt);
2910 HSliderOption *mpks = new HSliderOption("meter-peak",
2911 _("Peak threshold [dBFS]"),
2912 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
2913 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak),
2917 Gtkmm2ext::UI::instance()->set_tip (
2919 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
2921 add_option (S_("Preferences|Metering"), mpks);
2923 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
2925 add_option (S_("Preferences|Metering"),
2927 "save-export-analysis-image",
2928 _("Save loudness analysis as image file"),
2929 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
2930 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
2933 /* TRANSPORT & Sync */
2935 add_option (_("Transport"), new OptionEditorHeading (_("General")));
2937 tsf = new BoolOption (
2938 "stop-at-session-end",
2939 _("Stop at the end of the session"),
2940 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
2941 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
2943 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2944 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
2945 "when it reaches the current session end marker\n\n"
2946 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
2948 add_option (_("Transport"), tsf);
2950 tsf = new BoolOption (
2951 "latched-record-enable",
2952 _("Keep record-enable engaged on stop"),
2953 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
2954 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
2956 add_option (_("Transport"), tsf);
2958 tsf = new BoolOption (
2959 "disable-disarm-during-roll",
2960 _("Disable per-track record disarm while rolling"),
2961 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
2962 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
2964 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("<b>When enabled</b> this will prevent you from accidentally stopping specific tracks recording during a take"));
2965 add_option (_("Transport"), tsf);
2967 tsf = new BoolOption (
2969 _("12dB gain reduction during fast-forward and fast-rewind"),
2970 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
2971 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2973 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2974 _("<b>When enabled</b> rhis will reduce the unpleasant increase in perceived volume "
2975 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2976 add_option (_("Transport"), tsf);
2978 ComboOption<float>* psc = new ComboOption<float> (
2981 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
2982 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
2984 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
2985 (_("The amount of preroll (in seconds) to apply when <b>Play with Preroll</b> is initiated.\n\n"
2986 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
2987 psc->add (0.0, _("0 (no pre-roll)"));
2988 psc->add (0.1, _("0.1 second"));
2989 psc->add (0.25, _("0.25 second"));
2990 psc->add (0.5, _("0.5 second"));
2991 psc->add (1.0, _("1.0 second"));
2992 psc->add (2.0, _("2.0 seconds"));
2993 add_option (_("Transport"), psc);
2996 add_option (_("Transport"), new OptionEditorHeading (_("Looping")));
2998 tsf = new BoolOption (
3000 _("Play loop is a transport mode"),
3001 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
3002 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
3004 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
3005 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
3006 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
3007 add_option (_("Transport"), tsf);
3009 tsf = new BoolOption (
3011 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
3012 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
3013 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
3015 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
3016 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
3017 "preventing any need to do a transport locate at the end of the loop\n\n"
3018 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
3019 "which will often cause a small click or delay"), PROGRAM_NAME));
3020 add_option (_("Transport"), tsf);
3022 add_option (_("Transport"), new OptionEditorHeading (_("Dropout (xrun) Handling")));
3023 tsf = new BoolOption (
3024 "stop-recording-on-xrun",
3025 _("Stop recording when an xrun occurs"),
3026 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
3027 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
3029 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
3030 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
3032 add_option (_("Transport"), tsf);
3034 tsf = new BoolOption (
3035 "create-xrun-marker",
3036 _("Create markers where xruns occur"),
3037 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
3038 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
3040 add_option (_("Transport"), tsf);
3045 add_option (_("Sync"), new OptionEditorHeading (_("External Syncronization")));
3047 _sync_source = new ComboOption<SyncSource> (
3049 _("External timecode source"),
3050 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
3051 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
3054 add_option (_("Sync"), _sync_source);
3056 _sync_framerate = new BoolOption (
3057 "timecode-sync-frame-rate",
3058 _("Match session video frame rate to external timecode"),
3059 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
3060 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
3062 Gtkmm2ext::UI::instance()->set_tip
3063 (_sync_framerate->tip_widget(),
3064 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
3065 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
3066 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
3067 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
3068 "timecode standard and the session standard."), PROGRAM_NAME));
3070 add_option (_("Sync"), _sync_framerate);
3072 _sync_genlock = new BoolOption (
3073 "timecode-source-is-synced",
3074 _("Sync-lock timecode to clock (disable drift compensation)"),
3075 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
3076 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
3078 Gtkmm2ext::UI::instance()->set_tip
3079 (_sync_genlock->tip_widget(),
3080 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
3081 "Sync Lock indicates that the selected external timecode source shares clock-sync "
3082 "(Black & Burst, Wordclock, etc) with the audio interface. "
3083 "This option disables drift compensation. The transport speed is fixed at 1.0. "
3084 "Vari-speed LTC will be ignored and cause drift."
3086 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
3087 "timecode sources shares clock sync."
3091 add_option (_("Sync"), _sync_genlock);
3093 _sync_source_2997 = new BoolOption (
3094 "timecode-source-2997",
3095 _("Lock to 29.9700 fps instead of 30000/1001"),
3096 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
3097 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
3099 Gtkmm2ext::UI::instance()->set_tip
3100 (_sync_source_2997->tip_widget(),
3101 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
3102 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
3103 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
3104 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
3105 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
3106 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
3109 add_option (_("Sync"), _sync_source_2997);
3111 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Reader")));
3113 _ltc_port = new ComboStringOption (
3115 _("LTC incoming port"),
3116 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
3117 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
3120 vector<string> physical_inputs;
3121 physical_inputs.push_back (_("None"));
3122 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
3123 _ltc_port->set_popdown_strings (physical_inputs);
3125 populate_sync_options ();
3126 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
3128 add_option (_("Sync/LTC"), _ltc_port);
3130 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Generator")));
3132 add_option (_("Sync/LTC"),
3135 _("Enable LTC generator"),
3136 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
3137 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
3140 _ltc_send_continuously = new BoolOption (
3141 "ltc-send-continuously",
3142 _("Send LTC while stopped"),
3143 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
3144 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
3146 Gtkmm2ext::UI::instance()->set_tip
3147 (_ltc_send_continuously->tip_widget(),
3148 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
3149 add_option (_("Sync/LTC"), _ltc_send_continuously);
3151 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level [dBFS]"),
3152 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_output_volume),
3153 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_output_volume),
3157 Gtkmm2ext::UI::instance()->set_tip
3158 (_ltc_volume_slider->tip_widget(),
3159 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
3161 add_option (_("Sync/LTC"), _ltc_volume_slider);
3164 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Beat Clock (Mclk) Generator")));
3166 add_option (_("Sync/MIDI"),
3169 _("Enable Mclk generator"),
3170 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
3171 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
3174 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC) Generator")));
3176 add_option (_("Sync/MIDI"),
3179 _("Enable MTC Generator"),
3180 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
3181 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
3184 add_option (_("Sync/MIDI"),
3185 new SpinOption<int> (
3186 "mtc-qf-speed-tolerance",
3187 _("Percentage either side of normal transport speed to transmit MTC"),
3188 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
3189 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
3193 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Machine Control (MMC)")));
3195 add_option (_("Sync/MIDI"),
3198 _("Respond to MMC commands"),
3199 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
3200 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
3203 add_option (_("Sync/MIDI"),
3206 _("Send MMC commands"),
3207 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
3208 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
3211 add_option (_("Sync/MIDI"),
3212 new SpinOption<uint8_t> (
3213 "mmc-receive-device-id",
3214 _("Inbound MMC device ID"),
3215 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
3216 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
3220 add_option (_("Sync/MIDI"),
3221 new SpinOption<uint8_t> (
3222 "mmc-send-device-id",
3223 _("Outbound MMC device ID"),
3224 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
3225 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
3230 /* Control Surfaces */
3232 add_option (_("Control Surfaces"), new OptionEditorHeading (_("Control Surfaces")));
3233 add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
3236 add_option (_("MIDI Ports"), new OptionEditorHeading (_("MIDI Port Options")));
3238 add_option (_("MIDI Ports"),
3240 "get-midi-input-follows-selection",
3241 _("MIDI input follows MIDI track selection"),
3242 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
3243 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
3246 add_option (_("MIDI Ports"), new MidiPortOptions ());
3247 add_option (_("MIDI Ports"), new OptionEditorBlank ());
3251 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3252 add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
3253 add_option (_("Plugins"),
3254 new RcActionButton (_("Scan for Plugins"),
3255 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3259 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
3261 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3262 bo = new BoolOption (
3263 "show-plugin-scan-window",
3264 _("Always Display Plugin Scan Progress"),
3265 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
3266 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
3268 add_option (_("Plugins"), bo);
3269 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3270 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
3273 bo = new BoolOption (
3274 "plugins-stop-with-transport",
3275 _("Silence plugins when the transport is stopped"),
3276 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
3277 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
3279 add_option (_("Plugins"), bo);
3280 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3281 _("<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."));
3283 bo = new BoolOption (
3284 "new-plugins-active",
3285 _("Make new plugins active"),
3286 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
3287 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
3289 add_option (_("Plugins"), bo);
3290 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3291 _("<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"));
3293 #if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
3294 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
3296 add_option (_("Plugins/VST"),
3297 new RcActionButton (_("Scan for Plugins"),
3298 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3301 #if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
3302 bo = new BoolOption (
3304 _("Enable Mac VST support (requires restart or re-scan)"),
3305 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
3306 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
3308 add_option (_("Plugins/VST"), bo);
3311 bo = new BoolOption (
3312 "discover-vst-on-start",
3313 _("Scan for [new] VST Plugins on Application Start"),
3314 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
3315 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
3317 add_option (_("Plugins/VST"), bo);
3318 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3319 _("<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"));
3321 #ifdef WINDOWS_VST_SUPPORT
3322 // currently verbose logging is only implemented for Windows VST.
3323 bo = new BoolOption (
3324 "verbose-plugin-scan",
3325 _("Verbose Plugin Scan"),
3326 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
3327 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
3329 add_option (_("Plugins/VST"), bo);
3330 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3331 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
3334 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
3336 add_option (_("Plugins/VST"),
3337 new RcActionButton (_("Clear"),
3338 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
3341 add_option (_("Plugins/VST"),
3342 new RcActionButton (_("Clear"),
3343 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
3344 _("VST Blacklist:")));
3347 #ifdef LXVST_SUPPORT
3348 add_option (_("Plugins/VST"),
3349 new RcActionButton (_("Edit"),
3350 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
3351 _("Linux VST Path:")));
3353 add_option (_("Plugins/VST"),
3354 new RcConfigDisplay (
3355 "plugin-path-lxvst",
3357 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
3361 #ifdef WINDOWS_VST_SUPPORT
3362 add_option (_("Plugins/VST"),
3363 new RcActionButton (_("Edit"),
3364 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
3365 _("Windows VST Path:")));
3366 add_option (_("Plugins/VST"),
3367 new RcConfigDisplay (
3370 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
3374 #ifdef AUDIOUNIT_SUPPORT
3376 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
3378 add_option (_("Plugins/Audio Unit"),
3379 new RcActionButton (_("Scan for Plugins"),
3380 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3383 bo = new BoolOption (
3384 "discover-audio-units",
3385 _("Scan for [new] AudioUnit Plugins on Application Start"),
3386 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
3387 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
3389 add_option (_("Plugins/Audio Unit"), bo);
3390 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3391 _("<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."));
3393 add_option (_("Plugins/Audio Unit"),
3394 new RcActionButton (_("Clear"),
3395 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
3398 add_option (_("Plugins/Audio Unit"),
3399 new RcActionButton (_("Clear"),
3400 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
3401 _("AU Blacklist:")));
3404 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
3405 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
3406 add_option (_("Plugins"),
3408 "open-gui-after-adding-plugin",
3409 _("Automatically open the plugin GUI when adding a new plugin"),
3410 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
3411 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3414 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3415 add_option (_("Plugins"),
3417 "show-inline-display-by-default",
3418 _("Show Plugin Inline Display on Mixerstrip by default"),
3419 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3420 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3423 _plugin_prefer_inline = new BoolOption (
3424 "prefer-inline-over-gui",
3425 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3426 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3427 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3429 add_option (_("Plugins"), _plugin_prefer_inline);
3432 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3434 bo = new BoolOption (
3435 "ask-replace-instrument",
3436 _("Ask to replace existing instrument plugin"),
3437 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3438 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3440 add_option (_("Plugins"), bo);
3442 bo = new BoolOption (
3443 "ask-setup_instrument",
3444 _("Interactively configure instrument plugins on insert"),
3445 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3446 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3448 add_option (_("Plugins"), bo);
3449 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3450 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3453 add_option (_("Plugins"), new OptionEditorBlank ());
3456 #if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
3457 add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Graphics Acceleration")));
3460 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3461 BoolOption* bgc = new BoolOption (
3462 "cairo-image-surface",
3463 _("Disable Graphics Hardware Acceleration (requires restart)"),
3464 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3465 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3468 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3469 _("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));
3470 add_option (S_("Preferences|GUI"), bgc);
3473 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3474 BoolOption* bgo = new BoolOption (
3476 _("Possibly improve slow graphical performance (requires restart)"),
3477 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3478 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3481 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));
3482 add_option (S_("Preferences|GUI"), bgo);
3484 add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Graphical User Interface")));
3486 add_option (S_("Preferences|GUI"),
3489 _("Highlight widgets on mouseover"),
3490 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3491 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3494 add_option (S_("Preferences|GUI"),
3497 _("Show tooltips if mouse hovers over a control"),
3498 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3499 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3502 bo = new BoolOption (
3503 "super-rapid-clock-update",
3504 _("Update clocks at TC Frame rate"),
3505 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3506 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3508 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3509 _("<b>When enabled</b> clock displays are updated every Timecode Frame (fps).\n\n"
3510 "<b>When disabled</b> clock displays are updated only every 100ms."
3512 add_option (S_("Preferences|GUI"), bo);
3514 add_option (S_("Preferences|GUI"),
3517 _("Blink Rec-Arm buttons"),
3518 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_rec_arm),
3519 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_rec_arm)
3524 /* font scaling does nothing with GDK/Quartz */
3525 add_option (S_("Preferences|GUI"), new FontScalingOptions ());
3528 /* Image cache size */
3530 HSliderOption *sics = new HSliderOption ("waveform-cache-size",
3531 _("Waveform image cache size (megabytes)"),
3532 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
3533 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size),
3534 1, 1024, 10 /* 1 MB to 1GB in steps of 10MB */
3536 sics->scale().set_digits (0);
3537 Gtkmm2ext::UI::instance()->set_tip (
3539 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
3540 add_option (S_("Preferences|GUI"), sics);
3542 if (!ARDOUR::Profile->get_mixbus()) {
3543 /* Lock GUI timeout */
3545 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
3546 _("Lock timeout (seconds)"),
3547 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
3548 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds),
3551 slts->scale().set_digits (0);
3552 Gtkmm2ext::UI::instance()->set_tip (
3554 _("Lock GUI after this many idle seconds (zero to never lock)"));
3555 add_option (S_("Preferences|GUI"), slts);
3558 add_option (_("GUI/Editor"), new OptionEditorHeading (_("General")));
3559 add_option (_("GUI/Editor"),
3561 "show-name-highlight",
3562 _("Use name highlight bars in region displays (requires a restart)"),
3563 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3564 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3567 add_option (_("GUI/Editor"),
3569 "color-regions-using-track-color",
3570 _("Region color follows track color"),
3571 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_color_regions_using_track_color),
3572 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_color_regions_using_track_color)
3575 add_option (_("GUI/Editor"), new OptionEditorHeading (_("Waveforms")));
3577 if (!Profile->get_mixbus()) {
3578 add_option (_("GUI/Editor"),
3581 _("Show waveforms in regions"),
3582 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
3583 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
3587 add_option (_("GUI/Editor"),
3589 "show-waveforms-while-recording",
3590 _("Show waveforms while recording"),
3591 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
3592 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
3595 add_option (_("GUI/Editor"),
3597 "show-waveform-clipping",
3598 _("Show waveform clipping"),
3599 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveform_clipping),
3600 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveform_clipping)
3603 add_option (_("GUI/Editor"), new ClipLevelOptions ());
3605 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
3607 _("Waveform scale"),
3608 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
3609 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
3612 wfs->add (Linear, _("linear"));
3613 wfs->add (Logarithmic, _("logarithmic"));
3615 add_option (_("GUI/Editor"), wfs);
3617 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
3619 _("Waveform shape"),
3620 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
3621 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
3624 wfsh->add (Traditional, _("traditional"));
3625 wfsh->add (Rectified, _("rectified"));
3627 add_option (_("GUI/Editor"), wfsh);
3629 add_option (_("GUI/Editor"), new OptionEditorHeading (_("Editor Meters")));
3631 add_option (_("GUI/Editor"),
3633 "show-track-meters",
3634 _("Show meters in track headers"),
3635 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3636 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3639 add_option (_("GUI/Editor"),
3641 "editor-stereo-only-meters",
3642 _("Limit track header meters to stereo"),
3643 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3644 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3647 add_option (_("GUI/Editor"), new OptionEditorBlank ());
3649 /* The names of these controls must be the same as those given in MixerStrip
3650 for the actual widgets being controlled.
3652 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3653 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3654 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3655 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3656 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3657 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3658 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3660 add_option (_("GUI/Mixer"),
3661 new VisibilityOption (
3663 &_mixer_strip_visibility,
3664 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3665 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3669 add_option (_("GUI/Mixer"),
3671 "default-narrow_ms",
3672 _("Use narrow strips in the mixer by default"),
3673 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3674 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3677 add_option (_("GUI/Mixer"), new OptionEditorBlank ());
3679 add_option (_("GUI/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items")));
3681 add_option (_("GUI/Toolbar"),
3683 "show-toolbar-selclock",
3684 _("Display Selection Clock"),
3685 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
3686 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
3689 if (!ARDOUR::Profile->get_small_screen()) {
3690 add_option (_("GUI/Toolbar"),
3692 "show-secondary-clock",
3693 _("Display Secondary Clock"),
3694 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
3695 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
3699 add_option (_("GUI/Toolbar"),
3701 "show-mini-timeline",
3702 _("Display Navigation Timeline"),
3703 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
3704 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
3707 add_option (_("GUI/Toolbar"),
3709 "show-editor-meter",
3710 _("Display Master Level Meter"),
3711 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
3712 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
3715 add_option (_("GUI/Toolbar"),
3716 new ColumVisibilityOption (
3717 "action-table-columns", _("Lua Action Script Button Visibility"), 4,
3718 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3719 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3722 add_option (_("GUI/Toolbar"), new OptionEditorBlank ());
3725 OptionEditorHeading* quirks_head = new OptionEditorHeading (_("Various Workarounds for Windowing Systems"));
3727 quirks_head->set_note (string_compose (_("These settings will only take effect after %1 is restarted."), PROGRAM_NAME));
3729 /* and now the theme manager */
3731 add_option (_("GUI/Theme"), new OptionEditorHeading (_("Theme")));
3733 add_option (_("GUI/Theme"), new BoolOption (
3735 _("Draw \"flat\" buttons"),
3736 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_flat_buttons),
3737 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_flat_buttons)
3740 add_option (_("GUI/Theme"), new BoolOption (
3742 _("LED meter style"),
3743 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3744 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3748 HSliderOption *gui_hs = new HSliderOption(
3749 "timeline-item-gradient-depth",
3750 _("Waveforms color gradient depth"),
3751 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_gradient_depth),
3752 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_gradient_depth),
3755 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3756 add_option (_("GUI/Theme"), gui_hs);
3758 gui_hs = new HSliderOption(
3759 "timeline-item-gradient-depth",
3760 _("Timeline item gradient depth"),
3761 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_timeline_item_gradient_depth),
3762 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_timeline_item_gradient_depth),
3765 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3766 add_option (_("GUI/Theme"), gui_hs);
3768 vector<string> icon_sets = ::get_icon_sets ();
3769 if (icon_sets.size() > 1) {
3770 ComboOption<std::string>* io = new ComboOption<std::string> (
3771 "icon-set", _("Icon Set"),
3772 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_icon_set),
3773 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_icon_set)
3775 for (vector<string>::const_iterator i = icon_sets.begin (); i != icon_sets.end (); ++i) {
3778 add_option (_("GUI/Theme"), io);
3781 add_option (_("GUI/Colors"), new OptionEditorHeading (_("Colors")));
3782 add_option (_("GUI/Colors"), new ColorThemeManager);
3783 add_option (_("GUI/Colors"), new OptionEditorBlank ());
3787 add_option (_("GUI/Quirks"), quirks_head);
3789 add_option (_("GUI/Quirks"),
3791 "use-wm-visibility",
3792 _("Use Window Manager/Desktop visibility information"),
3793 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3794 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3798 bo = new BoolOption (
3799 "all-floating-windows-are-dialogs",
3800 _("All floating windows are dialogs"),
3801 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_all_floating_windows_are_dialogs),
3802 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_all_floating_windows_are_dialogs)
3804 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3805 _("Mark all floating windows to be type \"Dialog\" rather than using \"Utility\" for some.\nThis may help with some window managers."));
3806 add_option (_("GUI/Quirks"), bo);
3808 bo = new BoolOption (
3809 "transients-follow-front",
3810 _("Transient windows follow front window."),
3811 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_transients_follow_front),
3812 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_transients_follow_front)
3814 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3815 _("Make transient windows follow the front window when toggling between the editor and mixer."));
3816 add_option (_("GUI/Quirks"), bo);
3819 if (!Profile->get_mixbus()) {
3820 bo = new BoolOption (
3821 "floating-monitor-section",
3822 _("Float detached monitor-section window"),
3823 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_floating_monitor_section),
3824 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_floating_monitor_section)
3826 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3827 _("When detaching the monitoring section, mark it as \"Utility\" window to stay in front."));
3828 add_option (_("GUI/Quirks"), bo);
3831 add_option (_("GUI/Quirks"), new OptionEditorBlank ());
3833 /* VIDEO Timeline */
3834 add_option (_("Video"), new OptionEditorHeading (_("Video Server")));
3835 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
3837 Widget::show_all ();
3839 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3840 parameter_changed ("send-ltc");
3841 parameter_changed ("sync-source");
3842 parameter_changed ("use-monitor-bus");
3843 parameter_changed ("open-gui-after-adding-plugin");
3845 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
3847 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
3848 (Gtk::StateType) here !!!
3850 Tabbable::set_state (*node, Stateful::loading_state_version);
3853 set_current_page (_("General"));
3857 RCOptionEditor::parameter_changed (string const & p)
3859 OptionEditor::parameter_changed (p);
3861 if (p == "use-monitor-bus") {
3862 bool const s = Config->get_use_monitor_bus ();
3864 /* we can't use this if we don't have a monitor bus */
3865 Config->set_solo_control_is_listen_control (false);
3867 _solo_control_is_listen_control->set_sensitive (s);
3868 _listen_position->set_sensitive (s);
3869 } else if (p == "sync-source") {
3870 _sync_source->set_sensitive (true);
3872 _sync_source->set_sensitive (!_session->config.get_external_sync());
3874 switch(Config->get_sync_source()) {
3877 _sync_genlock->set_sensitive (true);
3878 _sync_framerate->set_sensitive (true);
3879 _sync_source_2997->set_sensitive (true);
3882 _sync_genlock->set_sensitive (false);
3883 _sync_framerate->set_sensitive (false);
3884 _sync_source_2997->set_sensitive (false);
3887 } else if (p == "send-ltc") {
3888 bool const s = Config->get_send_ltc ();
3889 _ltc_send_continuously->set_sensitive (s);
3890 _ltc_volume_slider->set_sensitive (s);
3891 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
3892 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3893 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
3896 } else if (p == "enable-translation") {
3897 _l10n->set_sensitive (ARDOUR::translations_are_enabled ());
3902 void RCOptionEditor::plugin_scan_refresh () {
3903 PluginManager::instance().refresh();
3906 void RCOptionEditor::clear_vst_cache () {
3907 PluginManager::instance().clear_vst_cache();
3910 void RCOptionEditor::clear_vst_blacklist () {
3911 PluginManager::instance().clear_vst_blacklist();
3914 void RCOptionEditor::clear_au_cache () {
3915 PluginManager::instance().clear_au_cache();
3918 void RCOptionEditor::clear_au_blacklist () {
3919 PluginManager::instance().clear_au_blacklist();
3922 void RCOptionEditor::edit_lxvst_path () {
3923 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
3924 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3925 *current_toplevel(), _("Set Linux VST Search Path"),
3926 _rc_config->get_plugin_path_lxvst(),
3927 PluginManager::instance().get_default_lxvst_path()
3929 ResponseType r = (ResponseType) pd->run ();
3931 if (r == RESPONSE_ACCEPT) {
3932 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
3937 void RCOptionEditor::edit_vst_path () {
3938 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3939 *current_toplevel(), _("Set Windows VST Search Path"),
3940 _rc_config->get_plugin_path_vst(),
3941 PluginManager::instance().get_default_windows_vst_path()
3943 ResponseType r = (ResponseType) pd->run ();
3945 if (r == RESPONSE_ACCEPT) {
3946 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
3953 RCOptionEditor::populate_sync_options ()
3955 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3957 _sync_source->clear ();
3959 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3960 _sync_source->add (*i, sync_source_to_string (*i));
3963 if (sync_opts.empty()) {
3964 _sync_source->set_sensitive(false);
3966 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3967 _rc_config->set_sync_source(sync_opts.front());
3971 parameter_changed ("sync-source");
3975 RCOptionEditor::use_own_window (bool and_fill_it)
3977 bool new_window = !own_window ();
3979 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
3981 if (win && new_window) {
3982 win->set_name ("PreferencesWindow");
3983 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
3990 RCOptionEditor::get_state ()
3992 XMLNode* node = new XMLNode (X_("Preferences"));
3993 node->add_child_nocopy (Tabbable::get_state());