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 _click_fader = new FaderOption (
119 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
120 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
123 _click_fader->add_to_page (this);
124 _click_fader->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);
149 } else if (p == "click-gain") {
150 _click_fader->set_state_from_config ();
154 void set_state_from_config ()
156 parameter_changed ("click-sound");
157 parameter_changed ("click-emphasis-sound");
158 parameter_changed ("use-click-emphasis");
163 void click_browse_clicked ()
165 SoundFileChooser sfdb (_("Choose Click"));
170 if (sfdb.run () == RESPONSE_OK) {
171 click_chosen (sfdb.get_filename());
175 void click_chosen (string const & path)
177 _click_path_entry.set_text (path);
178 _rc_config->set_click_sound (path);
181 void click_changed ()
183 click_chosen (_click_path_entry.get_text ());
186 void click_emphasis_browse_clicked ()
188 SoundFileChooser sfdb (_("Choose Click Emphasis"));
193 if (sfdb.run () == RESPONSE_OK) {
194 click_emphasis_chosen (sfdb.get_filename());
198 void click_emphasis_chosen (string const & path)
200 _click_emphasis_path_entry.set_text (path);
201 _rc_config->set_click_emphasis_sound (path);
204 void click_emphasis_changed ()
206 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
209 void use_default_click_toggled ()
211 if (_use_default_click_check_button.get_active ()) {
212 _rc_config->set_click_sound ("");
213 _rc_config->set_click_emphasis_sound ("");
214 _click_path_entry.set_sensitive (false);
215 _click_emphasis_path_entry.set_sensitive (false);
216 _click_browse_button.set_sensitive (false);
217 _click_emphasis_browse_button.set_sensitive (false);
219 _click_path_entry.set_sensitive (true);
220 _click_emphasis_path_entry.set_sensitive (true);
221 _click_browse_button.set_sensitive (true);
222 _click_emphasis_browse_button.set_sensitive (true);
226 void use_emphasis_on_click_toggled ()
228 if (_use_emphasis_on_click_check_button.get_active ()) {
229 _rc_config->set_use_click_emphasis(true);
231 _rc_config->set_use_click_emphasis(false);
235 RCConfiguration* _rc_config;
236 CheckButton _use_default_click_check_button;
237 CheckButton _use_emphasis_on_click_check_button;
238 Entry _click_path_entry;
239 Entry _click_emphasis_path_entry;
240 Button _click_browse_button;
241 Button _click_emphasis_browse_button;
242 FaderOption* _click_fader;
245 class UndoOptions : public OptionEditorComponent
248 UndoOptions (RCConfiguration* c) :
250 _limit_undo_button (_("Limit undo history to")),
251 _save_undo_button (_("Save undo history of"))
253 // TODO get rid of GTK -> use OptionEditor SpinOption
254 _limit_undo_spin.set_range (0, 512);
255 _limit_undo_spin.set_increments (1, 10);
257 _save_undo_spin.set_range (0, 512);
258 _save_undo_spin.set_increments (1, 10);
260 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
261 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
262 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
263 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
266 void parameter_changed (string const & p)
268 if (p == "history-depth") {
269 int32_t const d = _rc_config->get_history_depth();
270 _limit_undo_button.set_active (d != 0);
271 _limit_undo_spin.set_sensitive (d != 0);
272 _limit_undo_spin.set_value (d);
273 } else if (p == "save-history") {
274 bool const x = _rc_config->get_save_history ();
275 _save_undo_button.set_active (x);
276 _save_undo_spin.set_sensitive (x);
277 } else if (p == "save-history-depth") {
278 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
282 void set_state_from_config ()
284 parameter_changed ("save-history");
285 parameter_changed ("history-depth");
286 parameter_changed ("save-history-depth");
289 void limit_undo_toggled ()
291 bool const x = _limit_undo_button.get_active ();
292 _limit_undo_spin.set_sensitive (x);
293 int32_t const n = x ? 16 : 0;
294 _limit_undo_spin.set_value (n);
295 _rc_config->set_history_depth (n);
298 void limit_undo_changed ()
300 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
303 void save_undo_toggled ()
305 bool const x = _save_undo_button.get_active ();
306 _rc_config->set_save_history (x);
309 void save_undo_changed ()
311 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
314 void add_to_page (OptionEditorPage* p)
316 int const n = p->table.property_n_rows();
317 Table* t = & p->table;
319 t->resize (n + 2, 3);
321 Label* l = manage (left_aligned_label (_("commands")));
322 HBox* box = manage (new HBox());
323 box->set_spacing (4);
324 box->pack_start (_limit_undo_spin, false, false);
325 box->pack_start (*l, true, true);
326 t->attach (_limit_undo_button, 1, 2, n, n +1, FILL);
327 t->attach (*box, 2, 3, n, n + 1, FILL | EXPAND);
329 l = manage (left_aligned_label (_("commands")));
330 box = manage (new HBox());
331 box->set_spacing (4);
332 box->pack_start (_save_undo_spin, false, false);
333 box->pack_start (*l, true, true);
334 t->attach (_save_undo_button, 1, 2, n + 1, n + 2, FILL);
335 t->attach (*box, 2, 3, n + 1, n + 2, FILL | EXPAND);
338 Gtk::Widget& tip_widget() {
339 return _limit_undo_button; // unused
343 RCConfiguration* _rc_config;
344 CheckButton _limit_undo_button;
345 SpinButton _limit_undo_spin;
346 CheckButton _save_undo_button;
347 SpinButton _save_undo_spin;
351 static const struct {
363 { "Key|Shift", GDK_SHIFT_MASK },
364 { "Command", GDK_MOD2_MASK },
365 { "Control", GDK_CONTROL_MASK },
366 { "Option", GDK_MOD1_MASK },
367 { "Command-Shift", GDK_MOD2_MASK|GDK_SHIFT_MASK },
368 { "Command-Option", GDK_MOD2_MASK|GDK_MOD1_MASK },
369 { "Command-Control", GDK_MOD2_MASK|GDK_CONTROL_MASK },
370 { "Command-Option-Control", GDK_MOD2_MASK|GDK_MOD1_MASK|GDK_CONTROL_MASK },
371 { "Option-Control", GDK_MOD1_MASK|GDK_CONTROL_MASK },
372 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
373 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
374 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_MOD2_MASK },
377 { "Key|Shift", GDK_SHIFT_MASK },
378 { "Control", GDK_CONTROL_MASK },
379 { "Alt", GDK_MOD1_MASK },
380 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
381 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
382 { "Control-Windows", GDK_CONTROL_MASK|GDK_MOD4_MASK },
383 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
384 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
385 { "Alt-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
386 { "Alt-Shift-Windows", GDK_MOD1_MASK|GDK_SHIFT_MASK|GDK_MOD4_MASK },
387 { "Mod2", GDK_MOD2_MASK },
388 { "Mod3", GDK_MOD3_MASK },
389 { "Windows", GDK_MOD4_MASK },
390 { "Mod5", GDK_MOD5_MASK },
396 class KeyboardOptions : public OptionEditorMiniPage
400 : _delete_button_adjustment (3, 1, 12)
401 , _delete_button_spin (_delete_button_adjustment)
402 , _edit_button_adjustment (3, 1, 5)
403 , _edit_button_spin (_edit_button_adjustment)
404 , _insert_note_button_adjustment (3, 1, 5)
405 , _insert_note_button_spin (_insert_note_button_adjustment)
407 // TODO get rid of GTK -> use OptionEditor Widgets
409 const std::string restart_msg = _("\nChanges to this setting will only persist after your project has been saved.");
410 /* internationalize and prepare for use with combos */
413 for (int i = 0; modifiers[i].name; ++i) {
414 dumb.push_back (S_(modifiers[i].name));
417 set_popdown_strings (_edit_modifier_combo, dumb);
418 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
419 Gtkmm2ext::UI::instance()->set_tip (_edit_modifier_combo,
420 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
427 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
428 l->set_name ("OptionsLabel");
432 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
433 strs.push_back (bf->first);
436 set_popdown_strings (_keyboard_layout_selector, strs);
437 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
438 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
440 t->attach (*l, col + 1, col + 2, row, row + 1, FILL, FILL);
441 t->attach (_keyboard_layout_selector, col + 2, col + 3, row, row + 1, FILL | EXPAND, FILL);
446 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Clicking:"))));
447 l->set_name ("OptionEditorHeading");
448 l->set_use_markup (true);
449 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
454 l = manage (left_aligned_label (_("Edit using:")));
455 l->set_name ("OptionsLabel");
457 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
458 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
460 l = manage (new Label (_("+ button")));
461 l->set_name ("OptionsLabel");
463 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
464 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, SHRINK , FILL);
466 _edit_button_spin.set_name ("OptionsEntry");
467 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
472 set_popdown_strings (_delete_modifier_combo, dumb);
473 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
474 Gtkmm2ext::UI::instance()->set_tip (_delete_modifier_combo,
475 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
477 l = manage (left_aligned_label (_("Delete using:")));
478 l->set_name ("OptionsLabel");
480 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
481 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
483 l = manage (new Label (_("+ button")));
484 l->set_name ("OptionsLabel");
486 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
487 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, SHRINK, FILL);
489 _delete_button_spin.set_name ("OptionsEntry");
490 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
495 set_popdown_strings (_insert_note_modifier_combo, dumb);
496 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
497 Gtkmm2ext::UI::instance()->set_tip (_insert_note_modifier_combo,
498 (string_compose (_("<b>Recommended Setting: %1 + button 1 (left mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
500 l = manage (left_aligned_label (_("Insert note using:")));
501 l->set_name ("OptionsLabel");
503 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
504 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
506 l = manage (new Label (_("+ button")));
507 l->set_name ("OptionsLabel");
509 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
510 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, SHRINK, FILL);
512 _insert_note_button_spin.set_name ("OptionsEntry");
513 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
517 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Beginning a Drag:"))));
518 l->set_name ("OptionEditorHeading");
519 l->set_use_markup (true);
520 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
526 set_popdown_strings (_copy_modifier_combo, dumb);
527 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
528 Gtkmm2ext::UI::instance()->set_tip (_copy_modifier_combo,
529 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
531 Keyboard::secondary_modifier_name (),
533 Keyboard::primary_modifier_name (),
537 l = manage (left_aligned_label (_("Copy items using:")));
538 l->set_name ("OptionsLabel");
540 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
541 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
546 /* constraint modifier */
547 set_popdown_strings (_constraint_modifier_combo, dumb);
548 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
549 Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo,
550 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
552 Keyboard::primary_modifier_name (),
554 Keyboard::tertiary_modifier_name (),
558 l = manage (left_aligned_label (_("Constrain drag using:")));
559 l->set_name ("OptionsLabel");
561 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
562 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
568 set_popdown_strings (_push_points_combo, dumb);
569 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
571 std::string mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
572 Gtkmm2ext::UI::instance()->set_tip (_push_points_combo,
573 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
575 l = manage (left_aligned_label (_("Push points using:")));
576 l->set_name ("OptionsLabel");
578 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
579 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
583 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Beginning a Trim:"))));
584 l->set_name ("OptionEditorHeading");
585 l->set_use_markup (true);
586 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
592 set_popdown_strings (_trim_contents_combo, dumb);
593 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
594 Gtkmm2ext::UI::instance()->set_tip (_trim_contents_combo,
595 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
597 l = manage (left_aligned_label (_("Trim contents using:")));
598 l->set_name ("OptionsLabel");
600 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
601 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
607 set_popdown_strings (_trim_anchored_combo, dumb);
608 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
610 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::tertiary_modifier_name ());
611 Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo,
612 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
614 l = manage (left_aligned_label (_("Anchored trim using:")));
615 l->set_name ("OptionsLabel");
617 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
619 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
624 /* jump trim disabled for now
625 set_popdown_strings (_trim_jump_combo, dumb);
626 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
628 l = manage (left_aligned_label (_("Jump after trim using:")));
629 l->set_name ("OptionsLabel");
631 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
633 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
639 /* note resize relative */
640 set_popdown_strings (_note_size_relative_combo, dumb);
641 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
642 Gtkmm2ext::UI::instance()->set_tip (_note_size_relative_combo,
643 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg))); // XXX 2ndary
645 l = manage (left_aligned_label (_("Resize notes relatively using:")));
646 l->set_name ("OptionsLabel");
648 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
650 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
654 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Dragging:"))));
655 l->set_name ("OptionEditorHeading");
656 l->set_use_markup (true);
657 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
663 set_popdown_strings (_snap_modifier_combo, dumb);
664 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
666 mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ());
668 mod_str = Keyboard::secondary_modifier_name();
670 Gtkmm2ext::UI::instance()->set_tip (_snap_modifier_combo,
671 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
673 l = manage (left_aligned_label (_("Ignore snap using:")));
674 l->set_name ("OptionsLabel");
676 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
677 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
683 set_popdown_strings (_snap_delta_combo, dumb);
684 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
686 mod_str = Keyboard::level4_modifier_name ();
688 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::level4_modifier_name ());
690 Gtkmm2ext::UI::instance()->set_tip (_snap_delta_combo,
691 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
693 l = manage (left_aligned_label (_("Snap relatively using:")));
694 l->set_name ("OptionsLabel");
696 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
697 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
701 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Trimming:"))));
702 l->set_name ("OptionEditorHeading");
703 l->set_use_markup (true);
704 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
710 set_popdown_strings (_trim_overlap_combo, dumb);
711 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
713 Gtkmm2ext::UI::instance()->set_tip (_trim_overlap_combo,
714 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
716 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
717 l->set_name ("OptionsLabel");
719 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
720 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
724 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Dragging Control Points:"))));
725 l->set_name ("OptionEditorHeading");
726 l->set_use_markup (true);
727 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
733 set_popdown_strings (_fine_adjust_combo, dumb);
734 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
736 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::secondary_modifier_name ()); // XXX just 2ndary ?!
737 Gtkmm2ext::UI::instance()->set_tip (_fine_adjust_combo,
738 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
740 l = manage (left_aligned_label (_("Fine adjust using:")));
741 l->set_name ("OptionsLabel");
743 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
744 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
746 OptionEditorHeading* h = new OptionEditorHeading (_("Reset"));
747 h->add_to_page (this);
749 RcActionButton* rb = new RcActionButton (_("Reset to recommended defaults"),
750 sigc::mem_fun (*this, &KeyboardOptions::reset_to_defaults));
751 rb->add_to_page (this);
753 set_state_from_config ();
756 void parameter_changed (string const &)
758 /* XXX: these aren't really config options... */
761 void set_state_from_config ()
763 _delete_button_adjustment.set_value (Keyboard::delete_button());
764 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
765 _edit_button_adjustment.set_value (Keyboard::edit_button());
767 for (int x = 0; modifiers[x].name; ++x) {
768 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
769 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
771 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
772 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
774 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
775 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
777 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
778 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
780 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
781 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
783 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
784 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
786 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
787 _push_points_combo.set_active_text (S_(modifiers[x].name));
789 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
790 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
792 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
793 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
796 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
797 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
800 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
801 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
803 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
804 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
806 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
807 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
809 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
810 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
815 void add_to_page (OptionEditorPage* p)
817 int const n = p->table.property_n_rows();
818 p->table.resize (n + 1, 3);
819 p->table.attach (box, 1, 3, n, n + 1, FILL | EXPAND, SHRINK, 0, 0);
824 void bindings_changed ()
826 string const txt = _keyboard_layout_selector.get_active_text();
828 /* XXX: config...? for all this keyboard stuff */
830 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
831 if (txt == i->first) {
832 if (Keyboard::load_keybindings (i->second)) {
833 Keyboard::save_keybindings ();
839 void edit_modifier_chosen ()
841 string const txt = _edit_modifier_combo.get_active_text();
843 for (int i = 0; modifiers[i].name; ++i) {
844 if (txt == S_(modifiers[i].name)) {
845 Keyboard::set_edit_modifier (modifiers[i].modifier);
851 void delete_modifier_chosen ()
853 string const txt = _delete_modifier_combo.get_active_text();
855 for (int i = 0; modifiers[i].name; ++i) {
856 if (txt == S_(modifiers[i].name)) {
857 Keyboard::set_delete_modifier (modifiers[i].modifier);
863 void copy_modifier_chosen ()
865 string const txt = _copy_modifier_combo.get_active_text();
867 for (int i = 0; modifiers[i].name; ++i) {
868 if (txt == S_(modifiers[i].name)) {
869 Keyboard::set_copy_modifier (modifiers[i].modifier);
875 void insert_note_modifier_chosen ()
877 string const txt = _insert_note_modifier_combo.get_active_text();
879 for (int i = 0; modifiers[i].name; ++i) {
880 if (txt == S_(modifiers[i].name)) {
881 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
887 void snap_modifier_chosen ()
889 string const txt = _snap_modifier_combo.get_active_text();
891 for (int i = 0; modifiers[i].name; ++i) {
892 if (txt == S_(modifiers[i].name)) {
893 Keyboard::set_snap_modifier (modifiers[i].modifier);
899 void snap_delta_modifier_chosen ()
901 string const txt = _snap_delta_combo.get_active_text();
903 for (int i = 0; modifiers[i].name; ++i) {
904 if (txt == S_(modifiers[i].name)) {
905 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
911 void constraint_modifier_chosen ()
913 string const txt = _constraint_modifier_combo.get_active_text();
915 for (int i = 0; modifiers[i].name; ++i) {
916 if (txt == S_(modifiers[i].name)) {
917 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
923 void trim_contents_modifier_chosen ()
925 string const txt = _trim_contents_combo.get_active_text();
927 for (int i = 0; modifiers[i].name; ++i) {
928 if (txt == S_(modifiers[i].name)) {
929 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
935 void trim_overlap_modifier_chosen ()
937 string const txt = _trim_overlap_combo.get_active_text();
939 for (int i = 0; modifiers[i].name; ++i) {
940 if (txt == S_(modifiers[i].name)) {
941 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
947 void trim_anchored_modifier_chosen ()
949 string const txt = _trim_anchored_combo.get_active_text();
951 for (int i = 0; modifiers[i].name; ++i) {
952 if (txt == S_(modifiers[i].name)) {
953 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
959 void fine_adjust_modifier_chosen ()
961 string const txt = _fine_adjust_combo.get_active_text();
963 for (int i = 0; modifiers[i].name; ++i) {
964 if (txt == S_(modifiers[i].name)) {
965 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
971 void push_points_modifier_chosen ()
973 string const txt = _push_points_combo.get_active_text();
975 for (int i = 0; modifiers[i].name; ++i) {
976 if (txt == S_(modifiers[i].name)) {
977 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
983 void note_size_relative_modifier_chosen ()
985 string const txt = _note_size_relative_combo.get_active_text();
987 for (int i = 0; modifiers[i].name; ++i) {
988 if (txt == S_(modifiers[i].name)) {
989 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
995 void delete_button_changed ()
997 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
1000 void edit_button_changed ()
1002 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
1005 void insert_note_button_changed ()
1007 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
1010 void reset_to_defaults ()
1013 Keyboard::set_edit_modifier (Keyboard::PrimaryModifier);
1014 Keyboard::set_edit_button (3);
1015 Keyboard::set_delete_modifier (Keyboard::TertiaryModifier);
1016 Keyboard::set_delete_button (3);
1017 Keyboard::set_insert_note_modifier (Keyboard::PrimaryModifier);
1018 Keyboard::set_insert_note_button (1);
1020 /* when beginning a drag */
1022 Keyboard::set_copy_modifier (Keyboard::SecondaryModifier);
1024 Keyboard::set_copy_modifier (Keyboard::PrimaryModifier);
1028 ArdourKeyboard::set_constraint_modifier (Keyboard::PrimaryModifier);
1030 ArdourKeyboard::set_constraint_modifier (Keyboard::TertiaryModifier);
1032 ArdourKeyboard::set_push_points_modifier (Keyboard::PrimaryModifier | Keyboard::Level4Modifier);
1034 /* when beginning a trim */
1035 ArdourKeyboard::set_trim_contents_modifier (Keyboard::PrimaryModifier);
1036 ArdourKeyboard::set_trim_anchored_modifier (Keyboard::PrimaryModifier | Keyboard::TertiaryModifier);
1037 ArdourKeyboard::set_note_size_relative_modifier (Keyboard::TertiaryModifier); // XXX better: 2ndary
1039 /* while dragging */
1041 Keyboard::set_snap_modifier (Keyboard::TertiaryModifier);
1043 Keyboard::set_snap_modifier (Keyboard::SecondaryModifier);
1046 Keyboard::set_snap_delta_modifier (Keyboard::Level4Modifier);
1048 Keyboard::set_snap_delta_modifier (Keyboard::SecondaryModifier | Keyboard::Level4Modifier);
1051 /* while trimming */
1052 ArdourKeyboard::set_trim_overlap_modifier (Keyboard::TertiaryModifier);
1054 /* while dragging ctrl points */
1055 ArdourKeyboard::set_fine_adjust_modifier (/*Keyboard::PrimaryModifier | */Keyboard::SecondaryModifier); // XXX
1057 set_state_from_config ();
1060 ComboBoxText _keyboard_layout_selector;
1061 ComboBoxText _edit_modifier_combo;
1062 ComboBoxText _delete_modifier_combo;
1063 ComboBoxText _copy_modifier_combo;
1064 ComboBoxText _insert_note_modifier_combo;
1065 ComboBoxText _snap_modifier_combo;
1066 ComboBoxText _snap_delta_combo;
1067 ComboBoxText _constraint_modifier_combo;
1068 ComboBoxText _trim_contents_combo;
1069 ComboBoxText _trim_overlap_combo;
1070 ComboBoxText _trim_anchored_combo;
1071 ComboBoxText _trim_jump_combo;
1072 ComboBoxText _fine_adjust_combo;
1073 ComboBoxText _push_points_combo;
1074 ComboBoxText _note_size_relative_combo;
1075 Adjustment _delete_button_adjustment;
1076 SpinButton _delete_button_spin;
1077 Adjustment _edit_button_adjustment;
1078 SpinButton _edit_button_spin;
1079 Adjustment _insert_note_button_adjustment;
1080 SpinButton _insert_note_button_spin;
1084 class FontScalingOptions : public HSliderOption
1087 FontScalingOptions ()
1088 : HSliderOption ("font-scale", _("GUI and Font scaling"),
1089 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_font_scale),
1090 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_font_scale),
1094 const std::string dflt = _("100%");
1095 const std::string empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
1097 _hscale.set_name("FontScaleSlider");
1098 _hscale.set_draw_value(false);
1099 _hscale.add_mark(50, Gtk::POS_TOP, empty);
1100 _hscale.add_mark(60, Gtk::POS_TOP, empty);
1101 _hscale.add_mark(70, Gtk::POS_TOP, empty);
1102 _hscale.add_mark(80, Gtk::POS_TOP, empty);
1103 _hscale.add_mark(90, Gtk::POS_TOP, empty);
1104 _hscale.add_mark(100, Gtk::POS_TOP, dflt);
1105 _hscale.add_mark(125, Gtk::POS_TOP, empty);
1106 _hscale.add_mark(150, Gtk::POS_TOP, empty);
1107 _hscale.add_mark(175, Gtk::POS_TOP, empty);
1108 _hscale.add_mark(200, Gtk::POS_TOP, empty);
1109 _hscale.add_mark(250, Gtk::POS_TOP, empty);
1111 set_note (_("Adjusting the scale requires an application restart to re-layout."));
1116 HSliderOption::changed ();
1117 /* XXX: should be triggered from the parameter changed signal */
1118 UIConfiguration::instance().reset_dpi ();
1122 class VstTimeOutSliderOption : public HSliderOption
1125 VstTimeOutSliderOption (RCConfiguration* c)
1126 : HSliderOption ("vst-scan-timeout", _("Scan Time Out"),
1127 sigc::mem_fun (*c, &RCConfiguration::get_vst_scan_timeout),
1128 sigc::mem_fun (*c, &RCConfiguration::set_vst_scan_timeout),
1131 _label.set_alignment (1.0, 0.5); // match buttons below
1132 _hscale.set_digits (0);
1133 _hscale.set_draw_value(false);
1134 _hscale.add_mark( 0, Gtk::POS_TOP, _("\u221e")); // infinity
1135 _hscale.add_mark( 300, Gtk::POS_TOP, _("30 sec"));
1136 _hscale.add_mark( 600, Gtk::POS_TOP, _("1 min"));
1137 _hscale.add_mark(1200, Gtk::POS_TOP, _("2 mins"));
1138 _hscale.add_mark(1800, Gtk::POS_TOP, _("3 mins"));
1139 _hscale.add_mark(2400, Gtk::POS_TOP, _("4 mins"));
1140 _hscale.add_mark(3000, Gtk::POS_TOP, _("5 mins"));
1142 Gtkmm2ext::UI::instance()->set_tip(_hscale,
1143 _("Specify the default timeout for plugin instantiation. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1147 class ClipLevelOptions : public OptionEditorComponent
1151 : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1152 , _clip_level_slider (_clip_level_adjustment)
1153 , _label (_("Waveform Clip Level (dBFS):"))
1155 _label.set_name ("OptionsLabel");
1157 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ());
1159 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1161 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1164 void parameter_changed (string const & p)
1166 if (p == "waveform-clip-level") {
1167 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level());
1169 if (p == "show-waveform-clipping") {
1170 _clip_level_slider.set_sensitive (UIConfiguration::instance().get_show_waveform_clipping ());
1174 void set_state_from_config ()
1176 parameter_changed ("waveform-clip-level");
1177 parameter_changed ("show-waveform-clipping");
1180 void add_to_page (OptionEditorPage* p) {
1181 add_widgets_to_page (p, &_label, &_clip_level_slider);
1184 Gtk::Widget& tip_widget() {
1185 return _clip_level_slider;
1190 void clip_level_changed ()
1192 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1193 /* XXX: should be triggered from the parameter changed signal */
1194 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1197 Adjustment _clip_level_adjustment;
1198 HScale _clip_level_slider;
1202 class BufferingOptions : public OptionEditorComponent
1205 BufferingOptions (RCConfiguration* c)
1207 , _label (_("Preset:"))
1208 , _playback ("playback-buffer-seconds", _("Playback (seconds of buffering)"),
1209 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_playback_buffer_seconds),
1210 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_playback_buffer_seconds),
1212 , _capture ("capture-buffer-seconds", _("Recording (seconds of buffering)"),
1213 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_capture_buffer_seconds),
1214 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_capture_buffer_seconds),
1217 // TODO use ComboOption
1218 vector<string> presets;
1220 /* these must match the order of the enums for BufferingPreset */
1221 presets.push_back (_("Small sessions (4-16 tracks)"));
1222 presets.push_back (_("Medium sessions (16-64 tracks)"));
1223 presets.push_back (_("Large sessions (64+ tracks)"));
1224 presets.push_back (_("Custom (set by sliders below)"));
1226 set_popdown_strings (_buffering_presets_combo, presets);
1227 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1229 _label.set_name ("OptionsLabel");
1230 _label.set_alignment (0, 0.5);
1234 add_to_page (OptionEditorPage* p)
1236 add_widgets_to_page (p, &_label, &_buffering_presets_combo);
1237 _playback.add_to_page (p);
1238 _capture.add_to_page (p);
1241 void parameter_changed (string const & p)
1243 if (p == "buffering-preset") {
1244 switch (_rc_config->get_buffering_preset()) {
1246 _playback.set_sensitive (false);
1247 _capture.set_sensitive (false);
1248 _buffering_presets_combo.set_active (0);
1251 _playback.set_sensitive (false);
1252 _capture.set_sensitive (false);
1253 _buffering_presets_combo.set_active (1);
1256 _playback.set_sensitive (false);
1257 _capture.set_sensitive (false);
1258 _buffering_presets_combo.set_active (2);
1261 _playback.set_sensitive (true);
1262 _capture.set_sensitive (true);
1263 _buffering_presets_combo.set_active (3);
1267 _playback.parameter_changed (p);
1268 _capture.parameter_changed (p);
1271 void set_state_from_config ()
1273 parameter_changed ("buffering-preset");
1274 _playback.set_state_from_config();
1275 _capture.set_state_from_config();
1278 Gtk::Widget& tip_widget() { return _buffering_presets_combo; }
1282 void preset_changed ()
1284 int index = _buffering_presets_combo.get_active_row_number ();
1290 _rc_config->set_buffering_preset (Small);
1293 _rc_config->set_buffering_preset (Medium);
1296 _rc_config->set_buffering_preset (Large);
1299 _rc_config->set_buffering_preset (Custom);
1302 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1307 RCConfiguration* _rc_config;
1309 HSliderOption _playback;
1310 HSliderOption _capture;
1311 ComboBoxText _buffering_presets_combo;
1314 class ControlSurfacesOptions : public OptionEditorMiniPage
1317 ControlSurfacesOptions ()
1318 : _ignore_view_change (0)
1320 _store = ListStore::create (_model);
1321 _view.set_model (_store);
1322 _view.append_column (_("Control Surface Protocol"), _model.name);
1323 _view.get_column(0)->set_resizable (true);
1324 _view.get_column(0)->set_expand (true);
1325 _view.append_column_editable (_("Enable"), _model.enabled);
1327 Gtk::HBox* edit_box = manage (new Gtk::HBox);
1328 edit_box->set_spacing(3);
1331 Label* label = manage (new Label);
1332 label->set_text (_("Edit the settings for selected protocol (it must be ENABLED first):"));
1333 edit_box->pack_start (*label, false, false);
1336 edit_button = manage (new Button(_("Show Protocol Settings")));
1337 edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
1338 edit_box->pack_start (*edit_button, true, true);
1339 edit_button->set_sensitive (false);
1340 edit_button->show ();
1342 int const n = table.property_n_rows();
1343 table.resize (n + 2, 3);
1344 table.attach (_view, 0, 3, n, n + 1);
1345 table.attach (*edit_box, 0, 3, n + 1, n + 2);
1347 ControlProtocolManager& m = ControlProtocolManager::instance ();
1348 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1349 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1351 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1352 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1353 _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
1356 void parameter_changed (std::string const &)
1361 void set_state_from_config ()
1365 ControlProtocolManager& m = ControlProtocolManager::instance ();
1366 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1368 if (!(*i)->mandatory) {
1369 TreeModel::Row r = *_store->append ();
1370 r[_model.name] = (*i)->name;
1371 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1372 r[_model.protocol_info] = *i;
1379 void protocol_status_changed (ControlProtocolInfo* cpi) {
1381 TreeModel::Children rows = _store->children();
1383 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1384 string n = ((*x)[_model.name]);
1386 if ((*x)[_model.protocol_info] == cpi) {
1387 _ignore_view_change++;
1388 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1389 _ignore_view_change--;
1395 void selection_changed ()
1397 //enable the Edit button when a row is selected for editing
1398 TreeModel::Row row = *(_view.get_selection()->get_selected());
1399 if (row && row[_model.enabled])
1400 edit_button->set_sensitive (true);
1402 edit_button->set_sensitive (false);
1405 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1407 TreeModel::Row r = *i;
1409 if (_ignore_view_change) {
1413 ControlProtocolInfo* cpi = r[_model.protocol_info];
1418 bool const was_enabled = (cpi->protocol != 0);
1419 bool const is_enabled = r[_model.enabled];
1422 if (was_enabled != is_enabled) {
1425 ControlProtocolManager::instance().activate (*cpi);
1427 ControlProtocolManager::instance().deactivate (*cpi);
1431 selection_changed ();
1434 void edit_btn_clicked ()
1437 ControlProtocolInfo* cpi;
1440 row = *(_view.get_selection()->get_selected());
1441 if (!row[_model.enabled]) {
1444 cpi = row[_model.protocol_info];
1445 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1448 Box* box = (Box*) cpi->protocol->get_gui ();
1452 if (box->get_parent()) {
1453 static_cast<ArdourWindow*>(box->get_parent())->present();
1456 WindowTitle title (Glib::get_application_name());
1457 title += row[_model.name];
1458 title += _("Configuration");
1459 /* once created, the window is managed by the surface itself (as ->get_parent())
1460 * Surface's tear_down_gui() is called on session close, when de-activating
1461 * or re-initializing a surface.
1462 * tear_down_gui() hides an deletes the Window if it exists.
1464 ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
1465 win->set_title ("Control Protocol Options");
1471 void edit_clicked (GdkEventButton* ev)
1473 if (ev->type != GDK_2BUTTON_PRESS) {
1480 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1484 ControlSurfacesModelColumns ()
1488 add (protocol_info);
1491 TreeModelColumn<string> name;
1492 TreeModelColumn<bool> enabled;
1493 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1496 Glib::RefPtr<ListStore> _store;
1497 ControlSurfacesModelColumns _model;
1499 PBD::ScopedConnection protocol_status_connection;
1500 uint32_t _ignore_view_change;
1501 Gtk::Button* edit_button;
1504 class VideoTimelineOptions : public OptionEditorMiniPage
1507 VideoTimelineOptions (RCConfiguration* c)
1509 , _show_video_export_info_button (_("Show Video Export Info before export"))
1510 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1511 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1512 , _xjadeo_browse_button (_("Browse..."))
1515 int n = table.property_n_rows();
1517 t->attach (_show_video_export_info_button, 1, 4, n, n + 1);
1518 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1519 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1520 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1523 t->attach (_show_video_server_dialog_button, 1, 4, n, n + 1);
1524 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1525 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1526 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1529 t->attach (_video_advanced_setup_button, 1, 4, n, n + 1, FILL);
1530 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1531 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1532 _("<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."));
1535 Label* l = manage (new Label (_("Video Server URL:")));
1536 l->set_alignment (0, 0.5);
1537 t->attach (*l, 1, 2, n, n + 1, FILL);
1538 t->attach (_video_server_url_entry, 2, 4, n, n + 1, FILL);
1539 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1540 _("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"));
1543 l = manage (new Label (_("Video Folder:")));
1544 l->set_alignment (0, 0.5);
1545 t->attach (*l, 1, 2, n, n + 1, FILL);
1546 t->attach (_video_server_docroot_entry, 2, 4, n, n + 1);
1547 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1548 _("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."));
1551 l = manage (new Label (""));
1552 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1555 l = manage (new Label (string_compose ("<b>%1</b>", _("Video Monitor"))));
1556 l->set_use_markup (true);
1557 l->set_alignment (0, 0.5);
1558 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1561 l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"),
1564 #elif defined PLATFORM_WINDOWS
1570 l->set_alignment (0, 0.5);
1571 t->attach (*l, 1, 4, n, n + 1, FILL);
1574 t->attach (_custom_xjadeo_path, 2, 3, n, n + 1, EXPAND|FILL);
1575 Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart."));
1576 t->attach (_xjadeo_browse_button, 3, 4, n, n + 1, FILL);
1578 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1579 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1580 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1581 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1582 _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed));
1583 _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked));
1585 // xjadeo-path is a UIConfig parameter
1586 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &VideoTimelineOptions::parameter_changed));
1589 void server_url_changed ()
1591 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1594 void server_docroot_changed ()
1596 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1599 void show_video_export_info_toggled ()
1601 bool const x = _show_video_export_info_button.get_active ();
1602 _rc_config->set_show_video_export_info (x);
1605 void show_video_server_dialog_toggled ()
1607 bool const x = _show_video_server_dialog_button.get_active ();
1608 _rc_config->set_show_video_server_dialog (x);
1611 void video_advanced_setup_toggled ()
1613 bool const x = _video_advanced_setup_button.get_active ();
1614 _rc_config->set_video_advanced_setup(x);
1617 void custom_xjadeo_path_changed ()
1619 UIConfiguration::instance().set_xjadeo_binary (_custom_xjadeo_path.get_text());
1622 void xjadeo_browse_clicked ()
1624 Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN);
1625 dialog.set_filename (UIConfiguration::instance().get_xjadeo_binary());
1626 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1627 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1628 if (dialog.run () == Gtk::RESPONSE_OK) {
1629 const std::string& filename = dialog.get_filename();
1630 if (!filename.empty() && (
1632 Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) ||
1634 Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)
1636 UIConfiguration::instance().set_xjadeo_binary (filename);
1641 void parameter_changed (string const & p)
1643 if (p == "video-server-url") {
1644 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1645 } else if (p == "video-server-docroot") {
1646 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1647 } else if (p == "show-video-export-info") {
1648 bool const x = _rc_config->get_show_video_export_info();
1649 _show_video_export_info_button.set_active (x);
1650 } else if (p == "show-video-server-dialog") {
1651 bool const x = _rc_config->get_show_video_server_dialog();
1652 _show_video_server_dialog_button.set_active (x);
1653 } else if (p == "video-advanced-setup") {
1654 bool const x = _rc_config->get_video_advanced_setup();
1655 _video_advanced_setup_button.set_active(x);
1656 _video_server_docroot_entry.set_sensitive(x);
1657 _video_server_url_entry.set_sensitive(x);
1658 } else if (p == "xjadeo-binary") {
1659 _custom_xjadeo_path.set_text (UIConfiguration::instance().get_xjadeo_binary());
1663 void set_state_from_config ()
1665 parameter_changed ("video-server-url");
1666 parameter_changed ("video-server-docroot");
1667 parameter_changed ("video-monitor-setup-dialog");
1668 parameter_changed ("show-video-export-info");
1669 parameter_changed ("show-video-server-dialog");
1670 parameter_changed ("video-advanced-setup");
1671 parameter_changed ("xjadeo-binary");
1675 RCConfiguration* _rc_config;
1676 Entry _video_server_url_entry;
1677 Entry _video_server_docroot_entry;
1678 Entry _custom_xjadeo_path;
1679 CheckButton _show_video_export_info_button;
1680 CheckButton _show_video_server_dialog_button;
1681 CheckButton _video_advanced_setup_button;
1682 Button _xjadeo_browse_button;
1685 class ColumVisibilityOption : public Option
1688 ColumVisibilityOption (string id, string name, uint32_t n_col, sigc::slot<uint32_t> get, sigc::slot<bool, uint32_t> set)
1695 cb = (CheckButton**) malloc (sizeof (CheckButton*) * n_col);
1696 for (uint32_t i = 0; i < n_col; ++i) {
1697 CheckButton* col = manage (new CheckButton (string_compose (_("Column %1"), i + 1)));
1698 col->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ColumVisibilityOption::column_toggled), i));
1699 _hbox.pack_start (*col);
1702 parameter_changed (id);
1705 ~ColumVisibilityOption () {
1709 Gtk::Widget& tip_widget() { return _hbox; }
1711 void set_state_from_config ()
1713 uint32_t c = _get();
1714 for (uint32_t i = 0; i < _n_col; ++i) {
1715 bool en = (c & (1<<i)) ? true : false;
1716 if (cb[i]->get_active () != en) {
1717 cb[i]->set_active (en);
1722 void add_to_page (OptionEditorPage* p)
1724 _heading.add_to_page (p);
1725 add_widget_to_page (p, &_hbox);
1729 void column_toggled (int b) {
1730 uint32_t c = _get();
1732 if (cb[b]->get_active ()) {
1743 OptionEditorHeading _heading;
1747 sigc::slot<uint32_t> _get;
1748 sigc::slot<bool, uint32_t> _set;
1752 /** A class which allows control of visibility of some editor components usign
1753 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1754 * which has the correct members, but with null widget pointers. This
1755 * class allows the user to set visibility of the members, the details
1756 * of which are stored in a configuration variable which can be watched
1757 * by parts of the editor that actually contain the widgets whose visibility
1758 * is being controlled.
1761 class VisibilityOption : public Option
1764 /** @param name User-visible name for this group.
1765 * @param g `Dummy' VisibilityGroup (as described above).
1766 * @param get Method to get the value of the appropriate configuration variable.
1767 * @param set Method to set the value of the appropriate configuration variable.
1769 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1770 : Option (g->get_state_name(), name)
1772 , _visibility_group (g)
1776 /* Watch for changes made by the user to our members */
1777 _visibility_group->VisibilityChanged.connect_same_thread (
1778 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1782 void set_state_from_config ()
1784 /* Set our state from the current configuration */
1785 _visibility_group->set_state (_get ());
1788 void add_to_page (OptionEditorPage* p)
1790 _heading.add_to_page (p);
1791 add_widget_to_page (p, _visibility_group->list_view ());
1794 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1799 /* The user has changed something, so reflect this change
1800 in the RCConfiguration.
1802 _set (_visibility_group->get_state_value ());
1805 OptionEditorHeading _heading;
1806 VisibilityGroup* _visibility_group;
1807 sigc::slot<std::string> _get;
1808 sigc::slot<bool, std::string> _set;
1809 PBD::ScopedConnection _visibility_group_connection;
1813 class MidiPortOptions : public OptionEditorMiniPage, public sigc::trackable
1818 setup_midi_port_view (midi_output_view, false);
1819 setup_midi_port_view (midi_input_view, true);
1821 OptionEditorHeading* h = new OptionEditorHeading (_("MIDI Inputs"));
1822 h->add_to_page (this);
1824 Gtk::ScrolledWindow* scroller = manage (new Gtk::ScrolledWindow);
1825 scroller->add (midi_input_view);
1826 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1827 scroller->set_size_request (-1, 180);
1829 int n = table.property_n_rows();
1830 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1832 h = new OptionEditorHeading (_("MIDI Outputs"));
1833 h->add_to_page (this);
1835 scroller = manage (new Gtk::ScrolledWindow);
1836 scroller->add (midi_output_view);
1837 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1838 scroller->set_size_request (-1, 180);
1840 n = table.property_n_rows();
1841 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1843 midi_output_view.show ();
1844 midi_input_view.show ();
1846 table.signal_show().connect (sigc::mem_fun (*this, &MidiPortOptions::on_show));
1849 void parameter_changed (string const&) {}
1850 void set_state_from_config() {}
1855 AudioEngine::instance()->PortRegisteredOrUnregistered.connect (connections,
1856 invalidator (*this),
1857 boost::bind (&MidiPortOptions::refill, this),
1859 AudioEngine::instance()->MidiPortInfoChanged.connect (connections,
1860 invalidator (*this),
1861 boost::bind (&MidiPortOptions::refill, this),
1863 AudioEngine::instance()->MidiSelectionPortsChanged.connect (connections,
1864 invalidator (*this),
1865 boost::bind (&MidiPortOptions::refill, this),
1871 if (refill_midi_ports (true, midi_input_view)) {
1872 input_label.show ();
1874 input_label.hide ();
1876 if (refill_midi_ports (false, midi_output_view)) {
1877 output_label.show ();
1879 output_label.hide ();
1884 PBD::ScopedConnectionList connections;
1886 /* MIDI port management */
1887 struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord {
1889 MidiPortColumns () {
1898 Gtk::TreeModelColumn<std::string> pretty_name;
1899 Gtk::TreeModelColumn<bool> music_data;
1900 Gtk::TreeModelColumn<bool> control_data;
1901 Gtk::TreeModelColumn<bool> selection;
1902 Gtk::TreeModelColumn<std::string> name;
1903 Gtk::TreeModelColumn<std::string> filler;
1906 MidiPortColumns midi_port_columns;
1907 Gtk::TreeView midi_input_view;
1908 Gtk::TreeView midi_output_view;
1909 Gtk::Label input_label;
1910 Gtk::Label output_label;
1912 void setup_midi_port_view (Gtk::TreeView&, bool with_selection);
1913 bool refill_midi_ports (bool for_input, Gtk::TreeView&);
1914 void pretty_name_edit (std::string const & path, std::string const & new_text, Gtk::TreeView*);
1915 void midi_music_column_toggled (std::string const & path, Gtk::TreeView*);
1916 void midi_control_column_toggled (std::string const & path, Gtk::TreeView*);
1917 void midi_selection_column_toggled (std::string const & path, Gtk::TreeView*);
1921 MidiPortOptions::setup_midi_port_view (Gtk::TreeView& view, bool with_selection)
1923 int pretty_name_column;
1926 int selection_column;
1927 TreeViewColumn* col;
1930 pretty_name_column = view.append_column_editable (_("Name (click to edit)"), midi_port_columns.pretty_name) - 1;
1932 col = manage (new TreeViewColumn ("", midi_port_columns.music_data));
1933 col->set_alignment (ALIGN_CENTER);
1934 l = manage (new Label (_("Music Data")));
1935 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of music performance data."), PROGRAM_NAME));
1936 col->set_widget (*l);
1938 music_column = view.append_column (*col) - 1;
1940 col = manage (new TreeViewColumn ("", midi_port_columns.control_data));
1941 col->set_alignment (ALIGN_CENTER);
1942 l = manage (new Label (_("Control Data")));
1943 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of control data."), PROGRAM_NAME));
1944 col->set_widget (*l);
1946 control_column = view.append_column (*col) - 1;
1948 if (with_selection) {
1949 col = manage (new TreeViewColumn (_("Follow Selection"), midi_port_columns.selection));
1950 selection_column = view.append_column (*col) - 1;
1951 l = manage (new Label (_("Follow Selection")));
1952 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));
1953 col->set_widget (*l);
1957 /* filler column so that the last real column doesn't expand */
1958 view.append_column ("", midi_port_columns.filler);
1960 CellRendererText* pretty_name_cell = dynamic_cast<CellRendererText*> (view.get_column_cell_renderer (pretty_name_column));
1961 pretty_name_cell->property_editable() = true;
1962 pretty_name_cell->signal_edited().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::pretty_name_edit), &view));
1964 CellRendererToggle* toggle_cell;
1966 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (music_column));
1967 toggle_cell->property_activatable() = true;
1968 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_music_column_toggled), &view));
1970 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (control_column));
1971 toggle_cell->property_activatable() = true;
1972 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_control_column_toggled), &view));
1974 if (with_selection) {
1975 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (selection_column));
1976 toggle_cell->property_activatable() = true;
1977 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_selection_column_toggled), &view));
1980 view.get_selection()->set_mode (SELECTION_NONE);
1981 view.set_tooltip_column (4); /* port "real" name */
1982 view.get_column(0)->set_resizable (true);
1983 view.get_column(0)->set_expand (true);
1987 MidiPortOptions::refill_midi_ports (bool for_input, Gtk::TreeView& view)
1989 using namespace ARDOUR;
1991 std::vector<string> ports;
1993 AudioEngine::instance()->get_known_midi_ports (ports);
1995 if (ports.empty()) {
2000 Glib::RefPtr<ListStore> model = Gtk::ListStore::create (midi_port_columns);
2002 for (vector<string>::const_iterator s = ports.begin(); s != ports.end(); ++s) {
2004 if (AudioEngine::instance()->port_is_mine (*s)) {
2008 PortManager::MidiPortInformation mpi (AudioEngine::instance()->midi_port_information (*s));
2010 if (mpi.pretty_name.empty()) {
2011 /* vanished since get_known_midi_ports() */
2015 if (for_input != mpi.input) {
2019 TreeModel::Row row = *(model->append());
2021 row[midi_port_columns.pretty_name] = mpi.pretty_name;
2022 row[midi_port_columns.music_data] = mpi.properties & MidiPortMusic;
2023 row[midi_port_columns.control_data] = mpi.properties & MidiPortControl;
2024 row[midi_port_columns.selection] = mpi.properties & MidiPortSelection;
2025 row[midi_port_columns.name] = *s;
2028 view.set_model (model);
2034 MidiPortOptions::midi_music_column_toggled (string const & path, TreeView* view)
2036 TreeIter iter = view->get_model()->get_iter (path);
2042 bool new_value = ! bool ((*iter)[midi_port_columns.music_data]);
2044 /* don't reset model - wait for MidiPortInfoChanged signal */
2047 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2049 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2054 MidiPortOptions::midi_control_column_toggled (string const & path, TreeView* view)
2056 TreeIter iter = view->get_model()->get_iter (path);
2062 bool new_value = ! bool ((*iter)[midi_port_columns.control_data]);
2064 /* don't reset model - wait for MidiPortInfoChanged signal */
2067 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2069 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2074 MidiPortOptions::midi_selection_column_toggled (string const & path, TreeView* view)
2076 TreeIter iter = view->get_model()->get_iter (path);
2082 bool new_value = ! bool ((*iter)[midi_port_columns.selection]);
2084 /* don't reset model - wait for MidiSelectionPortsChanged signal */
2087 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2089 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2094 MidiPortOptions::pretty_name_edit (std::string const & path, string const & new_text, Gtk::TreeView* view)
2096 TreeIter iter = view->get_model()->get_iter (path);
2102 boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
2104 ARDOUR::PortEngine::PortHandle ph = backend->get_port_by_name ((*iter)[midi_port_columns.name]);
2106 backend->set_port_property (ph, "http://jackaudio.org/metadata/pretty-name", new_text, "");
2107 (*iter)[midi_port_columns.pretty_name] = new_text;
2115 RCOptionEditor::RCOptionEditor ()
2116 : OptionEditorContainer (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
2117 , Tabbable (*this, _("Preferences")) /* pack self-as-vbox into tabbable */
2118 , _rc_config (Config)
2119 , _mixer_strip_visibility ("mixer-element-visibility")
2121 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
2125 uint32_t hwcpus = hardware_concurrency ();
2127 BoolComboOption* bco;
2130 add_option (_("General"), new OptionEditorHeading (_("DSP CPU Utilization")));
2132 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
2134 _("Signal processing uses"),
2135 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
2136 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
2139 procs->add (-1, _("all but one processor"));
2140 procs->add (0, _("all available processors"));
2142 for (uint32_t i = 1; i <= hwcpus; ++i) {
2143 procs->add (i, string_compose (P_("%1 processor", "%1 processors", i), i));
2146 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
2148 add_option (_("General"), procs);
2151 /* Image cache size */
2152 add_option (_("General"), new OptionEditorHeading (_("Memory Usage")));
2154 HSliderOption *sics = new HSliderOption ("waveform-cache-size",
2155 _("Waveform image cache size (megabytes)"),
2156 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
2157 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size),
2158 1, 1024, 10 /* 1 MB to 1GB in steps of 10MB */
2160 sics->scale().set_digits (0);
2161 Gtkmm2ext::UI::instance()->set_tip (
2163 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
2164 add_option (_("General"), sics);
2166 add_option (_("General"), new OptionEditorHeading (S_("Options|Undo")));
2168 add_option (_("General"), new UndoOptions (_rc_config));
2170 add_option (_("General"),
2172 "verify-remove-last-capture",
2173 _("Verify removal of last capture"),
2174 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
2175 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
2178 add_option (_("General"), new OptionEditorHeading (_("Session Management")));
2180 add_option (_("General"),
2182 "periodic-safety-backups",
2183 _("Make periodic backups of the session file"),
2184 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
2185 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
2188 add_option (_("General"),
2190 "only-copy-imported-files",
2191 _("Always copy imported files"),
2192 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
2193 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
2196 add_option (_("General"), new DirectoryOption (
2197 X_("default-session-parent-dir"),
2198 _("Default folder for new sessions:"),
2199 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
2200 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
2203 add_option (_("General"),
2204 new SpinOption<uint32_t> (
2205 "max-recent-sessions",
2206 _("Maximum number of recent sessions"),
2207 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
2208 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
2212 add_option (_("General"), new OptionEditorHeading (_("Automation")));
2214 add_option (_("General"),
2215 new SpinOption<double> (
2216 "automation-thinning-factor",
2217 _("Thinning factor (larger value => less data)"),
2218 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
2219 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
2223 add_option (_("General"),
2224 new SpinOption<double> (
2225 "automation-interval-msecs",
2226 _("Automation sampling interval (milliseconds)"),
2227 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
2228 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
2232 add_option (_("General"), new OptionEditorHeading (_("Tempo")));
2234 bo = new BoolOption (
2235 "allow-non-quarter-pulse",
2236 _("Allow non quarter-note pulse"),
2237 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_allow_non_quarter_pulse),
2238 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_allow_non_quarter_pulse)
2240 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2241 string_compose (_("<b>When enabled</b> %1 will allow tempo to be expressed in divisions per minute\n"
2242 "<b>When disabled</b> %1 will only allow tempo to be expressed in quarter notes per minute"),
2244 add_option (_("General"), bo);
2246 if (!ARDOUR::Profile->get_mixbus()) {
2247 add_option (_("General"), new OptionEditorHeading (_("GUI Lock")));
2248 /* Lock GUI timeout */
2250 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2251 _("Lock timeout (seconds)"),
2252 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
2253 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds),
2256 slts->scale().set_digits (0);
2257 Gtkmm2ext::UI::instance()->set_tip (
2259 _("Lock GUI after this many idle seconds (zero to never lock)"));
2260 add_option (_("General"), slts);
2265 add_option (_("General/Translation"), new OptionEditorHeading (_("Internationalization")));
2267 bo = new BoolOption (
2268 "enable-translation",
2269 _("Use translations"),
2270 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2271 sigc::ptr_fun (ARDOUR::set_translations_enabled)
2274 bo->set_note (string_compose (_("These settings will only take effect after %1 is restarted (if available for your language preferences)."), PROGRAM_NAME));
2276 add_option (_("General/Translation"), bo);
2278 _l10n = new ComboOption<ARDOUR::LocaleMode> (
2281 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_locale_mode),
2282 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_locale_mode)
2285 _l10n->add (ARDOUR::SET_LC_ALL, _("Set complete locale"));
2286 _l10n->add (ARDOUR::SET_LC_MESSAGES, _("Enable only message translation"));
2287 _l10n->add (ARDOUR::SET_LC_MESSAGES_AND_LC_NUMERIC, _("Translate messages and format numeric format"));
2288 _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."));
2290 add_option (_("General/Translation"), _l10n);
2291 parameter_changed ("enable-translation");
2292 #endif // ENABLE_NLS
2297 add_option (_("Editor"), new OptionEditorHeading (_("General")));
2299 add_option (_("Editor"),
2301 "rubberbanding-snaps-to-grid",
2302 _("Snap rubberband to grid"),
2303 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2304 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2307 bo = new BoolOption (
2309 _("Prompt for new marker names"),
2310 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2311 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2313 add_option (_("Editor"), bo);
2314 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."
2315 "\n\nYou can always rename markers by right-clicking on them"));
2317 add_option (_("Editor"),
2319 "draggable-playhead",
2320 _("Allow dragging of playhead"),
2321 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2322 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2325 if (!Profile->get_mixbus()) {
2327 add_option (_("Editor"),
2329 "use-mouse-position-as-zoom-focus-on-scroll",
2330 _("Zoom to mouse position when zooming with scroll wheel"),
2331 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2332 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2336 add_option (_("Editor"),
2338 "use-time-rulers-to-zoom-with-vertical-drag",
2339 _("Zoom with vertical drag in rulers"),
2340 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag),
2341 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag)
2344 add_option (_("Editor"),
2346 "use-double-click-to-zoom-to-selection",
2347 _("Double click zooms to selection"),
2348 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection),
2349 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection)
2352 add_option (_("Editor"),
2354 "update-editor-during-summary-drag",
2355 _("Update editor window during drags of the summary"),
2356 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2357 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2360 add_option (_("Editor"),
2362 "autoscroll-editor",
2363 _("Auto-scroll editor window when dragging near its edges"),
2364 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2365 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2368 add_option (_("Editor"),
2369 new BoolComboOption (
2370 "show-region-gain-envelopes",
2371 _("Show gain envelopes in audio regions"),
2373 _("only in Draw and Internal Edit modes"),
2374 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2375 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2378 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2380 add_option (_("Editor"),
2382 "automation-follows-regions",
2383 _("Move relevant automation when audio regions are moved"),
2384 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2385 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2388 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2389 "default-fade-shape",
2390 _("Default fade shape"),
2391 sigc::mem_fun (*_rc_config,
2392 &RCConfiguration::get_default_fade_shape),
2393 sigc::mem_fun (*_rc_config,
2394 &RCConfiguration::set_default_fade_shape)
2397 fadeshape->add (FadeLinear,
2398 _("Linear (for highly correlated material)"));
2399 fadeshape->add (FadeConstantPower, _("Constant power"));
2400 fadeshape->add (FadeSymmetric, _("Symmetric"));
2401 fadeshape->add (FadeSlow, _("Slow"));
2402 fadeshape->add (FadeFast, _("Fast"));
2404 add_option (_("Editor"), fadeshape);
2406 bco = new BoolComboOption (
2407 "use-overlap-equivalency",
2408 _("Regions in edit groups are edited together"),
2409 _("whenever they overlap in time"),
2410 _("only if they have identical length and position"),
2411 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2412 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2415 add_option (_("Editor"), bco);
2417 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2419 _("Layering model"),
2420 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2421 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2424 lm->add (LaterHigher, _("later is higher"));
2425 lm->add (Manual, _("manual layering"));
2426 add_option (_("Editor"), lm);
2428 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2429 "region-selection-after-split",
2430 _("After splitting selected regions, select"),
2431 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2432 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2434 // TODO: decide which of these modes are really useful
2435 rsas->add(None, _("no regions"));
2436 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2437 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2438 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2439 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2440 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2441 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2442 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2444 add_option (_("Editor"), rsas);
2446 add_option (_("Editor/Modifiers"), new OptionEditorHeading (_("Keyboard Modifiers")));
2447 add_option (_("Editor/Modifiers"), new KeyboardOptions);
2448 add_option (_("Editor/Modifiers"), new OptionEditorBlank ());
2450 /* MIXER -- SOLO AND MUTE */
2452 add_option (_("Mixer"), new OptionEditorHeading (_("Solo")));
2454 _solo_control_is_listen_control = new BoolOption (
2455 "solo-control-is-listen-control",
2456 _("Solo controls are Listen controls"),
2457 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2458 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2461 add_option (_("Mixer"), _solo_control_is_listen_control);
2463 add_option (_("Mixer"),
2466 _("Exclusive solo"),
2467 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2468 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2471 add_option (_("Mixer"),
2474 _("Show solo muting"),
2475 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2476 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2479 add_option (_("Mixer"),
2481 "solo-mute-override",
2482 _("Soloing overrides muting"),
2483 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2484 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2487 add_option (_("Mixer"),
2490 _("Solo-in-place mute cut (dB)"),
2491 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2492 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2495 _listen_position = new ComboOption<ListenPosition> (
2497 _("Listen Position"),
2498 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2499 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2502 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2503 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2505 add_option (_("Mixer"), _listen_position);
2507 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2509 _("PFL signals come from"),
2510 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2511 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2514 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2515 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2517 add_option (_("Mixer"), pp);
2519 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2521 _("AFL signals come from"),
2522 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2523 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2526 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2527 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2529 add_option (_("Mixer"), pa);
2531 add_option (_("Mixer"), new OptionEditorHeading (_("Default Track / Bus Muting Options")));
2533 add_option (_("Mixer"),
2535 "mute-affects-pre-fader",
2536 _("Mute affects pre-fader sends"),
2537 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2538 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2541 add_option (_("Mixer"),
2543 "mute-affects-post-fader",
2544 _("Mute affects post-fader sends"),
2545 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2546 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2549 add_option (_("Mixer"),
2551 "mute-affects-control-outs",
2552 _("Mute affects control outputs"),
2553 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2554 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2557 add_option (_("Mixer"),
2559 "mute-affects-main-outs",
2560 _("Mute affects main outputs"),
2561 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2562 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2566 if (!ARDOUR::Profile->get_mixbus()) {
2567 add_option (_("Mixer"), new OptionEditorHeading (_("Send Routing")));
2568 add_option (_("Mixer"),
2570 "link-send-and-route-panner",
2571 _("Link panners of Aux and External Sends with main panner by default"),
2572 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2573 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2579 add_option (_("Signal Flow"), new OptionEditorHeading (_("Monitoring")));
2581 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2583 _("Record monitoring handled by"),
2584 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2585 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2588 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2589 mm->add (HardwareMonitoring, _("via Audio Driver"));
2592 string prog (PROGRAM_NAME);
2593 boost::algorithm::to_lower (prog);
2594 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2595 mm->add (ExternalMonitoring, _("audio hardware"));
2597 add_option (_("Signal Flow"), mm);
2599 bo = new BoolOption (
2600 "tape-machine-mode",
2601 _("Tape machine mode"),
2602 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2603 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2605 add_option (_("Signal Flow"), bo);
2606 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2607 string_compose (_("<b>When enabled</b> %1 will not monitor a track's input if the transport is stopped."),
2610 if (!Profile->get_mixbus()) {
2612 add_option (_("Signal Flow"), new OptionEditorHeading (_("Track and Bus Connections")));
2614 add_option (_("Signal Flow"),
2616 "auto-connect-standard-busses",
2617 _("Auto-connect master/monitor busses"),
2618 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2619 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2622 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2623 "input-auto-connect",
2624 _("Connect track inputs"),
2625 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2626 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2629 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2630 iac->add (ManualConnect, _("manually"));
2632 add_option (_("Signal Flow"), iac);
2634 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2635 "output-auto-connect",
2636 _("Connect track and bus outputs"),
2637 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2638 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2641 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2642 oac->add (AutoConnectMaster, _("automatically to master bus"));
2643 oac->add (ManualConnect, _("manually"));
2645 add_option (_("Signal Flow"), oac);
2647 bo = new BoolOption (
2649 _("Use 'Strict-I/O' for new tracks or Busses"),
2650 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2651 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2654 add_option (_("Signal Flow"), bo);
2655 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2656 _("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."));
2663 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2665 add_option (_("Audio"), new BufferingOptions (_rc_config));
2667 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2669 add_option (_("Audio"),
2671 "denormal-protection",
2672 _("Use DC bias to protect against denormals"),
2673 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2674 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2677 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2679 _("Processor handling"),
2680 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2681 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2685 dm->add (DenormalNone, _("no processor handling"));
2687 FPU* fpu = FPU::instance();
2689 if (fpu->has_flush_to_zero()) {
2691 dm->add (DenormalFTZ, _("use FlushToZero"));
2692 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2693 _rc_config->set_denormal_model(DenormalNone);
2696 if (fpu->has_denormals_are_zero()) {
2698 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2699 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2700 _rc_config->set_denormal_model(DenormalNone);
2703 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2705 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2706 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2707 _rc_config->set_denormal_model(DenormalNone);
2711 dm->set_sensitive(false);
2714 add_option (_("Audio"), dm);
2716 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2718 add_option (_("Audio"),
2720 "auto-analyse-audio",
2721 _("Enable automatic analysis of audio"),
2722 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2723 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2726 add_option (_("Audio"),
2728 "replicate-missing-region-channels",
2729 _("Replicate missing region channels"),
2730 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2731 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2736 add_option (_("MIDI"), new OptionEditorHeading (_("Buffering")));
2738 add_option (_("MIDI"),
2739 new SpinOption<float> (
2741 _("MIDI read-ahead time (seconds)"),
2742 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2743 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2748 add_option (_("MIDI"), new OptionEditorHeading (_("Session")));
2750 add_option (_("MIDI"),
2751 new SpinOption<int32_t> (
2752 "initial-program-change",
2753 _("Initial program change"),
2754 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2755 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2759 add_option (_("MIDI"), new OptionEditorHeading (_("Audition")));
2761 add_option (_("MIDI"),
2764 _("Sound MIDI notes as they are selected in the editor"),
2765 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2766 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2769 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2770 "midi-audition-synth-uri",
2771 _("MIDI Audition Synth (LV2)"),
2772 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2773 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2776 audition_synth->add(X_(""), _("None"));
2777 PluginInfoList all_plugs;
2778 PluginManager& manager (PluginManager::instance());
2780 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2782 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2783 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2784 if (!(*i)->is_instrument()) continue;
2785 if ((*i)->type != ARDOUR::LV2) continue;
2786 if ((*i)->name.length() > 46) {
2787 audition_synth->add((*i)->unique_id, (*i)->name.substr (0, 44) + "...");
2789 audition_synth->add((*i)->unique_id, (*i)->name);
2794 add_option (_("MIDI"), audition_synth);
2798 add_option (_("Metronome"), new OptionEditorHeading (_("Metronome")));
2799 add_option (_("Metronome"), new ClickOptions (_rc_config));
2803 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2805 ComboOption<float>* mht = new ComboOption<float> (
2807 _("Peak hold time"),
2808 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
2809 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
2812 mht->add (MeterHoldOff, _("off"));
2813 mht->add (MeterHoldShort, _("short"));
2814 mht->add (MeterHoldMedium, _("medium"));
2815 mht->add (MeterHoldLong, _("long"));
2817 add_option (S_("Preferences|Metering"), mht);
2819 ComboOption<float>* mfo = new ComboOption<float> (
2822 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2823 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2826 mfo->add (METER_FALLOFF_OFF, _("off"));
2827 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2828 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2829 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2830 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2831 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2832 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
2834 add_option (S_("Preferences|Metering"), mfo);
2836 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2837 "meter-line-up-level",
2838 _("Meter line-up level; 0dBu"),
2839 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
2840 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
2843 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2844 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2845 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2846 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2848 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."));
2850 add_option (S_("Preferences|Metering"), mlu);
2852 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2853 "meter-line-up-din",
2854 _("IEC1/DIN Meter line-up level; 0dBu"),
2855 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
2856 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
2859 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2860 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2861 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2862 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2864 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2866 add_option (S_("Preferences|Metering"), mld);
2868 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2869 "meter-vu-standard",
2870 _("VU Meter standard"),
2871 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
2872 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
2875 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2876 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2877 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2878 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2880 add_option (S_("Preferences|Metering"), mvu);
2882 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
2883 "meter-type-master",
2884 _("Default Meter Type for Master Bus"),
2885 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
2886 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
2888 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2889 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2890 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2891 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2892 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2893 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2894 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2895 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
2897 add_option (S_("Preferences|Metering"), mtm);
2900 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
2902 _("Default Meter Type for Busses"),
2903 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
2904 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
2906 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2907 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2908 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2909 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2910 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2911 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2912 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2913 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
2915 add_option (S_("Preferences|Metering"), mtb);
2917 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
2919 _("Default Meter Type for Tracks"),
2920 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
2921 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
2923 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2924 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
2926 add_option (S_("Preferences|Metering"), mtt);
2928 HSliderOption *mpks = new HSliderOption("meter-peak",
2929 _("Peak threshold [dBFS]"),
2930 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
2931 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak),
2935 Gtkmm2ext::UI::instance()->set_tip (
2937 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
2939 add_option (S_("Preferences|Metering"), mpks);
2941 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
2943 add_option (S_("Preferences|Metering"),
2945 "save-export-analysis-image",
2946 _("Save loudness analysis as image file"),
2947 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
2948 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
2951 /* TRANSPORT & Sync */
2953 add_option (_("Transport"), new OptionEditorHeading (_("General")));
2955 bo = new BoolOption (
2956 "stop-at-session-end",
2957 _("Stop at the end of the session"),
2958 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
2959 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
2961 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2962 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
2963 "when it reaches the current session end marker\n\n"
2964 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
2966 add_option (_("Transport"), bo);
2968 bo = new BoolOption (
2969 "latched-record-enable",
2970 _("Keep record-enable engaged on stop"),
2971 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
2972 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
2974 add_option (_("Transport"), bo);
2975 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2976 _("<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."));
2978 bo = new BoolOption (
2979 "disable-disarm-during-roll",
2980 _("Disable per-track record disarm while rolling"),
2981 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
2982 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
2984 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."));
2985 add_option (_("Transport"), bo);
2987 bo = new BoolOption (
2989 _("12dB gain reduction during fast-forward and fast-rewind"),
2990 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
2991 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2993 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2994 _("<b>When enabled</b> rhis will reduce the unpleasant increase in perceived volume "
2995 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2996 add_option (_("Transport"), bo);
2998 ComboOption<float>* psc = new ComboOption<float> (
3001 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
3002 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
3004 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
3005 (_("The amount of preroll to apply when <b>Play with Preroll</b> or <b>Record with Preroll</b>is initiated.\n\n"
3006 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
3007 psc->add (-4.0, _("4 Bars"));
3008 psc->add (-2.0, _("2 Bars"));
3009 psc->add (-1.0, _("1 Bar"));
3010 psc->add (0.0, _("0 (no pre-roll)"));
3011 psc->add (0.1, _("0.1 second"));
3012 psc->add (0.25, _("0.25 second"));
3013 psc->add (0.5, _("0.5 second"));
3014 psc->add (1.0, _("1.0 second"));
3015 psc->add (2.0, _("2.0 seconds"));
3016 add_option (_("Transport"), psc);
3019 add_option (_("Transport"), new OptionEditorHeading (_("Looping")));
3021 bo = new BoolOption (
3023 _("Play loop is a transport mode"),
3024 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
3025 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
3027 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3028 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
3029 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
3030 add_option (_("Transport"), bo);
3032 bo = new BoolOption (
3034 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
3035 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
3036 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
3038 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3039 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
3040 "preventing any need to do a transport locate at the end of the loop\n\n"
3041 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
3042 "which will often cause a small click or delay"), PROGRAM_NAME));
3043 add_option (_("Transport"), bo);
3045 add_option (_("Transport"), new OptionEditorHeading (_("Dropout (xrun) Handling")));
3046 bo = new BoolOption (
3047 "stop-recording-on-xrun",
3048 _("Stop recording when an xrun occurs"),
3049 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
3050 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
3052 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3053 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
3055 add_option (_("Transport"), bo);
3057 bo = new BoolOption (
3058 "create-xrun-marker",
3059 _("Create markers where xruns occur"),
3060 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
3061 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
3063 add_option (_("Transport"), bo);
3068 add_option (_("Sync"), new OptionEditorHeading (_("External Syncronization")));
3070 _sync_source = new ComboOption<SyncSource> (
3072 _("External timecode source"),
3073 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
3074 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
3077 add_option (_("Sync"), _sync_source);
3079 _sync_framerate = new BoolOption (
3080 "timecode-sync-frame-rate",
3081 _("Match session video frame rate to external timecode"),
3082 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
3083 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
3085 Gtkmm2ext::UI::instance()->set_tip
3086 (_sync_framerate->tip_widget(),
3087 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
3088 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
3089 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
3090 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
3091 "timecode standard and the session standard."), PROGRAM_NAME));
3093 add_option (_("Sync"), _sync_framerate);
3095 _sync_genlock = new BoolOption (
3096 "timecode-source-is-synced",
3097 _("Sync-lock timecode to clock (disable drift compensation)"),
3098 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
3099 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
3101 Gtkmm2ext::UI::instance()->set_tip
3102 (_sync_genlock->tip_widget(),
3103 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
3104 "Sync Lock indicates that the selected external timecode source shares clock-sync "
3105 "(Black & Burst, Wordclock, etc) with the audio interface. "
3106 "This option disables drift compensation. The transport speed is fixed at 1.0. "
3107 "Vari-speed LTC will be ignored and cause drift."
3109 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
3110 "timecode sources shares clock sync."
3114 add_option (_("Sync"), _sync_genlock);
3116 _sync_source_2997 = new BoolOption (
3117 "timecode-source-2997",
3118 _("Lock to 29.9700 fps instead of 30000/1001"),
3119 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
3120 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
3122 Gtkmm2ext::UI::instance()->set_tip
3123 (_sync_source_2997->tip_widget(),
3124 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
3125 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
3126 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
3127 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
3128 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
3129 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
3132 add_option (_("Sync"), _sync_source_2997);
3134 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Reader")));
3136 _ltc_port = new ComboStringOption (
3138 _("LTC incoming port"),
3139 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
3140 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
3143 vector<string> physical_inputs;
3144 physical_inputs.push_back (_("None"));
3145 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
3146 _ltc_port->set_popdown_strings (physical_inputs);
3148 populate_sync_options ();
3149 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
3151 add_option (_("Sync/LTC"), _ltc_port);
3153 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Generator")));
3155 add_option (_("Sync/LTC"),
3158 _("Enable LTC generator"),
3159 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
3160 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
3163 _ltc_send_continuously = new BoolOption (
3164 "ltc-send-continuously",
3165 _("Send LTC while stopped"),
3166 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
3167 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
3169 Gtkmm2ext::UI::instance()->set_tip
3170 (_ltc_send_continuously->tip_widget(),
3171 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
3172 add_option (_("Sync/LTC"), _ltc_send_continuously);
3174 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level [dBFS]"),
3175 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_output_volume),
3176 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_output_volume),
3180 Gtkmm2ext::UI::instance()->set_tip
3181 (_ltc_volume_slider->tip_widget(),
3182 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
3184 add_option (_("Sync/LTC"), _ltc_volume_slider);
3187 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Beat Clock (Mclk) Generator")));
3189 add_option (_("Sync/MIDI"),
3192 _("Enable Mclk generator"),
3193 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
3194 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
3197 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC) Generator")));
3199 add_option (_("Sync/MIDI"),
3202 _("Enable MTC Generator"),
3203 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
3204 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
3207 add_option (_("Sync/MIDI"),
3208 new SpinOption<int> (
3209 "mtc-qf-speed-tolerance",
3210 _("Percentage either side of normal transport speed to transmit MTC"),
3211 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
3212 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
3216 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Machine Control (MMC)")));
3218 add_option (_("Sync/MIDI"),
3221 _("Respond to MMC commands"),
3222 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
3223 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
3226 add_option (_("Sync/MIDI"),
3229 _("Send MMC commands"),
3230 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
3231 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
3234 add_option (_("Sync/MIDI"),
3235 new SpinOption<uint8_t> (
3236 "mmc-receive-device-id",
3237 _("Inbound MMC device ID"),
3238 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
3239 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
3243 add_option (_("Sync/MIDI"),
3244 new SpinOption<uint8_t> (
3245 "mmc-send-device-id",
3246 _("Outbound MMC device ID"),
3247 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
3248 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
3253 /* Control Surfaces */
3255 add_option (_("Control Surfaces"), new OptionEditorHeading (_("Control Surfaces")));
3256 add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
3259 add_option (_("MIDI Ports"), new OptionEditorHeading (_("MIDI Port Options")));
3261 add_option (_("MIDI Ports"),
3263 "get-midi-input-follows-selection",
3264 _("MIDI input follows MIDI track selection"),
3265 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
3266 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
3269 add_option (_("MIDI Ports"), new MidiPortOptions ());
3270 add_option (_("MIDI Ports"), new OptionEditorBlank ());
3274 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3275 add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
3276 add_option (_("Plugins"),
3277 new RcActionButton (_("Scan for Plugins"),
3278 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3282 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
3284 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3285 bo = new BoolOption (
3286 "show-plugin-scan-window",
3287 _("Always Display Plugin Scan Progress"),
3288 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
3289 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
3291 add_option (_("Plugins"), bo);
3292 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3293 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
3296 bo = new BoolOption (
3297 "plugins-stop-with-transport",
3298 _("Silence plugins when the transport is stopped"),
3299 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
3300 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
3302 add_option (_("Plugins"), bo);
3303 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3304 _("<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."));
3306 bo = new BoolOption (
3307 "new-plugins-active",
3308 _("Make new plugins active"),
3309 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
3310 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
3312 add_option (_("Plugins"), bo);
3313 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3314 _("<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"));
3316 #if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
3317 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
3319 add_option (_("Plugins/VST"),
3320 new RcActionButton (_("Scan for Plugins"),
3321 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3324 #if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
3325 bo = new BoolOption (
3327 _("Enable Mac VST support (requires restart or re-scan)"),
3328 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
3329 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
3331 add_option (_("Plugins/VST"), bo);
3334 bo = new BoolOption (
3335 "discover-vst-on-start",
3336 _("Scan for [new] VST Plugins on Application Start"),
3337 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
3338 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
3340 add_option (_("Plugins/VST"), bo);
3341 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3342 _("<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"));
3344 #ifdef WINDOWS_VST_SUPPORT
3345 // currently verbose logging is only implemented for Windows VST.
3346 bo = new BoolOption (
3347 "verbose-plugin-scan",
3348 _("Verbose Plugin Scan"),
3349 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
3350 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
3352 add_option (_("Plugins/VST"), bo);
3353 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3354 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
3357 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
3359 add_option (_("Plugins/VST"),
3360 new RcActionButton (_("Clear"),
3361 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
3364 add_option (_("Plugins/VST"),
3365 new RcActionButton (_("Clear"),
3366 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
3367 _("VST Blacklist:")));
3370 #ifdef LXVST_SUPPORT
3371 add_option (_("Plugins/VST"),
3372 new RcActionButton (_("Edit"),
3373 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
3374 _("Linux VST Path:")));
3376 add_option (_("Plugins/VST"),
3377 new RcConfigDisplay (
3378 "plugin-path-lxvst",
3380 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
3384 #ifdef WINDOWS_VST_SUPPORT
3385 add_option (_("Plugins/VST"),
3386 new RcActionButton (_("Edit"),
3387 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
3388 _("Windows VST Path:")));
3389 add_option (_("Plugins/VST"),
3390 new RcConfigDisplay (
3393 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
3397 #ifdef AUDIOUNIT_SUPPORT
3399 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
3401 add_option (_("Plugins/Audio Unit"),
3402 new RcActionButton (_("Scan for Plugins"),
3403 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3406 bo = new BoolOption (
3407 "discover-audio-units",
3408 _("Scan for [new] AudioUnit Plugins on Application Start"),
3409 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
3410 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
3412 add_option (_("Plugins/Audio Unit"), bo);
3413 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3414 _("<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."));
3416 add_option (_("Plugins/Audio Unit"),
3417 new RcActionButton (_("Clear"),
3418 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
3421 add_option (_("Plugins/Audio Unit"),
3422 new RcActionButton (_("Clear"),
3423 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
3424 _("AU Blacklist:")));
3427 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
3428 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
3429 add_option (_("Plugins"),
3431 "open-gui-after-adding-plugin",
3432 _("Automatically open the plugin GUI when adding a new plugin"),
3433 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
3434 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3437 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3438 add_option (_("Plugins"),
3440 "show-inline-display-by-default",
3441 _("Show Plugin Inline Display on Mixerstrip by default"),
3442 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3443 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3446 _plugin_prefer_inline = new BoolOption (
3447 "prefer-inline-over-gui",
3448 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3449 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3450 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3452 add_option (_("Plugins"), _plugin_prefer_inline);
3455 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3457 bo = new BoolOption (
3458 "ask-replace-instrument",
3459 _("Ask to replace existing instrument plugin"),
3460 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3461 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3463 add_option (_("Plugins"), bo);
3465 bo = new BoolOption (
3466 "ask-setup_instrument",
3467 _("Interactively configure instrument plugins on insert"),
3468 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3469 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3471 add_option (_("Plugins"), bo);
3472 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3473 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3476 add_option (_("Plugins"), new OptionEditorBlank ());
3479 #if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
3480 add_option (_("Appearance"), new OptionEditorHeading (_("Graphics Acceleration")));
3483 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3484 BoolOption* bgc = new BoolOption (
3485 "cairo-image-surface",
3486 _("Disable Graphics Hardware Acceleration (requires restart)"),
3487 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3488 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3491 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3492 _("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));
3493 add_option (_("Appearance"), bgc);
3496 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3497 BoolOption* bgo = new BoolOption (
3499 _("Possibly improve slow graphical performance (requires restart)"),
3500 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3501 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3504 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));
3505 add_option (_("Appearance"), bgo);
3507 add_option (_("Appearance"), new OptionEditorHeading (_("Graphical User Interface")));
3509 add_option (_("Appearance"),
3512 _("Highlight widgets on mouseover"),
3513 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3514 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3517 add_option (_("Appearance"),
3520 _("Show tooltips if mouse hovers over a control"),
3521 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3522 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3525 bo = new BoolOption (
3526 "super-rapid-clock-update",
3527 _("Update clocks at TC Frame rate"),
3528 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3529 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3531 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3532 _("<b>When enabled</b> clock displays are updated every Timecode Frame (fps).\n\n"
3533 "<b>When disabled</b> clock displays are updated only every 100ms."
3535 add_option (_("Appearance"), bo);
3537 add_option (_("Appearance"),
3540 _("Blink Rec-Arm buttons"),
3541 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_rec_arm),
3542 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_rec_arm)
3547 /* font scaling does nothing with GDK/Quartz */
3548 add_option (_("Appearance"), new FontScalingOptions ());
3550 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("General")));
3551 add_option (_("Appearance/Editor"),
3553 "show-name-highlight",
3554 _("Use name highlight bars in region displays (requires a restart)"),
3555 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3556 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3559 add_option (_("Appearance/Editor"),
3561 "color-regions-using-track-color",
3562 _("Region color follows track color"),
3563 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_color_regions_using_track_color),
3564 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_color_regions_using_track_color)
3567 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Waveforms")));
3569 if (!Profile->get_mixbus()) {
3570 add_option (_("Appearance/Editor"),
3573 _("Show waveforms in regions"),
3574 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
3575 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
3579 add_option (_("Appearance/Editor"),
3581 "show-waveforms-while-recording",
3582 _("Show waveforms while recording"),
3583 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
3584 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
3587 add_option (_("Appearance/Editor"),
3589 "show-waveform-clipping",
3590 _("Show waveform clipping"),
3591 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveform_clipping),
3592 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveform_clipping)
3595 add_option (_("Appearance/Editor"), new ClipLevelOptions ());
3597 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
3599 _("Waveform scale"),
3600 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
3601 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
3604 wfs->add (Linear, _("linear"));
3605 wfs->add (Logarithmic, _("logarithmic"));
3607 add_option (_("Appearance/Editor"), wfs);
3609 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
3611 _("Waveform shape"),
3612 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
3613 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
3616 wfsh->add (Traditional, _("traditional"));
3617 wfsh->add (Rectified, _("rectified"));
3619 add_option (_("Appearance/Editor"), wfsh);
3621 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Editor Meters")));
3623 add_option (_("Appearance/Editor"),
3625 "show-track-meters",
3626 _("Show meters in track headers"),
3627 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3628 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3631 add_option (_("Appearance/Editor"),
3633 "editor-stereo-only-meters",
3634 _("Limit track header meters to stereo"),
3635 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3636 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3639 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("MIDI Regions")));
3641 add_option (_("Appearance/Editor"),
3643 "display-first-midi-bank-as-zero",
3644 _("Display first MIDI bank/program as 0"),
3645 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
3646 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
3649 add_option (_("Appearance/Editor"),
3651 "never-display-periodic-midi",
3652 _("Don't display periodic (MTC, MMC) SysEx messages in MIDI Regions"),
3653 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
3654 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
3657 add_option (_("Appearance/Editor"), new OptionEditorBlank ());
3659 /* The names of these controls must be the same as those given in MixerStrip
3660 for the actual widgets being controlled.
3662 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3663 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3664 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3665 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3666 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3667 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3668 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3670 add_option (_("Appearance/Mixer"),
3671 new VisibilityOption (
3673 &_mixer_strip_visibility,
3674 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3675 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3679 add_option (_("Appearance/Mixer"),
3681 "default-narrow_ms",
3682 _("Use narrow strips in the mixer by default"),
3683 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3684 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3687 add_option (_("Appearance/Mixer"), new OptionEditorBlank ());
3689 add_option (_("Appearance/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items")));
3691 add_option (_("Appearance/Toolbar"),
3693 "show-toolbar-recpunch",
3694 _("Display Record/Punch Options"),
3695 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_recpunch),
3696 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_recpunch)
3699 add_option (_("Appearance/Toolbar"),
3701 "show-toolbar-monitoring",
3702 _("Display Monitor Options"),
3703 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_monitoring),
3704 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_monitoring)
3707 add_option (_("Appearance/Toolbar"),
3709 "show-toolbar-selclock",
3710 _("Display Selection Clock"),
3711 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
3712 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
3715 if (!ARDOUR::Profile->get_small_screen()) {
3716 add_option (_("Appearance/Toolbar"),
3718 "show-secondary-clock",
3719 _("Display Secondary Clock"),
3720 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
3721 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
3725 add_option (_("Appearance/Toolbar"),
3727 "show-mini-timeline",
3728 _("Display Navigation Timeline"),
3729 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
3730 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
3733 add_option (_("Appearance/Toolbar"),
3735 "show-editor-meter",
3736 _("Display Master Level Meter"),
3737 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
3738 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
3741 add_option (_("Appearance/Toolbar"),
3742 new ColumVisibilityOption (
3743 "action-table-columns", _("Lua Action Script Button Visibility"), 4,
3744 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3745 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3748 add_option (_("Appearance/Toolbar"), new OptionEditorBlank ());
3751 OptionEditorHeading* quirks_head = new OptionEditorHeading (_("Various Workarounds for Windowing Systems"));
3753 quirks_head->set_note (string_compose (_("Rules for closing, minimizing, maximizing, and stay-on-top can vary\n\
3754 with each version of your OS, and the preferences that you've set in your OS.\n\n\
3755 You can adjust the options, below, to change how %1's windows and dialogs behave.\n\n\
3756 These settings will only take effect after %1 is restarted.\n\
3759 /* and now the theme manager */
3761 add_option (_("Appearance/Theme"), new OptionEditorHeading (_("Theme")));
3763 add_option (_("Appearance/Theme"), new BoolOption (
3765 _("Draw \"flat\" buttons"),
3766 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_flat_buttons),
3767 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_flat_buttons)
3770 add_option (_("Appearance/Theme"), new BoolOption (
3772 _("LED meter style"),
3773 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3774 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3778 HSliderOption *gui_hs = new HSliderOption(
3779 "timeline-item-gradient-depth",
3780 _("Waveforms color gradient depth"),
3781 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_gradient_depth),
3782 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_gradient_depth),
3785 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3786 add_option (_("Appearance/Theme"), gui_hs);
3788 gui_hs = new HSliderOption(
3789 "timeline-item-gradient-depth",
3790 _("Timeline item gradient depth"),
3791 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_timeline_item_gradient_depth),
3792 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_timeline_item_gradient_depth),
3795 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3796 add_option (_("Appearance/Theme"), gui_hs);
3798 vector<string> icon_sets = ::get_icon_sets ();
3799 if (icon_sets.size() > 1) {
3800 ComboOption<std::string>* io = new ComboOption<std::string> (
3801 "icon-set", _("Icon Set"),
3802 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_icon_set),
3803 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_icon_set)
3805 for (vector<string>::const_iterator i = icon_sets.begin (); i != icon_sets.end (); ++i) {
3808 add_option (_("Appearance/Theme"), io);
3811 add_option (_("Appearance/Colors"), new OptionEditorHeading (_("Colors")));
3812 add_option (_("Appearance/Colors"), new ColorThemeManager);
3813 add_option (_("Appearance/Colors"), new OptionEditorBlank ());
3817 add_option (_("Appearance/Quirks"), quirks_head);
3819 bo = new BoolOption (
3820 "use-wm-visibility",
3821 _("Use visibility information provided by your Window Manager/Desktop"),
3822 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3823 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3825 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3826 _("If you have trouble toggling between hidden Editor and Mixer windows, try changing this setting."));
3827 add_option (_("Appearance/Quirks"), bo);
3830 bo = new BoolOption (
3831 "all-floating-windows-are-dialogs",
3832 _("All floating windows are dialogs"),
3833 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_all_floating_windows_are_dialogs),
3834 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_all_floating_windows_are_dialogs)
3836 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3837 _("Mark all floating windows to be type \"Dialog\" rather than using \"Utility\" for some.\nThis may help with some window managers."));
3838 add_option (_("Appearance/Quirks"), bo);
3840 bo = new BoolOption (
3841 "transients-follow-front",
3842 _("Transient windows follow front window."),
3843 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_transients_follow_front),
3844 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_transients_follow_front)
3846 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3847 _("Make transient windows follow the front window when toggling between the editor and mixer."));
3848 add_option (_("Appearance/Quirks"), bo);
3851 if (!Profile->get_mixbus()) {
3852 bo = new BoolOption (
3853 "floating-monitor-section",
3854 _("Float detached monitor-section window"),
3855 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_floating_monitor_section),
3856 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_floating_monitor_section)
3858 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3859 _("When detaching the monitoring section, mark it as \"Utility\" window to stay in front."));
3860 add_option (_("Appearance/Quirks"), bo);
3863 add_option (_("Appearance/Quirks"), new OptionEditorBlank ());
3865 /* VIDEO Timeline */
3866 add_option (_("Video"), new OptionEditorHeading (_("Video Server")));
3867 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
3869 Widget::show_all ();
3871 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3872 parameter_changed ("send-ltc");
3873 parameter_changed ("sync-source");
3874 parameter_changed ("use-monitor-bus");
3875 parameter_changed ("open-gui-after-adding-plugin");
3877 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
3879 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
3880 (Gtk::StateType) here !!!
3882 Tabbable::set_state (*node, Stateful::loading_state_version);
3885 set_current_page (_("General"));
3889 RCOptionEditor::parameter_changed (string const & p)
3891 OptionEditor::parameter_changed (p);
3893 if (p == "use-monitor-bus") {
3894 bool const s = Config->get_use_monitor_bus ();
3896 /* we can't use this if we don't have a monitor bus */
3897 Config->set_solo_control_is_listen_control (false);
3899 _solo_control_is_listen_control->set_sensitive (s);
3900 _listen_position->set_sensitive (s);
3901 } else if (p == "sync-source") {
3902 _sync_source->set_sensitive (true);
3904 _sync_source->set_sensitive (!_session->config.get_external_sync());
3906 switch(Config->get_sync_source()) {
3909 _sync_genlock->set_sensitive (true);
3910 _sync_framerate->set_sensitive (true);
3911 _sync_source_2997->set_sensitive (true);
3914 _sync_genlock->set_sensitive (false);
3915 _sync_framerate->set_sensitive (false);
3916 _sync_source_2997->set_sensitive (false);
3919 } else if (p == "send-ltc") {
3920 bool const s = Config->get_send_ltc ();
3921 _ltc_send_continuously->set_sensitive (s);
3922 _ltc_volume_slider->set_sensitive (s);
3923 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
3924 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3925 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
3928 } else if (p == "enable-translation") {
3929 _l10n->set_sensitive (ARDOUR::translations_are_enabled ());
3934 void RCOptionEditor::plugin_scan_refresh () {
3935 PluginManager::instance().refresh();
3938 void RCOptionEditor::clear_vst_cache () {
3939 PluginManager::instance().clear_vst_cache();
3942 void RCOptionEditor::clear_vst_blacklist () {
3943 PluginManager::instance().clear_vst_blacklist();
3946 void RCOptionEditor::clear_au_cache () {
3947 PluginManager::instance().clear_au_cache();
3950 void RCOptionEditor::clear_au_blacklist () {
3951 PluginManager::instance().clear_au_blacklist();
3954 void RCOptionEditor::edit_lxvst_path () {
3955 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
3956 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3957 *current_toplevel(), _("Set Linux VST Search Path"),
3958 _rc_config->get_plugin_path_lxvst(),
3959 PluginManager::instance().get_default_lxvst_path()
3961 ResponseType r = (ResponseType) pd->run ();
3963 if (r == RESPONSE_ACCEPT) {
3964 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
3969 void RCOptionEditor::edit_vst_path () {
3970 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3971 *current_toplevel(), _("Set Windows VST Search Path"),
3972 _rc_config->get_plugin_path_vst(),
3973 PluginManager::instance().get_default_windows_vst_path()
3975 ResponseType r = (ResponseType) pd->run ();
3977 if (r == RESPONSE_ACCEPT) {
3978 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
3985 RCOptionEditor::populate_sync_options ()
3987 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3989 _sync_source->clear ();
3991 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3992 _sync_source->add (*i, sync_source_to_string (*i));
3995 if (sync_opts.empty()) {
3996 _sync_source->set_sensitive(false);
3998 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3999 _rc_config->set_sync_source(sync_opts.front());
4003 parameter_changed ("sync-source");
4007 RCOptionEditor::use_own_window (bool and_fill_it)
4009 bool new_window = !own_window ();
4011 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
4013 if (win && new_window) {
4014 win->set_name ("PreferencesWindow");
4015 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
4017 win->set_resizable (false);
4024 RCOptionEditor::get_state ()
4026 XMLNode* node = new XMLNode (X_("Preferences"));
4027 node->add_child_nocopy (Tabbable::get_state());