2 Copyright (C) 2001-2011 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "gtk2ardour-config.h"
24 #if !defined USE_CAIRO_IMAGE_SURFACE && !defined NDEBUG
25 #define OPTIONAL_CAIRO_IMAGE_SURFACE
28 #include <cairo/cairo.h>
30 #include <boost/algorithm/string.hpp>
32 #include <gtkmm/liststore.h>
33 #include <gtkmm/stock.h>
34 #include <gtkmm/scale.h>
36 #include <gtkmm2ext/utils.h>
37 #include <gtkmm2ext/slider_controller.h>
38 #include <gtkmm2ext/gtk_ui.h>
39 #include <gtkmm2ext/paths_dialog.h>
40 #include <gtkmm2ext/window_title.h>
46 #include "ardour/audio_backend.h"
47 #include "ardour/audioengine.h"
48 #include "ardour/profile.h"
49 #include "ardour/dB.h"
50 #include "ardour/rc_configuration.h"
51 #include "ardour/control_protocol_manager.h"
52 #include "ardour/port_manager.h"
53 #include "ardour/plugin_manager.h"
54 #include "control_protocol/control_protocol.h"
56 #include "canvas/wave_view.h"
58 #include "ardour_dialog.h"
59 #include "ardour_ui.h"
60 #include "ardour_window.h"
61 #include "color_theme_manager.h"
62 #include "gui_thread.h"
64 #include "meter_patterns.h"
65 #include "midi_tracer.h"
66 #include "rc_option_editor.h"
69 #include "ui_config.h"
74 using namespace Gtkmm2ext;
76 using namespace ARDOUR;
77 using namespace ARDOUR_UI_UTILS;
79 class ClickOptions : public OptionEditorMiniPage
82 ClickOptions (RCConfiguration* c)
84 , _click_browse_button (_("Browse..."))
85 , _click_emphasis_browse_button (_("Browse..."))
87 // TODO get rid of GTK -> use OptionEditor Widgets
90 Label* l = manage (left_aligned_label (_("Emphasis on first beat")));
91 _use_emphasis_on_click_check_button.add (*l);
92 t->attach (_use_emphasis_on_click_check_button, 1, 3, 0, 1, FILL);
93 _use_emphasis_on_click_check_button.signal_toggled().connect (
94 sigc::mem_fun (*this, &ClickOptions::use_emphasis_on_click_toggled));
96 l = manage (left_aligned_label (_("Use built-in default sounds")));
97 _use_default_click_check_button.add (*l);
98 t->attach (_use_default_click_check_button, 1, 3, 1, 2, FILL);
99 _use_default_click_check_button.signal_toggled().connect (
100 sigc::mem_fun (*this, &ClickOptions::use_default_click_toggled));
102 l = manage (left_aligned_label (_("Audio file:")));
103 t->attach (*l, 1, 2, 2, 3, FILL);
104 t->attach (_click_path_entry, 2, 3, 2, 3, FILL);
105 _click_browse_button.signal_clicked ().connect (
106 sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
107 t->attach (_click_browse_button, 3, 4, 2, 3, FILL);
109 l = manage (left_aligned_label (_("Emphasis audio file:")));
110 t->attach (*l, 1, 2, 3, 4, FILL);
111 t->attach (_click_emphasis_path_entry, 2, 3, 3, 4, FILL);
112 _click_emphasis_browse_button.signal_clicked ().connect (
113 sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
114 t->attach (_click_emphasis_browse_button, 3, 4, 3, 4, FILL);
116 _click_fader = new FaderOption (
119 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
120 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
123 _click_fader->add_to_page (this);
124 _click_fader->set_state_from_config ();
126 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
127 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
129 if (_rc_config->get_click_sound ().empty() &&
130 _rc_config->get_click_emphasis_sound().empty()) {
131 _use_default_click_check_button.set_active (true);
132 _use_emphasis_on_click_check_button.set_active (true);
135 _use_default_click_check_button.set_active (false);
136 _use_emphasis_on_click_check_button.set_active (false);
140 void parameter_changed (string const & p)
142 if (p == "click-sound") {
143 _click_path_entry.set_text (_rc_config->get_click_sound());
144 } else if (p == "click-emphasis-sound") {
145 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
146 } else if (p == "use-click-emphasis") {
147 bool x = _rc_config->get_use_click_emphasis ();
148 _use_emphasis_on_click_check_button.set_active (x);
149 } else if (p == "click-gain") {
150 _click_fader->set_state_from_config ();
154 void set_state_from_config ()
156 parameter_changed ("click-sound");
157 parameter_changed ("click-emphasis-sound");
158 parameter_changed ("use-click-emphasis");
163 void click_browse_clicked ()
165 SoundFileChooser sfdb (_("Choose Click"));
170 if (sfdb.run () == RESPONSE_OK) {
171 click_chosen (sfdb.get_filename());
175 void click_chosen (string const & path)
177 _click_path_entry.set_text (path);
178 _rc_config->set_click_sound (path);
181 void click_changed ()
183 click_chosen (_click_path_entry.get_text ());
186 void click_emphasis_browse_clicked ()
188 SoundFileChooser sfdb (_("Choose Click Emphasis"));
193 if (sfdb.run () == RESPONSE_OK) {
194 click_emphasis_chosen (sfdb.get_filename());
198 void click_emphasis_chosen (string const & path)
200 _click_emphasis_path_entry.set_text (path);
201 _rc_config->set_click_emphasis_sound (path);
204 void click_emphasis_changed ()
206 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
209 void use_default_click_toggled ()
211 if (_use_default_click_check_button.get_active ()) {
212 _rc_config->set_click_sound ("");
213 _rc_config->set_click_emphasis_sound ("");
214 _click_path_entry.set_sensitive (false);
215 _click_emphasis_path_entry.set_sensitive (false);
216 _click_browse_button.set_sensitive (false);
217 _click_emphasis_browse_button.set_sensitive (false);
219 _click_path_entry.set_sensitive (true);
220 _click_emphasis_path_entry.set_sensitive (true);
221 _click_browse_button.set_sensitive (true);
222 _click_emphasis_browse_button.set_sensitive (true);
226 void use_emphasis_on_click_toggled ()
228 if (_use_emphasis_on_click_check_button.get_active ()) {
229 _rc_config->set_use_click_emphasis(true);
231 _rc_config->set_use_click_emphasis(false);
235 RCConfiguration* _rc_config;
236 CheckButton _use_default_click_check_button;
237 CheckButton _use_emphasis_on_click_check_button;
238 Entry _click_path_entry;
239 Entry _click_emphasis_path_entry;
240 Button _click_browse_button;
241 Button _click_emphasis_browse_button;
242 FaderOption* _click_fader;
245 class UndoOptions : public OptionEditorComponent
248 UndoOptions (RCConfiguration* c) :
250 _limit_undo_button (_("Limit undo history to")),
251 _save_undo_button (_("Save undo history of"))
253 // TODO get rid of GTK -> use OptionEditor SpinOption
254 _limit_undo_spin.set_range (0, 512);
255 _limit_undo_spin.set_increments (1, 10);
257 _save_undo_spin.set_range (0, 512);
258 _save_undo_spin.set_increments (1, 10);
260 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
261 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
262 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
263 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
266 void parameter_changed (string const & p)
268 if (p == "history-depth") {
269 int32_t const d = _rc_config->get_history_depth();
270 _limit_undo_button.set_active (d != 0);
271 _limit_undo_spin.set_sensitive (d != 0);
272 _limit_undo_spin.set_value (d);
273 } else if (p == "save-history") {
274 bool const x = _rc_config->get_save_history ();
275 _save_undo_button.set_active (x);
276 _save_undo_spin.set_sensitive (x);
277 } else if (p == "save-history-depth") {
278 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
282 void set_state_from_config ()
284 parameter_changed ("save-history");
285 parameter_changed ("history-depth");
286 parameter_changed ("save-history-depth");
289 void limit_undo_toggled ()
291 bool const x = _limit_undo_button.get_active ();
292 _limit_undo_spin.set_sensitive (x);
293 int32_t const n = x ? 16 : 0;
294 _limit_undo_spin.set_value (n);
295 _rc_config->set_history_depth (n);
298 void limit_undo_changed ()
300 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
303 void save_undo_toggled ()
305 bool const x = _save_undo_button.get_active ();
306 _rc_config->set_save_history (x);
309 void save_undo_changed ()
311 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
314 void add_to_page (OptionEditorPage* p)
316 int const n = p->table.property_n_rows();
317 Table* t = & p->table;
319 t->resize (n + 2, 3);
321 Label* l = manage (left_aligned_label (_("commands")));
322 HBox* box = manage (new HBox());
323 box->set_spacing (4);
324 box->pack_start (_limit_undo_spin, false, false);
325 box->pack_start (*l, true, true);
326 t->attach (_limit_undo_button, 1, 2, n, n +1, FILL);
327 t->attach (*box, 2, 3, n, n + 1, FILL | EXPAND);
329 l = manage (left_aligned_label (_("commands")));
330 box = manage (new HBox());
331 box->set_spacing (4);
332 box->pack_start (_save_undo_spin, false, false);
333 box->pack_start (*l, true, true);
334 t->attach (_save_undo_button, 1, 2, n + 1, n + 2, FILL);
335 t->attach (*box, 2, 3, n + 1, n + 2, FILL | EXPAND);
338 Gtk::Widget& tip_widget() {
339 return _limit_undo_button; // unused
343 RCConfiguration* _rc_config;
344 CheckButton _limit_undo_button;
345 SpinButton _limit_undo_spin;
346 CheckButton _save_undo_button;
347 SpinButton _save_undo_spin;
351 static const struct {
363 { "Key|Shift", GDK_SHIFT_MASK },
364 { "Command", GDK_MOD2_MASK },
365 { "Control", GDK_CONTROL_MASK },
366 { "Option", GDK_MOD1_MASK },
367 { "Command-Shift", GDK_MOD2_MASK|GDK_SHIFT_MASK },
368 { "Command-Option", GDK_MOD2_MASK|GDK_MOD1_MASK },
369 { "Command-Control", GDK_MOD2_MASK|GDK_CONTROL_MASK },
370 { "Command-Option-Control", GDK_MOD2_MASK|GDK_MOD1_MASK|GDK_CONTROL_MASK },
371 { "Option-Control", GDK_MOD1_MASK|GDK_CONTROL_MASK },
372 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
373 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
374 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_MOD2_MASK },
377 { "Key|Shift", GDK_SHIFT_MASK },
378 { "Control", GDK_CONTROL_MASK },
379 { "Alt", GDK_MOD1_MASK },
380 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
381 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
382 { "Control-Windows", GDK_CONTROL_MASK|GDK_MOD4_MASK },
383 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
384 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
385 { "Alt-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
386 { "Alt-Shift-Windows", GDK_MOD1_MASK|GDK_SHIFT_MASK|GDK_MOD4_MASK },
387 { "Mod2", GDK_MOD2_MASK },
388 { "Mod3", GDK_MOD3_MASK },
389 { "Windows", GDK_MOD4_MASK },
390 { "Mod5", GDK_MOD5_MASK },
396 class KeyboardOptions : public OptionEditorMiniPage
400 : _delete_button_adjustment (3, 1, 12)
401 , _delete_button_spin (_delete_button_adjustment)
402 , _edit_button_adjustment (3, 1, 5)
403 , _edit_button_spin (_edit_button_adjustment)
404 , _insert_note_button_adjustment (3, 1, 5)
405 , _insert_note_button_spin (_insert_note_button_adjustment)
407 // TODO get rid of GTK -> use OptionEditor Widgets
409 const std::string restart_msg = _("\nChanges to this setting will only persist after your project has been saved.");
410 /* internationalize and prepare for use with combos */
413 for (int i = 0; modifiers[i].name; ++i) {
414 dumb.push_back (S_(modifiers[i].name));
417 set_popdown_strings (_edit_modifier_combo, dumb);
418 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
419 Gtkmm2ext::UI::instance()->set_tip (_edit_modifier_combo,
420 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
427 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
428 l->set_name ("OptionsLabel");
432 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
433 strs.push_back (bf->first);
436 set_popdown_strings (_keyboard_layout_selector, strs);
437 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
438 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
440 t->attach (*l, col + 1, col + 2, row, row + 1, FILL, FILL);
441 t->attach (_keyboard_layout_selector, col + 2, col + 3, row, row + 1, FILL | EXPAND, FILL);
446 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Clicking:"))));
447 l->set_name ("OptionEditorHeading");
448 l->set_use_markup (true);
449 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
454 l = manage (left_aligned_label (_("Edit using:")));
455 l->set_name ("OptionsLabel");
457 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
458 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
460 l = manage (new Label (_("+ button")));
461 l->set_name ("OptionsLabel");
463 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
464 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, SHRINK , FILL);
466 _edit_button_spin.set_name ("OptionsEntry");
467 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
472 set_popdown_strings (_delete_modifier_combo, dumb);
473 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
474 Gtkmm2ext::UI::instance()->set_tip (_delete_modifier_combo,
475 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
477 l = manage (left_aligned_label (_("Delete using:")));
478 l->set_name ("OptionsLabel");
480 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
481 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
483 l = manage (new Label (_("+ button")));
484 l->set_name ("OptionsLabel");
486 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
487 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, SHRINK, FILL);
489 _delete_button_spin.set_name ("OptionsEntry");
490 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
495 set_popdown_strings (_insert_note_modifier_combo, dumb);
496 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
497 Gtkmm2ext::UI::instance()->set_tip (_insert_note_modifier_combo,
498 (string_compose (_("<b>Recommended Setting: %1 + button 1 (left mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
500 l = manage (left_aligned_label (_("Insert note using:")));
501 l->set_name ("OptionsLabel");
503 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
504 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
506 l = manage (new Label (_("+ button")));
507 l->set_name ("OptionsLabel");
509 t->attach (*l, col + 3, col + 4, row, row + 1, FILL, FILL);
510 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, SHRINK, FILL);
512 _insert_note_button_spin.set_name ("OptionsEntry");
513 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
517 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Beginning a Drag:"))));
518 l->set_name ("OptionEditorHeading");
519 l->set_use_markup (true);
520 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
526 set_popdown_strings (_copy_modifier_combo, dumb);
527 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
528 Gtkmm2ext::UI::instance()->set_tip (_copy_modifier_combo,
529 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
531 Keyboard::secondary_modifier_name (),
533 Keyboard::primary_modifier_name (),
537 l = manage (left_aligned_label (_("Copy items using:")));
538 l->set_name ("OptionsLabel");
540 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
541 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
546 /* constraint modifier */
547 set_popdown_strings (_constraint_modifier_combo, dumb);
548 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
549 Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo,
550 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
552 Keyboard::primary_modifier_name (),
554 Keyboard::tertiary_modifier_name (),
558 l = manage (left_aligned_label (_("Constrain drag using:")));
559 l->set_name ("OptionsLabel");
561 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
562 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
568 set_popdown_strings (_push_points_combo, dumb);
569 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
571 std::string mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
572 Gtkmm2ext::UI::instance()->set_tip (_push_points_combo,
573 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
575 l = manage (left_aligned_label (_("Push points using:")));
576 l->set_name ("OptionsLabel");
578 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
579 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
583 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("When Beginning a Trim:"))));
584 l->set_name ("OptionEditorHeading");
585 l->set_use_markup (true);
586 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
592 set_popdown_strings (_trim_contents_combo, dumb);
593 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
594 Gtkmm2ext::UI::instance()->set_tip (_trim_contents_combo,
595 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
597 l = manage (left_aligned_label (_("Trim contents using:")));
598 l->set_name ("OptionsLabel");
600 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
601 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
607 set_popdown_strings (_trim_anchored_combo, dumb);
608 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
610 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::tertiary_modifier_name ());
611 Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo,
612 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
614 l = manage (left_aligned_label (_("Anchored trim using:")));
615 l->set_name ("OptionsLabel");
617 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
619 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
624 /* jump trim disabled for now
625 set_popdown_strings (_trim_jump_combo, dumb);
626 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
628 l = manage (left_aligned_label (_("Jump after trim using:")));
629 l->set_name ("OptionsLabel");
631 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
633 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
639 /* note resize relative */
640 set_popdown_strings (_note_size_relative_combo, dumb);
641 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
642 Gtkmm2ext::UI::instance()->set_tip (_note_size_relative_combo,
643 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg))); // XXX 2ndary
645 l = manage (left_aligned_label (_("Resize notes relatively using:")));
646 l->set_name ("OptionsLabel");
648 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
650 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
654 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Dragging:"))));
655 l->set_name ("OptionEditorHeading");
656 l->set_use_markup (true);
657 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
663 set_popdown_strings (_snap_modifier_combo, dumb);
664 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
666 mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ());
668 mod_str = Keyboard::secondary_modifier_name();
670 Gtkmm2ext::UI::instance()->set_tip (_snap_modifier_combo,
671 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
673 l = manage (left_aligned_label (_("Ignore snap using:")));
674 l->set_name ("OptionsLabel");
676 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
677 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
683 set_popdown_strings (_snap_delta_combo, dumb);
684 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
686 mod_str = Keyboard::level4_modifier_name ();
688 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::level4_modifier_name ());
690 Gtkmm2ext::UI::instance()->set_tip (_snap_delta_combo,
691 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
693 l = manage (left_aligned_label (_("Snap relatively using:")));
694 l->set_name ("OptionsLabel");
696 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
697 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
701 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Trimming:"))));
702 l->set_name ("OptionEditorHeading");
703 l->set_use_markup (true);
704 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
710 set_popdown_strings (_trim_overlap_combo, dumb);
711 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
713 Gtkmm2ext::UI::instance()->set_tip (_trim_overlap_combo,
714 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
716 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
717 l->set_name ("OptionsLabel");
719 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
720 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
724 l = manage (left_aligned_label (string_compose ("<b>%1</b>", _("While Dragging Control Points:"))));
725 l->set_name ("OptionEditorHeading");
726 l->set_use_markup (true);
727 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
733 set_popdown_strings (_fine_adjust_combo, dumb);
734 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
736 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::secondary_modifier_name ()); // XXX just 2ndary ?!
737 Gtkmm2ext::UI::instance()->set_tip (_fine_adjust_combo,
738 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
740 l = manage (left_aligned_label (_("Fine adjust using:")));
741 l->set_name ("OptionsLabel");
743 t->attach (*l, col, col + 1, row, row + 1, FILL, FILL);
744 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
746 OptionEditorHeading* h = new OptionEditorHeading (_("Reset"));
747 h->add_to_page (this);
749 RcActionButton* rb = new RcActionButton (_("Reset to recommended defaults"),
750 sigc::mem_fun (*this, &KeyboardOptions::reset_to_defaults));
751 rb->add_to_page (this);
753 set_state_from_config ();
756 void parameter_changed (string const &)
758 /* XXX: these aren't really config options... */
761 void set_state_from_config ()
763 _delete_button_adjustment.set_value (Keyboard::delete_button());
764 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
765 _edit_button_adjustment.set_value (Keyboard::edit_button());
767 for (int x = 0; modifiers[x].name; ++x) {
768 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
769 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
771 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
772 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
774 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
775 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
777 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
778 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
780 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
781 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
783 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
784 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
786 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
787 _push_points_combo.set_active_text (S_(modifiers[x].name));
789 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
790 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
792 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
793 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
796 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
797 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
800 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
801 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
803 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
804 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
806 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
807 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
809 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
810 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
815 void add_to_page (OptionEditorPage* p)
817 int const n = p->table.property_n_rows();
818 p->table.resize (n + 1, 3);
819 p->table.attach (box, 1, 3, n, n + 1, FILL | EXPAND, SHRINK, 0, 0);
824 void bindings_changed ()
826 string const txt = _keyboard_layout_selector.get_active_text();
828 /* XXX: config...? for all this keyboard stuff */
830 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
831 if (txt == i->first) {
832 if (Keyboard::load_keybindings (i->second)) {
833 Keyboard::save_keybindings ();
839 void edit_modifier_chosen ()
841 string const txt = _edit_modifier_combo.get_active_text();
843 for (int i = 0; modifiers[i].name; ++i) {
844 if (txt == S_(modifiers[i].name)) {
845 Keyboard::set_edit_modifier (modifiers[i].modifier);
851 void delete_modifier_chosen ()
853 string const txt = _delete_modifier_combo.get_active_text();
855 for (int i = 0; modifiers[i].name; ++i) {
856 if (txt == S_(modifiers[i].name)) {
857 Keyboard::set_delete_modifier (modifiers[i].modifier);
863 void copy_modifier_chosen ()
865 string const txt = _copy_modifier_combo.get_active_text();
867 for (int i = 0; modifiers[i].name; ++i) {
868 if (txt == S_(modifiers[i].name)) {
869 Keyboard::set_copy_modifier (modifiers[i].modifier);
875 void insert_note_modifier_chosen ()
877 string const txt = _insert_note_modifier_combo.get_active_text();
879 for (int i = 0; modifiers[i].name; ++i) {
880 if (txt == S_(modifiers[i].name)) {
881 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
887 void snap_modifier_chosen ()
889 string const txt = _snap_modifier_combo.get_active_text();
891 for (int i = 0; modifiers[i].name; ++i) {
892 if (txt == S_(modifiers[i].name)) {
893 Keyboard::set_snap_modifier (modifiers[i].modifier);
899 void snap_delta_modifier_chosen ()
901 string const txt = _snap_delta_combo.get_active_text();
903 for (int i = 0; modifiers[i].name; ++i) {
904 if (txt == S_(modifiers[i].name)) {
905 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
911 void constraint_modifier_chosen ()
913 string const txt = _constraint_modifier_combo.get_active_text();
915 for (int i = 0; modifiers[i].name; ++i) {
916 if (txt == S_(modifiers[i].name)) {
917 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
923 void trim_contents_modifier_chosen ()
925 string const txt = _trim_contents_combo.get_active_text();
927 for (int i = 0; modifiers[i].name; ++i) {
928 if (txt == S_(modifiers[i].name)) {
929 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
935 void trim_overlap_modifier_chosen ()
937 string const txt = _trim_overlap_combo.get_active_text();
939 for (int i = 0; modifiers[i].name; ++i) {
940 if (txt == S_(modifiers[i].name)) {
941 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
947 void trim_anchored_modifier_chosen ()
949 string const txt = _trim_anchored_combo.get_active_text();
951 for (int i = 0; modifiers[i].name; ++i) {
952 if (txt == S_(modifiers[i].name)) {
953 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
959 void fine_adjust_modifier_chosen ()
961 string const txt = _fine_adjust_combo.get_active_text();
963 for (int i = 0; modifiers[i].name; ++i) {
964 if (txt == S_(modifiers[i].name)) {
965 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
971 void push_points_modifier_chosen ()
973 string const txt = _push_points_combo.get_active_text();
975 for (int i = 0; modifiers[i].name; ++i) {
976 if (txt == S_(modifiers[i].name)) {
977 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
983 void note_size_relative_modifier_chosen ()
985 string const txt = _note_size_relative_combo.get_active_text();
987 for (int i = 0; modifiers[i].name; ++i) {
988 if (txt == S_(modifiers[i].name)) {
989 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
995 void delete_button_changed ()
997 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
1000 void edit_button_changed ()
1002 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
1005 void insert_note_button_changed ()
1007 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
1010 void reset_to_defaults ()
1013 Keyboard::set_edit_modifier (Keyboard::PrimaryModifier);
1014 Keyboard::set_edit_button (3);
1015 Keyboard::set_delete_modifier (Keyboard::TertiaryModifier);
1016 Keyboard::set_delete_button (3);
1017 Keyboard::set_insert_note_modifier (Keyboard::PrimaryModifier);
1018 Keyboard::set_insert_note_button (1);
1020 /* when beginning a drag */
1022 Keyboard::set_copy_modifier (Keyboard::SecondaryModifier);
1024 Keyboard::set_copy_modifier (Keyboard::PrimaryModifier);
1028 ArdourKeyboard::set_constraint_modifier (Keyboard::PrimaryModifier);
1030 ArdourKeyboard::set_constraint_modifier (Keyboard::TertiaryModifier);
1032 ArdourKeyboard::set_push_points_modifier (Keyboard::PrimaryModifier | Keyboard::Level4Modifier);
1034 /* when beginning a trim */
1035 ArdourKeyboard::set_trim_contents_modifier (Keyboard::PrimaryModifier);
1036 ArdourKeyboard::set_trim_anchored_modifier (Keyboard::PrimaryModifier | Keyboard::TertiaryModifier);
1037 ArdourKeyboard::set_note_size_relative_modifier (Keyboard::TertiaryModifier); // XXX better: 2ndary
1039 /* while dragging */
1041 Keyboard::set_snap_modifier (Keyboard::TertiaryModifier);
1043 Keyboard::set_snap_modifier (Keyboard::SecondaryModifier);
1046 Keyboard::set_snap_delta_modifier (Keyboard::Level4Modifier);
1048 Keyboard::set_snap_delta_modifier (Keyboard::SecondaryModifier | Keyboard::Level4Modifier);
1051 /* while trimming */
1052 ArdourKeyboard::set_trim_overlap_modifier (Keyboard::TertiaryModifier);
1054 /* while dragging ctrl points */
1055 ArdourKeyboard::set_fine_adjust_modifier (/*Keyboard::PrimaryModifier | */Keyboard::SecondaryModifier); // XXX
1057 set_state_from_config ();
1060 ComboBoxText _keyboard_layout_selector;
1061 ComboBoxText _edit_modifier_combo;
1062 ComboBoxText _delete_modifier_combo;
1063 ComboBoxText _copy_modifier_combo;
1064 ComboBoxText _insert_note_modifier_combo;
1065 ComboBoxText _snap_modifier_combo;
1066 ComboBoxText _snap_delta_combo;
1067 ComboBoxText _constraint_modifier_combo;
1068 ComboBoxText _trim_contents_combo;
1069 ComboBoxText _trim_overlap_combo;
1070 ComboBoxText _trim_anchored_combo;
1071 ComboBoxText _trim_jump_combo;
1072 ComboBoxText _fine_adjust_combo;
1073 ComboBoxText _push_points_combo;
1074 ComboBoxText _note_size_relative_combo;
1075 Adjustment _delete_button_adjustment;
1076 SpinButton _delete_button_spin;
1077 Adjustment _edit_button_adjustment;
1078 SpinButton _edit_button_spin;
1079 Adjustment _insert_note_button_adjustment;
1080 SpinButton _insert_note_button_spin;
1084 class FontScalingOptions : public HSliderOption
1087 FontScalingOptions ()
1088 : HSliderOption ("font-scale", _("GUI and Font scaling"),
1089 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_font_scale),
1090 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_font_scale),
1094 const std::string dflt = _("100%");
1095 const std::string empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
1097 _hscale.set_name("FontScaleSlider");
1098 _hscale.set_draw_value(false);
1099 _hscale.add_mark(50, Gtk::POS_TOP, empty);
1100 _hscale.add_mark(60, Gtk::POS_TOP, empty);
1101 _hscale.add_mark(70, Gtk::POS_TOP, empty);
1102 _hscale.add_mark(80, Gtk::POS_TOP, empty);
1103 _hscale.add_mark(90, Gtk::POS_TOP, empty);
1104 _hscale.add_mark(100, Gtk::POS_TOP, dflt);
1105 _hscale.add_mark(125, Gtk::POS_TOP, empty);
1106 _hscale.add_mark(150, Gtk::POS_TOP, empty);
1107 _hscale.add_mark(175, Gtk::POS_TOP, empty);
1108 _hscale.add_mark(200, Gtk::POS_TOP, empty);
1109 _hscale.add_mark(250, Gtk::POS_TOP, empty);
1111 set_note (_("Adjusting the scale requires an application restart to re-layout."));
1116 HSliderOption::changed ();
1117 /* XXX: should be triggered from the parameter changed signal */
1118 UIConfiguration::instance().reset_dpi ();
1122 class VstTimeOutSliderOption : public HSliderOption
1125 VstTimeOutSliderOption (RCConfiguration* c)
1126 : HSliderOption ("vst-scan-timeout", _("Scan Time Out"),
1127 sigc::mem_fun (*c, &RCConfiguration::get_vst_scan_timeout),
1128 sigc::mem_fun (*c, &RCConfiguration::set_vst_scan_timeout),
1131 _label.set_alignment (1.0, 0.5); // match buttons below
1132 _hscale.set_digits (0);
1133 _hscale.set_draw_value(false);
1134 _hscale.add_mark( 0, Gtk::POS_TOP, _("\u221e")); // infinity
1135 _hscale.add_mark( 300, Gtk::POS_TOP, _("30 sec"));
1136 _hscale.add_mark( 600, Gtk::POS_TOP, _("1 min"));
1137 _hscale.add_mark(1200, Gtk::POS_TOP, _("2 mins"));
1138 _hscale.add_mark(1800, Gtk::POS_TOP, _("3 mins"));
1139 _hscale.add_mark(2400, Gtk::POS_TOP, _("4 mins"));
1140 _hscale.add_mark(3000, Gtk::POS_TOP, _("5 mins"));
1142 Gtkmm2ext::UI::instance()->set_tip(_hscale,
1143 _("Specify the default timeout for plugin instantiation. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1147 class ClipLevelOptions : public OptionEditorComponent
1151 : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1152 , _clip_level_slider (_clip_level_adjustment)
1153 , _label (_("Waveform Clip Level (dBFS):"))
1155 _label.set_name ("OptionsLabel");
1157 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ());
1159 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1161 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1164 void parameter_changed (string const & p)
1166 if (p == "waveform-clip-level") {
1167 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level());
1169 if (p == "show-waveform-clipping") {
1170 _clip_level_slider.set_sensitive (UIConfiguration::instance().get_show_waveform_clipping ());
1174 void set_state_from_config ()
1176 parameter_changed ("waveform-clip-level");
1177 parameter_changed ("show-waveform-clipping");
1180 void add_to_page (OptionEditorPage* p) {
1181 add_widgets_to_page (p, &_label, &_clip_level_slider);
1184 Gtk::Widget& tip_widget() {
1185 return _clip_level_slider;
1190 void clip_level_changed ()
1192 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1193 /* XXX: should be triggered from the parameter changed signal */
1194 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1197 Adjustment _clip_level_adjustment;
1198 HScale _clip_level_slider;
1202 class BufferingOptions : public OptionEditorComponent
1205 BufferingOptions (RCConfiguration* c)
1207 , _label (_("Preset:"))
1208 , _playback ("playback-buffer-seconds", _("Playback (seconds of buffering)"),
1209 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_playback_buffer_seconds),
1210 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_playback_buffer_seconds),
1212 , _capture ("capture-buffer-seconds", _("Recording (seconds of buffering)"),
1213 sigc::mem_fun (*_rc_config, &RCConfiguration::get_audio_capture_buffer_seconds),
1214 sigc::mem_fun (*_rc_config, &RCConfiguration::set_audio_capture_buffer_seconds),
1217 // TODO use ComboOption
1218 vector<string> presets;
1220 /* these must match the order of the enums for BufferingPreset */
1221 presets.push_back (_("Small sessions (4-16 tracks)"));
1222 presets.push_back (_("Medium sessions (16-64 tracks)"));
1223 presets.push_back (_("Large sessions (64+ tracks)"));
1224 presets.push_back (_("Custom (set by sliders below)"));
1226 set_popdown_strings (_buffering_presets_combo, presets);
1227 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1229 _label.set_name ("OptionsLabel");
1230 _label.set_alignment (0, 0.5);
1234 add_to_page (OptionEditorPage* p)
1236 add_widgets_to_page (p, &_label, &_buffering_presets_combo);
1237 _playback.add_to_page (p);
1238 _capture.add_to_page (p);
1241 void parameter_changed (string const & p)
1243 if (p == "buffering-preset") {
1244 switch (_rc_config->get_buffering_preset()) {
1246 _playback.set_sensitive (false);
1247 _capture.set_sensitive (false);
1248 _buffering_presets_combo.set_active (0);
1251 _playback.set_sensitive (false);
1252 _capture.set_sensitive (false);
1253 _buffering_presets_combo.set_active (1);
1256 _playback.set_sensitive (false);
1257 _capture.set_sensitive (false);
1258 _buffering_presets_combo.set_active (2);
1261 _playback.set_sensitive (true);
1262 _capture.set_sensitive (true);
1263 _buffering_presets_combo.set_active (3);
1267 _playback.parameter_changed (p);
1268 _capture.parameter_changed (p);
1271 void set_state_from_config ()
1273 parameter_changed ("buffering-preset");
1274 _playback.set_state_from_config();
1275 _capture.set_state_from_config();
1278 Gtk::Widget& tip_widget() { return _buffering_presets_combo; }
1282 void preset_changed ()
1284 int index = _buffering_presets_combo.get_active_row_number ();
1290 _rc_config->set_buffering_preset (Small);
1293 _rc_config->set_buffering_preset (Medium);
1296 _rc_config->set_buffering_preset (Large);
1299 _rc_config->set_buffering_preset (Custom);
1302 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1307 RCConfiguration* _rc_config;
1309 HSliderOption _playback;
1310 HSliderOption _capture;
1311 ComboBoxText _buffering_presets_combo;
1314 class ControlSurfacesOptions : public OptionEditorMiniPage
1317 ControlSurfacesOptions ()
1318 : _ignore_view_change (0)
1320 _store = ListStore::create (_model);
1321 _view.set_model (_store);
1322 _view.append_column (_("Control Surface Protocol"), _model.name);
1323 _view.get_column(0)->set_resizable (true);
1324 _view.get_column(0)->set_expand (true);
1325 _view.append_column_editable (_("Enable"), _model.enabled);
1327 Gtk::HBox* edit_box = manage (new Gtk::HBox);
1328 edit_box->set_spacing(3);
1331 Label* label = manage (new Label);
1332 label->set_text (_("Edit the settings for selected protocol (it must be ENABLED first):"));
1333 edit_box->pack_start (*label, false, false);
1336 edit_button = manage (new Button(_("Show Protocol Settings")));
1337 edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
1338 edit_box->pack_start (*edit_button, true, true);
1339 edit_button->set_sensitive (false);
1340 edit_button->show ();
1342 int const n = table.property_n_rows();
1343 table.resize (n + 2, 3);
1344 table.attach (_view, 0, 3, n, n + 1);
1345 table.attach (*edit_box, 0, 3, n + 1, n + 2);
1347 ControlProtocolManager& m = ControlProtocolManager::instance ();
1348 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1349 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1351 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1352 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1353 _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
1356 void parameter_changed (std::string const &)
1361 void set_state_from_config ()
1365 ControlProtocolManager& m = ControlProtocolManager::instance ();
1366 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1368 if (!(*i)->mandatory) {
1369 TreeModel::Row r = *_store->append ();
1370 r[_model.name] = (*i)->name;
1371 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1372 r[_model.protocol_info] = *i;
1379 void protocol_status_changed (ControlProtocolInfo* cpi) {
1381 TreeModel::Children rows = _store->children();
1383 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1384 string n = ((*x)[_model.name]);
1386 if ((*x)[_model.protocol_info] == cpi) {
1387 _ignore_view_change++;
1388 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1389 _ignore_view_change--;
1395 void selection_changed ()
1397 //enable the Edit button when a row is selected for editing
1398 TreeModel::Row row = *(_view.get_selection()->get_selected());
1399 if (row && row[_model.enabled])
1400 edit_button->set_sensitive (true);
1402 edit_button->set_sensitive (false);
1405 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1407 TreeModel::Row r = *i;
1409 if (_ignore_view_change) {
1413 ControlProtocolInfo* cpi = r[_model.protocol_info];
1418 bool const was_enabled = (cpi->protocol != 0);
1419 bool const is_enabled = r[_model.enabled];
1422 if (was_enabled != is_enabled) {
1425 ControlProtocolManager::instance().activate (*cpi);
1427 ControlProtocolManager::instance().deactivate (*cpi);
1431 selection_changed ();
1434 void edit_btn_clicked ()
1437 ControlProtocolInfo* cpi;
1440 row = *(_view.get_selection()->get_selected());
1441 if (!row[_model.enabled]) {
1444 cpi = row[_model.protocol_info];
1445 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1448 Box* box = (Box*) cpi->protocol->get_gui ();
1452 if (box->get_parent()) {
1453 static_cast<ArdourWindow*>(box->get_parent())->present();
1456 WindowTitle title (Glib::get_application_name());
1457 title += row[_model.name];
1458 title += _("Configuration");
1459 /* once created, the window is managed by the surface itself (as ->get_parent())
1460 * Surface's tear_down_gui() is called on session close, when de-activating
1461 * or re-initializing a surface.
1462 * tear_down_gui() hides an deletes the Window if it exists.
1464 ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
1465 win->set_title ("Control Protocol Options");
1471 void edit_clicked (GdkEventButton* ev)
1473 if (ev->type != GDK_2BUTTON_PRESS) {
1480 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1484 ControlSurfacesModelColumns ()
1488 add (protocol_info);
1491 TreeModelColumn<string> name;
1492 TreeModelColumn<bool> enabled;
1493 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1496 Glib::RefPtr<ListStore> _store;
1497 ControlSurfacesModelColumns _model;
1499 PBD::ScopedConnection protocol_status_connection;
1500 uint32_t _ignore_view_change;
1501 Gtk::Button* edit_button;
1504 class VideoTimelineOptions : public OptionEditorMiniPage
1507 VideoTimelineOptions (RCConfiguration* c)
1509 , _show_video_export_info_button (_("Show Video Export Info before export"))
1510 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1511 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1512 , _xjadeo_browse_button (_("Browse..."))
1515 int n = table.property_n_rows();
1517 t->attach (_show_video_export_info_button, 1, 4, n, n + 1);
1518 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1519 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1520 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1523 t->attach (_show_video_server_dialog_button, 1, 4, n, n + 1);
1524 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1525 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1526 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1529 t->attach (_video_advanced_setup_button, 1, 4, n, n + 1, FILL);
1530 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1531 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1532 _("<b>When enabled</b> you can speficify a custom video-server URL and docroot. - Do not enable this option unless you know what you are doing."));
1535 Label* l = manage (new Label (_("Video Server URL:")));
1536 l->set_alignment (0, 0.5);
1537 t->attach (*l, 1, 2, n, n + 1, FILL);
1538 t->attach (_video_server_url_entry, 2, 4, n, n + 1, FILL);
1539 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1540 _("Base URL of the video-server including http prefix. This is usually 'http://hostname.example.org:1554/' and defaults to 'http://localhost:1554/' when the video-server is running locally"));
1543 l = manage (new Label (_("Video Folder:")));
1544 l->set_alignment (0, 0.5);
1545 t->attach (*l, 1, 2, n, n + 1, FILL);
1546 t->attach (_video_server_docroot_entry, 2, 4, n, n + 1);
1547 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1548 _("Local path to the video-server document-root. Only files below this directory will be accessible by the video-server. If the server run on a remote host, it should point to a network mounted folder of the server's docroot or be left empty if it is unvailable. It is used for the local video-monitor and file-browsing when opening/adding a video file."));
1551 l = manage (new Label (""));
1552 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1555 l = manage (new Label (string_compose ("<b>%1</b>", _("Video Monitor"))));
1556 l->set_use_markup (true);
1557 l->set_alignment (0, 0.5);
1558 t->attach (*l, 0, 4, n, n + 1, EXPAND | FILL);
1561 l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"),
1564 #elif defined PLATFORM_WINDOWS
1570 l->set_alignment (0, 0.5);
1571 t->attach (*l, 1, 4, n, n + 1, FILL);
1574 t->attach (_custom_xjadeo_path, 2, 3, n, n + 1, EXPAND|FILL);
1575 Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart."));
1576 t->attach (_xjadeo_browse_button, 3, 4, n, n + 1, FILL);
1578 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1579 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1580 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1581 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1582 _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed));
1583 _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked));
1585 // xjadeo-path is a UIConfig parameter
1586 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &VideoTimelineOptions::parameter_changed));
1589 void server_url_changed ()
1591 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1594 void server_docroot_changed ()
1596 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1599 void show_video_export_info_toggled ()
1601 bool const x = _show_video_export_info_button.get_active ();
1602 _rc_config->set_show_video_export_info (x);
1605 void show_video_server_dialog_toggled ()
1607 bool const x = _show_video_server_dialog_button.get_active ();
1608 _rc_config->set_show_video_server_dialog (x);
1611 void video_advanced_setup_toggled ()
1613 bool const x = _video_advanced_setup_button.get_active ();
1614 _rc_config->set_video_advanced_setup(x);
1617 void custom_xjadeo_path_changed ()
1619 UIConfiguration::instance().set_xjadeo_binary (_custom_xjadeo_path.get_text());
1622 void xjadeo_browse_clicked ()
1624 Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN);
1625 dialog.set_filename (UIConfiguration::instance().get_xjadeo_binary());
1626 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1627 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1628 if (dialog.run () == Gtk::RESPONSE_OK) {
1629 const std::string& filename = dialog.get_filename();
1630 if (!filename.empty() && (
1632 Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) ||
1634 Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)
1636 UIConfiguration::instance().set_xjadeo_binary (filename);
1641 void parameter_changed (string const & p)
1643 if (p == "video-server-url") {
1644 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1645 } else if (p == "video-server-docroot") {
1646 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1647 } else if (p == "show-video-export-info") {
1648 bool const x = _rc_config->get_show_video_export_info();
1649 _show_video_export_info_button.set_active (x);
1650 } else if (p == "show-video-server-dialog") {
1651 bool const x = _rc_config->get_show_video_server_dialog();
1652 _show_video_server_dialog_button.set_active (x);
1653 } else if (p == "video-advanced-setup") {
1654 bool const x = _rc_config->get_video_advanced_setup();
1655 _video_advanced_setup_button.set_active(x);
1656 _video_server_docroot_entry.set_sensitive(x);
1657 _video_server_url_entry.set_sensitive(x);
1658 } else if (p == "xjadeo-binary") {
1659 _custom_xjadeo_path.set_text (UIConfiguration::instance().get_xjadeo_binary());
1663 void set_state_from_config ()
1665 parameter_changed ("video-server-url");
1666 parameter_changed ("video-server-docroot");
1667 parameter_changed ("video-monitor-setup-dialog");
1668 parameter_changed ("show-video-export-info");
1669 parameter_changed ("show-video-server-dialog");
1670 parameter_changed ("video-advanced-setup");
1671 parameter_changed ("xjadeo-binary");
1675 RCConfiguration* _rc_config;
1676 Entry _video_server_url_entry;
1677 Entry _video_server_docroot_entry;
1678 Entry _custom_xjadeo_path;
1679 CheckButton _show_video_export_info_button;
1680 CheckButton _show_video_server_dialog_button;
1681 CheckButton _video_advanced_setup_button;
1682 Button _xjadeo_browse_button;
1685 class ColumVisibilityOption : public Option
1688 ColumVisibilityOption (string id, string name, uint32_t n_col, sigc::slot<uint32_t> get, sigc::slot<bool, uint32_t> set)
1695 cb = (CheckButton**) malloc (sizeof (CheckButton*) * n_col);
1696 for (uint32_t i = 0; i < n_col; ++i) {
1697 CheckButton* col = manage (new CheckButton (string_compose (_("Column %1"), i + 1)));
1698 col->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ColumVisibilityOption::column_toggled), i));
1699 _hbox.pack_start (*col);
1702 parameter_changed (id);
1705 ~ColumVisibilityOption () {
1709 Gtk::Widget& tip_widget() { return _hbox; }
1711 void set_state_from_config ()
1713 uint32_t c = _get();
1714 for (uint32_t i = 0; i < _n_col; ++i) {
1715 bool en = (c & (1<<i)) ? true : false;
1716 if (cb[i]->get_active () != en) {
1717 cb[i]->set_active (en);
1722 void add_to_page (OptionEditorPage* p)
1724 _heading.add_to_page (p);
1725 add_widget_to_page (p, &_hbox);
1729 void column_toggled (int b) {
1730 uint32_t c = _get();
1732 if (cb[b]->get_active ()) {
1743 OptionEditorHeading _heading;
1747 sigc::slot<uint32_t> _get;
1748 sigc::slot<bool, uint32_t> _set;
1752 /** A class which allows control of visibility of some editor components usign
1753 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1754 * which has the correct members, but with null widget pointers. This
1755 * class allows the user to set visibility of the members, the details
1756 * of which are stored in a configuration variable which can be watched
1757 * by parts of the editor that actually contain the widgets whose visibility
1758 * is being controlled.
1761 class VisibilityOption : public Option
1764 /** @param name User-visible name for this group.
1765 * @param g `Dummy' VisibilityGroup (as described above).
1766 * @param get Method to get the value of the appropriate configuration variable.
1767 * @param set Method to set the value of the appropriate configuration variable.
1769 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1770 : Option (g->get_state_name(), name)
1772 , _visibility_group (g)
1776 /* Watch for changes made by the user to our members */
1777 _visibility_group->VisibilityChanged.connect_same_thread (
1778 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1782 void set_state_from_config ()
1784 /* Set our state from the current configuration */
1785 _visibility_group->set_state (_get ());
1788 void add_to_page (OptionEditorPage* p)
1790 _heading.add_to_page (p);
1791 add_widget_to_page (p, _visibility_group->list_view ());
1794 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1799 /* The user has changed something, so reflect this change
1800 in the RCConfiguration.
1802 _set (_visibility_group->get_state_value ());
1805 OptionEditorHeading _heading;
1806 VisibilityGroup* _visibility_group;
1807 sigc::slot<std::string> _get;
1808 sigc::slot<bool, std::string> _set;
1809 PBD::ScopedConnection _visibility_group_connection;
1813 class MidiPortOptions : public OptionEditorMiniPage, public sigc::trackable
1818 setup_midi_port_view (midi_output_view, false);
1819 setup_midi_port_view (midi_input_view, true);
1821 OptionEditorHeading* h = new OptionEditorHeading (_("MIDI Inputs"));
1822 h->add_to_page (this);
1824 Gtk::ScrolledWindow* scroller = manage (new Gtk::ScrolledWindow);
1825 scroller->add (midi_input_view);
1826 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1827 scroller->set_size_request (-1, 180);
1829 int n = table.property_n_rows();
1830 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1832 h = new OptionEditorHeading (_("MIDI Outputs"));
1833 h->add_to_page (this);
1835 scroller = manage (new Gtk::ScrolledWindow);
1836 scroller->add (midi_output_view);
1837 scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
1838 scroller->set_size_request (-1, 180);
1840 n = table.property_n_rows();
1841 table.attach (*scroller, 0, 3, n, n + 1, FILL | EXPAND);
1843 midi_output_view.show ();
1844 midi_input_view.show ();
1846 table.signal_show().connect (sigc::mem_fun (*this, &MidiPortOptions::on_show));
1849 void parameter_changed (string const&) {}
1850 void set_state_from_config() {}
1855 AudioEngine::instance()->PortRegisteredOrUnregistered.connect (connections,
1856 invalidator (*this),
1857 boost::bind (&MidiPortOptions::refill, this),
1859 AudioEngine::instance()->MidiPortInfoChanged.connect (connections,
1860 invalidator (*this),
1861 boost::bind (&MidiPortOptions::refill, this),
1863 AudioEngine::instance()->MidiSelectionPortsChanged.connect (connections,
1864 invalidator (*this),
1865 boost::bind (&MidiPortOptions::refill, this),
1871 if (refill_midi_ports (true, midi_input_view)) {
1872 input_label.show ();
1874 input_label.hide ();
1876 if (refill_midi_ports (false, midi_output_view)) {
1877 output_label.show ();
1879 output_label.hide ();
1884 PBD::ScopedConnectionList connections;
1886 /* MIDI port management */
1887 struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord {
1889 MidiPortColumns () {
1898 Gtk::TreeModelColumn<std::string> pretty_name;
1899 Gtk::TreeModelColumn<bool> music_data;
1900 Gtk::TreeModelColumn<bool> control_data;
1901 Gtk::TreeModelColumn<bool> selection;
1902 Gtk::TreeModelColumn<std::string> name;
1903 Gtk::TreeModelColumn<std::string> filler;
1906 MidiPortColumns midi_port_columns;
1907 Gtk::TreeView midi_input_view;
1908 Gtk::TreeView midi_output_view;
1909 Gtk::Label input_label;
1910 Gtk::Label output_label;
1912 void setup_midi_port_view (Gtk::TreeView&, bool with_selection);
1913 bool refill_midi_ports (bool for_input, Gtk::TreeView&);
1914 void pretty_name_edit (std::string const & path, std::string const & new_text, Gtk::TreeView*);
1915 void midi_music_column_toggled (std::string const & path, Gtk::TreeView*);
1916 void midi_control_column_toggled (std::string const & path, Gtk::TreeView*);
1917 void midi_selection_column_toggled (std::string const & path, Gtk::TreeView*);
1921 MidiPortOptions::setup_midi_port_view (Gtk::TreeView& view, bool with_selection)
1923 int pretty_name_column;
1926 int selection_column;
1927 TreeViewColumn* col;
1930 pretty_name_column = view.append_column_editable (_("Name (click to edit)"), midi_port_columns.pretty_name) - 1;
1932 col = manage (new TreeViewColumn ("", midi_port_columns.music_data));
1933 col->set_alignment (ALIGN_CENTER);
1934 l = manage (new Label (_("Music Data")));
1935 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of music performance data."), PROGRAM_NAME));
1936 col->set_widget (*l);
1938 music_column = view.append_column (*col) - 1;
1940 col = manage (new TreeViewColumn ("", midi_port_columns.control_data));
1941 col->set_alignment (ALIGN_CENTER);
1942 l = manage (new Label (_("Control Data")));
1943 set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of control data."), PROGRAM_NAME));
1944 col->set_widget (*l);
1946 control_column = view.append_column (*col) - 1;
1948 if (with_selection) {
1949 col = manage (new TreeViewColumn (_("Follow Selection"), midi_port_columns.selection));
1950 selection_column = view.append_column (*col) - 1;
1951 l = manage (new Label (_("Follow Selection")));
1952 set_tooltip (*l, string_compose (_("If ticked, and \"MIDI input follows selection\" is enabled,\n%1 will automatically connect the first selected MIDI track to this port.\n"), PROGRAM_NAME));
1953 col->set_widget (*l);
1957 /* filler column so that the last real column doesn't expand */
1958 view.append_column ("", midi_port_columns.filler);
1960 CellRendererText* pretty_name_cell = dynamic_cast<CellRendererText*> (view.get_column_cell_renderer (pretty_name_column));
1961 pretty_name_cell->property_editable() = true;
1962 pretty_name_cell->signal_edited().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::pretty_name_edit), &view));
1964 CellRendererToggle* toggle_cell;
1966 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (music_column));
1967 toggle_cell->property_activatable() = true;
1968 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_music_column_toggled), &view));
1970 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (control_column));
1971 toggle_cell->property_activatable() = true;
1972 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_control_column_toggled), &view));
1974 if (with_selection) {
1975 toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (selection_column));
1976 toggle_cell->property_activatable() = true;
1977 toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_selection_column_toggled), &view));
1980 view.get_selection()->set_mode (SELECTION_NONE);
1981 view.set_tooltip_column (4); /* port "real" name */
1982 view.get_column(0)->set_resizable (true);
1983 view.get_column(0)->set_expand (true);
1987 MidiPortOptions::refill_midi_ports (bool for_input, Gtk::TreeView& view)
1989 using namespace ARDOUR;
1991 std::vector<string> ports;
1993 AudioEngine::instance()->get_known_midi_ports (ports);
1995 if (ports.empty()) {
2000 Glib::RefPtr<ListStore> model = Gtk::ListStore::create (midi_port_columns);
2002 for (vector<string>::const_iterator s = ports.begin(); s != ports.end(); ++s) {
2004 if (AudioEngine::instance()->port_is_mine (*s)) {
2008 PortManager::MidiPortInformation mpi (AudioEngine::instance()->midi_port_information (*s));
2010 if (mpi.pretty_name.empty()) {
2011 /* vanished since get_known_midi_ports() */
2015 if (for_input != mpi.input) {
2019 TreeModel::Row row = *(model->append());
2021 row[midi_port_columns.pretty_name] = mpi.pretty_name;
2022 row[midi_port_columns.music_data] = mpi.properties & MidiPortMusic;
2023 row[midi_port_columns.control_data] = mpi.properties & MidiPortControl;
2024 row[midi_port_columns.selection] = mpi.properties & MidiPortSelection;
2025 row[midi_port_columns.name] = *s;
2028 view.set_model (model);
2034 MidiPortOptions::midi_music_column_toggled (string const & path, TreeView* view)
2036 TreeIter iter = view->get_model()->get_iter (path);
2042 bool new_value = ! bool ((*iter)[midi_port_columns.music_data]);
2044 /* don't reset model - wait for MidiPortInfoChanged signal */
2047 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2049 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
2054 MidiPortOptions::midi_control_column_toggled (string const & path, TreeView* view)
2056 TreeIter iter = view->get_model()->get_iter (path);
2062 bool new_value = ! bool ((*iter)[midi_port_columns.control_data]);
2064 /* don't reset model - wait for MidiPortInfoChanged signal */
2067 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2069 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
2074 MidiPortOptions::midi_selection_column_toggled (string const & path, TreeView* view)
2076 TreeIter iter = view->get_model()->get_iter (path);
2082 bool new_value = ! bool ((*iter)[midi_port_columns.selection]);
2084 /* don't reset model - wait for MidiSelectionPortsChanged signal */
2087 ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2089 ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
2094 MidiPortOptions::pretty_name_edit (std::string const & path, string const & new_text, Gtk::TreeView* view)
2096 TreeIter iter = view->get_model()->get_iter (path);
2102 boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
2104 ARDOUR::PortEngine::PortHandle ph = backend->get_port_by_name ((*iter)[midi_port_columns.name]);
2106 backend->set_port_property (ph, "http://jackaudio.org/metadata/pretty-name", new_text, "");
2107 (*iter)[midi_port_columns.pretty_name] = new_text;
2115 RCOptionEditor::RCOptionEditor ()
2116 : OptionEditorContainer (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
2117 , Tabbable (*this, _("Preferences")) /* pack self-as-vbox into tabbable */
2118 , _rc_config (Config)
2119 , _mixer_strip_visibility ("mixer-element-visibility")
2121 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
2125 uint32_t hwcpus = hardware_concurrency ();
2127 BoolComboOption* bco;
2130 add_option (_("General"), new OptionEditorHeading (_("DSP CPU Utilization")));
2132 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
2134 _("Signal processing uses"),
2135 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
2136 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
2139 procs->add (-1, _("all but one processor"));
2140 procs->add (0, _("all available processors"));
2142 for (uint32_t i = 1; i <= hwcpus; ++i) {
2143 procs->add (i, string_compose (P_("%1 processor", "%1 processors", i), i));
2146 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
2148 add_option (_("General"), procs);
2151 /* Image cache size */
2152 add_option (_("General"), new OptionEditorHeading (_("Memory Usage")));
2154 HSliderOption *sics = new HSliderOption ("waveform-cache-size",
2155 _("Waveform image cache size (megabytes)"),
2156 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
2157 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size),
2158 1, 1024, 10 /* 1 MB to 1GB in steps of 10MB */
2160 sics->scale().set_digits (0);
2161 Gtkmm2ext::UI::instance()->set_tip (
2163 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
2164 add_option (_("General"), sics);
2166 add_option (_("General"), new OptionEditorHeading (_("Engine")));
2168 add_option (_("General"),
2170 "try-autostart-engine",
2171 _("Try to auto-launch audio/midi engine"),
2172 sigc::mem_fun (*_rc_config, &RCConfiguration::get_try_autostart_engine),
2173 sigc::mem_fun (*_rc_config, &RCConfiguration::set_try_autostart_engine)
2176 add_option (_("General"), new OptionEditorHeading (_("Automation")));
2178 add_option (_("General"),
2179 new SpinOption<double> (
2180 "automation-thinning-factor",
2181 _("Thinning factor (larger value => less data)"),
2182 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
2183 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
2187 add_option (_("General"),
2188 new SpinOption<double> (
2189 "automation-interval-msecs",
2190 _("Automation sampling interval (milliseconds)"),
2191 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
2192 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
2196 add_option (_("General"), new OptionEditorHeading (_("Tempo")));
2198 bo = new BoolOption (
2199 "allow-non-quarter-pulse",
2200 _("Allow non quarter-note pulse"),
2201 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_allow_non_quarter_pulse),
2202 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_allow_non_quarter_pulse)
2204 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2205 string_compose (_("<b>When enabled</b> %1 will allow tempo to be expressed in divisions per minute\n"
2206 "<b>When disabled</b> %1 will only allow tempo to be expressed in quarter notes per minute"),
2208 add_option (_("General"), bo);
2210 if (!ARDOUR::Profile->get_mixbus()) {
2211 add_option (_("General"), new OptionEditorHeading (_("GUI Lock")));
2212 /* Lock GUI timeout */
2214 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2215 _("Lock timeout (seconds)"),
2216 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
2217 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds),
2220 slts->scale().set_digits (0);
2221 Gtkmm2ext::UI::instance()->set_tip (
2223 _("Lock GUI after this many idle seconds (zero to never lock)"));
2224 add_option (_("General"), slts);
2227 add_option (_("General/Session"), new OptionEditorHeading (S_("Options|Undo")));
2229 add_option (_("General/Session"), new UndoOptions (_rc_config));
2231 add_option (_("General/Session"),
2233 "verify-remove-last-capture",
2234 _("Verify removal of last capture"),
2235 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
2236 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
2239 add_option (_("General/Session"), new OptionEditorHeading (_("Session Management")));
2241 add_option (_("General/Session"),
2243 "periodic-safety-backups",
2244 _("Make periodic backups of the session file"),
2245 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
2246 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
2249 add_option (_("General/Session"),
2251 "only-copy-imported-files",
2252 _("Always copy imported files"),
2253 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
2254 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
2257 add_option (_("General/Session"), new DirectoryOption (
2258 X_("default-session-parent-dir"),
2259 _("Default folder for new sessions:"),
2260 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
2261 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
2264 add_option (_("General/Session"),
2265 new SpinOption<uint32_t> (
2266 "max-recent-sessions",
2267 _("Maximum number of recent sessions"),
2268 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
2269 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
2276 add_option (_("General/Translation"), new OptionEditorHeading (_("Internationalization")));
2278 bo = new BoolOption (
2279 "enable-translation",
2280 _("Use translations"),
2281 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2282 sigc::ptr_fun (ARDOUR::set_translations_enabled)
2285 bo->set_note (string_compose (_("These settings will only take effect after %1 is restarted (if available for your language preferences)."), PROGRAM_NAME));
2287 add_option (_("General/Translation"), bo);
2289 _l10n = new ComboOption<ARDOUR::LocaleMode> (
2292 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_locale_mode),
2293 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_locale_mode)
2296 _l10n->add (ARDOUR::SET_LC_ALL, _("Set complete locale"));
2297 _l10n->add (ARDOUR::SET_LC_MESSAGES, _("Enable only message translation"));
2298 _l10n->add (ARDOUR::SET_LC_MESSAGES_AND_LC_NUMERIC, _("Translate messages and format numeric format"));
2299 _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."));
2301 add_option (_("General/Translation"), _l10n);
2302 parameter_changed ("enable-translation");
2303 #endif // ENABLE_NLS
2308 add_option (_("Editor"), new OptionEditorHeading (_("General")));
2310 add_option (_("Editor"),
2312 "rubberbanding-snaps-to-grid",
2313 _("Snap rubberband to grid"),
2314 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2315 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2318 bo = new BoolOption (
2320 _("Prompt for new marker names"),
2321 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2322 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2324 add_option (_("Editor"), bo);
2325 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."
2326 "\n\nYou can always rename markers by right-clicking on them"));
2328 add_option (_("Editor"),
2330 "draggable-playhead",
2331 _("Allow dragging of playhead"),
2332 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2333 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2336 if (!Profile->get_mixbus()) {
2338 add_option (_("Editor"),
2340 "use-mouse-position-as-zoom-focus-on-scroll",
2341 _("Zoom to mouse position when zooming with scroll wheel"),
2342 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2343 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2347 add_option (_("Editor"),
2349 "use-time-rulers-to-zoom-with-vertical-drag",
2350 _("Zoom with vertical drag in rulers"),
2351 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag),
2352 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag)
2355 add_option (_("Editor"),
2357 "use-double-click-to-zoom-to-selection",
2358 _("Double click zooms to selection"),
2359 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection),
2360 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection)
2363 add_option (_("Editor"),
2365 "update-editor-during-summary-drag",
2366 _("Update editor window during drags of the summary"),
2367 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2368 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2371 add_option (_("Editor"),
2373 "autoscroll-editor",
2374 _("Auto-scroll editor window when dragging near its edges"),
2375 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2376 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2379 add_option (_("Editor"),
2380 new BoolComboOption (
2381 "show-region-gain-envelopes",
2382 _("Show gain envelopes in audio regions"),
2384 _("only in Draw and Internal Edit modes"),
2385 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2386 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2389 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2391 add_option (_("Editor"),
2393 "automation-follows-regions",
2394 _("Move relevant automation when audio regions are moved"),
2395 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2396 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2399 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2400 "default-fade-shape",
2401 _("Default fade shape"),
2402 sigc::mem_fun (*_rc_config,
2403 &RCConfiguration::get_default_fade_shape),
2404 sigc::mem_fun (*_rc_config,
2405 &RCConfiguration::set_default_fade_shape)
2408 fadeshape->add (FadeLinear,
2409 _("Linear (for highly correlated material)"));
2410 fadeshape->add (FadeConstantPower, _("Constant power"));
2411 fadeshape->add (FadeSymmetric, _("Symmetric"));
2412 fadeshape->add (FadeSlow, _("Slow"));
2413 fadeshape->add (FadeFast, _("Fast"));
2415 add_option (_("Editor"), fadeshape);
2417 bco = new BoolComboOption (
2418 "use-overlap-equivalency",
2419 _("Regions in edit groups are edited together"),
2420 _("whenever they overlap in time"),
2421 _("only if they have identical length and position"),
2422 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2423 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2426 add_option (_("Editor"), bco);
2428 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2430 _("Layering model"),
2431 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2432 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2435 lm->add (LaterHigher, _("later is higher"));
2436 lm->add (Manual, _("manual layering"));
2437 add_option (_("Editor"), lm);
2439 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2440 "region-selection-after-split",
2441 _("After splitting selected regions, select"),
2442 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2443 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2445 // TODO: decide which of these modes are really useful
2446 rsas->add(None, _("no regions"));
2447 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2448 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2449 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2450 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2451 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2452 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2453 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2455 add_option (_("Editor"), rsas);
2457 add_option (_("Editor/Modifiers"), new OptionEditorHeading (_("Keyboard Modifiers")));
2458 add_option (_("Editor/Modifiers"), new KeyboardOptions);
2459 add_option (_("Editor/Modifiers"), new OptionEditorBlank ());
2461 /* MIXER -- SOLO AND MUTE */
2463 add_option (_("Mixer"), new OptionEditorHeading (_("Solo")));
2465 _solo_control_is_listen_control = new BoolOption (
2466 "solo-control-is-listen-control",
2467 _("Solo controls are Listen controls"),
2468 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2469 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2472 add_option (_("Mixer"), _solo_control_is_listen_control);
2474 add_option (_("Mixer"),
2477 _("Exclusive solo"),
2478 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2479 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2482 add_option (_("Mixer"),
2485 _("Show solo muting"),
2486 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2487 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2490 add_option (_("Mixer"),
2492 "solo-mute-override",
2493 _("Soloing overrides muting"),
2494 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2495 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2498 add_option (_("Mixer"),
2501 _("Solo-in-place mute cut (dB)"),
2502 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2503 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2506 _listen_position = new ComboOption<ListenPosition> (
2508 _("Listen Position"),
2509 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2510 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2513 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2514 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2516 add_option (_("Mixer"), _listen_position);
2518 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2520 _("PFL signals come from"),
2521 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2522 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2525 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2526 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2528 add_option (_("Mixer"), pp);
2530 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2532 _("AFL signals come from"),
2533 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2534 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2537 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2538 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2540 add_option (_("Mixer"), pa);
2542 add_option (_("Mixer"), new OptionEditorHeading (_("Default Track / Bus Muting Options")));
2544 add_option (_("Mixer"),
2546 "mute-affects-pre-fader",
2547 _("Mute affects pre-fader sends"),
2548 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2549 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2552 add_option (_("Mixer"),
2554 "mute-affects-post-fader",
2555 _("Mute affects post-fader sends"),
2556 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2557 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2560 add_option (_("Mixer"),
2562 "mute-affects-control-outs",
2563 _("Mute affects control outputs"),
2564 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2565 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2568 add_option (_("Mixer"),
2570 "mute-affects-main-outs",
2571 _("Mute affects main outputs"),
2572 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2573 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2577 if (!ARDOUR::Profile->get_mixbus()) {
2578 add_option (_("Mixer"), new OptionEditorHeading (_("Send Routing")));
2579 add_option (_("Mixer"),
2581 "link-send-and-route-panner",
2582 _("Link panners of Aux and External Sends with main panner by default"),
2583 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2584 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2590 add_option (_("Signal Flow"), new OptionEditorHeading (_("Monitoring")));
2592 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2594 _("Record monitoring handled by"),
2595 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2596 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2599 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2600 mm->add (HardwareMonitoring, _("via Audio Driver"));
2603 string prog (PROGRAM_NAME);
2604 boost::algorithm::to_lower (prog);
2605 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2606 mm->add (ExternalMonitoring, _("audio hardware"));
2608 add_option (_("Signal Flow"), mm);
2610 bo = new BoolOption (
2611 "tape-machine-mode",
2612 _("Tape machine mode"),
2613 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2614 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2616 add_option (_("Signal Flow"), bo);
2617 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2618 string_compose (_("<b>When enabled</b> %1 will not monitor a track's input if the transport is stopped."),
2621 if (!Profile->get_mixbus()) {
2623 add_option (_("Signal Flow"), new OptionEditorHeading (_("Track and Bus Connections")));
2625 add_option (_("Signal Flow"),
2627 "auto-connect-standard-busses",
2628 _("Auto-connect master/monitor busses"),
2629 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2630 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2633 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2634 "input-auto-connect",
2635 _("Connect track inputs"),
2636 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2637 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2640 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2641 iac->add (ManualConnect, _("manually"));
2643 add_option (_("Signal Flow"), iac);
2645 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2646 "output-auto-connect",
2647 _("Connect track and bus outputs"),
2648 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2649 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2652 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2653 oac->add (AutoConnectMaster, _("automatically to master bus"));
2654 oac->add (ManualConnect, _("manually"));
2656 add_option (_("Signal Flow"), oac);
2658 bo = new BoolOption (
2660 _("Use 'Strict-I/O' for new tracks or Busses"),
2661 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2662 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2665 add_option (_("Signal Flow"), bo);
2666 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2667 _("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."));
2674 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2676 add_option (_("Audio"), new BufferingOptions (_rc_config));
2678 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2680 add_option (_("Audio"),
2682 "denormal-protection",
2683 _("Use DC bias to protect against denormals"),
2684 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2685 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2688 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2690 _("Processor handling"),
2691 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2692 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2696 dm->add (DenormalNone, _("no processor handling"));
2698 FPU* fpu = FPU::instance();
2700 if (fpu->has_flush_to_zero()) {
2702 dm->add (DenormalFTZ, _("use FlushToZero"));
2703 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2704 _rc_config->set_denormal_model(DenormalNone);
2707 if (fpu->has_denormals_are_zero()) {
2709 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2710 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2711 _rc_config->set_denormal_model(DenormalNone);
2714 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2716 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2717 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2718 _rc_config->set_denormal_model(DenormalNone);
2722 dm->set_sensitive(false);
2725 add_option (_("Audio"), dm);
2727 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2729 add_option (_("Audio"),
2731 "auto-analyse-audio",
2732 _("Enable automatic analysis of audio"),
2733 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2734 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2737 add_option (_("Audio"),
2739 "replicate-missing-region-channels",
2740 _("Replicate missing region channels"),
2741 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2742 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2747 add_option (_("MIDI"), new OptionEditorHeading (_("Buffering")));
2749 add_option (_("MIDI"),
2750 new SpinOption<float> (
2752 _("MIDI read-ahead time (seconds)"),
2753 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2754 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2759 add_option (_("MIDI"), new OptionEditorHeading (_("Session")));
2761 add_option (_("MIDI"),
2762 new SpinOption<int32_t> (
2763 "initial-program-change",
2764 _("Initial program change"),
2765 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2766 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2770 add_option (_("MIDI"), new OptionEditorHeading (_("Audition")));
2772 add_option (_("MIDI"),
2775 _("Sound MIDI notes as they are selected in the editor"),
2776 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2777 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2780 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2781 "midi-audition-synth-uri",
2782 _("MIDI Audition Synth (LV2)"),
2783 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2784 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2787 audition_synth->add(X_(""), _("None"));
2788 PluginInfoList all_plugs;
2789 PluginManager& manager (PluginManager::instance());
2791 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2793 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2794 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2795 if (!(*i)->is_instrument()) continue;
2796 if ((*i)->type != ARDOUR::LV2) continue;
2797 if ((*i)->name.length() > 46) {
2798 audition_synth->add((*i)->unique_id, (*i)->name.substr (0, 44) + "...");
2800 audition_synth->add((*i)->unique_id, (*i)->name);
2805 add_option (_("MIDI"), audition_synth);
2809 add_option (_("Metronome"), new OptionEditorHeading (_("Metronome")));
2810 add_option (_("Metronome"), new ClickOptions (_rc_config));
2814 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2816 ComboOption<float>* mht = new ComboOption<float> (
2818 _("Peak hold time"),
2819 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
2820 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
2823 mht->add (MeterHoldOff, _("off"));
2824 mht->add (MeterHoldShort, _("short"));
2825 mht->add (MeterHoldMedium, _("medium"));
2826 mht->add (MeterHoldLong, _("long"));
2828 add_option (S_("Preferences|Metering"), mht);
2830 ComboOption<float>* mfo = new ComboOption<float> (
2833 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2834 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2837 mfo->add (METER_FALLOFF_OFF, _("off"));
2838 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2839 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2840 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2841 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2842 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2843 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
2845 add_option (S_("Preferences|Metering"), mfo);
2847 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2848 "meter-line-up-level",
2849 _("Meter line-up level; 0dBu"),
2850 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
2851 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
2854 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2855 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2856 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2857 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2859 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."));
2861 add_option (S_("Preferences|Metering"), mlu);
2863 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2864 "meter-line-up-din",
2865 _("IEC1/DIN Meter line-up level; 0dBu"),
2866 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
2867 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
2870 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2871 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2872 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2873 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2875 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2877 add_option (S_("Preferences|Metering"), mld);
2879 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2880 "meter-vu-standard",
2881 _("VU Meter standard"),
2882 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
2883 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
2886 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2887 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2888 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2889 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2891 add_option (S_("Preferences|Metering"), mvu);
2893 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
2894 "meter-type-master",
2895 _("Default Meter Type for Master Bus"),
2896 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
2897 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
2899 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2900 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2901 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2902 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2903 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2904 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2905 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2906 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
2908 add_option (S_("Preferences|Metering"), mtm);
2911 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
2913 _("Default Meter Type for Busses"),
2914 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
2915 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
2917 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2918 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2919 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2920 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2921 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2922 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2923 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2924 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
2926 add_option (S_("Preferences|Metering"), mtb);
2928 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
2930 _("Default Meter Type for Tracks"),
2931 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
2932 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
2934 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2935 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
2937 add_option (S_("Preferences|Metering"), mtt);
2939 HSliderOption *mpks = new HSliderOption("meter-peak",
2940 _("Peak threshold [dBFS]"),
2941 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
2942 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak),
2946 Gtkmm2ext::UI::instance()->set_tip (
2948 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
2950 add_option (S_("Preferences|Metering"), mpks);
2952 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
2954 add_option (S_("Preferences|Metering"),
2956 "save-export-analysis-image",
2957 _("Save loudness analysis as image file"),
2958 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
2959 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
2962 /* TRANSPORT & Sync */
2964 add_option (_("Transport"), new OptionEditorHeading (_("General")));
2966 bo = new BoolOption (
2967 "stop-at-session-end",
2968 _("Stop at the end of the session"),
2969 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
2970 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
2972 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2973 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
2974 "when it reaches the current session end marker\n\n"
2975 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
2977 add_option (_("Transport"), bo);
2979 bo = new BoolOption (
2980 "latched-record-enable",
2981 _("Keep record-enable engaged on stop"),
2982 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
2983 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
2985 add_option (_("Transport"), bo);
2986 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2987 _("<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."));
2989 bo = new BoolOption (
2990 "disable-disarm-during-roll",
2991 _("Disable per-track record disarm while rolling"),
2992 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
2993 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
2995 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."));
2996 add_option (_("Transport"), bo);
2998 bo = new BoolOption (
3000 _("12dB gain reduction during fast-forward and fast-rewind"),
3001 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
3002 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
3004 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3005 _("<b>When enabled</b> rhis will reduce the unpleasant increase in perceived volume "
3006 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
3007 add_option (_("Transport"), bo);
3009 ComboOption<float>* psc = new ComboOption<float> (
3012 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
3013 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
3015 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
3016 (_("The amount of preroll to apply when <b>Play with Preroll</b> or <b>Record with Preroll</b>is initiated.\n\n"
3017 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
3018 psc->add (-4.0, _("4 Bars"));
3019 psc->add (-2.0, _("2 Bars"));
3020 psc->add (-1.0, _("1 Bar"));
3021 psc->add (0.0, _("0 (no pre-roll)"));
3022 psc->add (0.1, _("0.1 second"));
3023 psc->add (0.25, _("0.25 second"));
3024 psc->add (0.5, _("0.5 second"));
3025 psc->add (1.0, _("1.0 second"));
3026 psc->add (2.0, _("2.0 seconds"));
3027 add_option (_("Transport"), psc);
3030 add_option (_("Transport"), new OptionEditorHeading (_("Looping")));
3032 bo = new BoolOption (
3034 _("Play loop is a transport mode"),
3035 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
3036 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
3038 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3039 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
3040 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
3041 add_option (_("Transport"), bo);
3043 bo = new BoolOption (
3045 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
3046 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
3047 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
3049 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3050 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
3051 "preventing any need to do a transport locate at the end of the loop\n\n"
3052 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
3053 "which will often cause a small click or delay"), PROGRAM_NAME));
3054 add_option (_("Transport"), bo);
3056 add_option (_("Transport"), new OptionEditorHeading (_("Dropout (xrun) Handling")));
3057 bo = new BoolOption (
3058 "stop-recording-on-xrun",
3059 _("Stop recording when an xrun occurs"),
3060 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
3061 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
3063 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3064 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
3066 add_option (_("Transport"), bo);
3068 bo = new BoolOption (
3069 "create-xrun-marker",
3070 _("Create markers where xruns occur"),
3071 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
3072 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
3074 add_option (_("Transport"), bo);
3079 add_option (_("Sync"), new OptionEditorHeading (_("External Syncronization")));
3081 _sync_source = new ComboOption<SyncSource> (
3083 _("External timecode source"),
3084 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
3085 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
3088 add_option (_("Sync"), _sync_source);
3090 _sync_framerate = new BoolOption (
3091 "timecode-sync-frame-rate",
3092 _("Match session video frame rate to external timecode"),
3093 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
3094 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
3096 Gtkmm2ext::UI::instance()->set_tip
3097 (_sync_framerate->tip_widget(),
3098 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
3099 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
3100 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
3101 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
3102 "timecode standard and the session standard."), PROGRAM_NAME));
3104 add_option (_("Sync"), _sync_framerate);
3106 _sync_genlock = new BoolOption (
3107 "timecode-source-is-synced",
3108 _("Sync-lock timecode to clock (disable drift compensation)"),
3109 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
3110 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
3112 Gtkmm2ext::UI::instance()->set_tip
3113 (_sync_genlock->tip_widget(),
3114 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
3115 "Sync Lock indicates that the selected external timecode source shares clock-sync "
3116 "(Black & Burst, Wordclock, etc) with the audio interface. "
3117 "This option disables drift compensation. The transport speed is fixed at 1.0. "
3118 "Vari-speed LTC will be ignored and cause drift."
3120 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
3121 "timecode sources shares clock sync."
3125 add_option (_("Sync"), _sync_genlock);
3127 _sync_source_2997 = new BoolOption (
3128 "timecode-source-2997",
3129 _("Lock to 29.9700 fps instead of 30000/1001"),
3130 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
3131 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
3133 Gtkmm2ext::UI::instance()->set_tip
3134 (_sync_source_2997->tip_widget(),
3135 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
3136 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
3137 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
3138 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
3139 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
3140 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
3143 add_option (_("Sync"), _sync_source_2997);
3145 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Reader")));
3147 _ltc_port = new ComboStringOption (
3149 _("LTC incoming port"),
3150 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
3151 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
3154 vector<string> physical_inputs;
3155 physical_inputs.push_back (_("None"));
3156 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
3157 _ltc_port->set_popdown_strings (physical_inputs);
3159 populate_sync_options ();
3160 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
3162 add_option (_("Sync/LTC"), _ltc_port);
3164 add_option (_("Sync/LTC"), new OptionEditorHeading (_("Linear Timecode (LTC) Generator")));
3166 add_option (_("Sync/LTC"),
3169 _("Enable LTC generator"),
3170 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
3171 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
3174 _ltc_send_continuously = new BoolOption (
3175 "ltc-send-continuously",
3176 _("Send LTC while stopped"),
3177 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
3178 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
3180 Gtkmm2ext::UI::instance()->set_tip
3181 (_ltc_send_continuously->tip_widget(),
3182 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
3183 add_option (_("Sync/LTC"), _ltc_send_continuously);
3185 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level [dBFS]"),
3186 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_output_volume),
3187 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_output_volume),
3191 Gtkmm2ext::UI::instance()->set_tip
3192 (_ltc_volume_slider->tip_widget(),
3193 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
3195 add_option (_("Sync/LTC"), _ltc_volume_slider);
3198 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Beat Clock (Mclk) Generator")));
3200 add_option (_("Sync/MIDI"),
3203 _("Enable Mclk generator"),
3204 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
3205 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
3208 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC) Generator")));
3210 add_option (_("Sync/MIDI"),
3213 _("Enable MTC Generator"),
3214 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
3215 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
3218 add_option (_("Sync/MIDI"),
3219 new SpinOption<int> (
3220 "mtc-qf-speed-tolerance",
3221 _("Percentage either side of normal transport speed to transmit MTC"),
3222 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
3223 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
3227 add_option (_("Sync/MIDI"), new OptionEditorHeading (_("MIDI Machine Control (MMC)")));
3229 add_option (_("Sync/MIDI"),
3232 _("Respond to MMC commands"),
3233 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
3234 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
3237 add_option (_("Sync/MIDI"),
3240 _("Send MMC commands"),
3241 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
3242 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
3245 add_option (_("Sync/MIDI"),
3246 new SpinOption<uint8_t> (
3247 "mmc-receive-device-id",
3248 _("Inbound MMC device ID"),
3249 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
3250 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
3254 add_option (_("Sync/MIDI"),
3255 new SpinOption<uint8_t> (
3256 "mmc-send-device-id",
3257 _("Outbound MMC device ID"),
3258 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
3259 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
3264 /* Control Surfaces */
3266 add_option (_("Control Surfaces"), new OptionEditorHeading (_("Control Surfaces")));
3267 add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
3270 add_option (_("MIDI Ports"), new OptionEditorHeading (_("MIDI Port Options")));
3272 add_option (_("MIDI Ports"),
3274 "get-midi-input-follows-selection",
3275 _("MIDI input follows MIDI track selection"),
3276 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
3277 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
3280 add_option (_("MIDI Ports"), new MidiPortOptions ());
3281 add_option (_("MIDI Ports"), new OptionEditorBlank ());
3285 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3286 add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
3287 add_option (_("Plugins"),
3288 new RcActionButton (_("Scan for Plugins"),
3289 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3293 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
3295 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
3296 bo = new BoolOption (
3297 "show-plugin-scan-window",
3298 _("Always Display Plugin Scan Progress"),
3299 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
3300 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
3302 add_option (_("Plugins"), bo);
3303 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3304 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
3307 bo = new BoolOption (
3308 "plugins-stop-with-transport",
3309 _("Silence plugins when the transport is stopped"),
3310 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
3311 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
3313 add_option (_("Plugins"), bo);
3314 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3315 _("<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."));
3317 bo = new BoolOption (
3318 "new-plugins-active",
3319 _("Make new plugins active"),
3320 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
3321 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
3323 add_option (_("Plugins"), bo);
3324 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3325 _("<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"));
3327 #if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
3328 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
3330 add_option (_("Plugins/VST"),
3331 new RcActionButton (_("Scan for Plugins"),
3332 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3335 #if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
3336 bo = new BoolOption (
3338 _("Enable Mac VST support (requires restart or re-scan)"),
3339 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
3340 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
3342 add_option (_("Plugins/VST"), bo);
3345 bo = new BoolOption (
3346 "discover-vst-on-start",
3347 _("Scan for [new] VST Plugins on Application Start"),
3348 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
3349 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
3351 add_option (_("Plugins/VST"), bo);
3352 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3353 _("<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"));
3355 #ifdef WINDOWS_VST_SUPPORT
3356 // currently verbose logging is only implemented for Windows VST.
3357 bo = new BoolOption (
3358 "verbose-plugin-scan",
3359 _("Verbose Plugin Scan"),
3360 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
3361 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
3363 add_option (_("Plugins/VST"), bo);
3364 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3365 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
3368 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
3370 add_option (_("Plugins/VST"),
3371 new RcActionButton (_("Clear"),
3372 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
3375 add_option (_("Plugins/VST"),
3376 new RcActionButton (_("Clear"),
3377 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
3378 _("VST Blacklist:")));
3381 #ifdef LXVST_SUPPORT
3382 add_option (_("Plugins/VST"),
3383 new RcActionButton (_("Edit"),
3384 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
3385 _("Linux VST Path:")));
3387 add_option (_("Plugins/VST"),
3388 new RcConfigDisplay (
3389 "plugin-path-lxvst",
3391 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
3395 #ifdef WINDOWS_VST_SUPPORT
3396 add_option (_("Plugins/VST"),
3397 new RcActionButton (_("Edit"),
3398 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
3399 _("Windows VST Path:")));
3400 add_option (_("Plugins/VST"),
3401 new RcConfigDisplay (
3404 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
3408 #ifdef AUDIOUNIT_SUPPORT
3410 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
3412 add_option (_("Plugins/Audio Unit"),
3413 new RcActionButton (_("Scan for Plugins"),
3414 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
3417 bo = new BoolOption (
3418 "discover-audio-units",
3419 _("Scan for [new] AudioUnit Plugins on Application Start"),
3420 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
3421 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
3423 add_option (_("Plugins/Audio Unit"), bo);
3424 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3425 _("<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."));
3427 add_option (_("Plugins/Audio Unit"),
3428 new RcActionButton (_("Clear"),
3429 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
3432 add_option (_("Plugins/Audio Unit"),
3433 new RcActionButton (_("Clear"),
3434 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
3435 _("AU Blacklist:")));
3438 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
3439 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
3440 add_option (_("Plugins"),
3442 "open-gui-after-adding-plugin",
3443 _("Automatically open the plugin GUI when adding a new plugin"),
3444 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
3445 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3448 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3449 add_option (_("Plugins"),
3451 "show-inline-display-by-default",
3452 _("Show Plugin Inline Display on Mixerstrip by default"),
3453 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3454 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3457 _plugin_prefer_inline = new BoolOption (
3458 "prefer-inline-over-gui",
3459 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3460 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3461 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3463 add_option (_("Plugins"), _plugin_prefer_inline);
3466 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3468 bo = new BoolOption (
3469 "ask-replace-instrument",
3470 _("Ask to replace existing instrument plugin"),
3471 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3472 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3474 add_option (_("Plugins"), bo);
3476 bo = new BoolOption (
3477 "ask-setup_instrument",
3478 _("Interactively configure instrument plugins on insert"),
3479 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3480 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3482 add_option (_("Plugins"), bo);
3483 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3484 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3487 add_option (_("Plugins"), new OptionEditorBlank ());
3490 #if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
3491 add_option (_("Appearance"), new OptionEditorHeading (_("Graphics Acceleration")));
3494 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3495 BoolOption* bgc = new BoolOption (
3496 "cairo-image-surface",
3497 _("Disable Graphics Hardware Acceleration (requires restart)"),
3498 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3499 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3502 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3503 _("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));
3504 add_option (_("Appearance"), bgc);
3507 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3508 BoolOption* bgo = new BoolOption (
3510 _("Possibly improve slow graphical performance (requires restart)"),
3511 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3512 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3515 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));
3516 add_option (_("Appearance"), bgo);
3518 add_option (_("Appearance"), new OptionEditorHeading (_("Graphical User Interface")));
3520 add_option (_("Appearance"),
3523 _("Highlight widgets on mouseover"),
3524 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3525 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3528 add_option (_("Appearance"),
3531 _("Show tooltips if mouse hovers over a control"),
3532 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3533 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3536 bo = new BoolOption (
3537 "super-rapid-clock-update",
3538 _("Update clocks at TC Frame rate"),
3539 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3540 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3542 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3543 _("<b>When enabled</b> clock displays are updated every Timecode Frame (fps).\n\n"
3544 "<b>When disabled</b> clock displays are updated only every 100ms."
3546 add_option (_("Appearance"), bo);
3548 add_option (_("Appearance"),
3551 _("Blink Rec-Arm buttons"),
3552 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_blink_rec_arm),
3553 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_blink_rec_arm)
3558 /* font scaling does nothing with GDK/Quartz */
3559 add_option (_("Appearance"), new FontScalingOptions ());
3561 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("General")));
3562 add_option (_("Appearance/Editor"),
3564 "show-name-highlight",
3565 _("Use name highlight bars in region displays (requires a restart)"),
3566 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3567 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3570 add_option (_("Appearance/Editor"),
3572 "color-regions-using-track-color",
3573 _("Region color follows track color"),
3574 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_color_regions_using_track_color),
3575 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_color_regions_using_track_color)
3578 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Waveforms")));
3580 if (!Profile->get_mixbus()) {
3581 add_option (_("Appearance/Editor"),
3584 _("Show waveforms in regions"),
3585 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
3586 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
3590 add_option (_("Appearance/Editor"),
3592 "show-waveforms-while-recording",
3593 _("Show waveforms while recording"),
3594 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
3595 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
3598 add_option (_("Appearance/Editor"),
3600 "show-waveform-clipping",
3601 _("Show waveform clipping"),
3602 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveform_clipping),
3603 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveform_clipping)
3606 add_option (_("Appearance/Editor"), new ClipLevelOptions ());
3608 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
3610 _("Waveform scale"),
3611 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
3612 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
3615 wfs->add (Linear, _("linear"));
3616 wfs->add (Logarithmic, _("logarithmic"));
3618 add_option (_("Appearance/Editor"), wfs);
3620 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
3622 _("Waveform shape"),
3623 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
3624 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
3627 wfsh->add (Traditional, _("traditional"));
3628 wfsh->add (Rectified, _("rectified"));
3630 add_option (_("Appearance/Editor"), wfsh);
3632 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("Editor Meters")));
3634 add_option (_("Appearance/Editor"),
3636 "show-track-meters",
3637 _("Show meters in track headers"),
3638 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3639 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3642 add_option (_("Appearance/Editor"),
3644 "editor-stereo-only-meters",
3645 _("Limit track header meters to stereo"),
3646 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3647 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3650 add_option (_("Appearance/Editor"), new OptionEditorHeading (_("MIDI Regions")));
3652 add_option (_("Appearance/Editor"),
3654 "display-first-midi-bank-as-zero",
3655 _("Display first MIDI bank/program as 0"),
3656 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
3657 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
3660 add_option (_("Appearance/Editor"),
3662 "never-display-periodic-midi",
3663 _("Don't display periodic (MTC, MMC) SysEx messages in MIDI Regions"),
3664 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
3665 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
3668 add_option (_("Appearance/Editor"), new OptionEditorBlank ());
3670 /* The names of these controls must be the same as those given in MixerStrip
3671 for the actual widgets being controlled.
3673 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3674 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3675 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3676 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3677 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3678 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3679 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3681 add_option (_("Appearance/Mixer"),
3682 new VisibilityOption (
3684 &_mixer_strip_visibility,
3685 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3686 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3690 add_option (_("Appearance/Mixer"),
3692 "default-narrow_ms",
3693 _("Use narrow strips in the mixer by default"),
3694 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3695 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3698 add_option (_("Appearance/Mixer"), new OptionEditorBlank ());
3700 add_option (_("Appearance/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items")));
3702 add_option (_("Appearance/Toolbar"),
3704 "show-toolbar-recpunch",
3705 _("Display Record/Punch Options"),
3706 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_recpunch),
3707 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_recpunch)
3710 add_option (_("Appearance/Toolbar"),
3712 "show-toolbar-monitoring",
3713 _("Display Monitor Options"),
3714 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_monitoring),
3715 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_monitoring)
3718 add_option (_("Appearance/Toolbar"),
3720 "show-toolbar-selclock",
3721 _("Display Selection Clock"),
3722 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
3723 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
3726 if (!ARDOUR::Profile->get_small_screen()) {
3727 add_option (_("Appearance/Toolbar"),
3729 "show-secondary-clock",
3730 _("Display Secondary Clock"),
3731 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
3732 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
3736 add_option (_("Appearance/Toolbar"),
3738 "show-mini-timeline",
3739 _("Display Navigation Timeline"),
3740 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
3741 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
3744 add_option (_("Appearance/Toolbar"),
3746 "show-editor-meter",
3747 _("Display Master Level Meter"),
3748 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
3749 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
3752 add_option (_("Appearance/Toolbar"),
3753 new ColumVisibilityOption (
3754 "action-table-columns", _("Lua Action Script Button Visibility"), 4,
3755 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3756 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3759 add_option (_("Appearance/Toolbar"), new OptionEditorBlank ());
3762 OptionEditorHeading* quirks_head = new OptionEditorHeading (_("Various Workarounds for Windowing Systems"));
3764 quirks_head->set_note (string_compose (_("Rules for closing, minimizing, maximizing, and stay-on-top can vary\n\
3765 with each version of your OS, and the preferences that you've set in your OS.\n\n\
3766 You can adjust the options, below, to change how %1's windows and dialogs behave.\n\n\
3767 These settings will only take effect after %1 is restarted.\n\
3770 /* and now the theme manager */
3772 add_option (_("Appearance/Theme"), new OptionEditorHeading (_("Theme")));
3774 add_option (_("Appearance/Theme"), new BoolOption (
3776 _("Draw \"flat\" buttons"),
3777 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_flat_buttons),
3778 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_flat_buttons)
3781 add_option (_("Appearance/Theme"), new BoolOption (
3783 _("LED meter style"),
3784 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3785 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3789 HSliderOption *gui_hs = new HSliderOption(
3790 "timeline-item-gradient-depth",
3791 _("Waveforms color gradient depth"),
3792 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_gradient_depth),
3793 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_gradient_depth),
3796 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3797 add_option (_("Appearance/Theme"), gui_hs);
3799 gui_hs = new HSliderOption(
3800 "timeline-item-gradient-depth",
3801 _("Timeline item gradient depth"),
3802 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_timeline_item_gradient_depth),
3803 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_timeline_item_gradient_depth),
3806 gui_hs->scale().set_update_policy (Gtk::UPDATE_DELAYED);
3807 add_option (_("Appearance/Theme"), gui_hs);
3809 vector<string> icon_sets = ::get_icon_sets ();
3810 if (icon_sets.size() > 1) {
3811 ComboOption<std::string>* io = new ComboOption<std::string> (
3812 "icon-set", _("Icon Set"),
3813 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_icon_set),
3814 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_icon_set)
3816 for (vector<string>::const_iterator i = icon_sets.begin (); i != icon_sets.end (); ++i) {
3819 add_option (_("Appearance/Theme"), io);
3822 add_option (_("Appearance/Colors"), new OptionEditorHeading (_("Colors")));
3823 add_option (_("Appearance/Colors"), new ColorThemeManager);
3824 add_option (_("Appearance/Colors"), new OptionEditorBlank ());
3828 add_option (_("Appearance/Quirks"), quirks_head);
3830 bo = new BoolOption (
3831 "use-wm-visibility",
3832 _("Use visibility information provided by your Window Manager/Desktop"),
3833 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3834 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3836 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3837 _("If you have trouble toggling between hidden Editor and Mixer windows, try changing this setting."));
3838 add_option (_("Appearance/Quirks"), bo);
3841 bo = new BoolOption (
3842 "all-floating-windows-are-dialogs",
3843 _("All floating windows are dialogs"),
3844 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_all_floating_windows_are_dialogs),
3845 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_all_floating_windows_are_dialogs)
3847 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3848 _("Mark all floating windows to be type \"Dialog\" rather than using \"Utility\" for some.\nThis may help with some window managers."));
3849 add_option (_("Appearance/Quirks"), bo);
3851 bo = new BoolOption (
3852 "transients-follow-front",
3853 _("Transient windows follow front window."),
3854 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_transients_follow_front),
3855 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_transients_follow_front)
3857 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3858 _("Make transient windows follow the front window when toggling between the editor and mixer."));
3859 add_option (_("Appearance/Quirks"), bo);
3862 if (!Profile->get_mixbus()) {
3863 bo = new BoolOption (
3864 "floating-monitor-section",
3865 _("Float detached monitor-section window"),
3866 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_floating_monitor_section),
3867 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_floating_monitor_section)
3869 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget (),
3870 _("When detaching the monitoring section, mark it as \"Utility\" window to stay in front."));
3871 add_option (_("Appearance/Quirks"), bo);
3874 add_option (_("Appearance/Quirks"), new OptionEditorBlank ());
3876 /* VIDEO Timeline */
3877 add_option (_("Video"), new OptionEditorHeading (_("Video Server")));
3878 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
3880 Widget::show_all ();
3882 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3883 parameter_changed ("send-ltc");
3884 parameter_changed ("sync-source");
3885 parameter_changed ("use-monitor-bus");
3886 parameter_changed ("open-gui-after-adding-plugin");
3888 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
3890 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
3891 (Gtk::StateType) here !!!
3893 Tabbable::set_state (*node, Stateful::loading_state_version);
3896 set_current_page (_("General"));
3900 RCOptionEditor::parameter_changed (string const & p)
3902 OptionEditor::parameter_changed (p);
3904 if (p == "use-monitor-bus") {
3905 bool const s = Config->get_use_monitor_bus ();
3907 /* we can't use this if we don't have a monitor bus */
3908 Config->set_solo_control_is_listen_control (false);
3910 _solo_control_is_listen_control->set_sensitive (s);
3911 _listen_position->set_sensitive (s);
3912 } else if (p == "sync-source") {
3913 _sync_source->set_sensitive (true);
3915 _sync_source->set_sensitive (!_session->config.get_external_sync());
3917 switch(Config->get_sync_source()) {
3920 _sync_genlock->set_sensitive (true);
3921 _sync_framerate->set_sensitive (true);
3922 _sync_source_2997->set_sensitive (true);
3925 _sync_genlock->set_sensitive (false);
3926 _sync_framerate->set_sensitive (false);
3927 _sync_source_2997->set_sensitive (false);
3930 } else if (p == "send-ltc") {
3931 bool const s = Config->get_send_ltc ();
3932 _ltc_send_continuously->set_sensitive (s);
3933 _ltc_volume_slider->set_sensitive (s);
3934 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
3935 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3936 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
3939 } else if (p == "enable-translation") {
3940 _l10n->set_sensitive (ARDOUR::translations_are_enabled ());
3945 void RCOptionEditor::plugin_scan_refresh () {
3946 PluginManager::instance().refresh();
3949 void RCOptionEditor::clear_vst_cache () {
3950 PluginManager::instance().clear_vst_cache();
3953 void RCOptionEditor::clear_vst_blacklist () {
3954 PluginManager::instance().clear_vst_blacklist();
3957 void RCOptionEditor::clear_au_cache () {
3958 PluginManager::instance().clear_au_cache();
3961 void RCOptionEditor::clear_au_blacklist () {
3962 PluginManager::instance().clear_au_blacklist();
3965 void RCOptionEditor::edit_lxvst_path () {
3966 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
3967 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3968 *current_toplevel(), _("Set Linux VST Search Path"),
3969 _rc_config->get_plugin_path_lxvst(),
3970 PluginManager::instance().get_default_lxvst_path()
3972 ResponseType r = (ResponseType) pd->run ();
3974 if (r == RESPONSE_ACCEPT) {
3975 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
3977 MessageDialog msg (_("Re-scan Plugins now?"),
3978 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
3979 msg.set_default_response (Gtk::RESPONSE_YES);
3980 if (msg.run() == Gtk::RESPONSE_YES) {
3981 plugin_scan_refresh ();
3987 void RCOptionEditor::edit_vst_path () {
3988 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3989 *current_toplevel(), _("Set Windows VST Search Path"),
3990 _rc_config->get_plugin_path_vst(),
3991 PluginManager::instance().get_default_windows_vst_path()
3993 ResponseType r = (ResponseType) pd->run ();
3995 if (r == RESPONSE_ACCEPT) {
3996 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
3997 MessageDialog msg (_("Re-scan Plugins now?"),
3998 false /*no markup*/, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true /*modal*/);
3999 msg.set_default_response (Gtk::RESPONSE_YES);
4000 if (msg.run() == Gtk::RESPONSE_YES) {
4001 plugin_scan_refresh ();
4009 RCOptionEditor::populate_sync_options ()
4011 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
4013 _sync_source->clear ();
4015 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
4016 _sync_source->add (*i, sync_source_to_string (*i));
4019 if (sync_opts.empty()) {
4020 _sync_source->set_sensitive(false);
4022 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
4023 _rc_config->set_sync_source(sync_opts.front());
4027 parameter_changed ("sync-source");
4031 RCOptionEditor::use_own_window (bool and_fill_it)
4033 bool new_window = !own_window ();
4035 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
4037 if (win && new_window) {
4038 win->set_name ("PreferencesWindow");
4039 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
4041 win->set_resizable (false);
4048 RCOptionEditor::get_state ()
4050 XMLNode* node = new XMLNode (X_("Preferences"));
4051 node->add_child_nocopy (Tabbable::get_state());