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