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 #include <boost/algorithm/string.hpp>
26 #include <gtkmm/liststore.h>
27 #include <gtkmm/stock.h>
28 #include <gtkmm/scale.h>
30 #include <gtkmm2ext/utils.h>
31 #include <gtkmm2ext/slider_controller.h>
32 #include <gtkmm2ext/gtk_ui.h>
33 #include <gtkmm2ext/paths_dialog.h>
38 #include "ardour/audioengine.h"
39 #include "ardour/dB.h"
40 #include "ardour/rc_configuration.h"
41 #include "ardour/control_protocol_manager.h"
42 #include "ardour/plugin_manager.h"
43 #include "control_protocol/control_protocol.h"
45 #include "canvas/wave_view.h"
47 #include "ardour_window.h"
48 #include "ardour_dialog.h"
49 #include "gui_thread.h"
50 #include "midi_tracer.h"
51 #include "rc_option_editor.h"
53 #include "midi_port_dialog.h"
60 using namespace Gtkmm2ext;
62 using namespace ARDOUR;
64 class ClickOptions : public OptionEditorBox
67 ClickOptions (RCConfiguration* c, Gtk::Window* p)
71 Table* t = manage (new Table (2, 3));
74 Label* l = manage (left_aligned_label (_("Click audio file:")));
75 t->attach (*l, 0, 1, 0, 1, FILL);
76 t->attach (_click_path_entry, 1, 2, 0, 1, FILL);
77 Button* b = manage (new Button (_("Browse...")));
78 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
79 t->attach (*b, 2, 3, 0, 1, FILL);
81 l = manage (left_aligned_label (_("Click emphasis audio file:")));
82 t->attach (*l, 0, 1, 1, 2, FILL);
83 t->attach (_click_emphasis_path_entry, 1, 2, 1, 2, FILL);
84 b = manage (new Button (_("Browse...")));
85 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
86 t->attach (*b, 2, 3, 1, 2, FILL);
88 _box->pack_start (*t, false, false);
90 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
91 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
94 void parameter_changed (string const & p)
96 if (p == "click-sound") {
97 _click_path_entry.set_text (_rc_config->get_click_sound());
98 } else if (p == "click-emphasis-sound") {
99 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
103 void set_state_from_config ()
105 parameter_changed ("click-sound");
106 parameter_changed ("click-emphasis-sound");
111 void click_browse_clicked ()
113 SoundFileChooser sfdb (_("Choose Click"));
115 if (sfdb.run () == RESPONSE_OK) {
116 click_chosen (sfdb.get_filename());
120 void click_chosen (string const & path)
122 _click_path_entry.set_text (path);
123 _rc_config->set_click_sound (path);
126 void click_changed ()
128 click_chosen (_click_path_entry.get_text ());
131 void click_emphasis_browse_clicked ()
133 SoundFileChooser sfdb (_("Choose Click Emphasis"));
138 if (sfdb.run () == RESPONSE_OK) {
139 click_emphasis_chosen (sfdb.get_filename());
143 void click_emphasis_chosen (string const & path)
145 _click_emphasis_path_entry.set_text (path);
146 _rc_config->set_click_emphasis_sound (path);
149 void click_emphasis_changed ()
151 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
154 RCConfiguration* _rc_config;
155 Gtk::Window* _parent;
156 Entry _click_path_entry;
157 Entry _click_emphasis_path_entry;
160 class UndoOptions : public OptionEditorBox
163 UndoOptions (RCConfiguration* c) :
165 _limit_undo_button (_("Limit undo history to")),
166 _save_undo_button (_("Save undo history of"))
168 Table* t = new Table (2, 3);
171 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
172 _limit_undo_spin.set_range (0, 512);
173 _limit_undo_spin.set_increments (1, 10);
174 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
175 Label* l = manage (left_aligned_label (_("commands")));
176 t->attach (*l, 2, 3, 0, 1);
178 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
179 _save_undo_spin.set_range (0, 512);
180 _save_undo_spin.set_increments (1, 10);
181 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
182 l = manage (left_aligned_label (_("commands")));
183 t->attach (*l, 2, 3, 1, 2);
185 _box->pack_start (*t);
187 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
188 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
189 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
190 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
193 void parameter_changed (string const & p)
195 if (p == "history-depth") {
196 int32_t const d = _rc_config->get_history_depth();
197 _limit_undo_button.set_active (d != 0);
198 _limit_undo_spin.set_sensitive (d != 0);
199 _limit_undo_spin.set_value (d);
200 } else if (p == "save-history") {
201 bool const x = _rc_config->get_save_history ();
202 _save_undo_button.set_active (x);
203 _save_undo_spin.set_sensitive (x);
204 } else if (p == "save-history-depth") {
205 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
209 void set_state_from_config ()
211 parameter_changed ("save-history");
212 parameter_changed ("history-depth");
213 parameter_changed ("save-history-depth");
216 void limit_undo_toggled ()
218 bool const x = _limit_undo_button.get_active ();
219 _limit_undo_spin.set_sensitive (x);
220 int32_t const n = x ? 16 : 0;
221 _limit_undo_spin.set_value (n);
222 _rc_config->set_history_depth (n);
225 void limit_undo_changed ()
227 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
230 void save_undo_toggled ()
232 bool const x = _save_undo_button.get_active ();
233 _rc_config->set_save_history (x);
236 void save_undo_changed ()
238 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
242 RCConfiguration* _rc_config;
243 CheckButton _limit_undo_button;
244 SpinButton _limit_undo_spin;
245 CheckButton _save_undo_button;
246 SpinButton _save_undo_spin;
251 static const struct {
263 { "Key|Shift", GDK_SHIFT_MASK },
264 { "Command", GDK_META_MASK },
265 { "Control", GDK_CONTROL_MASK },
266 { "Option", GDK_MOD1_MASK },
267 { "Command-Shift", GDK_META_MASK|GDK_SHIFT_MASK },
268 { "Command-Option", GDK_MOD1_MASK|GDK_META_MASK },
269 { "Shift-Option", GDK_SHIFT_MASK|GDK_MOD1_MASK },
270 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_META_MASK },
273 { "Key|Shift", GDK_SHIFT_MASK },
274 { "Control", GDK_CONTROL_MASK },
275 { "Alt (Mod1)", GDK_MOD1_MASK },
276 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
277 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
278 { "Shift-Alt", GDK_SHIFT_MASK|GDK_MOD1_MASK },
279 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
280 { "Mod2", GDK_MOD2_MASK },
281 { "Mod3", GDK_MOD3_MASK },
282 { "Mod4", GDK_MOD4_MASK },
283 { "Mod5", GDK_MOD5_MASK },
289 class KeyboardOptions : public OptionEditorBox
293 _delete_button_adjustment (3, 1, 12),
294 _delete_button_spin (_delete_button_adjustment),
295 _edit_button_adjustment (3, 1, 5),
296 _edit_button_spin (_edit_button_adjustment),
297 _insert_note_button_adjustment (3, 1, 5),
298 _insert_note_button_spin (_insert_note_button_adjustment)
300 /* internationalize and prepare for use with combos */
303 for (int i = 0; modifiers[i].name; ++i) {
304 dumb.push_back (S_(modifiers[i].name));
307 set_popdown_strings (_edit_modifier_combo, dumb);
308 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
310 for (int x = 0; modifiers[x].name; ++x) {
311 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
312 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
317 Table* t = manage (new Table (4, 4));
320 Label* l = manage (left_aligned_label (_("Edit using:")));
321 l->set_name ("OptionsLabel");
323 t->attach (*l, 0, 1, 0, 1, FILL | EXPAND, FILL);
324 t->attach (_edit_modifier_combo, 1, 2, 0, 1, FILL | EXPAND, FILL);
326 l = manage (new Label (_("+ button")));
327 l->set_name ("OptionsLabel");
329 t->attach (*l, 3, 4, 0, 1, FILL | EXPAND, FILL);
330 t->attach (_edit_button_spin, 4, 5, 0, 1, FILL | EXPAND, FILL);
332 _edit_button_spin.set_name ("OptionsEntry");
333 _edit_button_adjustment.set_value (Keyboard::edit_button());
334 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
336 set_popdown_strings (_delete_modifier_combo, dumb);
337 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
339 for (int x = 0; modifiers[x].name; ++x) {
340 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
341 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
346 l = manage (left_aligned_label (_("Delete using:")));
347 l->set_name ("OptionsLabel");
349 t->attach (*l, 0, 1, 1, 2, FILL | EXPAND, FILL);
350 t->attach (_delete_modifier_combo, 1, 2, 1, 2, FILL | EXPAND, FILL);
352 l = manage (new Label (_("+ button")));
353 l->set_name ("OptionsLabel");
355 t->attach (*l, 3, 4, 1, 2, FILL | EXPAND, FILL);
356 t->attach (_delete_button_spin, 4, 5, 1, 2, FILL | EXPAND, FILL);
358 _delete_button_spin.set_name ("OptionsEntry");
359 _delete_button_adjustment.set_value (Keyboard::delete_button());
360 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
363 set_popdown_strings (_insert_note_modifier_combo, dumb);
364 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
366 for (int x = 0; modifiers[x].name; ++x) {
367 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
368 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
373 l = manage (left_aligned_label (_("Insert note using:")));
374 l->set_name ("OptionsLabel");
376 t->attach (*l, 0, 1, 2, 3, FILL | EXPAND, FILL);
377 t->attach (_insert_note_modifier_combo, 1, 2, 2, 3, FILL | EXPAND, FILL);
379 l = manage (new Label (_("+ button")));
380 l->set_name ("OptionsLabel");
382 t->attach (*l, 3, 4, 2, 3, FILL | EXPAND, FILL);
383 t->attach (_insert_note_button_spin, 4, 5, 2, 3, FILL | EXPAND, FILL);
385 _insert_note_button_spin.set_name ("OptionsEntry");
386 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
387 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
390 set_popdown_strings (_snap_modifier_combo, dumb);
391 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
393 for (int x = 0; modifiers[x].name; ++x) {
394 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
395 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
400 l = manage (left_aligned_label (_("Ignore snap using:")));
401 l->set_name ("OptionsLabel");
403 t->attach (*l, 0, 1, 3, 4, FILL | EXPAND, FILL);
404 t->attach (_snap_modifier_combo, 1, 2, 3, 4, FILL | EXPAND, FILL);
408 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
409 strs.push_back (bf->first);
412 set_popdown_strings (_keyboard_layout_selector, strs);
413 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
414 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
416 l = manage (left_aligned_label (_("Keyboard layout:")));
417 l->set_name ("OptionsLabel");
419 t->attach (*l, 0, 1, 4, 5, FILL | EXPAND, FILL);
420 t->attach (_keyboard_layout_selector, 1, 2, 4, 5, FILL | EXPAND, FILL);
422 _box->pack_start (*t, false, false);
425 void parameter_changed (string const &)
427 /* XXX: these aren't really config options... */
430 void set_state_from_config ()
432 /* XXX: these aren't really config options... */
437 void bindings_changed ()
439 string const txt = _keyboard_layout_selector.get_active_text();
441 /* XXX: config...? for all this keyboard stuff */
443 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
444 if (txt == i->first) {
445 if (Keyboard::load_keybindings (i->second)) {
446 Keyboard::save_keybindings ();
452 void edit_modifier_chosen ()
454 string const txt = _edit_modifier_combo.get_active_text();
456 for (int i = 0; modifiers[i].name; ++i) {
457 if (txt == _(modifiers[i].name)) {
458 Keyboard::set_edit_modifier (modifiers[i].modifier);
464 void delete_modifier_chosen ()
466 string const txt = _delete_modifier_combo.get_active_text();
468 for (int i = 0; modifiers[i].name; ++i) {
469 if (txt == _(modifiers[i].name)) {
470 Keyboard::set_delete_modifier (modifiers[i].modifier);
476 void insert_note_modifier_chosen ()
478 string const txt = _insert_note_modifier_combo.get_active_text();
480 for (int i = 0; modifiers[i].name; ++i) {
481 if (txt == _(modifiers[i].name)) {
482 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
488 void snap_modifier_chosen ()
490 string const txt = _snap_modifier_combo.get_active_text();
492 for (int i = 0; modifiers[i].name; ++i) {
493 if (txt == _(modifiers[i].name)) {
494 Keyboard::set_snap_modifier (modifiers[i].modifier);
500 void delete_button_changed ()
502 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
505 void edit_button_changed ()
507 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
510 void insert_note_button_changed ()
512 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
515 ComboBoxText _keyboard_layout_selector;
516 ComboBoxText _edit_modifier_combo;
517 ComboBoxText _delete_modifier_combo;
518 ComboBoxText _insert_note_modifier_combo;
519 ComboBoxText _snap_modifier_combo;
520 Adjustment _delete_button_adjustment;
521 SpinButton _delete_button_spin;
522 Adjustment _edit_button_adjustment;
523 SpinButton _edit_button_spin;
524 Adjustment _insert_note_button_adjustment;
525 SpinButton _insert_note_button_spin;
529 class FontScalingOptions : public OptionEditorBox
532 FontScalingOptions (RCConfiguration* c) :
534 _dpi_adjustment (50, 50, 250, 1, 10),
535 _dpi_slider (_dpi_adjustment)
537 _dpi_adjustment.set_value (floor ((double)(_rc_config->get_font_scale () / 1024)));
539 Label* l = manage (new Label (_("Font scaling:")));
540 l->set_name ("OptionsLabel");
542 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
543 HBox* h = manage (new HBox);
545 h->pack_start (*l, false, false);
546 h->pack_start (_dpi_slider, true, true);
548 _box->pack_start (*h, false, false);
550 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
553 void parameter_changed (string const & p)
555 if (p == "font-scale") {
556 _dpi_adjustment.set_value (floor ((double)(_rc_config->get_font_scale() / 1024)));
560 void set_state_from_config ()
562 parameter_changed ("font-scale");
569 _rc_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024));
570 /* XXX: should be triggered from the parameter changed signal */
574 RCConfiguration* _rc_config;
575 Adjustment _dpi_adjustment;
579 class ClipLevelOptions : public OptionEditorBox
582 ClipLevelOptions (RCConfiguration* c)
584 , _clip_level_adjustment (0, -128.0, 2.0, 0.1, 1.0) /* units of dB */
585 , _clip_level_slider (_clip_level_adjustment)
587 _clip_level_adjustment.set_value (_rc_config->get_waveform_clip_level ());
589 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
590 l->set_name ("OptionsLabel");
592 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
593 HBox* h = manage (new HBox);
595 h->pack_start (*l, false, false);
596 h->pack_start (_clip_level_slider, true, true);
598 _box->pack_start (*h, false, false);
600 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
603 void parameter_changed (string const & p)
605 if (p == "waveform-clip-level") {
606 _clip_level_adjustment.set_value (_rc_config->get_waveform_clip_level());
610 void set_state_from_config ()
612 parameter_changed ("waveform-clip-level");
617 void clip_level_changed ()
619 _rc_config->set_waveform_clip_level (_clip_level_adjustment.get_value());
620 /* XXX: should be triggered from the parameter changed signal */
621 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
624 RCConfiguration* _rc_config;
625 Adjustment _clip_level_adjustment;
626 HScale _clip_level_slider;
629 class BufferingOptions : public OptionEditorBox
632 BufferingOptions (RCConfiguration* c)
634 , _playback_adjustment (5, 1, 60, 1, 4)
635 , _capture_adjustment (5, 1, 60, 1, 4)
636 , _playback_slider (_playback_adjustment)
637 , _capture_slider (_capture_adjustment)
639 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
641 Label* l = manage (new Label (_("Playback (seconds of buffering):")));
642 l->set_name ("OptionsLabel");
644 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
645 HBox* h = manage (new HBox);
647 h->pack_start (*l, false, false);
648 h->pack_start (_playback_slider, true, true);
650 _box->pack_start (*h, false, false);
652 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
654 l = manage (new Label (_("Recording (seconds of buffering):")));
655 l->set_name ("OptionsLabel");
657 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
658 h = manage (new HBox);
660 h->pack_start (*l, false, false);
661 h->pack_start (_capture_slider, true, true);
663 _box->pack_start (*h, false, false);
665 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
666 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
669 void parameter_changed (string const & p)
671 if (p == "playback-buffer-seconds") {
672 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
673 } else if (p == "capture-buffer-seconds") {
674 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
678 void set_state_from_config ()
680 parameter_changed ("playback-buffer-seconds");
681 parameter_changed ("capture-buffer-seconds");
686 void playback_changed ()
688 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
691 void capture_changed ()
693 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
696 RCConfiguration* _rc_config;
697 Adjustment _playback_adjustment;
698 Adjustment _capture_adjustment;
699 HScale _playback_slider;
700 HScale _capture_slider;
703 class ControlSurfacesOptions : public OptionEditorBox
706 ControlSurfacesOptions (Gtk::Window& parent)
708 , _ignore_view_change (0)
710 _store = ListStore::create (_model);
711 _view.set_model (_store);
712 _view.append_column (_("Control Surface Protocol"), _model.name);
713 _view.get_column(0)->set_resizable (true);
714 _view.get_column(0)->set_expand (true);
715 _view.append_column_editable (_("Enabled"), _model.enabled);
716 _view.append_column_editable (_("Feedback"), _model.feedback);
718 _box->pack_start (_view, false, false);
720 Label* label = manage (new Label);
721 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
723 _box->pack_start (*label, false, false);
726 ControlProtocolManager& m = ControlProtocolManager::instance ();
727 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
728 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
730 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
731 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
734 void parameter_changed (std::string const &)
739 void set_state_from_config ()
743 ControlProtocolManager& m = ControlProtocolManager::instance ();
744 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
746 if (!(*i)->mandatory) {
747 TreeModel::Row r = *_store->append ();
748 r[_model.name] = (*i)->name;
749 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
750 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
751 r[_model.protocol_info] = *i;
758 void protocol_status_changed (ControlProtocolInfo* cpi) {
760 TreeModel::Children rows = _store->children();
762 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
763 string n = ((*x)[_model.name]);
765 if ((*x)[_model.protocol_info] == cpi) {
766 _ignore_view_change++;
767 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
768 _ignore_view_change--;
774 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
776 TreeModel::Row r = *i;
778 if (_ignore_view_change) {
782 ControlProtocolInfo* cpi = r[_model.protocol_info];
787 bool const was_enabled = (cpi->protocol != 0);
788 bool const is_enabled = r[_model.enabled];
791 if (was_enabled != is_enabled) {
794 ControlProtocolManager::instance().activate (*cpi);
796 Gtk::Window* win = r[_model.editor];
801 ControlProtocolManager::instance().deactivate (*cpi);
805 r[_model.editor] = 0;
810 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
811 bool const is_feedback = r[_model.feedback];
813 if (was_feedback != is_feedback && cpi->protocol) {
814 cpi->protocol->set_feedback (is_feedback);
818 void edit_clicked (GdkEventButton* ev)
820 if (ev->type != GDK_2BUTTON_PRESS) {
825 ControlProtocolInfo* cpi;
828 row = *(_view.get_selection()->get_selected());
830 Window* win = row[_model.editor];
831 if (win && !win->is_visible()) {
834 cpi = row[_model.protocol_info];
836 if (cpi && cpi->protocol && cpi->protocol->has_editor ()) {
837 Box* box = (Box*) cpi->protocol->get_gui ();
839 string title = row[_model.name];
840 ArdourWindow* win = new ArdourWindow (_parent, title);
841 win->set_title ("Control Protocol Options");
845 row[_model.editor] = win;
851 class ControlSurfacesModelColumns : public TreeModelColumnRecord
855 ControlSurfacesModelColumns ()
864 TreeModelColumn<string> name;
865 TreeModelColumn<bool> enabled;
866 TreeModelColumn<bool> feedback;
867 TreeModelColumn<ControlProtocolInfo*> protocol_info;
868 TreeModelColumn<Gtk::Window*> editor;
871 Glib::RefPtr<ListStore> _store;
872 ControlSurfacesModelColumns _model;
874 Gtk::Window& _parent;
875 PBD::ScopedConnection protocol_status_connection;
876 uint32_t _ignore_view_change;
879 class VideoTimelineOptions : public OptionEditorBox
882 VideoTimelineOptions (RCConfiguration* c)
884 , _show_video_export_info_button (_("Show Video Export Info before export"))
885 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
886 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
888 Table* t = manage (new Table (2, 6));
891 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
892 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
893 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
894 _("<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."));
896 Label* l = manage (new Label (_("Video Server URL:")));
897 l->set_alignment (0, 0.5);
898 t->attach (*l, 0, 1, 1, 2, FILL);
899 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
900 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
901 _("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"));
903 l = manage (new Label (_("Video Folder:")));
904 l->set_alignment (0, 0.5);
905 t->attach (*l, 0, 1, 2, 3, FILL);
906 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
907 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
908 _("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."));
910 /* small vspace y=3..4 */
912 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
913 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
914 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
915 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
917 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
918 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
919 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
920 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
922 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
923 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
924 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
925 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
927 _box->pack_start (*t,true,true);
930 void server_url_changed ()
932 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
935 void server_docroot_changed ()
937 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
940 void show_video_export_info_toggled ()
942 bool const x = _show_video_export_info_button.get_active ();
943 _rc_config->set_show_video_export_info (x);
946 void show_video_server_dialog_toggled ()
948 bool const x = _show_video_server_dialog_button.get_active ();
949 _rc_config->set_show_video_server_dialog (x);
952 void video_advanced_setup_toggled ()
954 bool const x = _video_advanced_setup_button.get_active ();
955 _rc_config->set_video_advanced_setup(x);
958 void parameter_changed (string const & p)
960 if (p == "video-server-url") {
961 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
962 } else if (p == "video-server-docroot") {
963 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
964 } else if (p == "show-video-export-info") {
965 bool const x = _rc_config->get_show_video_export_info();
966 _show_video_export_info_button.set_active (x);
967 } else if (p == "show-video-server-dialog") {
968 bool const x = _rc_config->get_show_video_server_dialog();
969 _show_video_server_dialog_button.set_active (x);
970 } else if (p == "video-advanced-setup") {
971 bool const x = _rc_config->get_video_advanced_setup();
972 _video_advanced_setup_button.set_active(x);
973 _video_server_docroot_entry.set_sensitive(x);
974 _video_server_url_entry.set_sensitive(x);
978 void set_state_from_config ()
980 parameter_changed ("video-server-url");
981 parameter_changed ("video-server-docroot");
982 parameter_changed ("video-monitor-setup-dialog");
983 parameter_changed ("show-video-export-info");
984 parameter_changed ("show-video-server-dialog");
985 parameter_changed ("video-advanced-setup");
989 RCConfiguration* _rc_config;
990 Entry _video_server_url_entry;
991 Entry _video_server_docroot_entry;
992 CheckButton _show_video_export_info_button;
993 CheckButton _show_video_server_dialog_button;
994 CheckButton _video_advanced_setup_button;
997 class PluginOptions : public OptionEditorBox
1000 PluginOptions (RCConfiguration* c)
1002 , _display_plugin_scan_progress (_("Always Display Plugin Scan Progress"))
1003 , _discover_vst_on_start (_("Scan for new VST Plugins on Application Start"))
1004 , _timeout_adjustment (0, 0, 3000, 50, 50)
1005 , _timeout_slider (_timeout_adjustment)
1008 std::stringstream ss;
1009 Table* t = manage (new Table (2, 6));
1010 t->set_spacings (4);
1014 ss << "<b>" << _("General") << "</b>";
1015 l = manage (left_aligned_label (ss.str()));
1016 l->set_use_markup (true);
1017 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1018 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1020 b = manage (new Button (_("Scan for Plugins")));
1021 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1022 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1024 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1025 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1026 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1027 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
1029 _timeout_slider.set_digits (0);
1030 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &PluginOptions::timeout_changed));
1032 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1033 _("Specify the default timeout for plugin instantiation in 1/10 seconds. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1035 l = manage (left_aligned_label (_("Scan Time Out [deciseconds]")));;
1036 HBox* h = manage (new HBox);
1038 h->pack_start (*l, false, false);
1039 h->pack_start (_timeout_slider, true, true);
1040 t->attach (*h, 0, 2, n, n+1); ++n;
1043 ss << "<b>" << _("VST") << "</b>";
1044 l = manage (left_aligned_label (ss.str()));
1045 l->set_use_markup (true);
1046 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1047 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1049 b = manage (new Button (_("Clear VST Cache")));
1050 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1051 t->attach (*b, 0, 1, n, n+1, FILL);
1053 b = manage (new Button (_("Clear VST Blacklist")));
1054 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1055 t->attach (*b, 1, 2, n, n+1, FILL);
1058 t->attach (_discover_vst_on_start, 0, 2, n, n+1); ++n;
1059 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1060 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1061 _("<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"));
1063 #ifdef WINDOWS_VST_SUPPORT
1064 t->attach (*manage (left_aligned_label (_("Windows VST Path:"))), 0, 1, n, n+1);
1065 b = manage (new Button (_("Edit")));
1066 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_vst_path_clicked));
1067 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1070 #ifdef LXVST_SUPPORT
1071 t->attach (*manage (left_aligned_label (_("Linux VST:"))), 0, 1, n, n+1);
1072 b = manage (new Button (_("Edit")));
1073 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_lxvst_path_clicked));
1074 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1077 _box->pack_start (*t,true,true);
1080 void parameter_changed (string const & p) {
1081 if (p == "show-plugin-scan-window") {
1082 bool const x = _rc_config->get_show_plugin_scan_window();
1083 _display_plugin_scan_progress.set_active (x);
1085 else if (p == "discover-vst-on-start") {
1086 bool const x = _rc_config->get_discover_vst_on_start();
1087 _discover_vst_on_start.set_active (x);
1089 else if (p == "vst-scan-timeout") {
1090 int const x = _rc_config->get_vst_scan_timeout();
1091 _timeout_adjustment.set_value (x);
1095 void set_state_from_config () {
1096 parameter_changed ("show-plugin-scan-window");
1097 parameter_changed ("discover-vst-on-start");
1098 parameter_changed ("vst-scan-timeout");
1102 RCConfiguration* _rc_config;
1103 CheckButton _display_plugin_scan_progress;
1104 CheckButton _discover_vst_on_start;
1105 Adjustment _timeout_adjustment;
1106 HScale _timeout_slider;
1108 void display_plugin_scan_progress_toggled () {
1109 bool const x = _display_plugin_scan_progress.get_active();
1110 _rc_config->set_show_plugin_scan_window(x);
1113 void discover_vst_on_start_toggled () {
1114 bool const x = _discover_vst_on_start.get_active();
1115 _rc_config->set_discover_vst_on_start(x);
1118 void timeout_changed () {
1119 int x = floor(_timeout_adjustment.get_value());
1120 _rc_config->set_vst_scan_timeout(x);
1123 void clear_vst_cache_clicked () {
1124 PluginManager::instance().clear_vst_cache();
1127 void clear_vst_blacklist_clicked () {
1128 PluginManager::instance().clear_vst_blacklist();
1131 void edit_vst_path_clicked () {
1132 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1133 _("Set Windows VST Search Path"),
1134 _rc_config->get_plugin_path_vst(),
1135 PluginManager::instance().get_default_windows_vst_path()
1137 ResponseType r = (ResponseType) pd->run ();
1139 if (r == RESPONSE_ACCEPT) {
1140 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
1145 // todo consolidate with edit_vst_path_clicked..
1146 void edit_lxvst_path_clicked () {
1147 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1148 _("Set Linux VST Search Path"),
1149 _rc_config->get_plugin_path_lxvst(),
1150 PluginManager::instance().get_default_lxvst_path()
1152 ResponseType r = (ResponseType) pd->run ();
1154 if (r == RESPONSE_ACCEPT) {
1155 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
1160 void refresh_clicked () {
1161 PluginManager::instance().refresh();
1166 /** A class which allows control of visibility of some editor components usign
1167 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1168 * which has the correct members, but with null widget pointers. This
1169 * class allows the user to set visibility of the members, the details
1170 * of which are stored in a configuration variable which can be watched
1171 * by parts of the editor that actually contain the widgets whose visibility
1172 * is being controlled.
1175 class VisibilityOption : public Option
1178 /** @param name User-visible name for this group.
1179 * @param g `Dummy' VisibilityGroup (as described above).
1180 * @param get Method to get the value of the appropriate configuration variable.
1181 * @param set Method to set the value of the appropriate configuration variable.
1183 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1184 : Option (g->get_state_name(), name)
1186 , _visibility_group (g)
1190 /* Watch for changes made by the user to our members */
1191 _visibility_group->VisibilityChanged.connect_same_thread (
1192 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1196 void set_state_from_config ()
1198 /* Set our state from the current configuration */
1199 _visibility_group->set_state (_get ());
1202 void add_to_page (OptionEditorPage* p)
1204 _heading.add_to_page (p);
1205 add_widget_to_page (p, _visibility_group->list_view ());
1208 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1213 /* The user has changed something, so reflect this change
1214 in the RCConfiguration.
1216 _set (_visibility_group->get_state_value ());
1219 OptionEditorHeading _heading;
1220 VisibilityGroup* _visibility_group;
1221 sigc::slot<std::string> _get;
1222 sigc::slot<bool, std::string> _set;
1223 PBD::ScopedConnection _visibility_group_connection;
1228 RCOptionEditor::RCOptionEditor ()
1229 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1230 , _rc_config (Config)
1231 , _mixer_strip_visibility ("mixer-strip-visibility")
1235 uint32_t hwcpus = hardware_concurrency ();
1237 BoolComboOption* bco;
1240 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1242 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1244 _("Signal processing uses"),
1245 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1246 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1249 procs->add (-1, _("all but one processor"));
1250 procs->add (0, _("all available processors"));
1252 for (uint32_t i = 1; i <= hwcpus; ++i) {
1253 procs->add (i, string_compose (_("%1 processors"), i));
1256 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1258 add_option (_("Misc"), procs);
1261 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1263 add_option (_("Misc"), new UndoOptions (_rc_config));
1265 add_option (_("Misc"),
1267 "verify-remove-last-capture",
1268 _("Verify removal of last capture"),
1269 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1270 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1273 add_option (_("Misc"),
1275 "periodic-safety-backups",
1276 _("Make periodic backups of the session file"),
1277 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1278 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1281 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1283 add_option (_("Misc"),
1285 "only-copy-imported-files",
1286 _("Always copy imported files"),
1287 sigc::mem_fun (*_rc_config, &RCConfiguration::get_only_copy_imported_files),
1288 sigc::mem_fun (*_rc_config, &RCConfiguration::set_only_copy_imported_files)
1291 add_option (_("Misc"), new DirectoryOption (
1292 X_("default-session-parent-dir"),
1293 _("Default folder for new sessions:"),
1294 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1295 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1298 add_option (_("Misc"),
1299 new SpinOption<uint32_t> (
1300 "max-recent-sessions",
1301 _("Maximum number of recent sessions"),
1302 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1303 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1307 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1309 add_option (_("Misc"), new ClickOptions (_rc_config, this));
1311 add_option (_("Misc"),
1314 _("Click gain level"),
1315 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1316 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1319 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1321 add_option (_("Misc"),
1322 new SpinOption<double> (
1323 "automation-thinning-factor",
1324 _("Thinning factor (larger value => less data)"),
1325 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1326 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1330 add_option (_("Misc"),
1331 new SpinOption<double> (
1332 "automation-interval-msecs",
1333 _("Automation sampling interval (milliseconds)"),
1334 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1335 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1343 tsf = new BoolOption (
1344 "latched-record-enable",
1345 _("Keep record-enable engaged on stop"),
1346 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1347 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1349 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1350 add_option (_("Transport"), tsf);
1352 tsf = new BoolOption (
1353 "stop-recording-on-xrun",
1354 _("Stop recording when an xrun occurs"),
1355 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1356 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1358 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1359 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
1361 add_option (_("Transport"), tsf);
1363 tsf = new BoolOption (
1364 "create-xrun-marker",
1365 _("Create markers where xruns occur"),
1366 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1367 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1369 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1370 add_option (_("Transport"), tsf);
1372 tsf = new BoolOption (
1373 "stop-at-session-end",
1374 _("Stop at the end of the session"),
1375 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1376 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1378 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1379 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
1380 "when it reaches the current session end marker\n\n"
1381 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
1383 add_option (_("Transport"), tsf);
1385 tsf = new BoolOption (
1387 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
1388 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1389 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1391 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1392 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1393 "preventing any need to do a transport locate at the end of the loop\n\n"
1394 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
1395 "which will often cause a small click or delay"), PROGRAM_NAME));
1396 add_option (_("Transport"), tsf);
1398 tsf = new BoolOption (
1399 "disable-disarm-during-roll",
1400 _("Disable per-track record disarm while rolling"),
1401 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
1402 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
1404 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("<b>When enabled</b> this will prevent you from accidentally stopping specific tracks recording during a take"));
1405 add_option (_("Transport"), tsf);
1407 tsf = new BoolOption (
1409 _("12dB gain reduction during fast-forward and fast-rewind"),
1410 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
1411 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
1413 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
1414 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
1415 add_option (_("Transport"), tsf);
1417 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
1419 _sync_source = new ComboOption<SyncSource> (
1421 _("External timecode source"),
1422 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
1423 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
1426 populate_sync_options ();
1427 add_option (_("Transport"), _sync_source);
1429 _sync_framerate = new BoolOption (
1430 "timecode-sync-frame-rate",
1431 _("Match session video frame rate to external timecode"),
1432 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
1433 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
1435 Gtkmm2ext::UI::instance()->set_tip
1436 (_sync_framerate->tip_widget(),
1437 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
1438 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
1439 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
1440 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
1441 "timecode standard and the session standard."), PROGRAM_NAME));
1443 add_option (_("Transport"), _sync_framerate);
1445 _sync_genlock = new BoolOption (
1446 "timecode-source-is-synced",
1447 _("External timecode is sync locked"),
1448 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
1449 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
1451 Gtkmm2ext::UI::instance()->set_tip
1452 (_sync_genlock->tip_widget(),
1453 _("<b>When enabled</b> indicates that the selected external timecode source shares sync (Black & Burst, Wordclock, etc) with the audio interface."));
1456 add_option (_("Transport"), _sync_genlock);
1458 _sync_source_2997 = new BoolOption (
1459 "timecode-source-2997",
1460 _("Lock to 29.9700 fps instead of 30000/1001"),
1461 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
1462 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
1464 Gtkmm2ext::UI::instance()->set_tip
1465 (_sync_source_2997->tip_widget(),
1466 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
1467 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
1468 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
1469 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
1470 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
1471 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
1474 add_option (_("Transport"), _sync_source_2997);
1476 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
1478 _ltc_port = new ComboStringOption (
1480 _("LTC incoming port"),
1481 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
1482 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
1485 vector<string> physical_inputs;
1486 physical_inputs.push_back (_("None"));
1487 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
1488 _ltc_port->set_popdown_strings (physical_inputs);
1490 add_option (_("Transport"), _ltc_port);
1492 // TODO; rather disable this button than not compile it..
1493 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
1495 add_option (_("Transport"),
1498 _("Enable LTC generator"),
1499 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
1500 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
1503 _ltc_send_continuously = new BoolOption (
1504 "ltc-send-continuously",
1505 _("send LTC while stopped"),
1506 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
1507 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
1509 Gtkmm2ext::UI::instance()->set_tip
1510 (_ltc_send_continuously->tip_widget(),
1511 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
1512 add_option (_("Transport"), _ltc_send_continuously);
1514 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
1515 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
1516 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
1517 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
1519 Gtkmm2ext::UI::instance()->set_tip
1520 (_ltc_volume_slider->tip_widget(),
1521 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
1523 add_option (_("Transport"), _ltc_volume_slider);
1524 parameter_changed ("send-ltc");
1526 parameter_changed ("sync-source");
1530 add_option (_("Editor"),
1532 "link-region-and-track-selection",
1533 _("Link selection of regions and tracks"),
1534 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_region_and_track_selection),
1535 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_region_and_track_selection)
1538 add_option (_("Editor"),
1540 "automation-follows-regions",
1541 _("Move relevant automation when audio regions are moved"),
1542 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
1543 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
1546 add_option (_("Editor"),
1548 "show-track-meters",
1549 _("Show meters on tracks in the editor"),
1550 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_track_meters),
1551 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_track_meters)
1554 add_option (_("Editor"),
1556 "show-editor-meter",
1557 _("Display master-meter in the toolbar"),
1558 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_editor_meter),
1559 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_editor_meter)
1562 bco = new BoolComboOption (
1563 "use-overlap-equivalency",
1564 _("Regions in active edit groups are edited together"),
1565 _("whenever they overlap in time"),
1566 _("only if they have identical length, position and origin"),
1567 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
1568 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
1571 add_option (_("Editor"), bco);
1573 add_option (_("Editor"),
1575 "rubberbanding-snaps-to-grid",
1576 _("Make rubberband selection rectangle snap to the grid"),
1577 sigc::mem_fun (*_rc_config, &RCConfiguration::get_rubberbanding_snaps_to_grid),
1578 sigc::mem_fun (*_rc_config, &RCConfiguration::set_rubberbanding_snaps_to_grid)
1581 add_option (_("Editor"),
1584 _("Show waveforms in regions"),
1585 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms),
1586 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms)
1589 add_option (_("Editor"),
1590 new BoolComboOption (
1591 "show-region-gain-envelopes",
1592 _("Show gain envelopes in audio regions"),
1594 _("only in region gain mode"),
1595 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_region_gain),
1596 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_region_gain)
1599 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
1601 _("Waveform scale"),
1602 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_scale),
1603 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_scale)
1606 wfs->add (Linear, _("linear"));
1607 wfs->add (Logarithmic, _("logarithmic"));
1609 add_option (_("Editor"), wfs);
1611 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
1613 _("Waveform shape"),
1614 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_shape),
1615 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_shape)
1618 wfsh->add (Traditional, _("traditional"));
1619 wfsh->add (Rectified, _("rectified"));
1621 add_option (_("Editor"), wfsh);
1623 add_option (_("Editor"), new ClipLevelOptions (_rc_config));
1625 add_option (_("Editor"),
1627 "show-waveforms-while-recording",
1628 _("Show waveforms for audio while it is being recorded"),
1629 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms_while_recording),
1630 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms_while_recording)
1633 add_option (_("Editor"),
1636 _("Show zoom toolbar"),
1637 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_zoom_tools),
1638 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_zoom_tools)
1641 add_option (_("Editor"),
1643 "update-editor-during-summary-drag",
1644 _("Update editor window during drags of the summary"),
1645 sigc::mem_fun (*_rc_config, &RCConfiguration::get_update_editor_during_summary_drag),
1646 sigc::mem_fun (*_rc_config, &RCConfiguration::set_update_editor_during_summary_drag)
1649 add_option (_("Editor"),
1651 "link-editor-and-mixer-selection",
1652 _("Synchronise editor and mixer selection"),
1653 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_editor_and_mixer_selection),
1654 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_editor_and_mixer_selection)
1657 bo = new BoolOption (
1659 _("Name new markers"),
1660 sigc::mem_fun (*_rc_config, &RCConfiguration::get_name_new_markers),
1661 sigc::mem_fun (*_rc_config, &RCConfiguration::set_name_new_markers)
1664 add_option (_("Editor"), bo);
1665 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."
1666 "\n\nYou can always rename markers by right-clicking on them"));
1668 add_option (_("Editor"),
1670 "autoscroll-editor",
1671 _("Auto-scroll editor window when dragging near its edges"),
1672 sigc::mem_fun (*_rc_config, &RCConfiguration::get_autoscroll_editor),
1673 sigc::mem_fun (*_rc_config, &RCConfiguration::set_autoscroll_editor)
1678 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
1680 add_option (_("Audio"), new BufferingOptions (_rc_config));
1682 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
1684 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
1686 _("Record monitoring handled by"),
1687 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
1688 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
1691 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
1692 mm->add (HardwareMonitoring, _("via Audio Driver"));
1695 string prog (PROGRAM_NAME);
1696 boost::algorithm::to_lower (prog);
1697 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
1698 mm->add (ExternalMonitoring, _("audio hardware"));
1700 add_option (_("Audio"), mm);
1702 add_option (_("Audio"),
1704 "tape-machine-mode",
1705 _("Tape machine mode"),
1706 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
1707 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
1710 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
1712 add_option (_("Audio"),
1714 "auto-connect-standard-busses",
1715 _("Auto-connect master/monitor busses"),
1716 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
1717 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
1720 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
1721 "input-auto-connect",
1722 _("Connect track inputs"),
1723 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
1724 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
1727 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
1728 iac->add (ManualConnect, _("manually"));
1730 add_option (_("Audio"), iac);
1732 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
1733 "output-auto-connect",
1734 _("Connect track and bus outputs"),
1735 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
1736 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
1739 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
1740 oac->add (AutoConnectMaster, _("automatically to master bus"));
1741 oac->add (ManualConnect, _("manually"));
1743 add_option (_("Audio"), oac);
1745 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
1747 add_option (_("Audio"),
1749 "denormal-protection",
1750 _("Use DC bias to protect against denormals"),
1751 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
1752 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
1755 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
1757 _("Processor handling"),
1758 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
1759 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
1762 dm->add (DenormalNone, _("no processor handling"));
1766 if (fpu.has_flush_to_zero()) {
1767 dm->add (DenormalFTZ, _("use FlushToZero"));
1770 if (fpu.has_denormals_are_zero()) {
1771 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
1774 if (fpu.has_flush_to_zero() && fpu.has_denormals_are_zero()) {
1775 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
1778 add_option (_("Audio"), dm);
1780 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
1782 add_option (_("Audio"),
1784 "plugins-stop-with-transport",
1785 _("Silence plugins when the transport is stopped"),
1786 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
1787 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
1790 add_option (_("Audio"),
1792 "new-plugins-active",
1793 _("Make new plugins active"),
1794 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
1795 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
1798 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
1800 add_option (_("Audio"),
1802 "auto-analyse-audio",
1803 _("Enable automatic analysis of audio"),
1804 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
1805 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
1808 add_option (_("Audio"),
1810 "replicate-missing-region-channels",
1811 _("Replicate missing region channels"),
1812 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
1813 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
1818 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
1820 add_option (_("Solo / mute"),
1823 _("Solo-in-place mute cut (dB)"),
1824 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
1825 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
1828 _solo_control_is_listen_control = new BoolOption (
1829 "solo-control-is-listen-control",
1830 _("Solo controls are Listen controls"),
1831 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
1832 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
1835 add_option (_("Solo / mute"), _solo_control_is_listen_control);
1837 _listen_position = new ComboOption<ListenPosition> (
1839 _("Listen Position"),
1840 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
1841 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
1844 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
1845 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
1847 add_option (_("Solo / mute"), _listen_position);
1849 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
1851 _("PFL signals come from"),
1852 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
1853 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
1856 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
1857 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
1859 add_option (_("Solo / mute"), pp);
1861 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
1863 _("AFL signals come from"),
1864 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
1865 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
1868 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
1869 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
1871 add_option (_("Solo / mute"), pa);
1873 parameter_changed ("use-monitor-bus");
1875 add_option (_("Solo / mute"),
1878 _("Exclusive solo"),
1879 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
1880 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
1883 add_option (_("Solo / mute"),
1886 _("Show solo muting"),
1887 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
1888 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
1891 add_option (_("Solo / mute"),
1893 "solo-mute-override",
1894 _("Soloing overrides muting"),
1895 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
1896 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
1899 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
1901 add_option (_("Solo / mute"),
1903 "mute-affects-pre-fader",
1904 _("Mute affects pre-fader sends"),
1905 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
1906 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
1909 add_option (_("Solo / mute"),
1911 "mute-affects-post-fader",
1912 _("Mute affects post-fader sends"),
1913 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
1914 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
1917 add_option (_("Solo / mute"),
1919 "mute-affects-control-outs",
1920 _("Mute affects control outputs"),
1921 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
1922 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
1925 add_option (_("Solo / mute"),
1927 "mute-affects-main-outs",
1928 _("Mute affects main outputs"),
1929 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
1930 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
1933 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
1935 add_option (_("Solo / mute"),
1937 "link-send-and-route-panner",
1938 _("Link panners of Aux and External Sends with main panner by default"),
1939 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
1940 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
1943 add_option (_("MIDI"),
1946 _("Send MIDI Clock"),
1947 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
1948 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
1951 add_option (_("MIDI"),
1954 _("Send MIDI Time Code"),
1955 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
1956 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
1959 add_option (_("MIDI"),
1960 new SpinOption<int> (
1961 "mtc-qf-speed-tolerance",
1962 _("Percentage either side of normal transport speed to transmit MTC"),
1963 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
1964 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
1968 add_option (_("MIDI"),
1971 _("Obey MIDI Machine Control commands"),
1972 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
1973 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
1976 add_option (_("MIDI"),
1979 _("Send MIDI Machine Control commands"),
1980 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
1981 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
1984 add_option (_("MIDI"),
1987 _("Send MIDI control feedback"),
1988 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
1989 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
1992 add_option (_("MIDI"),
1993 new SpinOption<uint8_t> (
1994 "mmc-receive-device-id",
1995 _("Inbound MMC device ID"),
1996 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
1997 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2001 add_option (_("MIDI"),
2002 new SpinOption<uint8_t> (
2003 "mmc-send-device-id",
2004 _("Outbound MMC device ID"),
2005 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2006 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2010 add_option (_("MIDI"),
2011 new SpinOption<int32_t> (
2012 "initial-program-change",
2013 _("Initial program change"),
2014 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2015 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2019 add_option (_("MIDI"),
2021 "display-first-midi-bank-as-zero",
2022 _("Display first MIDI bank/program as 0"),
2023 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2024 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2027 add_option (_("MIDI"),
2029 "never-display-periodic-midi",
2030 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2031 sigc::mem_fun (*_rc_config, &RCConfiguration::get_never_display_periodic_midi),
2032 sigc::mem_fun (*_rc_config, &RCConfiguration::set_never_display_periodic_midi)
2035 add_option (_("MIDI"),
2038 _("Sound MIDI notes as they are selected"),
2039 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sound_midi_notes),
2040 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sound_midi_notes)
2043 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2045 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2046 "midi-audition-synth-uri",
2047 _("Midi Audition Synth (LV2)"),
2048 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2049 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2052 audition_synth->add(X_(""), _("None"));
2053 PluginInfoList all_plugs;
2054 PluginManager& manager (PluginManager::instance());
2056 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2058 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2059 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2060 if (!(*i)->is_instrument()) continue;
2061 if ((*i)->type != ARDOUR::LV2) continue;
2062 audition_synth->add((*i)->unique_id, (*i)->name);
2066 add_option (_("MIDI"), audition_synth);
2068 /* USER INTERACTION */
2070 if (getenv ("ARDOUR_BUNDLED")) {
2071 add_option (_("User interaction"),
2073 "enable-translation",
2074 string_compose (_("Use translations of %1 messages\n"
2075 " <i>(requires a restart of %1 to take effect)</i>\n"
2076 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2077 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2078 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2081 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2083 add_option (_("User interaction"), new KeyboardOptions);
2085 /* Control Surfaces */
2087 add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2089 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2091 _("Control surface remote ID"),
2092 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2093 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2096 rm->add (UserOrdered, _("assigned by user"));
2097 rm->add (MixerOrdered, _("follows order of mixer"));
2099 add_option (_("Control Surfaces"), rm);
2101 /* VIDEO Timeline */
2102 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2104 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
2105 /* Plugin options (currrently VST only) */
2106 add_option (_("Plugins"), new PluginOptions (_rc_config));
2111 add_option (S_("Preferences|GUI"),
2114 _("Graphically indicate mouse pointer hovering over various widgets"),
2115 sigc::mem_fun (*_rc_config, &RCConfiguration::get_widget_prelight),
2116 sigc::mem_fun (*_rc_config, &RCConfiguration::set_widget_prelight)
2119 add_option (S_("Preferences|GUI"),
2122 _("Show tooltips if mouse hovers over a control"),
2123 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_tooltips),
2124 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_tooltips)
2127 add_option (S_("Preferences|GUI"),
2129 "show-name-highlight",
2130 _("use name highlight bars in region displays"),
2131 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_name_highlight),
2132 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_name_highlight)
2136 /* font scaling does nothing with GDK/Quartz */
2137 add_option (S_("Preferences|GUI"), new FontScalingOptions (_rc_config));
2140 add_option (S_("GUI"),
2142 "super-rapid-clock-update",
2143 _("update transport clock display every 40ms instead of every 100ms"),
2144 sigc::mem_fun (*_rc_config, &RCConfiguration::get_super_rapid_clock_update),
2145 sigc::mem_fun (*_rc_config, &RCConfiguration::set_super_rapid_clock_update)
2148 /* The names of these controls must be the same as those given in MixerStrip
2149 for the actual widgets being controlled.
2151 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2152 _mixer_strip_visibility.add (0, X_("SoloSafe"), _("Solo Safe"));
2153 _mixer_strip_visibility.add (0, X_("SoloIsolated"), _("Solo Isolated"));
2154 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2155 _mixer_strip_visibility.add (0, X_("Group"), _("Group"));
2156 _mixer_strip_visibility.add (0, X_("MeterPoint"), _("Meter Point"));
2159 S_("Preferences|GUI"),
2160 new VisibilityOption (
2162 &_mixer_strip_visibility,
2163 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mixer_strip_visibility),
2164 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mixer_strip_visibility)
2168 add_option (S_("Preferences|GUI"),
2170 "default-narrow_ms",
2171 _("Use narrow strips in the mixer by default"),
2172 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_narrow_ms),
2173 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_narrow_ms)
2176 add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Metering")));
2178 ComboOption<float>* mht = new ComboOption<float> (
2180 _("Peak hold time"),
2181 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_hold),
2182 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_hold)
2185 mht->add (MeterHoldOff, _("off"));
2186 mht->add (MeterHoldShort, _("short"));
2187 mht->add (MeterHoldMedium, _("medium"));
2188 mht->add (MeterHoldLong, _("long"));
2190 add_option (S_("Preferences|GUI"), mht);
2192 ComboOption<float>* mfo = new ComboOption<float> (
2195 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2196 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2199 mfo->add (METER_FALLOFF_OFF, _("off"));
2200 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2201 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2202 mfo->add (METER_FALLOFF_SLOWISH, _("slowish [12.0dB/sec] (DIN)"));
2203 mfo->add (METER_FALLOFF_MODERATE, _("moderate [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2204 mfo->add (METER_FALLOFF_MEDIUM, _("medium [20dB/sec]"));
2205 mfo->add (METER_FALLOFF_FAST, _("fast [32dB/sec]"));
2206 mfo->add (METER_FALLOFF_FASTER, _("faster [46dB/sec]"));
2207 mfo->add (METER_FALLOFF_FASTEST, _("fastest [70dB/sec]"));
2209 add_option (S_("Preferences|GUI"), mfo);
2211 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2212 "meter-line-up-level",
2213 _("Meter line-up level; 0dBu"),
2214 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_line_up_level),
2215 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_line_up_level)
2218 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2219 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2220 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2221 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2223 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."));
2225 add_option (S_("Preferences|GUI"), mlu);
2227 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2228 "meter-line-up-din",
2229 _("IEC1/DIN Meter line-up level; 0dBu"),
2230 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_line_up_din),
2231 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_line_up_din)
2234 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2235 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2236 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2237 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2239 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2241 add_option (S_("Preferences|GUI"), mld);
2243 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2244 "meter-vu-standard",
2245 _("VU Meter standard"),
2246 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_vu_standard),
2247 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_vu_standard)
2250 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2251 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2252 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2253 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2255 add_option (S_("Preferences|GUI"), mvu);
2257 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
2258 HSliderOption *mpks = new HSliderOption("meter-peak",
2259 _("Peak threshold [dBFS]"),
2261 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_peak),
2262 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_peak)
2265 Gtkmm2ext::UI::instance()->set_tip
2266 (mpks->tip_widget(),
2267 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
2269 add_option (S_("Preferences|GUI"), mpks);
2271 add_option (S_("Preferences|GUI"),
2274 _("LED meter style"),
2275 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_style_led),
2276 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_style_led)
2282 RCOptionEditor::parameter_changed (string const & p)
2284 OptionEditor::parameter_changed (p);
2286 if (p == "use-monitor-bus") {
2287 bool const s = Config->get_use_monitor_bus ();
2289 /* we can't use this if we don't have a monitor bus */
2290 Config->set_solo_control_is_listen_control (false);
2292 _solo_control_is_listen_control->set_sensitive (s);
2293 _listen_position->set_sensitive (s);
2294 } else if (p == "sync-source") {
2295 _sync_source->set_sensitive (true);
2297 _sync_source->set_sensitive (!_session->config.get_external_sync());
2299 switch(Config->get_sync_source()) {
2302 _sync_genlock->set_sensitive (true);
2303 _sync_framerate->set_sensitive (true);
2304 _sync_source_2997->set_sensitive (true);
2307 _sync_genlock->set_sensitive (false);
2308 _sync_framerate->set_sensitive (false);
2309 _sync_source_2997->set_sensitive (false);
2312 } else if (p == "send-ltc") {
2313 bool const s = Config->get_send_ltc ();
2314 _ltc_send_continuously->set_sensitive (s);
2315 _ltc_volume_slider->set_sensitive (s);
2319 void RCOptionEditor::ltc_generator_volume_changed () {
2320 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
2324 RCOptionEditor::populate_sync_options ()
2326 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
2328 _sync_source->clear ();
2330 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
2331 _sync_source->add (*i, sync_source_to_string (*i));