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 Settings"));
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")
2119 , false // detached by default (first start, no instant.xml)
2121 ) /* pack self-as-vbox into tabbable */
2122 , _rc_config (Config)
2123 , _mixer_strip_visibility ("mixer-element-visibility")
2125 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
2129 uint32_t hwcpus = hardware_concurrency ();
2131 BoolComboOption* bco;
2134 add_option (_("General"), new OptionEditorHeading (_("DSP CPU Utilization")));
2136 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
2138 _("Signal processing uses"),
2139 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
2140 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
2143 procs->add (-1, _("all but one processor"));
2144 procs->add (0, _("all available processors"));
2146 for (uint32_t i = 1; i <= hwcpus; ++i) {
2147 procs->add (i, string_compose (P_("%1 processor", "%1 processors", i), i));
2150 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
2152 add_option (_("General"), procs);
2155 /* Image cache size */
2156 add_option (_("General"), new OptionEditorHeading (_("Memory Usage")));
2158 HSliderOption *sics = new HSliderOption ("waveform-cache-size",
2159 _("Waveform image cache size (megabytes)"),
2160 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
2161 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size),
2162 1, 1024, 10 /* 1 MB to 1GB in steps of 10MB */
2164 sics->scale().set_digits (0);
2165 Gtkmm2ext::UI::instance()->set_tip (
2167 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
2168 add_option (_("General"), sics);
2170 add_option (_("General"), new OptionEditorHeading (_("Engine")));
2172 add_option (_("General"),
2174 "try-autostart-engine",
2175 _("Try to auto-launch audio/midi engine"),
2176 sigc::mem_fun (*_rc_config, &RCConfiguration::get_try_autostart_engine),
2177 sigc::mem_fun (*_rc_config, &RCConfiguration::set_try_autostart_engine)
2180 add_option (_("General"), new OptionEditorHeading (_("Automation")));
2182 add_option (_("General"),
2183 new SpinOption<double> (
2184 "automation-thinning-factor",
2185 _("Thinning factor (larger value => less data)"),
2186 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
2187 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
2191 add_option (_("General"),
2192 new SpinOption<double> (
2193 "automation-interval-msecs",
2194 _("Automation sampling interval (milliseconds)"),
2195 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
2196 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
2200 add_option (_("General"), new OptionEditorHeading (_("Tempo")));
2202 bo = new BoolOption (
2203 "allow-non-quarter-pulse",
2204 _("Allow non quarter-note pulse"),
2205 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_allow_non_quarter_pulse),
2206 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_allow_non_quarter_pulse)
2208 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2209 string_compose (_("<b>When enabled</b> %1 will allow tempo to be expressed in divisions per minute\n"
2210 "<b>When disabled</b> %1 will only allow tempo to be expressed in quarter notes per minute"),
2212 add_option (_("General"), bo);
2214 if (!ARDOUR::Profile->get_mixbus()) {
2215 add_option (_("General"), new OptionEditorHeading (_("GUI Lock")));
2216 /* Lock GUI timeout */
2218 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2219 _("Lock timeout (seconds)"),
2220 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
2221 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds),
2224 slts->scale().set_digits (0);
2225 Gtkmm2ext::UI::instance()->set_tip (
2227 _("Lock GUI after this many idle seconds (zero to never lock)"));
2228 add_option (_("General"), slts);
2231 add_option (_("General/Session"), new OptionEditorHeading (S_("Options|Undo")));
2233 add_option (_("General/Session"), new UndoOptions (_rc_config));
2235 add_option (_("General/Session"),
2237 "verify-remove-last-capture",
2238 _("Verify removal of last capture"),
2239 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
2240 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
2243 add_option (_("General/Session"), new OptionEditorHeading (_("Session Management")));
2245 add_option (_("General/Session"),
2247 "periodic-safety-backups",
2248 _("Make periodic backups of the session file"),
2249 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
2250 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
2253 add_option (_("General/Session"),
2255 "only-copy-imported-files",
2256 _("Always copy imported files"),
2257 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
2258 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
2261 add_option (_("General/Session"), new DirectoryOption (
2262 X_("default-session-parent-dir"),
2263 _("Default folder for new sessions:"),
2264 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
2265 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
2268 add_option (_("General/Session"),
2269 new SpinOption<uint32_t> (
2270 "max-recent-sessions",
2271 _("Maximum number of recent sessions"),
2272 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
2273 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
2280 add_option (_("General/Translation"), new OptionEditorHeading (_("Internationalization")));
2282 bo = new BoolOption (
2283 "enable-translation",
2284 _("Use translations"),
2285 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2286 sigc::ptr_fun (ARDOUR::set_translations_enabled)
2289 bo->set_note (string_compose (_("These settings will only take effect after %1 is restarted (if available for your language preferences)."), PROGRAM_NAME));
2291 add_option (_("General/Translation"), bo);
2293 _l10n = new ComboOption<ARDOUR::LocaleMode> (
2296 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_locale_mode),
2297 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_locale_mode)
2300 _l10n->add (ARDOUR::SET_LC_ALL, _("Set complete locale"));
2301 _l10n->add (ARDOUR::SET_LC_MESSAGES, _("Enable only message translation"));
2302 _l10n->add (ARDOUR::SET_LC_MESSAGES_AND_LC_NUMERIC, _("Translate messages and format numeric format"));
2303 _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."));
2305 add_option (_("General/Translation"), _l10n);
2306 parameter_changed ("enable-translation");
2307 #endif // ENABLE_NLS
2312 add_option (_("Editor"), new OptionEditorHeading (_("General")));
2314 add_option (_("Editor"),
2316 "rubberbanding-snaps-to-grid",
2317 _("Snap rubberband to grid"),
2318 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2319 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2322 bo = new BoolOption (
2324 _("Prompt for new marker names"),
2325 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2326 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2328 add_option (_("Editor"), bo);
2329 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."
2330 "\n\nYou can always rename markers by right-clicking on them"));
2332 add_option (_("Editor"),
2334 "draggable-playhead",
2335 _("Allow dragging of playhead"),
2336 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2337 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2340 if (!Profile->get_mixbus()) {
2342 add_option (_("Editor"),
2344 "use-mouse-position-as-zoom-focus-on-scroll",
2345 _("Zoom to mouse position when zooming with scroll wheel"),
2346 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2347 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2351 add_option (_("Editor"),
2353 "use-time-rulers-to-zoom-with-vertical-drag",
2354 _("Zoom with vertical drag in rulers"),
2355 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag),
2356 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag)
2359 add_option (_("Editor"),
2361 "use-double-click-to-zoom-to-selection",
2362 _("Double click zooms to selection"),
2363 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection),
2364 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection)
2367 add_option (_("Editor"),
2369 "update-editor-during-summary-drag",
2370 _("Update editor window during drags of the summary"),
2371 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2372 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2375 add_option (_("Editor"),
2377 "autoscroll-editor",
2378 _("Auto-scroll editor window when dragging near its edges"),
2379 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2380 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2383 add_option (_("Editor"),
2384 new BoolComboOption (
2385 "show-region-gain-envelopes",
2386 _("Show gain envelopes in audio regions"),
2388 _("only in Draw and Internal Edit modes"),
2389 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2390 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2393 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2395 add_option (_("Editor"),
2397 "automation-follows-regions",
2398 _("Move relevant automation when audio regions are moved"),
2399 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2400 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2403 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2404 "default-fade-shape",
2405 _("Default fade shape"),
2406 sigc::mem_fun (*_rc_config,
2407 &RCConfiguration::get_default_fade_shape),
2408 sigc::mem_fun (*_rc_config,
2409 &RCConfiguration::set_default_fade_shape)
2412 fadeshape->add (FadeLinear,
2413 _("Linear (for highly correlated material)"));
2414 fadeshape->add (FadeConstantPower, _("Constant power"));
2415 fadeshape->add (FadeSymmetric, _("Symmetric"));
2416 fadeshape->add (FadeSlow, _("Slow"));
2417 fadeshape->add (FadeFast, _("Fast"));
2419 add_option (_("Editor"), fadeshape);
2421 bco = new BoolComboOption (
2422 "use-overlap-equivalency",
2423 _("Regions in edit groups are edited together"),
2424 _("whenever they overlap in time"),
2425 _("only if they have identical length and position"),
2426 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2427 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2430 add_option (_("Editor"), bco);
2432 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2434 _("Layering model"),
2435 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2436 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2439 lm->add (LaterHigher, _("later is higher"));
2440 lm->add (Manual, _("manual layering"));
2441 add_option (_("Editor"), lm);
2443 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2444 "region-selection-after-split",
2445 _("After splitting selected regions, select"),
2446 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2447 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2449 // TODO: decide which of these modes are really useful
2450 rsas->add(None, _("no regions"));
2451 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2452 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2453 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2454 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2455 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2456 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2457 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2459 add_option (_("Editor"), rsas);
2461 add_option (_("Editor/Modifiers"), new OptionEditorHeading (_("Keyboard Modifiers")));
2462 add_option (_("Editor/Modifiers"), new KeyboardOptions);
2463 add_option (_("Editor/Modifiers"), new OptionEditorBlank ());
2465 /* MIXER -- SOLO AND MUTE */
2467 add_option (_("Mixer"), new OptionEditorHeading (_("Solo")));
2469 _solo_control_is_listen_control = new BoolOption (
2470 "solo-control-is-listen-control",
2471 _("Solo controls are Listen controls"),
2472 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2473 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2476 add_option (_("Mixer"), _solo_control_is_listen_control);
2478 add_option (_("Mixer"),
2481 _("Exclusive solo"),
2482 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2483 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2486 add_option (_("Mixer"),
2489 _("Show solo muting"),
2490 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2491 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2494 add_option (_("Mixer"),
2496 "solo-mute-override",
2497 _("Soloing overrides muting"),
2498 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2499 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2502 add_option (_("Mixer"),
2505 _("Solo-in-place mute cut (dB)"),
2506 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2507 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2510 _listen_position = new ComboOption<ListenPosition> (
2512 _("Listen Position"),
2513 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2514 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2517 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2518 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2520 add_option (_("Mixer"), _listen_position);
2522 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2524 _("PFL signals come from"),
2525 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2526 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2529 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2530 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2532 add_option (_("Mixer"), pp);
2534 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2536 _("AFL signals come from"),
2537 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2538 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2541 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2542 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2544 add_option (_("Mixer"), pa);
2546 add_option (_("Mixer"), new OptionEditorHeading (_("Default Track / Bus Muting Options")));
2548 add_option (_("Mixer"),
2550 "mute-affects-pre-fader",
2551 _("Mute affects pre-fader sends"),
2552 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2553 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2556 add_option (_("Mixer"),
2558 "mute-affects-post-fader",
2559 _("Mute affects post-fader sends"),
2560 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2561 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2564 add_option (_("Mixer"),
2566 "mute-affects-control-outs",
2567 _("Mute affects control outputs"),
2568 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2569 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2572 add_option (_("Mixer"),
2574 "mute-affects-main-outs",
2575 _("Mute affects main outputs"),
2576 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2577 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2581 if (!ARDOUR::Profile->get_mixbus()) {
2582 add_option (_("Mixer"), new OptionEditorHeading (_("Send Routing")));
2583 add_option (_("Mixer"),
2585 "link-send-and-route-panner",
2586 _("Link panners of Aux and External Sends with main panner by default"),
2587 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2588 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2594 add_option (_("Signal Flow"), new OptionEditorHeading (_("Monitoring")));
2596 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2598 _("Record monitoring handled by"),
2599 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2600 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2603 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2604 mm->add (HardwareMonitoring, _("via Audio Driver"));
2607 string prog (PROGRAM_NAME);
2608 boost::algorithm::to_lower (prog);
2609 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2610 mm->add (ExternalMonitoring, _("audio hardware"));
2612 add_option (_("Signal Flow"), mm);
2614 bo = new BoolOption (
2615 "tape-machine-mode",
2616 _("Tape machine mode"),
2617 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2618 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2620 add_option (_("Signal Flow"), bo);
2621 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2622 string_compose (_("<b>When enabled</b> %1 will not monitor a track's input if the transport is stopped."),
2625 if (!Profile->get_mixbus()) {
2627 add_option (_("Signal Flow"), new OptionEditorHeading (_("Track and Bus Connections")));
2629 add_option (_("Signal Flow"),
2631 "auto-connect-standard-busses",
2632 _("Auto-connect master/monitor busses"),
2633 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2634 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2637 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2638 "input-auto-connect",
2639 _("Connect track inputs"),
2640 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2641 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2644 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2645 iac->add (ManualConnect, _("manually"));
2647 add_option (_("Signal Flow"), iac);
2649 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2650 "output-auto-connect",
2651 _("Connect track and bus outputs"),
2652 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2653 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2656 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2657 oac->add (AutoConnectMaster, _("automatically to master bus"));
2658 oac->add (ManualConnect, _("manually"));
2660 add_option (_("Signal Flow"), oac);
2662 bo = new BoolOption (
2664 _("Use 'Strict-I/O' for new tracks or Busses"),
2665 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2666 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2669 add_option (_("Signal Flow"), bo);
2670 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2671 _("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."));
2678 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2680 add_option (_("Audio"), new BufferingOptions (_rc_config));
2682 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2684 add_option (_("Audio"),
2686 "denormal-protection",
2687 _("Use DC bias to protect against denormals"),
2688 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2689 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2692 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2694 _("Processor handling"),
2695 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2696 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2700 dm->add (DenormalNone, _("no processor handling"));
2702 FPU* fpu = FPU::instance();
2704 if (fpu->has_flush_to_zero()) {
2706 dm->add (DenormalFTZ, _("use FlushToZero"));
2707 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2708 _rc_config->set_denormal_model(DenormalNone);
2711 if (fpu->has_denormals_are_zero()) {
2713 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2714 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2715 _rc_config->set_denormal_model(DenormalNone);
2718 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2720 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2721 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2722 _rc_config->set_denormal_model(DenormalNone);
2726 dm->set_sensitive(false);
2729 add_option (_("Audio"), dm);
2731 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2733 add_option (_("Audio"),
2735 "auto-analyse-audio",
2736 _("Enable automatic analysis of audio"),
2737 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2738 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2741 add_option (_("Audio"),
2743 "replicate-missing-region-channels",
2744 _("Replicate missing region channels"),
2745 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2746 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2751 add_option (_("MIDI"), new OptionEditorHeading (_("Buffering")));
2753 add_option (_("MIDI"),
2754 new SpinOption<float> (
2756 _("MIDI read-ahead time (seconds)"),
2757 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2758 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2763 add_option (_("MIDI"), new OptionEditorHeading (_("Session")));
2765 add_option (_("MIDI"),
2766 new SpinOption<int32_t> (
2767 "initial-program-change",
2768 _("Initial program change"),
2769 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2770 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2774 add_option (_("MIDI"), new OptionEditorHeading (_("Audition")));
2776 add_option (_("MIDI"),
2779 _("Sound MIDI notes as they are selected in the editor"),
2780 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2781 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2784 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2785 "midi-audition-synth-uri",
2786 _("MIDI Audition Synth (LV2)"),
2787 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2788 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2791 audition_synth->add(X_(""), _("None"));
2792 PluginInfoList all_plugs;
2793 PluginManager& manager (PluginManager::instance());
2795 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2797 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2798 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2799 if (!(*i)->is_instrument()) continue;
2800 if ((*i)->type != ARDOUR::LV2) continue;
2801 if ((*i)->name.length() > 46) {
2802 audition_synth->add((*i)->unique_id, (*i)->name.substr (0, 44) + "...");
2804 audition_synth->add((*i)->unique_id, (*i)->name);
2809 add_option (_("MIDI"), audition_synth);
2813 add_option (_("Metronome"), new OptionEditorHeading (_("Metronome")));
2814 add_option (_("Metronome"), new ClickOptions (_rc_config));
2818 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2820 ComboOption<float>* mht = new ComboOption<float> (
2822 _("Peak hold time"),
2823 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
2824 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
2827 mht->add (MeterHoldOff, _("off"));
2828 mht->add (MeterHoldShort, _("short"));
2829 mht->add (MeterHoldMedium, _("medium"));
2830 mht->add (MeterHoldLong, _("long"));
2832 add_option (S_("Preferences|Metering"), mht);
2834 ComboOption<float>* mfo = new ComboOption<float> (
2837 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2838 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2841 mfo->add (METER_FALLOFF_OFF, _("off"));
2842 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2843 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2844 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2845 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2846 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2847 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
2849 add_option (S_("Preferences|Metering"), mfo);
2851 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2852 "meter-line-up-level",
2853 _("Meter line-up level; 0dBu"),
2854 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
2855 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
2858 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2859 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2860 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2861 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2863 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."));
2865 add_option (S_("Preferences|Metering"), mlu);
2867 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2868 "meter-line-up-din",
2869 _("IEC1/DIN Meter line-up level; 0dBu"),
2870 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
2871 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
2874 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2875 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2876 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2877 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2879 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2881 add_option (S_("Preferences|Metering"), mld);
2883 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2884 "meter-vu-standard",
2885 _("VU Meter standard"),
2886 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
2887 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
2890 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2891 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2892 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2893 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2895 add_option (S_("Preferences|Metering"), mvu);
2897 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
2898 "meter-type-master",
2899 _("Default Meter Type for Master Bus"),
2900 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
2901 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
2903 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2904 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2905 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2906 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2907 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2908 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2909 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2910 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
2912 add_option (S_("Preferences|Metering"), mtm);
2915 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
2917 _("Default Meter Type for Busses"),
2918 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
2919 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
2921 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2922 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2923 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2924 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2925 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2926 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2927 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2928 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
2930 add_option (S_("Preferences|Metering"), mtb);
2932 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
2934 _("Default Meter Type for Tracks"),
2935 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
2936 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
2938 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2939 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
2941 add_option (S_("Preferences|Metering"), mtt);
2943 HSliderOption *mpks = new HSliderOption("meter-peak",
2944 _("Peak threshold [dBFS]"),
2945 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
2946 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak),
2950 Gtkmm2ext::UI::instance()->set_tip (
2952 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
2954 add_option (S_("Preferences|Metering"), mpks);
2956 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
2958 add_option (S_("Preferences|Metering"),
2960 "save-export-analysis-image",
2961 _("Save loudness analysis as image file"),
2962 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
2963 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
2966 /* TRANSPORT & Sync */
2968 add_option (_("Transport"), new OptionEditorHeading (_("General")));
2970 bo = new BoolOption (
2971 "stop-at-session-end",
2972 _("Stop at the end of the session"),
2973 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
2974 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
2976 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2977 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
2978 "when it reaches the current session end marker\n\n"
2979 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
2981 add_option (_("Transport"), bo);
2983 bo = new BoolOption (
2984 "latched-record-enable",
2985 _("Keep record-enable engaged on stop"),
2986 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
2987 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
2989 add_option (_("Transport"), bo);
2990 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2991 _("<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."));
2993 bo = new BoolOption (
2994 "disable-disarm-during-roll",
2995 _("Disable per-track record disarm while rolling"),
2996 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
2997 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
2999 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."));
3000 add_option (_("Transport"), bo);
3002 bo = new BoolOption (
3004 _("12dB gain reduction during fast-forward and fast-rewind"),
3005 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
3006 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
3008 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3009 _("<b>When enabled</b> rhis will reduce the unpleasant increase in perceived volume "
3010 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
3011 add_option (_("Transport"), bo);
3013 ComboOption<float>* psc = new ComboOption<float> (
3016 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
3017 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
3019 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
3020 (_("The amount of preroll to apply when <b>Play with Preroll</b> or <b>Record with Preroll</b>is initiated.\n\n"
3021 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
3022 psc->add (-4.0, _("4 Bars"));
3023 psc->add (-2.0, _("2 Bars"));
3024 psc->add (-1.0, _("1 Bar"));
3025 psc->add (0.0, _("0 (no pre-roll)"));
3026 psc->add (0.1, _("0.1 second"));
3027 psc->add (0.25, _("0.25 second"));
3028 psc->add (0.5, _("0.5 second"));
3029 psc->add (1.0, _("1.0 second"));
3030 psc->add (2.0, _("2.0 seconds"));
3031 add_option (_("Transport"), psc);
3034 add_option (_("Transport"), new OptionEditorHeading (_("Looping")));
3036 bo = new BoolOption (
3038 _("Play loop is a transport mode"),
3039 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
3040 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
3042 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3043 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
3044 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
3045 add_option (_("Transport"), bo);
3047 bo = new BoolOption (
3049 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
3050 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
3051 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
3053 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3054 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
3055 "preventing any need to do a transport locate at the end of the loop\n\n"
3056 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
3057 "which will often cause a small click or delay"), PROGRAM_NAME));
3058 add_option (_("Transport"), bo);
3060 add_option (_("Transport"), new OptionEditorHeading (_("Dropout (xrun) Handling")));
3061 bo = new BoolOption (
3062 "stop-recording-on-xrun",
3063 _("Stop recording when an xrun occurs"),
3064 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
3065 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
3067 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3068 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
3070 add_option (_("Transport"), bo);
3072 bo = new BoolOption (
3073 "create-xrun-marker",
3074 _("Create markers where xruns occur"),
3075 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
3076 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
3078 add_option (_("Transport"), bo);
3083 add_option (_("Sync"), new OptionEditorHeading (_("External Syncronization")));
3085 _sync_source = new ComboOption<SyncSource> (
3087 _("External timecode source"),
3088 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
3089 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
3092 add_option (_("Sync"), _sync_source);
3094 _sync_framerate = new BoolOption (
3095 "timecode-sync-frame-rate",
3096 _("Match session video frame rate to external timecode"),
3097 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
3098 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
3100 Gtkmm2ext::UI::instance()->set_tip
3101 (_sync_framerate->tip_widget(),
3102 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
3103 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
3104 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
3105 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
3106 "timecode standard and the session standard."), PROGRAM_NAME));
3108 add_option (_("Sync"), _sync_framerate);
3110 _sync_genlock = new BoolOption (
3111 "timecode-source-is-synced",
3112 _("Sync-lock timecode to clock (disable drift compensation)"),
3113 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
3114 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
3116 Gtkmm2ext::UI::instance()->set_tip
3117 (_sync_genlock->tip_widget(),
3118 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
3119 "Sync Lock indicates that the selected external timecode source shares clock-sync "
3120 "(Black & Burst, Wordclock, etc) with the audio interface. "
3121 "This option disables drift compensation. The transport speed is fixed at 1.0. "
3122 "Vari-speed LTC will be ignored and cause drift."
3124 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
3125 "timecode sources shares clock sync."
3129 add_option (_("Sync"), _sync_genlock);
3131 _sync_source_2997 = new BoolOption (
3132 "timecode-source-2997",
3133 _("Lock to 29.9700 fps instead of 30000/1001"),
3134 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
3135 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
3137 Gtkmm2ext::UI::instance()->set_tip
3138 (_sync_source_2997->tip_widget(),
3139 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
3140 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
3141 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
3142 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
3143 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
3144 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
3147 add_option (_("Sync"), _sync_source_2997);
3149 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Reader")));
3151 _ltc_port = new ComboStringOption (
3153 _("LTC incoming port"),
3154 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
3155 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
3158 vector<string> physical_inputs;
3159 physical_inputs.push_back (_("None"));
3160 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
3161 _ltc_port->set_popdown_strings (physical_inputs);
3163 populate_sync_options ();
3164 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
3166 add_option (_("Sync/LTC"), _ltc_port);
3168 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Generator")));
3170 add_option (_("Sync/LTC"),
3173 _("Enable LTC generator"),
3174 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
3175 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
3178 _ltc_send_continuously = new BoolOption (
3179 "ltc-send-continuously",
3180 _("Send LTC while stopped"),
3181 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
3182 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
3184 Gtkmm2ext::UI::instance()->set_tip
3185 (_ltc_send_continuously->tip_widget(),
3186 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
3187 add_option (_("Sync/LTC"), _ltc_send_continuously);
3189 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level [dBFS]"),
3190 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_output_volume),
3191 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_output_volume),
3195 Gtkmm2ext::UI::instance()->set_tip
3196 (_ltc_volume_slider->tip_widget(),
3197 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
3199 add_option (_("Sync/LTC"), _ltc_volume_slider);
3202 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Beat Clock (Mclk) Generator")));
3204 add_option (_("Sync/MIDI"),
3207 _("Enable Mclk generator"),
3208 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
3209 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
3212 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC) Generator")));
3214 add_option (_("Sync/MIDI"),
3217 _("Enable MTC Generator"),
3218 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
3219 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
3222 add_option (_("Sync/MIDI"),
3223 new SpinOption<int> (
3224 "mtc-qf-speed-tolerance",
3225 _("Percentage either side of normal transport speed to transmit MTC"),
3226 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
3227 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
3231 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Machine Control (MMC)")));
3233 add_option (_("Sync/MIDI"),
3236 _("Respond to MMC commands"),
3237 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
3238 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
3241 add_option (_("Sync/MIDI"),
3244 _("Send MMC commands"),
3245 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
3246 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
3249 add_option (_("Sync/MIDI"),
3250 new SpinOption<uint8_t> (
3251 "mmc-receive-device-id",
3252 _("Inbound MMC device ID"),
3253 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
3254 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
3258 add_option (_("Sync/MIDI"),
3259 new SpinOption<uint8_t> (
3260 "mmc-send-device-id",
3261 _("Outbound MMC device ID"),
3262 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
3263 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
3268 /* Control Surfaces */
3270 add_option (_("Control Surfaces"), new OptionEditorHeading (_("Control Surfaces")));
3271 add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
3274 add_option (_("MIDI Ports"), new OptionEditorHeading (_("MIDI Port Options")));
3276 add_option (_("MIDI Ports"),
3278 "get-midi-input-follows-selection",
3279 _("MIDI input follows MIDI track selection"),
3280 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
3281 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
3284 add_option (_("MIDI Ports"), new MidiPortOptions ());
3285 add_option (_("MIDI Ports"), new OptionEditorBlank ());
3289 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3290 add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
3291 add_option (_("Plugins"),
3292 new RcActionButton (_("Scan for Plugins"),
3293 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3297 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
3299 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3300 bo = new BoolOption (
3301 "show-plugin-scan-window",
3302 _("Always Display Plugin Scan Progress"),
3303 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
3304 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
3306 add_option (_("Plugins"), bo);
3307 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3308 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
3311 bo = new BoolOption (
3312 "plugins-stop-with-transport",
3313 _("Silence plugins when the transport is stopped"),
3314 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
3315 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
3317 add_option (_("Plugins"), bo);
3318 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3319 _("<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."));
3321 bo = new BoolOption (
3322 "new-plugins-active",
3323 _("Make new plugins active"),
3324 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
3325 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
3327 add_option (_("Plugins"), bo);
3328 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3329 _("<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"));
3331 #if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
3332 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
3334 add_option (_("Plugins/VST"),
3335 new RcActionButton (_("Scan for Plugins"),
3336 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3339 #if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
3340 bo = new BoolOption (
3342 _("Enable Mac VST support (requires restart or re-scan)"),
3343 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
3344 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
3346 add_option (_("Plugins/VST"), bo);
3349 bo = new BoolOption (
3350 "discover-vst-on-start",
3351 _("Scan for [new] VST Plugins on Application Start"),
3352 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
3353 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
3355 add_option (_("Plugins/VST"), bo);
3356 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3357 _("<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"));
3359 #ifdef WINDOWS_VST_SUPPORT
3360 // currently verbose logging is only implemented for Windows VST.
3361 bo = new BoolOption (
3362 "verbose-plugin-scan",
3363 _("Verbose Plugin Scan"),
3364 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
3365 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
3367 add_option (_("Plugins/VST"), bo);
3368 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3369 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
3372 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
3374 add_option (_("Plugins/VST"),
3375 new RcActionButton (_("Clear"),
3376 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
3379 add_option (_("Plugins/VST"),
3380 new RcActionButton (_("Clear"),
3381 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
3382 _("VST Blacklist:")));
3385 #ifdef LXVST_SUPPORT
3386 add_option (_("Plugins/VST"),
3387 new RcActionButton (_("Edit"),
3388 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
3389 _("Linux VST Path:")));
3391 add_option (_("Plugins/VST"),
3392 new RcConfigDisplay (
3393 "plugin-path-lxvst",
3395 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
3399 #ifdef WINDOWS_VST_SUPPORT
3400 add_option (_("Plugins/VST"),
3401 new RcActionButton (_("Edit"),
3402 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
3403 _("Windows VST Path:")));
3404 add_option (_("Plugins/VST"),
3405 new RcConfigDisplay (
3408 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
3412 #ifdef AUDIOUNIT_SUPPORT
3414 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
3416 add_option (_("Plugins/Audio Unit"),
3417 new RcActionButton (_("Scan for Plugins"),
3418 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3421 bo = new BoolOption (
3422 "discover-audio-units",
3423 _("Scan for [new] AudioUnit Plugins on Application Start"),
3424 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
3425 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
3427 add_option (_("Plugins/Audio Unit"), bo);
3428 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3429 _("<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."));
3431 add_option (_("Plugins/Audio Unit"),
3432 new RcActionButton (_("Clear"),
3433 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
3436 add_option (_("Plugins/Audio Unit"),
3437 new RcActionButton (_("Clear"),
3438 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
3439 _("AU Blacklist:")));
3442 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
3443 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
3444 add_option (_("Plugins"),
3446 "open-gui-after-adding-plugin",
3447 _("Automatically open the plugin GUI when adding a new plugin"),
3448 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
3449 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3452 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3453 add_option (_("Plugins"),
3455 "show-inline-display-by-default",
3456 _("Show Plugin Inline Display on Mixerstrip by default"),
3457 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3458 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3461 _plugin_prefer_inline = new BoolOption (
3462 "prefer-inline-over-gui",
3463 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3464 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3465 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3467 add_option (_("Plugins"), _plugin_prefer_inline);
3470 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3472 bo = new BoolOption (
3473 "ask-replace-instrument",
3474 _("Ask to replace existing instrument plugin"),
3475 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3476 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3478 add_option (_("Plugins"), bo);
3480 bo = new BoolOption (
3481 "ask-setup_instrument",
3482 _("Interactively configure instrument plugins on insert"),
3483 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3484 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3486 add_option (_("Plugins"), bo);
3487 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3488 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3491 add_option (_("Plugins"), new OptionEditorBlank ());
3494 #if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
3495 add_option (_("Appearance"), new OptionEditorHeading (_("Graphics Acceleration")));
3498 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3499 BoolOption* bgc = new BoolOption (
3500 "cairo-image-surface",
3501 _("Disable Graphics Hardware Acceleration (requires restart)"),
3502 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3503 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3506 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3507 _("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));
3508 add_option (_("Appearance"), bgc);
3511 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3512 BoolOption* bgo = new BoolOption (
3514 _("Possibly improve slow graphical performance (requires restart)"),
3515 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3516 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3519 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));
3520 add_option (_("Appearance"), bgo);
3522 add_option (_("Appearance"), new OptionEditorHeading (_("Graphical User Interface")));
3524 add_option (_("Appearance"),
3527 _("Highlight widgets on mouseover"),
3528 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3529 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3532 add_option (_("Appearance"),
3535 _("Show tooltips if mouse hovers over a control"),
3536 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3537 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3540 bo = new BoolOption (
3541 "super-rapid-clock-update",
3542 _("Update clocks at TC Frame rate"),
3543 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3544 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3546 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3547 _("<b>When enabled</b> clock displays are updated every Timecode Frame (fps).\n\n"
3548 "<b>When disabled</b> clock displays are updated only every 100ms."
3550 add_option (_("Appearance"), bo);
3552 add_option (_("Appearance"),
3555 _("Blink Rec-Arm buttons"),
3556 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_rec_arm),
3557 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_rec_arm)
3562 /* font scaling does nothing with GDK/Quartz */
3563 add_option (_("Appearance"), new FontScalingOptions ());
3565 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("General")));
3566 add_option (_("Appearance/Editor"),
3568 "show-name-highlight",
3569 _("Use name highlight bars in region displays (requires a restart)"),
3570 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3571 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3574 add_option (_("Appearance/Editor"),
3576 "color-regions-using-track-color",
3577 _("Region color follows track color"),
3578 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_color_regions_using_track_color),
3579 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_color_regions_using_track_color)
3582 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Waveforms")));
3584 if (!Profile->get_mixbus()) {
3585 add_option (_("Appearance/Editor"),
3588 _("Show waveforms in regions"),
3589 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
3590 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
3594 add_option (_("Appearance/Editor"),
3596 "show-waveforms-while-recording",
3597 _("Show waveforms while recording"),
3598 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
3599 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
3602 add_option (_("Appearance/Editor"),
3604 "show-waveform-clipping",
3605 _("Show waveform clipping"),
3606 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveform_clipping),
3607 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveform_clipping)
3610 add_option (_("Appearance/Editor"), new ClipLevelOptions ());
3612 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
3614 _("Waveform scale"),
3615 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
3616 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
3619 wfs->add (Linear, _("linear"));
3620 wfs->add (Logarithmic, _("logarithmic"));
3622 add_option (_("Appearance/Editor"), wfs);
3624 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
3626 _("Waveform shape"),
3627 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
3628 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
3631 wfsh->add (Traditional, _("traditional"));
3632 wfsh->add (Rectified, _("rectified"));
3634 add_option (_("Appearance/Editor"), wfsh);
3636 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Editor Meters")));
3638 add_option (_("Appearance/Editor"),
3640 "show-track-meters",
3641 _("Show meters in track headers"),
3642 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3643 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3646 add_option (_("Appearance/Editor"),
3648 "editor-stereo-only-meters",
3649 _("Limit track header meters to stereo"),
3650 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3651 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3654 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("MIDI Regions")));
3656 add_option (_("Appearance/Editor"),
3658 "display-first-midi-bank-as-zero",
3659 _("Display first MIDI bank/program as 0"),
3660 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
3661 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
3664 add_option (_("Appearance/Editor"),
3666 "never-display-periodic-midi",
3667 _("Don't display periodic (MTC, MMC) SysEx messages in MIDI Regions"),
3668 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
3669 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
3672 add_option (_("Appearance/Editor"), new OptionEditorBlank ());
3674 /* The names of these controls must be the same as those given in MixerStrip
3675 for the actual widgets being controlled.
3677 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3678 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3679 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3680 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3681 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3682 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3683 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3685 add_option (_("Appearance/Mixer"),
3686 new VisibilityOption (
3688 &_mixer_strip_visibility,
3689 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3690 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3694 add_option (_("Appearance/Mixer"),
3696 "default-narrow_ms",
3697 _("Use narrow strips in the mixer for new strips by default"),
3698 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3699 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3702 add_option (_("Appearance/Mixer"), new OptionEditorBlank ());
3704 add_option (_("Appearance/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items")));
3706 add_option (_("Appearance/Toolbar"),
3708 "show-toolbar-recpunch",
3709 _("Display Record/Punch Options"),
3710 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_recpunch),
3711 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_recpunch)
3714 add_option (_("Appearance/Toolbar"),
3716 "show-toolbar-monitoring",
3717 _("Display Monitor Options"),
3718 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_monitoring),
3719 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_monitoring)
3722 add_option (_("Appearance/Toolbar"),
3724 "show-toolbar-selclock",
3725 _("Display Selection Clock"),
3726 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
3727 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
3730 if (!ARDOUR::Profile->get_small_screen()) {
3731 add_option (_("Appearance/Toolbar"),
3733 "show-secondary-clock",
3734 _("Display Secondary Clock"),
3735 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
3736 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
3740 add_option (_("Appearance/Toolbar"),
3742 "show-mini-timeline",
3743 _("Display Navigation Timeline"),
3744 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
3745 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
3748 add_option (_("Appearance/Toolbar"),
3750 "show-editor-meter",
3751 _("Display Master Level Meter"),
3752 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
3753 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
3756 add_option (_("Appearance/Toolbar"),
3757 new ColumVisibilityOption (
3758 "action-table-columns", _("Lua Action Script Button Visibility"), 4,
3759 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3760 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3763 add_option (_("Appearance/Toolbar"), new OptionEditorBlank ());
3766 /* and now the theme manager */
3768 add_option (_("Appearance/Theme"), new OptionEditorHeading (_("Theme")));
3770 add_option (_("Appearance/Theme"), new BoolOption (
3772 _("Draw \"flat\" buttons"),
3773 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_flat_buttons),
3774 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_flat_buttons)
3777 add_option (_("Appearance/Theme"), new BoolOption (
3779 _("LED meter style"),
3780 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3781 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3785 HSliderOption *gui_hs = new HSliderOption(
3786 "timeline-item-gradient-depth",
3787 _("Waveforms color gradient depth"),
3788 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_gradient_depth),
3789 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_gradient_depth),
3792 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3793 add_option (_("Appearance/Theme"), gui_hs);
3795 gui_hs = new HSliderOption(
3796 "timeline-item-gradient-depth",
3797 _("Timeline item gradient depth"),
3798 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_timeline_item_gradient_depth),
3799 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_timeline_item_gradient_depth),
3802 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3803 add_option (_("Appearance/Theme"), gui_hs);
3805 vector<string> icon_sets = ::get_icon_sets ();
3806 if (icon_sets.size() > 1) {
3807 ComboOption<std::string>* io = new ComboOption<std::string> (
3808 "icon-set", _("Icon Set"),
3809 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_icon_set),
3810 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_icon_set)
3812 for (vector<string>::const_iterator i = icon_sets.begin (); i != icon_sets.end (); ++i) {
3815 add_option (_("Appearance/Theme"), io);
3818 add_option (_("Appearance/Colors"), new OptionEditorHeading (_("Colors")));
3819 add_option (_("Appearance/Colors"), new ColorThemeManager);
3820 add_option (_("Appearance/Colors"), new OptionEditorBlank ());
3824 OptionEditorHeading* quirks_head = new OptionEditorHeading (_("Various Workarounds for Windowing Systems"));
3826 quirks_head->set_note (string_compose (_("Rules for closing, minimizing, maximizing, and stay-on-top can vary\
3827 with each version of your OS, and the preferences that you've set in your OS.\n\n\
3828 You can adjust the options, below, to change how %1's windows and dialogs behave.\n\n\
3829 These settings will only take effect after %1 is restarted.\n\
3832 add_option (_("Appearance/Quirks"), quirks_head);
3834 bo = new BoolOption (
3835 "use-wm-visibility",
3836 _("Use visibility information provided by your Window Manager/Desktop"),
3837 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3838 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3840 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3841 _("If you have trouble toggling between hidden Editor and Mixer windows, try changing this setting."));
3842 add_option (_("Appearance/Quirks"), bo);
3845 bo = new BoolOption (
3846 "all-floating-windows-are-dialogs",
3847 _("All floating windows are dialogs"),
3848 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_all_floating_windows_are_dialogs),
3849 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_all_floating_windows_are_dialogs)
3851 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3852 _("Mark all floating windows to be type \"Dialog\" rather than using \"Utility\" for some.\nThis may help with some window managers."));
3853 add_option (_("Appearance/Quirks"), bo);
3855 bo = new BoolOption (
3856 "transients-follow-front",
3857 _("Transient windows follow front window."),
3858 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_transients_follow_front),
3859 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_transients_follow_front)
3861 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3862 _("Make transient windows follow the front window when toggling between the editor and mixer."));
3863 add_option (_("Appearance/Quirks"), bo);
3866 if (!Profile->get_mixbus()) {
3867 bo = new BoolOption (
3868 "floating-monitor-section",
3869 _("Float detached monitor-section window"),
3870 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_floating_monitor_section),
3871 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_floating_monitor_section)
3873 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3874 _("When detaching the monitoring section, mark it as \"Utility\" window to stay in front."));
3875 add_option (_("Appearance/Quirks"), bo);
3878 add_option (_("Appearance/Quirks"), new OptionEditorBlank ());
3880 /* VIDEO Timeline */
3881 add_option (_("Video"), new OptionEditorHeading (_("Video Server")));
3882 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
3884 Widget::show_all ();
3886 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3887 parameter_changed ("send-ltc");
3888 parameter_changed ("sync-source");
3889 parameter_changed ("use-monitor-bus");
3890 parameter_changed ("open-gui-after-adding-plugin");
3892 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
3894 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
3895 (Gtk::StateType) here !!!
3897 Tabbable::set_state (*node, Stateful::loading_state_version);
3900 set_current_page (_("General"));
3904 RCOptionEditor::parameter_changed (string const & p)
3906 OptionEditor::parameter_changed (p);
3908 if (p == "use-monitor-bus") {
3909 bool const s = Config->get_use_monitor_bus ();
3911 /* we can't use this if we don't have a monitor bus */
3912 Config->set_solo_control_is_listen_control (false);
3914 _solo_control_is_listen_control->set_sensitive (s);
3915 _listen_position->set_sensitive (s);
3916 } else if (p == "sync-source") {
3917 _sync_source->set_sensitive (true);
3919 _sync_source->set_sensitive (!_session->config.get_external_sync());
3921 switch(Config->get_sync_source()) {
3924 _sync_genlock->set_sensitive (true);
3925 _sync_framerate->set_sensitive (true);
3926 _sync_source_2997->set_sensitive (true);
3929 _sync_genlock->set_sensitive (false);
3930 _sync_framerate->set_sensitive (false);
3931 _sync_source_2997->set_sensitive (false);
3934 } else if (p == "send-ltc") {
3935 bool const s = Config->get_send_ltc ();
3936 _ltc_send_continuously->set_sensitive (s);
3937 _ltc_volume_slider->set_sensitive (s);
3938 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
3939 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3940 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
3943 } else if (p == "enable-translation") {
3944 _l10n->set_sensitive (ARDOUR::translations_are_enabled ());
3949 void RCOptionEditor::plugin_scan_refresh () {
3950 PluginManager::instance().refresh();
3953 void RCOptionEditor::clear_vst_cache () {
3954 PluginManager::instance().clear_vst_cache();
3957 void RCOptionEditor::clear_vst_blacklist () {
3958 PluginManager::instance().clear_vst_blacklist();
3961 void RCOptionEditor::clear_au_cache () {
3962 PluginManager::instance().clear_au_cache();
3965 void RCOptionEditor::clear_au_blacklist () {
3966 PluginManager::instance().clear_au_blacklist();
3969 void RCOptionEditor::edit_lxvst_path () {
3970 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
3971 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3972 *current_toplevel(), _("Set Linux VST Search Path"),
3973 _rc_config->get_plugin_path_lxvst(),
3974 PluginManager::instance().get_default_lxvst_path()
3976 ResponseType r = (ResponseType) pd->run ();
3978 if (r == RESPONSE_ACCEPT) {
3979 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
3981 MessageDialog msg (_("Re-scan Plugins now?"),
3982 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
3983 msg.set_default_response (Gtk::RESPONSE_YES);
3984 if (msg.run() == Gtk::RESPONSE_YES) {
3985 plugin_scan_refresh ();
3991 void RCOptionEditor::edit_vst_path () {
3992 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3993 *current_toplevel(), _("Set Windows VST Search Path"),
3994 _rc_config->get_plugin_path_vst(),
3995 PluginManager::instance().get_default_windows_vst_path()
3997 ResponseType r = (ResponseType) pd->run ();
3999 if (r == RESPONSE_ACCEPT) {
4000 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
4001 MessageDialog msg (_("Re-scan Plugins now?"),
4002 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
4003 msg.set_default_response (Gtk::RESPONSE_YES);
4004 if (msg.run() == Gtk::RESPONSE_YES) {
4005 plugin_scan_refresh ();
4013 RCOptionEditor::populate_sync_options ()
4015 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
4017 _sync_source->clear ();
4019 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
4020 _sync_source->add (*i, sync_source_to_string (*i));
4023 if (sync_opts.empty()) {
4024 _sync_source->set_sensitive(false);
4026 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
4027 _rc_config->set_sync_source(sync_opts.front());
4031 parameter_changed ("sync-source");
4035 RCOptionEditor::use_own_window (bool and_fill_it)
4037 bool new_window = !own_window ();
4039 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
4041 if (win && new_window) {
4042 win->set_name ("PreferencesWindow");
4043 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
4045 win->set_resizable (false);
4052 RCOptionEditor::get_state ()
4054 XMLNode* node = new XMLNode (X_("Preferences"));
4055 node->add_child_nocopy (Tabbable::get_state());