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>
37 #include "ardour/audioengine.h"
38 #include "ardour/dB.h"
39 #include "ardour/rc_configuration.h"
40 #include "ardour/control_protocol_manager.h"
41 #include "ardour/plugin_manager.h"
42 #include "control_protocol/control_protocol.h"
44 #include "canvas/wave_view.h"
46 #include "ardour_window.h"
47 #include "ardour_dialog.h"
48 #include "gui_thread.h"
49 #include "midi_tracer.h"
50 #include "paths_dialog.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 (Session *s, RCConfiguration* c)
1003 , _display_plugin_scan_progress (_("Display Plugin Scan Progress"))
1004 , _discover_vst_on_start (_("Scan for new VST Plugins on Application Start"))
1007 std::stringstream ss;
1008 Table* t = manage (new Table (2, 6));
1009 t->set_spacings (4);
1013 ss << "<b>" << _("General") << "</b>";
1014 l = manage (left_aligned_label (ss.str()));
1015 l->set_use_markup (true);
1016 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1017 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1019 b = manage (new Button (_("Refresh Plugin List")));
1020 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1021 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1023 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1024 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1025 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1026 _("<b>When enabled</b> display a popup window showing plugin scan progress."));
1029 ss << "<b>" << _("VST") << "</b>";
1030 l = manage (left_aligned_label (ss.str()));
1031 l->set_use_markup (true);
1032 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1033 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1035 b = manage (new Button (_("Clear VST Cache")));
1036 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1037 t->attach (*b, 0, 1, n, n+1, FILL);
1039 b = manage (new Button (_("Clear VST Blacklist")));
1040 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1041 t->attach (*b, 1, 2, n, n+1, FILL);
1044 t->attach (_discover_vst_on_start, 0, 2, n, n+1); ++n;
1045 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1046 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1047 _("<b>When enabled</b> VST plugins are searched and tested on application start. When disabled they a Refresh will have to be tiggered manually"));
1049 #ifdef WINDOWS_VST_SUPPORT
1050 t->attach (*manage (left_aligned_label (_("Windows VST Path:"))), 0, 1, n, n+1);
1051 b = manage (new Button (_("Edit")));
1052 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_vst_path_clicked));
1053 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1056 #ifdef LXVST_SUPPORT
1057 t->attach (*manage (left_aligned_label (_("Linux VST:"))), 0, 1, n, n+1);
1058 b = manage (new Button (_("Edit")));
1059 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_lxvst_path_clicked));
1060 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1063 _box->pack_start (*t,true,true);
1066 void parameter_changed (string const & p) {
1067 if (p == "show-plugin-scan-window") {
1068 bool const x = _rc_config->get_show_plugin_scan_window();
1069 _display_plugin_scan_progress.set_active (x);
1071 else if (p == "discover-vst-on-start") {
1072 bool const x = _rc_config->get_discover_vst_on_start();
1073 _discover_vst_on_start.set_active (x);
1077 void set_state_from_config () {
1078 parameter_changed ("show-plugin-scan-window");
1079 parameter_changed ("discover-vst-on-start");
1083 RCConfiguration* _rc_config;
1085 CheckButton _display_plugin_scan_progress;
1086 CheckButton _discover_vst_on_start;
1088 void display_plugin_scan_progress_toggled () {
1089 bool const x = _display_plugin_scan_progress.get_active();
1090 _rc_config->set_show_plugin_scan_window(x);
1093 void discover_vst_on_start_toggled () {
1094 bool const x = _discover_vst_on_start.get_active();
1095 _rc_config->set_discover_vst_on_start(x);
1098 void clear_vst_cache_clicked () {
1099 PluginManager::instance().clear_vst_cache();
1102 void clear_vst_blacklist_clicked () {
1103 PluginManager::instance().clear_vst_blacklist();
1106 void edit_vst_path_clicked () {
1107 PathsDialog *pd = new PathsDialog(_session,
1108 _rc_config->get_plugin_path_vst(),
1109 PluginManager::instance().get_windows_vst_path()
1111 ResponseType r = (ResponseType) pd->run ();
1113 if (r == RESPONSE_ACCEPT) {
1114 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
1119 // todo consolidate with edit_vst_path_clicked..
1120 void edit_lxvst_path_clicked () {
1121 PathsDialog *pd = new PathsDialog(_session,
1122 _rc_config->get_plugin_path_lxvst(),
1123 PluginManager::instance().get_lxvst_path()
1125 ResponseType r = (ResponseType) pd->run ();
1127 if (r == RESPONSE_ACCEPT) {
1128 printf("%s", pd->get_serialized_paths().c_str());
1133 void refresh_clicked () {
1134 PluginManager::instance().refresh();
1139 /** A class which allows control of visibility of some editor components usign
1140 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1141 * which has the correct members, but with null widget pointers. This
1142 * class allows the user to set visibility of the members, the details
1143 * of which are stored in a configuration variable which can be watched
1144 * by parts of the editor that actually contain the widgets whose visibility
1145 * is being controlled.
1148 class VisibilityOption : public Option
1151 /** @param name User-visible name for this group.
1152 * @param g `Dummy' VisibilityGroup (as described above).
1153 * @param get Method to get the value of the appropriate configuration variable.
1154 * @param set Method to set the value of the appropriate configuration variable.
1156 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1157 : Option (g->get_state_name(), name)
1159 , _visibility_group (g)
1163 /* Watch for changes made by the user to our members */
1164 _visibility_group->VisibilityChanged.connect_same_thread (
1165 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1169 void set_state_from_config ()
1171 /* Set our state from the current configuration */
1172 _visibility_group->set_state (_get ());
1175 void add_to_page (OptionEditorPage* p)
1177 _heading.add_to_page (p);
1178 add_widget_to_page (p, _visibility_group->list_view ());
1181 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1186 /* The user has changed something, so reflect this change
1187 in the RCConfiguration.
1189 _set (_visibility_group->get_state_value ());
1192 OptionEditorHeading _heading;
1193 VisibilityGroup* _visibility_group;
1194 sigc::slot<std::string> _get;
1195 sigc::slot<bool, std::string> _set;
1196 PBD::ScopedConnection _visibility_group_connection;
1201 RCOptionEditor::RCOptionEditor ()
1202 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1203 , _rc_config (Config)
1204 , _mixer_strip_visibility ("mixer-strip-visibility")
1208 uint32_t hwcpus = hardware_concurrency ();
1210 BoolComboOption* bco;
1213 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1215 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1217 _("Signal processing uses"),
1218 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1219 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1222 procs->add (-1, _("all but one processor"));
1223 procs->add (0, _("all available processors"));
1225 for (uint32_t i = 1; i <= hwcpus; ++i) {
1226 procs->add (i, string_compose (_("%1 processors"), i));
1229 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1231 add_option (_("Misc"), procs);
1234 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1236 add_option (_("Misc"), new UndoOptions (_rc_config));
1238 add_option (_("Misc"),
1240 "verify-remove-last-capture",
1241 _("Verify removal of last capture"),
1242 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1243 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1246 add_option (_("Misc"),
1248 "periodic-safety-backups",
1249 _("Make periodic backups of the session file"),
1250 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1251 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1254 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1256 add_option (_("Misc"),
1258 "only-copy-imported-files",
1259 _("Always copy imported files"),
1260 sigc::mem_fun (*_rc_config, &RCConfiguration::get_only_copy_imported_files),
1261 sigc::mem_fun (*_rc_config, &RCConfiguration::set_only_copy_imported_files)
1264 add_option (_("Misc"), new DirectoryOption (
1265 X_("default-session-parent-dir"),
1266 _("Default folder for new sessions:"),
1267 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1268 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1271 add_option (_("Misc"),
1272 new SpinOption<uint32_t> (
1273 "max-recent-sessions",
1274 _("Maximum number of recent sessions"),
1275 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1276 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1280 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1282 add_option (_("Misc"), new ClickOptions (_rc_config, this));
1284 add_option (_("Misc"),
1287 _("Click gain level"),
1288 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1289 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1292 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1294 add_option (_("Misc"),
1295 new SpinOption<double> (
1296 "automation-thinning-factor",
1297 _("Thinning factor (larger value => less data)"),
1298 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1299 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1303 add_option (_("Misc"),
1304 new SpinOption<double> (
1305 "automation-interval-msecs",
1306 _("Automation sampling interval (milliseconds)"),
1307 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1308 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1316 tsf = new BoolOption (
1317 "latched-record-enable",
1318 _("Keep record-enable engaged on stop"),
1319 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1320 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1322 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1323 add_option (_("Transport"), tsf);
1325 tsf = new BoolOption (
1326 "stop-recording-on-xrun",
1327 _("Stop recording when an xrun occurs"),
1328 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1329 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1331 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1332 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
1334 add_option (_("Transport"), tsf);
1336 tsf = new BoolOption (
1337 "create-xrun-marker",
1338 _("Create markers where xruns occur"),
1339 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1340 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1342 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1343 add_option (_("Transport"), tsf);
1345 tsf = new BoolOption (
1346 "stop-at-session-end",
1347 _("Stop at the end of the session"),
1348 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1349 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1351 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1352 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
1353 "when it reaches the current session end marker\n\n"
1354 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
1356 add_option (_("Transport"), tsf);
1358 tsf = new BoolOption (
1360 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
1361 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1362 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1364 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1365 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1366 "preventing any need to do a transport locate at the end of the loop\n\n"
1367 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
1368 "which will often cause a small click or delay"), PROGRAM_NAME));
1369 add_option (_("Transport"), tsf);
1371 tsf = new BoolOption (
1372 "disable-disarm-during-roll",
1373 _("Disable per-track record disarm while rolling"),
1374 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
1375 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
1377 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"));
1378 add_option (_("Transport"), tsf);
1380 tsf = new BoolOption (
1382 _("12dB gain reduction during fast-forward and fast-rewind"),
1383 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
1384 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
1386 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
1387 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
1388 add_option (_("Transport"), tsf);
1390 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
1392 _sync_source = new ComboOption<SyncSource> (
1394 _("External timecode source"),
1395 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
1396 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
1399 populate_sync_options ();
1400 add_option (_("Transport"), _sync_source);
1402 _sync_framerate = new BoolOption (
1403 "timecode-sync-frame-rate",
1404 _("Match session video frame rate to external timecode"),
1405 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
1406 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
1408 Gtkmm2ext::UI::instance()->set_tip
1409 (_sync_framerate->tip_widget(),
1410 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
1411 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
1412 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
1413 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
1414 "timecode standard and the session standard."), PROGRAM_NAME));
1416 add_option (_("Transport"), _sync_framerate);
1418 _sync_genlock = new BoolOption (
1419 "timecode-source-is-synced",
1420 _("External timecode is sync locked"),
1421 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
1422 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
1424 Gtkmm2ext::UI::instance()->set_tip
1425 (_sync_genlock->tip_widget(),
1426 _("<b>When enabled</b> indicates that the selected external timecode source shares sync (Black & Burst, Wordclock, etc) with the audio interface."));
1429 add_option (_("Transport"), _sync_genlock);
1431 _sync_source_2997 = new BoolOption (
1432 "timecode-source-2997",
1433 _("Lock to 29.9700 fps instead of 30000/1001"),
1434 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
1435 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
1437 Gtkmm2ext::UI::instance()->set_tip
1438 (_sync_source_2997->tip_widget(),
1439 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
1440 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
1441 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
1442 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
1443 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
1444 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
1447 add_option (_("Transport"), _sync_source_2997);
1449 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
1451 _ltc_port = new ComboStringOption (
1453 _("LTC incoming port"),
1454 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
1455 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
1458 vector<string> physical_inputs;
1459 physical_inputs.push_back (_("None"));
1460 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
1461 _ltc_port->set_popdown_strings (physical_inputs);
1463 add_option (_("Transport"), _ltc_port);
1465 // TODO; rather disable this button than not compile it..
1466 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
1468 add_option (_("Transport"),
1471 _("Enable LTC generator"),
1472 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
1473 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
1476 _ltc_send_continuously = new BoolOption (
1477 "ltc-send-continuously",
1478 _("send LTC while stopped"),
1479 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
1480 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
1482 Gtkmm2ext::UI::instance()->set_tip
1483 (_ltc_send_continuously->tip_widget(),
1484 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
1485 add_option (_("Transport"), _ltc_send_continuously);
1487 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
1488 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
1489 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
1490 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
1492 Gtkmm2ext::UI::instance()->set_tip
1493 (_ltc_volume_slider->tip_widget(),
1494 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
1496 add_option (_("Transport"), _ltc_volume_slider);
1497 parameter_changed ("send-ltc");
1499 parameter_changed ("sync-source");
1503 add_option (_("Editor"),
1505 "link-region-and-track-selection",
1506 _("Link selection of regions and tracks"),
1507 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_region_and_track_selection),
1508 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_region_and_track_selection)
1511 add_option (_("Editor"),
1513 "automation-follows-regions",
1514 _("Move relevant automation when audio regions are moved"),
1515 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
1516 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
1519 add_option (_("Editor"),
1521 "show-track-meters",
1522 _("Show meters on tracks in the editor"),
1523 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_track_meters),
1524 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_track_meters)
1527 add_option (_("Editor"),
1529 "show-editor-meter",
1530 _("Display master-meter in the toolbar"),
1531 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_editor_meter),
1532 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_editor_meter)
1535 bco = new BoolComboOption (
1536 "use-overlap-equivalency",
1537 _("Regions in active edit groups are edited together"),
1538 _("whenever they overlap in time"),
1539 _("only if they have identical length, position and origin"),
1540 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
1541 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
1544 add_option (_("Editor"), bco);
1546 add_option (_("Editor"),
1548 "rubberbanding-snaps-to-grid",
1549 _("Make rubberband selection rectangle snap to the grid"),
1550 sigc::mem_fun (*_rc_config, &RCConfiguration::get_rubberbanding_snaps_to_grid),
1551 sigc::mem_fun (*_rc_config, &RCConfiguration::set_rubberbanding_snaps_to_grid)
1554 add_option (_("Editor"),
1557 _("Show waveforms in regions"),
1558 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms),
1559 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms)
1562 add_option (_("Editor"),
1563 new BoolComboOption (
1564 "show-region-gain-envelopes",
1565 _("Show gain envelopes in audio regions"),
1567 _("only in region gain mode"),
1568 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_region_gain),
1569 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_region_gain)
1572 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
1574 _("Waveform scale"),
1575 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_scale),
1576 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_scale)
1579 wfs->add (Linear, _("linear"));
1580 wfs->add (Logarithmic, _("logarithmic"));
1582 add_option (_("Editor"), wfs);
1584 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
1586 _("Waveform shape"),
1587 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_shape),
1588 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_shape)
1591 wfsh->add (Traditional, _("traditional"));
1592 wfsh->add (Rectified, _("rectified"));
1594 add_option (_("Editor"), wfsh);
1596 add_option (_("Editor"), new ClipLevelOptions (_rc_config));
1598 add_option (_("Editor"),
1600 "show-waveforms-while-recording",
1601 _("Show waveforms for audio while it is being recorded"),
1602 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms_while_recording),
1603 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms_while_recording)
1606 add_option (_("Editor"),
1609 _("Show zoom toolbar"),
1610 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_zoom_tools),
1611 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_zoom_tools)
1614 add_option (_("Editor"),
1616 "update-editor-during-summary-drag",
1617 _("Update editor window during drags of the summary"),
1618 sigc::mem_fun (*_rc_config, &RCConfiguration::get_update_editor_during_summary_drag),
1619 sigc::mem_fun (*_rc_config, &RCConfiguration::set_update_editor_during_summary_drag)
1622 add_option (_("Editor"),
1624 "link-editor-and-mixer-selection",
1625 _("Synchronise editor and mixer selection"),
1626 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_editor_and_mixer_selection),
1627 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_editor_and_mixer_selection)
1630 bo = new BoolOption (
1632 _("Name new markers"),
1633 sigc::mem_fun (*_rc_config, &RCConfiguration::get_name_new_markers),
1634 sigc::mem_fun (*_rc_config, &RCConfiguration::set_name_new_markers)
1637 add_option (_("Editor"), bo);
1638 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."
1639 "\n\nYou can always rename markers by right-clicking on them"));
1641 add_option (_("Editor"),
1643 "autoscroll-editor",
1644 _("Auto-scroll editor window when dragging near its edges"),
1645 sigc::mem_fun (*_rc_config, &RCConfiguration::get_autoscroll_editor),
1646 sigc::mem_fun (*_rc_config, &RCConfiguration::set_autoscroll_editor)
1651 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
1653 add_option (_("Audio"), new BufferingOptions (_rc_config));
1655 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
1657 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
1659 _("Record monitoring handled by"),
1660 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
1661 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
1664 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
1665 mm->add (HardwareMonitoring, _("via Audio Driver"));
1668 string prog (PROGRAM_NAME);
1669 boost::algorithm::to_lower (prog);
1670 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
1671 mm->add (ExternalMonitoring, _("audio hardware"));
1673 add_option (_("Audio"), mm);
1675 add_option (_("Audio"),
1677 "tape-machine-mode",
1678 _("Tape machine mode"),
1679 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
1680 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
1683 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
1685 add_option (_("Audio"),
1687 "auto-connect-standard-busses",
1688 _("Auto-connect master/monitor busses"),
1689 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
1690 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
1693 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
1694 "input-auto-connect",
1695 _("Connect track inputs"),
1696 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
1697 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
1700 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
1701 iac->add (ManualConnect, _("manually"));
1703 add_option (_("Audio"), iac);
1705 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
1706 "output-auto-connect",
1707 _("Connect track and bus outputs"),
1708 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
1709 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
1712 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
1713 oac->add (AutoConnectMaster, _("automatically to master bus"));
1714 oac->add (ManualConnect, _("manually"));
1716 add_option (_("Audio"), oac);
1718 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
1720 add_option (_("Audio"),
1722 "denormal-protection",
1723 _("Use DC bias to protect against denormals"),
1724 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
1725 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
1728 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
1730 _("Processor handling"),
1731 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
1732 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
1735 dm->add (DenormalNone, _("no processor handling"));
1739 if (fpu.has_flush_to_zero()) {
1740 dm->add (DenormalFTZ, _("use FlushToZero"));
1743 if (fpu.has_denormals_are_zero()) {
1744 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
1747 if (fpu.has_flush_to_zero() && fpu.has_denormals_are_zero()) {
1748 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
1751 add_option (_("Audio"), dm);
1753 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
1755 add_option (_("Audio"),
1757 "plugins-stop-with-transport",
1758 _("Silence plugins when the transport is stopped"),
1759 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
1760 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
1763 add_option (_("Audio"),
1765 "new-plugins-active",
1766 _("Make new plugins active"),
1767 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
1768 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
1771 add_option (_("Audio"),
1773 "auto-analyse-audio",
1774 _("Enable automatic analysis of audio"),
1775 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
1776 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
1779 add_option (_("Audio"),
1781 "replicate-missing-region-channels",
1782 _("Replicate missing region channels"),
1783 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
1784 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
1789 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
1791 add_option (_("Solo / mute"),
1794 _("Solo-in-place mute cut (dB)"),
1795 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
1796 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
1799 _solo_control_is_listen_control = new BoolOption (
1800 "solo-control-is-listen-control",
1801 _("Solo controls are Listen controls"),
1802 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
1803 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
1806 add_option (_("Solo / mute"), _solo_control_is_listen_control);
1808 _listen_position = new ComboOption<ListenPosition> (
1810 _("Listen Position"),
1811 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
1812 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
1815 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
1816 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
1818 add_option (_("Solo / mute"), _listen_position);
1820 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
1822 _("PFL signals come from"),
1823 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
1824 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
1827 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
1828 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
1830 add_option (_("Solo / mute"), pp);
1832 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
1834 _("AFL signals come from"),
1835 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
1836 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
1839 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
1840 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
1842 add_option (_("Solo / mute"), pa);
1844 parameter_changed ("use-monitor-bus");
1846 add_option (_("Solo / mute"),
1849 _("Exclusive solo"),
1850 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
1851 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
1854 add_option (_("Solo / mute"),
1857 _("Show solo muting"),
1858 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
1859 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
1862 add_option (_("Solo / mute"),
1864 "solo-mute-override",
1865 _("Soloing overrides muting"),
1866 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
1867 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
1870 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
1872 add_option (_("Solo / mute"),
1874 "mute-affects-pre-fader",
1875 _("Mute affects pre-fader sends"),
1876 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
1877 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
1880 add_option (_("Solo / mute"),
1882 "mute-affects-post-fader",
1883 _("Mute affects post-fader sends"),
1884 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
1885 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
1888 add_option (_("Solo / mute"),
1890 "mute-affects-control-outs",
1891 _("Mute affects control outputs"),
1892 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
1893 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
1896 add_option (_("Solo / mute"),
1898 "mute-affects-main-outs",
1899 _("Mute affects main outputs"),
1900 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
1901 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
1904 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
1906 add_option (_("Solo / mute"),
1908 "link-send-and-route-panner",
1909 _("Link panners of Aux and External Sends with main panner by default"),
1910 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
1911 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
1914 add_option (_("MIDI"),
1917 _("Send MIDI Clock"),
1918 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
1919 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
1922 add_option (_("MIDI"),
1925 _("Send MIDI Time Code"),
1926 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
1927 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
1930 add_option (_("MIDI"),
1931 new SpinOption<int> (
1932 "mtc-qf-speed-tolerance",
1933 _("Percentage either side of normal transport speed to transmit MTC"),
1934 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
1935 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
1939 add_option (_("MIDI"),
1942 _("Obey MIDI Machine Control commands"),
1943 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
1944 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
1947 add_option (_("MIDI"),
1950 _("Send MIDI Machine Control commands"),
1951 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
1952 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
1955 add_option (_("MIDI"),
1958 _("Send MIDI control feedback"),
1959 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
1960 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
1963 add_option (_("MIDI"),
1964 new SpinOption<uint8_t> (
1965 "mmc-receive-device-id",
1966 _("Inbound MMC device ID"),
1967 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
1968 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
1972 add_option (_("MIDI"),
1973 new SpinOption<uint8_t> (
1974 "mmc-send-device-id",
1975 _("Outbound MMC device ID"),
1976 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
1977 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
1981 add_option (_("MIDI"),
1982 new SpinOption<int32_t> (
1983 "initial-program-change",
1984 _("Initial program change"),
1985 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
1986 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
1990 add_option (_("MIDI"),
1992 "diplay-first-midi-bank-as-zero",
1993 _("Display first MIDI bank/program as 0"),
1994 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
1995 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
1998 add_option (_("MIDI"),
2000 "never-display-periodic-midi",
2001 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2002 sigc::mem_fun (*_rc_config, &RCConfiguration::get_never_display_periodic_midi),
2003 sigc::mem_fun (*_rc_config, &RCConfiguration::set_never_display_periodic_midi)
2006 add_option (_("MIDI"),
2009 _("Sound MIDI notes as they are selected"),
2010 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sound_midi_notes),
2011 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sound_midi_notes)
2014 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2016 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2017 "midi-audition-synth-uri",
2018 _("Midi Audition Synth (LV2)"),
2019 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2020 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2023 audition_synth->add(X_(""), _("None"));
2024 PluginInfoList all_plugs;
2025 PluginManager& manager (PluginManager::instance());
2027 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2029 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2030 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2031 if (!(*i)->is_instrument()) continue;
2032 if ((*i)->type != ARDOUR::LV2) continue;
2033 audition_synth->add((*i)->unique_id, (*i)->name);
2037 add_option (_("MIDI"), audition_synth);
2039 /* USER INTERACTION */
2041 if (getenv ("ARDOUR_BUNDLED")) {
2042 add_option (_("User interaction"),
2044 "enable-translation",
2045 string_compose (_("Use translations of %1 messages\n"
2046 " <i>(requires a restart of %1 to take effect)</i>\n"
2047 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2048 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2049 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2052 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2054 add_option (_("User interaction"), new KeyboardOptions);
2056 /* Control Surfaces */
2058 add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2060 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2062 _("Control surface remote ID"),
2063 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2064 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2067 rm->add (UserOrdered, _("assigned by user"));
2068 rm->add (MixerOrdered, _("follows order of mixer"));
2070 add_option (_("Control Surfaces"), rm);
2072 /* VIDEO Timeline */
2073 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2075 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
2076 /* Plugin options (currrently VST only) */
2077 add_option (_("Plugins"), new PluginOptions (_session, _rc_config));
2082 add_option (S_("Preferences|GUI"),
2085 _("Graphically indicate mouse pointer hovering over various widgets"),
2086 sigc::mem_fun (*_rc_config, &RCConfiguration::get_widget_prelight),
2087 sigc::mem_fun (*_rc_config, &RCConfiguration::set_widget_prelight)
2090 add_option (S_("Preferences|GUI"),
2093 _("Show tooltips if mouse hovers over a control"),
2094 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_tooltips),
2095 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_tooltips)
2099 /* font scaling does nothing with GDK/Quartz */
2100 add_option (S_("Preferences|GUI"), new FontScalingOptions (_rc_config));
2103 add_option (S_("GUI"),
2105 "super-rapid-clock-update",
2106 _("update transport clock display every 40ms instead of every 100ms"),
2107 sigc::mem_fun (*_rc_config, &RCConfiguration::get_super_rapid_clock_update),
2108 sigc::mem_fun (*_rc_config, &RCConfiguration::set_super_rapid_clock_update)
2111 /* The names of these controls must be the same as those given in MixerStrip
2112 for the actual widgets being controlled.
2114 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2115 _mixer_strip_visibility.add (0, X_("SoloSafe"), _("Solo Safe"));
2116 _mixer_strip_visibility.add (0, X_("SoloIsolated"), _("Solo Isolated"));
2117 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2118 _mixer_strip_visibility.add (0, X_("MeterPoint"), _("Meter Point"));
2121 S_("Preferences|GUI"),
2122 new VisibilityOption (
2124 &_mixer_strip_visibility,
2125 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mixer_strip_visibility),
2126 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mixer_strip_visibility)
2130 add_option (S_("Preferences|GUI"),
2132 "default-narrow_ms",
2133 _("Use narrow strips in the mixer by default"),
2134 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_narrow_ms),
2135 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_narrow_ms)
2138 add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Metering")));
2140 ComboOption<float>* mht = new ComboOption<float> (
2142 _("Peak hold time"),
2143 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_hold),
2144 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_hold)
2147 mht->add (MeterHoldOff, _("off"));
2148 mht->add (MeterHoldShort, _("short"));
2149 mht->add (MeterHoldMedium, _("medium"));
2150 mht->add (MeterHoldLong, _("long"));
2152 add_option (S_("Preferences|GUI"), mht);
2154 ComboOption<float>* mfo = new ComboOption<float> (
2157 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2158 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2161 mfo->add (METER_FALLOFF_OFF, _("off"));
2162 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2163 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2164 mfo->add (METER_FALLOFF_SLOWISH, _("slowish [12.0dB/sec] (DIN)"));
2165 mfo->add (METER_FALLOFF_MODERATE, _("moderate [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2166 mfo->add (METER_FALLOFF_MEDIUM, _("medium [20dB/sec]"));
2167 mfo->add (METER_FALLOFF_FAST, _("fast [32dB/sec]"));
2168 mfo->add (METER_FALLOFF_FASTER, _("faster [46dB/sec]"));
2169 mfo->add (METER_FALLOFF_FASTEST, _("fastest [70dB/sec]"));
2171 add_option (S_("Preferences|GUI"), mfo);
2173 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2174 "meter-line-up-level",
2175 _("Meter line-up level; 0dBu"),
2176 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_line_up_level),
2177 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_line_up_level)
2180 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2181 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2182 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2183 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2185 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."));
2187 add_option (S_("Preferences|GUI"), mlu);
2189 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2190 "meter-line-up-din",
2191 _("IEC1/DIN Meter line-up level; 0dBu"),
2192 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_line_up_din),
2193 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_line_up_din)
2196 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2197 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2198 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2199 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2201 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2203 add_option (S_("Preferences|GUI"), mld);
2205 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2206 "meter-vu-standard",
2207 _("VU Meter standard"),
2208 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_vu_standard),
2209 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_vu_standard)
2212 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2213 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2214 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2215 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2217 add_option (S_("Preferences|GUI"), mvu);
2219 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
2220 HSliderOption *mpks = new HSliderOption("meter-peak",
2221 _("Peak threshold [dBFS]"),
2223 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_peak),
2224 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_peak)
2227 Gtkmm2ext::UI::instance()->set_tip
2228 (mpks->tip_widget(),
2229 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
2231 add_option (S_("Preferences|GUI"), mpks);
2233 add_option (S_("Preferences|GUI"),
2236 _("LED meter style"),
2237 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_style_led),
2238 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_style_led)
2244 RCOptionEditor::parameter_changed (string const & p)
2246 OptionEditor::parameter_changed (p);
2248 if (p == "use-monitor-bus") {
2249 bool const s = Config->get_use_monitor_bus ();
2251 /* we can't use this if we don't have a monitor bus */
2252 Config->set_solo_control_is_listen_control (false);
2254 _solo_control_is_listen_control->set_sensitive (s);
2255 _listen_position->set_sensitive (s);
2256 } else if (p == "sync-source") {
2257 _sync_source->set_sensitive (true);
2259 _sync_source->set_sensitive (!_session->config.get_external_sync());
2261 switch(Config->get_sync_source()) {
2264 _sync_genlock->set_sensitive (true);
2265 _sync_framerate->set_sensitive (true);
2266 _sync_source_2997->set_sensitive (true);
2269 _sync_genlock->set_sensitive (false);
2270 _sync_framerate->set_sensitive (false);
2271 _sync_source_2997->set_sensitive (false);
2274 } else if (p == "send-ltc") {
2275 bool const s = Config->get_send_ltc ();
2276 _ltc_send_continuously->set_sensitive (s);
2277 _ltc_volume_slider->set_sensitive (s);
2281 void RCOptionEditor::ltc_generator_volume_changed () {
2282 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
2286 RCOptionEditor::populate_sync_options ()
2288 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
2290 _sync_source->clear ();
2292 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
2293 _sync_source->add (*i, sync_source_to_string (*i));