option to en/dis-able VST plugin discovery on startup
[ardour.git] / gtk2_ardour / rc_option_editor.cc
1 /*
2     Copyright (C) 2001-2011 Paul Davis
3
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.
8
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.
13
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.
17
18 */
19
20 #ifdef WAF_BUILD
21 #include "gtk2ardour-config.h"
22 #endif
23
24 #include <boost/algorithm/string.hpp>    
25
26 #include <gtkmm/liststore.h>
27 #include <gtkmm/stock.h>
28 #include <gtkmm/scale.h>
29
30 #include <gtkmm2ext/utils.h>
31 #include <gtkmm2ext/slider_controller.h>
32 #include <gtkmm2ext/gtk_ui.h>
33
34 #include "pbd/fpu.h"
35 #include "pbd/cpus.h"
36
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"
43
44 #include "canvas/wave_view.h"
45
46 #include "ardour_window.h"
47 #include "ardour_dialog.h"
48 #include "gui_thread.h"
49 #include "midi_tracer.h"
50 #include "rc_option_editor.h"
51 #include "utils.h"
52 #include "midi_port_dialog.h"
53 #include "sfdb_ui.h"
54 #include "keyboard.h"
55 #include "i18n.h"
56
57 using namespace std;
58 using namespace Gtk;
59 using namespace Gtkmm2ext;
60 using namespace PBD;
61 using namespace ARDOUR;
62
63 class ClickOptions : public OptionEditorBox
64 {
65 public:
66         ClickOptions (RCConfiguration* c, Gtk::Window* p)
67                 : _rc_config (c),
68                   _parent (p)
69         {
70                 Table* t = manage (new Table (2, 3));
71                 t->set_spacings (4);
72
73                 Label* l = manage (left_aligned_label (_("Click audio file:")));
74                 t->attach (*l, 0, 1, 0, 1, FILL);
75                 t->attach (_click_path_entry, 1, 2, 0, 1, FILL);
76                 Button* b = manage (new Button (_("Browse...")));
77                 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
78                 t->attach (*b, 2, 3, 0, 1, FILL);
79
80                 l = manage (left_aligned_label (_("Click emphasis audio file:")));
81                 t->attach (*l, 0, 1, 1, 2, FILL);
82                 t->attach (_click_emphasis_path_entry, 1, 2, 1, 2, FILL);
83                 b = manage (new Button (_("Browse...")));
84                 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
85                 t->attach (*b, 2, 3, 1, 2, FILL);
86                 
87                 _box->pack_start (*t, false, false);
88
89                 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));      
90                 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
91         }
92
93         void parameter_changed (string const & p)
94         {
95                 if (p == "click-sound") {
96                         _click_path_entry.set_text (_rc_config->get_click_sound());
97                 } else if (p == "click-emphasis-sound") {
98                         _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
99                 }
100         }
101
102         void set_state_from_config ()
103         {
104                 parameter_changed ("click-sound");
105                 parameter_changed ("click-emphasis-sound");
106         }
107
108 private:
109
110         void click_browse_clicked ()
111         {
112                 SoundFileChooser sfdb (_("Choose Click"));
113
114                 if (sfdb.run () == RESPONSE_OK) {
115                         click_chosen (sfdb.get_filename());
116                 }
117         }
118
119         void click_chosen (string const & path)
120         {
121                 _click_path_entry.set_text (path);
122                 _rc_config->set_click_sound (path);
123         }
124
125         void click_changed ()
126         {
127                 click_chosen (_click_path_entry.get_text ());
128         }
129         
130         void click_emphasis_browse_clicked ()
131         {
132                 SoundFileChooser sfdb (_("Choose Click Emphasis"));
133
134                 sfdb.show_all ();
135                 sfdb.present ();
136
137                 if (sfdb.run () == RESPONSE_OK) {
138                         click_emphasis_chosen (sfdb.get_filename());
139                 }
140         }
141
142         void click_emphasis_chosen (string const & path)
143         {
144                 _click_emphasis_path_entry.set_text (path);
145                 _rc_config->set_click_emphasis_sound (path);
146         }
147
148         void click_emphasis_changed ()
149         {
150                 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
151         }
152
153         RCConfiguration* _rc_config;
154         Gtk::Window* _parent;
155         Entry _click_path_entry;
156         Entry _click_emphasis_path_entry;
157 };
158
159 class UndoOptions : public OptionEditorBox
160 {
161 public:
162         UndoOptions (RCConfiguration* c) :
163                 _rc_config (c),
164                 _limit_undo_button (_("Limit undo history to")),
165                 _save_undo_button (_("Save undo history of"))
166         {
167                 Table* t = new Table (2, 3);
168                 t->set_spacings (4);
169
170                 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
171                 _limit_undo_spin.set_range (0, 512);
172                 _limit_undo_spin.set_increments (1, 10);
173                 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
174                 Label* l = manage (left_aligned_label (_("commands")));
175                 t->attach (*l, 2, 3, 0, 1);
176
177                 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
178                 _save_undo_spin.set_range (0, 512);
179                 _save_undo_spin.set_increments (1, 10);
180                 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
181                 l = manage (left_aligned_label (_("commands")));
182                 t->attach (*l, 2, 3, 1, 2);
183
184                 _box->pack_start (*t);
185
186                 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
187                 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
188                 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
189                 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
190         }
191
192         void parameter_changed (string const & p)
193         {
194                 if (p == "history-depth") {
195                         int32_t const d = _rc_config->get_history_depth();
196                         _limit_undo_button.set_active (d != 0);
197                         _limit_undo_spin.set_sensitive (d != 0);
198                         _limit_undo_spin.set_value (d);
199                 } else if (p == "save-history") {
200                         bool const x = _rc_config->get_save_history ();
201                         _save_undo_button.set_active (x);
202                         _save_undo_spin.set_sensitive (x);
203                 } else if (p == "save-history-depth") {
204                         _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
205                 }
206         }
207
208         void set_state_from_config ()
209         {
210                 parameter_changed ("save-history");
211                 parameter_changed ("history-depth");
212                 parameter_changed ("save-history-depth");
213         }
214
215         void limit_undo_toggled ()
216         {
217                 bool const x = _limit_undo_button.get_active ();
218                 _limit_undo_spin.set_sensitive (x);
219                 int32_t const n = x ? 16 : 0;
220                 _limit_undo_spin.set_value (n);
221                 _rc_config->set_history_depth (n);
222         }
223
224         void limit_undo_changed ()
225         {
226                 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
227         }
228
229         void save_undo_toggled ()
230         {
231                 bool const x = _save_undo_button.get_active ();
232                 _rc_config->set_save_history (x);
233         }
234
235         void save_undo_changed ()
236         {
237                 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
238         }
239
240 private:
241         RCConfiguration* _rc_config;
242         CheckButton _limit_undo_button;
243         SpinButton _limit_undo_spin;
244         CheckButton _save_undo_button;
245         SpinButton _save_undo_spin;
246 };
247
248
249
250 static const struct {
251     const char *name;
252     guint modifier;
253 } modifiers[] = {
254
255         { "Unmodified", 0 },
256
257 #ifdef GTKOSX
258
259         /* Command = Meta
260            Option/Alt = Mod1
261         */
262         { "Key|Shift", GDK_SHIFT_MASK },
263         { "Command", GDK_META_MASK },
264         { "Control", GDK_CONTROL_MASK },
265         { "Option", GDK_MOD1_MASK },
266         { "Command-Shift", GDK_META_MASK|GDK_SHIFT_MASK },
267         { "Command-Option", GDK_MOD1_MASK|GDK_META_MASK },
268         { "Shift-Option", GDK_SHIFT_MASK|GDK_MOD1_MASK },
269         { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_META_MASK },
270
271 #else
272         { "Key|Shift", GDK_SHIFT_MASK },
273         { "Control", GDK_CONTROL_MASK },
274         { "Alt (Mod1)", GDK_MOD1_MASK },
275         { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
276         { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
277         { "Shift-Alt", GDK_SHIFT_MASK|GDK_MOD1_MASK },
278         { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
279         { "Mod2", GDK_MOD2_MASK },
280         { "Mod3", GDK_MOD3_MASK },
281         { "Mod4", GDK_MOD4_MASK },
282         { "Mod5", GDK_MOD5_MASK },
283 #endif
284         { 0, 0 }
285 };
286
287
288 class KeyboardOptions : public OptionEditorBox
289 {
290 public:
291         KeyboardOptions () :
292                   _delete_button_adjustment (3, 1, 12),
293                   _delete_button_spin (_delete_button_adjustment),
294                   _edit_button_adjustment (3, 1, 5),
295                   _edit_button_spin (_edit_button_adjustment),
296                   _insert_note_button_adjustment (3, 1, 5),
297                   _insert_note_button_spin (_insert_note_button_adjustment)
298         {
299                 /* internationalize and prepare for use with combos */
300
301                 vector<string> dumb;
302                 for (int i = 0; modifiers[i].name; ++i) {
303                         dumb.push_back (S_(modifiers[i].name));
304                 }
305
306                 set_popdown_strings (_edit_modifier_combo, dumb);
307                 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
308
309                 for (int x = 0; modifiers[x].name; ++x) {
310                         if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
311                                 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
312                                 break;
313                         }
314                 }
315
316                 Table* t = manage (new Table (4, 4));
317                 t->set_spacings (4);
318
319                 Label* l = manage (left_aligned_label (_("Edit using:")));
320                 l->set_name ("OptionsLabel");
321
322                 t->attach (*l, 0, 1, 0, 1, FILL | EXPAND, FILL);
323                 t->attach (_edit_modifier_combo, 1, 2, 0, 1, FILL | EXPAND, FILL);
324
325                 l = manage (new Label (_("+ button")));
326                 l->set_name ("OptionsLabel");
327
328                 t->attach (*l, 3, 4, 0, 1, FILL | EXPAND, FILL);
329                 t->attach (_edit_button_spin, 4, 5, 0, 1, FILL | EXPAND, FILL);
330
331                 _edit_button_spin.set_name ("OptionsEntry");
332                 _edit_button_adjustment.set_value (Keyboard::edit_button());
333                 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
334
335                 set_popdown_strings (_delete_modifier_combo, dumb);
336                 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
337
338                 for (int x = 0; modifiers[x].name; ++x) {
339                         if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
340                                 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
341                                 break;
342                         }
343                 }
344
345                 l = manage (left_aligned_label (_("Delete using:")));
346                 l->set_name ("OptionsLabel");
347
348                 t->attach (*l, 0, 1, 1, 2, FILL | EXPAND, FILL);
349                 t->attach (_delete_modifier_combo, 1, 2, 1, 2, FILL | EXPAND, FILL);
350
351                 l = manage (new Label (_("+ button")));
352                 l->set_name ("OptionsLabel");
353
354                 t->attach (*l, 3, 4, 1, 2, FILL | EXPAND, FILL);
355                 t->attach (_delete_button_spin, 4, 5, 1, 2, FILL | EXPAND, FILL);
356
357                 _delete_button_spin.set_name ("OptionsEntry");
358                 _delete_button_adjustment.set_value (Keyboard::delete_button());
359                 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
360
361
362                 set_popdown_strings (_insert_note_modifier_combo, dumb);
363                 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
364
365                 for (int x = 0; modifiers[x].name; ++x) {
366                         if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
367                                 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
368                                 break;
369                         }
370                 }
371
372                 l = manage (left_aligned_label (_("Insert note using:")));
373                 l->set_name ("OptionsLabel");
374
375                 t->attach (*l, 0, 1, 2, 3, FILL | EXPAND, FILL);
376                 t->attach (_insert_note_modifier_combo, 1, 2, 2, 3, FILL | EXPAND, FILL);
377
378                 l = manage (new Label (_("+ button")));
379                 l->set_name ("OptionsLabel");
380
381                 t->attach (*l, 3, 4, 2, 3, FILL | EXPAND, FILL);
382                 t->attach (_insert_note_button_spin, 4, 5, 2, 3, FILL | EXPAND, FILL);
383
384                 _insert_note_button_spin.set_name ("OptionsEntry");
385                 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
386                 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
387
388
389                 set_popdown_strings (_snap_modifier_combo, dumb);
390                 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
391
392                 for (int x = 0; modifiers[x].name; ++x) {
393                         if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
394                                 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
395                                 break;
396                         }
397                 }
398
399                 l = manage (left_aligned_label (_("Ignore snap using:")));
400                 l->set_name ("OptionsLabel");
401
402                 t->attach (*l, 0, 1, 3, 4, FILL | EXPAND, FILL);
403                 t->attach (_snap_modifier_combo, 1, 2, 3, 4, FILL | EXPAND, FILL);
404
405                 vector<string> strs;
406
407                 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
408                         strs.push_back (bf->first);
409                 }
410
411                 set_popdown_strings (_keyboard_layout_selector, strs);
412                 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
413                 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
414
415                 l = manage (left_aligned_label (_("Keyboard layout:")));
416                 l->set_name ("OptionsLabel");
417
418                 t->attach (*l, 0, 1, 4, 5, FILL | EXPAND, FILL);
419                 t->attach (_keyboard_layout_selector, 1, 2, 4, 5, FILL | EXPAND, FILL);
420
421                 _box->pack_start (*t, false, false);
422         }
423
424         void parameter_changed (string const &)
425         {
426                 /* XXX: these aren't really config options... */
427         }
428
429         void set_state_from_config ()
430         {
431                 /* XXX: these aren't really config options... */
432         }
433
434 private:
435
436         void bindings_changed ()
437         {
438                 string const txt = _keyboard_layout_selector.get_active_text();
439
440                 /* XXX: config...?  for all this keyboard stuff */
441
442                 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
443                         if (txt == i->first) {
444                                 if (Keyboard::load_keybindings (i->second)) {
445                                         Keyboard::save_keybindings ();
446                                 }
447                         }
448                 }
449         }
450
451         void edit_modifier_chosen ()
452         {
453                 string const txt = _edit_modifier_combo.get_active_text();
454
455                 for (int i = 0; modifiers[i].name; ++i) {
456                         if (txt == _(modifiers[i].name)) {
457                                 Keyboard::set_edit_modifier (modifiers[i].modifier);
458                                 break;
459                         }
460                 }
461         }
462
463         void delete_modifier_chosen ()
464         {
465                 string const txt = _delete_modifier_combo.get_active_text();
466
467                 for (int i = 0; modifiers[i].name; ++i) {
468                         if (txt == _(modifiers[i].name)) {
469                                 Keyboard::set_delete_modifier (modifiers[i].modifier);
470                                 break;
471                         }
472                 }
473         }
474
475         void insert_note_modifier_chosen ()
476         {
477                 string const txt = _insert_note_modifier_combo.get_active_text();
478
479                 for (int i = 0; modifiers[i].name; ++i) {
480                         if (txt == _(modifiers[i].name)) {
481                                 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
482                                 break;
483                         }
484                 }
485         }
486
487         void snap_modifier_chosen ()
488         {
489                 string const txt = _snap_modifier_combo.get_active_text();
490
491                 for (int i = 0; modifiers[i].name; ++i) {
492                         if (txt == _(modifiers[i].name)) {
493                                 Keyboard::set_snap_modifier (modifiers[i].modifier);
494                                 break;
495                         }
496                 }
497         }
498
499         void delete_button_changed ()
500         {
501                 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
502         }
503
504         void edit_button_changed ()
505         {
506                 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
507         }
508
509         void insert_note_button_changed ()
510         {
511                 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
512         }
513
514         ComboBoxText _keyboard_layout_selector;
515         ComboBoxText _edit_modifier_combo;
516         ComboBoxText _delete_modifier_combo;
517         ComboBoxText _insert_note_modifier_combo;
518         ComboBoxText _snap_modifier_combo;
519         Adjustment _delete_button_adjustment;
520         SpinButton _delete_button_spin;
521         Adjustment _edit_button_adjustment;
522         SpinButton _edit_button_spin;
523         Adjustment _insert_note_button_adjustment;
524         SpinButton _insert_note_button_spin;
525
526 };
527
528 class FontScalingOptions : public OptionEditorBox
529 {
530 public:
531         FontScalingOptions (RCConfiguration* c) :
532                 _rc_config (c),
533                 _dpi_adjustment (50, 50, 250, 1, 10),
534                 _dpi_slider (_dpi_adjustment)
535         {
536                 _dpi_adjustment.set_value (floor ((double)(_rc_config->get_font_scale () / 1024)));
537
538                 Label* l = manage (new Label (_("Font scaling:")));
539                 l->set_name ("OptionsLabel");
540
541                 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
542                 HBox* h = manage (new HBox);
543                 h->set_spacing (4);
544                 h->pack_start (*l, false, false);
545                 h->pack_start (_dpi_slider, true, true);
546
547                 _box->pack_start (*h, false, false);
548
549                 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
550         }
551
552         void parameter_changed (string const & p)
553         {
554                 if (p == "font-scale") {
555                         _dpi_adjustment.set_value (floor ((double)(_rc_config->get_font_scale() / 1024)));
556                 }
557         }
558
559         void set_state_from_config ()
560         {
561                 parameter_changed ("font-scale");
562         }
563
564 private:
565
566         void dpi_changed ()
567         {
568                 _rc_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024));
569                 /* XXX: should be triggered from the parameter changed signal */
570                 reset_dpi ();
571         }
572
573         RCConfiguration* _rc_config;
574         Adjustment _dpi_adjustment;
575         HScale _dpi_slider;
576 };
577
578 class ClipLevelOptions : public OptionEditorBox
579 {
580 public:
581         ClipLevelOptions (RCConfiguration* c) 
582                 : _rc_config (c)
583                 , _clip_level_adjustment (0, -128.0, 2.0, 0.1, 1.0) /* units of dB */
584                 , _clip_level_slider (_clip_level_adjustment)
585         {
586                 _clip_level_adjustment.set_value (_rc_config->get_waveform_clip_level ());
587
588                 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
589                 l->set_name ("OptionsLabel");
590
591                 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
592                 HBox* h = manage (new HBox);
593                 h->set_spacing (4);
594                 h->pack_start (*l, false, false);
595                 h->pack_start (_clip_level_slider, true, true);
596
597                 _box->pack_start (*h, false, false);
598
599                 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
600         }
601
602         void parameter_changed (string const & p)
603         {
604                 if (p == "waveform-clip-level") {
605                         _clip_level_adjustment.set_value (_rc_config->get_waveform_clip_level());
606                 }
607         }
608
609         void set_state_from_config ()
610         {
611                 parameter_changed ("waveform-clip-level");
612         }
613
614 private:
615
616         void clip_level_changed ()
617         {
618                 _rc_config->set_waveform_clip_level (_clip_level_adjustment.get_value());
619                 /* XXX: should be triggered from the parameter changed signal */
620                 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
621         }
622
623         RCConfiguration* _rc_config;
624         Adjustment _clip_level_adjustment;
625         HScale _clip_level_slider;
626 };
627
628 class BufferingOptions : public OptionEditorBox
629 {
630 public:
631         BufferingOptions (RCConfiguration* c)
632                 : _rc_config (c)
633                 , _playback_adjustment (5, 1, 60, 1, 4)
634                 , _capture_adjustment (5, 1, 60, 1, 4)
635                 , _playback_slider (_playback_adjustment)
636                 , _capture_slider (_capture_adjustment)
637         {
638                 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
639
640                 Label* l = manage (new Label (_("Playback (seconds of buffering):")));
641                 l->set_name ("OptionsLabel");
642
643                 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
644                 HBox* h = manage (new HBox);
645                 h->set_spacing (4);
646                 h->pack_start (*l, false, false);
647                 h->pack_start (_playback_slider, true, true);
648
649                 _box->pack_start (*h, false, false);
650
651                 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
652
653                 l = manage (new Label (_("Recording (seconds of buffering):")));
654                 l->set_name ("OptionsLabel");
655
656                 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
657                 h = manage (new HBox);
658                 h->set_spacing (4);
659                 h->pack_start (*l, false, false);
660                 h->pack_start (_capture_slider, true, true);
661
662                 _box->pack_start (*h, false, false);
663
664                 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
665                 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
666         }
667
668         void parameter_changed (string const & p)
669         {
670                 if (p == "playback-buffer-seconds") {
671                         _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
672                 } else if (p == "capture-buffer-seconds") {
673                         _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
674                 }
675         }
676
677         void set_state_from_config ()
678         {
679                 parameter_changed ("playback-buffer-seconds");
680                 parameter_changed ("capture-buffer-seconds");
681         }
682
683 private:
684
685         void playback_changed ()
686         {
687                 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
688         }
689
690         void capture_changed ()
691         {
692                 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
693         }
694
695         RCConfiguration* _rc_config;
696         Adjustment _playback_adjustment;
697         Adjustment _capture_adjustment;
698         HScale _playback_slider;
699         HScale _capture_slider;
700 };
701
702 class ControlSurfacesOptions : public OptionEditorBox
703 {
704 public:
705         ControlSurfacesOptions (Gtk::Window& parent)
706                 : _parent (parent)
707                 , _ignore_view_change (0)
708         {
709                 _store = ListStore::create (_model);
710                 _view.set_model (_store);
711                 _view.append_column (_("Control Surface Protocol"), _model.name);
712                 _view.get_column(0)->set_resizable (true);
713                 _view.get_column(0)->set_expand (true);
714                 _view.append_column_editable (_("Enabled"), _model.enabled);
715                 _view.append_column_editable (_("Feedback"), _model.feedback);
716
717                 _box->pack_start (_view, false, false);
718
719                 Label* label = manage (new Label);
720                 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
721
722                 _box->pack_start (*label, false, false);
723                 label->show ();
724
725                 ControlProtocolManager& m = ControlProtocolManager::instance ();
726                 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
727                                                 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
728
729                 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
730                 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
731         }
732
733         void parameter_changed (std::string const &)
734         {
735
736         }
737
738         void set_state_from_config ()
739         {
740                 _store->clear ();
741
742                 ControlProtocolManager& m = ControlProtocolManager::instance ();
743                 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
744
745                         if (!(*i)->mandatory) {
746                                 TreeModel::Row r = *_store->append ();
747                                 r[_model.name] = (*i)->name;
748                                 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
749                                 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
750                                 r[_model.protocol_info] = *i;
751                         }
752                 }
753         }
754
755 private:
756
757         void protocol_status_changed (ControlProtocolInfo* cpi) {
758                 /* find the row */
759                 TreeModel::Children rows = _store->children();
760                 
761                 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
762                         string n = ((*x)[_model.name]);
763
764                         if ((*x)[_model.protocol_info] == cpi) {
765                                 _ignore_view_change++;
766                                 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
767                                 _ignore_view_change--;
768                                 break;
769                         }
770                 }
771         }
772
773         void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
774         {
775                 TreeModel::Row r = *i;
776
777                 if (_ignore_view_change) {
778                         return;
779                 }
780
781                 ControlProtocolInfo* cpi = r[_model.protocol_info];
782                 if (!cpi) {
783                         return;
784                 }
785
786                 bool const was_enabled = (cpi->protocol != 0);
787                 bool const is_enabled = r[_model.enabled];
788
789
790                 if (was_enabled != is_enabled) {
791
792                         if (!was_enabled) {
793                                 ControlProtocolManager::instance().activate (*cpi);
794                         } else {
795                                 Gtk::Window* win = r[_model.editor];
796                                 if (win) {
797                                         win->hide ();
798                                 }
799
800                                 ControlProtocolManager::instance().deactivate (*cpi);
801                                         
802                                 if (win) {
803                                         delete win;
804                                         r[_model.editor] = 0;
805                                 }
806                         }
807                 }
808
809                 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
810                 bool const is_feedback = r[_model.feedback];
811
812                 if (was_feedback != is_feedback && cpi->protocol) {
813                         cpi->protocol->set_feedback (is_feedback);
814                 }
815         }
816
817         void edit_clicked (GdkEventButton* ev)
818         {
819                 if (ev->type != GDK_2BUTTON_PRESS) {
820                         return;
821                 }
822
823                 std::string name;
824                 ControlProtocolInfo* cpi;
825                 TreeModel::Row row;
826
827                 row = *(_view.get_selection()->get_selected());
828
829                 Window* win = row[_model.editor];
830                 if (win && !win->is_visible()) {
831                         win->present ();
832                 } else {
833                         cpi = row[_model.protocol_info];
834
835                         if (cpi && cpi->protocol && cpi->protocol->has_editor ()) {
836                                 Box* box = (Box*) cpi->protocol->get_gui ();
837                                 if (box) {
838                                         string title = row[_model.name];
839                                         ArdourWindow* win = new ArdourWindow (_parent, title);
840                                         win->set_title ("Control Protocol Options");
841                                         win->add (*box);
842                                         box->show ();
843                                         win->present ();
844                                         row[_model.editor] = win;
845                                 }
846                         }
847                 }
848         }
849
850         class ControlSurfacesModelColumns : public TreeModelColumnRecord
851         {
852         public:
853
854                 ControlSurfacesModelColumns ()
855                 {
856                         add (name);
857                         add (enabled);
858                         add (feedback);
859                         add (protocol_info);
860                         add (editor);
861                 }
862
863                 TreeModelColumn<string> name;
864                 TreeModelColumn<bool> enabled;
865                 TreeModelColumn<bool> feedback;
866                 TreeModelColumn<ControlProtocolInfo*> protocol_info;
867                 TreeModelColumn<Gtk::Window*> editor;
868         };
869
870         Glib::RefPtr<ListStore> _store;
871         ControlSurfacesModelColumns _model;
872         TreeView _view;
873         Gtk::Window& _parent;
874         PBD::ScopedConnection protocol_status_connection;
875         uint32_t _ignore_view_change;
876 };
877
878 class VideoTimelineOptions : public OptionEditorBox
879 {
880 public:
881         VideoTimelineOptions (RCConfiguration* c)
882                 : _rc_config (c)
883                 , _show_video_export_info_button (_("Show Video Export Info before export"))
884                 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
885                 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
886         {
887                 Table* t = manage (new Table (2, 6));
888                 t->set_spacings (4);
889
890                 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
891                 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
892                 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
893                                             _("<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."));
894
895                 Label* l = manage (new Label (_("Video Server URL:")));
896                 l->set_alignment (0, 0.5);
897                 t->attach (*l, 0, 1, 1, 2, FILL);
898                 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
899                 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
900                                             _("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"));
901
902                 l = manage (new Label (_("Video Folder:")));
903                 l->set_alignment (0, 0.5);
904                 t->attach (*l, 0, 1, 2, 3, FILL);
905                 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
906                 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
907                                             _("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."));
908
909                 /* small vspace  y=3..4 */
910
911                 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
912                 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
913                 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
914                                             _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
915
916                 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
917                 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
918                 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
919                                             _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
920
921                 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
922                 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
923                 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
924                 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
925
926                 _box->pack_start (*t,true,true);
927         }
928
929         void server_url_changed ()
930         {
931                 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
932         }
933
934         void server_docroot_changed ()
935         {
936                 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
937         }
938
939         void show_video_export_info_toggled ()
940         {
941                 bool const x = _show_video_export_info_button.get_active ();
942                 _rc_config->set_show_video_export_info (x);
943         }
944
945         void show_video_server_dialog_toggled ()
946         {
947                 bool const x = _show_video_server_dialog_button.get_active ();
948                 _rc_config->set_show_video_server_dialog (x);
949         }
950
951         void video_advanced_setup_toggled ()
952         {
953                 bool const x = _video_advanced_setup_button.get_active ();
954                 _rc_config->set_video_advanced_setup(x);
955         }
956
957         void parameter_changed (string const & p)
958         {
959                 if (p == "video-server-url") {
960                         _video_server_url_entry.set_text (_rc_config->get_video_server_url());
961                 } else if (p == "video-server-docroot") {
962                         _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
963                 } else if (p == "show-video-export-info") {
964                         bool const x = _rc_config->get_show_video_export_info();
965                         _show_video_export_info_button.set_active (x);
966                 } else if (p == "show-video-server-dialog") {
967                         bool const x = _rc_config->get_show_video_server_dialog();
968                         _show_video_server_dialog_button.set_active (x);
969                 } else if (p == "video-advanced-setup") {
970                         bool const x = _rc_config->get_video_advanced_setup();
971                         _video_advanced_setup_button.set_active(x);
972                         _video_server_docroot_entry.set_sensitive(x);
973                         _video_server_url_entry.set_sensitive(x);
974                 }
975         }
976
977         void set_state_from_config ()
978         {
979                 parameter_changed ("video-server-url");
980                 parameter_changed ("video-server-docroot");
981                 parameter_changed ("video-monitor-setup-dialog");
982                 parameter_changed ("show-video-export-info");
983                 parameter_changed ("show-video-server-dialog");
984                 parameter_changed ("video-advanced-setup");
985         }
986
987 private:
988         RCConfiguration* _rc_config;
989         Entry _video_server_url_entry;
990         Entry _video_server_docroot_entry;
991         CheckButton _show_video_export_info_button;
992         CheckButton _show_video_server_dialog_button;
993         CheckButton _video_advanced_setup_button;
994 };
995
996 class PluginOptions : public OptionEditorBox
997 {
998 public:
999         PluginOptions (RCConfiguration* c)
1000                 : _rc_config (c)
1001                 , _display_plugin_scan_progress (_("Display Plugin Scan Progress"))
1002                 , _discover_vst_on_start (_("Scan for new VST Plugin on Application Start"))
1003         {
1004                 Table* t = manage (new Table (2, 6));
1005                 t->set_spacings (4);
1006                 Button* b;
1007
1008                 b = manage (new Button (_("Refresh Plugin List")));
1009                 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1010                 t->attach (*b, 0, 2, 0, 1, FILL);
1011
1012                 b = manage (new Button (_("Clear VST Cache")));
1013                 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1014                 t->attach (*b, 0, 2, 1, 2, FILL);
1015
1016                 b = manage (new Button (_("Clear VST Blacklist")));
1017                 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1018                 t->attach (*b, 0, 2, 2, 3, FILL);
1019
1020                 t->attach (_discover_vst_on_start, 0, 2, 3, 4);
1021                 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1022                 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1023                                             _("<b>When enabled</b> VST plugins are searched and tested on application start. When disabled they a Refresh will have to be tiggered manually"));
1024
1025                 t->attach (_display_plugin_scan_progress, 0, 2, 4, 5);
1026                 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1027                 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1028                                             _("<b>When enabled</b> display a popup window showing plugin scan progress."));
1029
1030
1031                 _box->pack_start (*t,true,true);
1032         }
1033
1034         void parameter_changed (string const & p) {
1035                 if (p == "show-plugin-scan-window") {
1036                         bool const x = _rc_config->get_show_plugin_scan_window();
1037                         _display_plugin_scan_progress.set_active (x);
1038                 }
1039                 else if (p == "discover-vst-on-start") {
1040                         bool const x = _rc_config->get_discover_vst_on_start();
1041                         _discover_vst_on_start.set_active (x);
1042                 }
1043         }
1044
1045         void set_state_from_config () {
1046                 parameter_changed ("show-plugin-scan-window");
1047                 parameter_changed ("discover-vst-on-start");
1048         }
1049
1050 private:
1051         RCConfiguration* _rc_config;
1052         CheckButton _display_plugin_scan_progress;
1053         CheckButton _discover_vst_on_start;
1054
1055         void display_plugin_scan_progress_toggled () {
1056                 bool const x = _display_plugin_scan_progress.get_active();
1057                 _rc_config->set_show_plugin_scan_window(x);
1058         }
1059
1060         void discover_vst_on_start_toggled () {
1061                 bool const x = _discover_vst_on_start.get_active();
1062                 _rc_config->set_discover_vst_on_start(x);
1063         }
1064
1065         void clear_vst_cache_clicked () {
1066                 PluginManager::instance().clear_vst_cache();
1067         }
1068
1069         void clear_vst_blacklist_clicked () {
1070                 PluginManager::instance().clear_vst_blacklist();
1071         }
1072
1073         void refresh_clicked () {
1074                 PluginManager::instance().refresh();
1075         }
1076 };
1077
1078
1079 /** A class which allows control of visibility of some editor components usign
1080  *  a VisibilityGroup.  The caller should pass in a `dummy' VisibilityGroup
1081  *  which has the correct members, but with null widget pointers.  This
1082  *  class allows the user to set visibility of the members, the details
1083  *  of which are stored in a configuration variable which can be watched
1084  *  by parts of the editor that actually contain the widgets whose visibility
1085  *  is being controlled.
1086  */
1087
1088 class VisibilityOption : public Option
1089 {
1090 public:
1091         /** @param name User-visible name for this group.
1092          *  @param g `Dummy' VisibilityGroup (as described above).
1093          *  @param get Method to get the value of the appropriate configuration variable.
1094          *  @param set Method to set the value of the appropriate configuration variable.
1095          */
1096         VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1097                 : Option (g->get_state_name(), name)
1098                 , _heading (name)
1099                 , _visibility_group (g)
1100                 , _get (get)
1101                 , _set (set)
1102         {
1103                 /* Watch for changes made by the user to our members */
1104                 _visibility_group->VisibilityChanged.connect_same_thread (
1105                         _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1106                         );
1107         }
1108
1109         void set_state_from_config ()
1110         {
1111                 /* Set our state from the current configuration */
1112                 _visibility_group->set_state (_get ());
1113         }
1114
1115         void add_to_page (OptionEditorPage* p)
1116         {
1117                 _heading.add_to_page (p);
1118                 add_widget_to_page (p, _visibility_group->list_view ());
1119         }
1120
1121         Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1122
1123 private:
1124         void changed ()
1125         {
1126                 /* The user has changed something, so reflect this change
1127                    in the RCConfiguration.
1128                 */
1129                 _set (_visibility_group->get_state_value ());
1130         }
1131         
1132         OptionEditorHeading _heading;
1133         VisibilityGroup* _visibility_group;
1134         sigc::slot<std::string> _get;
1135         sigc::slot<bool, std::string> _set;
1136         PBD::ScopedConnection _visibility_group_connection;
1137 };
1138
1139
1140
1141 RCOptionEditor::RCOptionEditor ()
1142         : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1143         , _rc_config (Config)
1144         , _mixer_strip_visibility ("mixer-strip-visibility")
1145 {
1146         /* MISC */
1147
1148         uint32_t hwcpus = hardware_concurrency ();
1149         BoolOption* bo;
1150         BoolComboOption* bco;
1151
1152         if (hwcpus > 1) {
1153                 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1154
1155                 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1156                         "processor-usage",
1157                         _("Signal processing uses"),
1158                         sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1159                         sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1160                         );
1161
1162                 procs->add (-1, _("all but one processor"));
1163                 procs->add (0, _("all available processors"));
1164
1165                 for (uint32_t i = 1; i <= hwcpus; ++i) {
1166                         procs->add (i, string_compose (_("%1 processors"), i));
1167                 }
1168
1169                 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1170
1171                 add_option (_("Misc"), procs);
1172         }
1173
1174         add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1175
1176         add_option (_("Misc"), new UndoOptions (_rc_config));
1177
1178         add_option (_("Misc"),
1179              new BoolOption (
1180                      "verify-remove-last-capture",
1181                      _("Verify removal of last capture"),
1182                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1183                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1184                      ));
1185
1186         add_option (_("Misc"),
1187              new BoolOption (
1188                      "periodic-safety-backups",
1189                      _("Make periodic backups of the session file"),
1190                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1191                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1192                      ));
1193
1194         add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1195
1196         add_option (_("Misc"),
1197              new BoolOption (
1198                      "only-copy-imported-files",
1199                      _("Always copy imported files"),
1200                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_only_copy_imported_files),
1201                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_only_copy_imported_files)
1202                      ));
1203
1204         add_option (_("Misc"), new DirectoryOption (
1205                             X_("default-session-parent-dir"),
1206                             _("Default folder for new sessions:"),
1207                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1208                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1209                             ));
1210
1211         add_option (_("Misc"),
1212              new SpinOption<uint32_t> (
1213                      "max-recent-sessions",
1214                      _("Maximum number of recent sessions"),
1215                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1216                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1217                      0, 1000, 1, 20
1218                      ));
1219
1220         add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1221
1222         add_option (_("Misc"), new ClickOptions (_rc_config, this));
1223
1224         add_option (_("Misc"),
1225              new FaderOption (
1226                      "click-gain",
1227                      _("Click gain level"),
1228                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1229                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1230                      ));
1231
1232         add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1233
1234         add_option (_("Misc"),
1235              new SpinOption<double> (
1236                      "automation-thinning-factor",
1237                      _("Thinning factor (larger value => less data)"),
1238                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1239                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1240                      0, 1000, 1, 20
1241                      ));
1242
1243         add_option (_("Misc"),
1244              new SpinOption<double> (
1245                      "automation-interval-msecs",
1246                      _("Automation sampling interval (milliseconds)"),
1247                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1248                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1249                      1, 1000, 1, 20
1250                      ));
1251
1252         /* TRANSPORT */
1253
1254         BoolOption* tsf;
1255
1256         tsf = new BoolOption (
1257                      "latched-record-enable",
1258                      _("Keep record-enable engaged on stop"),
1259                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1260                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1261                      );
1262         // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1263         add_option (_("Transport"), tsf);
1264
1265         tsf = new BoolOption (
1266                      "stop-recording-on-xrun",
1267                      _("Stop recording when an xrun occurs"),
1268                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1269                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1270                      );
1271         Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), 
1272                                             string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
1273                                                             PROGRAM_NAME));
1274         add_option (_("Transport"), tsf);
1275
1276         tsf = new BoolOption (
1277                      "create-xrun-marker",
1278                      _("Create markers where xruns occur"),
1279                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1280                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1281                      );
1282         // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1283         add_option (_("Transport"), tsf);
1284
1285         tsf = new BoolOption (
1286                      "stop-at-session-end",
1287                      _("Stop at the end of the session"),
1288                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1289                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1290                      );
1291         Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), 
1292                                             string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
1293                                                               "when it reaches the current session end marker\n\n"
1294                                                               "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
1295                                                             PROGRAM_NAME));
1296         add_option (_("Transport"), tsf);
1297
1298         tsf = new BoolOption (
1299                      "seamless-loop",
1300                      _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
1301                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1302                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1303                      );
1304         Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), 
1305                                             string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1306                                                               "preventing any need to do a transport locate at the end of the loop\n\n"
1307                                                               "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
1308                                                               "which will often cause a small click or delay"), PROGRAM_NAME));
1309         add_option (_("Transport"), tsf);
1310
1311         tsf = new BoolOption (
1312                      "disable-disarm-during-roll",
1313                      _("Disable per-track record disarm while rolling"),
1314                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
1315                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
1316                      );
1317         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"));
1318         add_option (_("Transport"), tsf);
1319
1320         tsf = new BoolOption (
1321                      "quieten_at_speed",
1322                      _("12dB gain reduction during fast-forward and fast-rewind"),
1323                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
1324                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
1325                      );
1326         Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
1327                                                    "that occurs when fast-forwarding or rewinding through some kinds of audio"));
1328         add_option (_("Transport"), tsf);
1329
1330         add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
1331
1332         _sync_source = new ComboOption<SyncSource> (
1333                 "sync-source",
1334                 _("External timecode source"),
1335                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
1336                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
1337                 );
1338
1339         populate_sync_options ();
1340         add_option (_("Transport"), _sync_source);
1341
1342         _sync_framerate = new BoolOption (
1343                      "timecode-sync-frame-rate",
1344                      _("Match session video frame rate to external timecode"),
1345                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
1346                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
1347                      );
1348         Gtkmm2ext::UI::instance()->set_tip 
1349                 (_sync_framerate->tip_widget(),
1350                  string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
1351                                    "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
1352                                    "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
1353                                    "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
1354                                    "timecode standard and the session standard."), PROGRAM_NAME));
1355
1356         add_option (_("Transport"), _sync_framerate);
1357
1358         _sync_genlock = new BoolOption (
1359                 "timecode-source-is-synced",
1360                 _("External timecode is sync locked"),
1361                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
1362                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
1363                 );
1364         Gtkmm2ext::UI::instance()->set_tip 
1365                 (_sync_genlock->tip_widget(), 
1366                  _("<b>When enabled</b> indicates that the selected external timecode source shares sync (Black &amp; Burst, Wordclock, etc) with the audio interface."));
1367
1368
1369         add_option (_("Transport"), _sync_genlock);
1370
1371         _sync_source_2997 = new BoolOption (
1372                 "timecode-source-2997",
1373                 _("Lock to 29.9700 fps instead of 30000/1001"),
1374                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
1375                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
1376                 );
1377         Gtkmm2ext::UI::instance()->set_tip
1378                 (_sync_source_2997->tip_widget(),
1379                  _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
1380                          "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
1381                          "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
1382                          "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
1383                          "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
1384                          "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
1385                          ));
1386
1387         add_option (_("Transport"), _sync_source_2997);
1388
1389         add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
1390
1391         _ltc_port = new ComboStringOption (
1392                 "ltc-source-port",
1393                 _("LTC incoming port"),
1394                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
1395                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
1396                 );
1397
1398         vector<string> physical_inputs;
1399         physical_inputs.push_back (_("None"));
1400         AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
1401         _ltc_port->set_popdown_strings (physical_inputs);
1402
1403         add_option (_("Transport"), _ltc_port);
1404
1405         // TODO; rather disable this button than not compile it..
1406         add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
1407
1408         add_option (_("Transport"),
1409                     new BoolOption (
1410                             "send-ltc",
1411                             _("Enable LTC generator"),
1412                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
1413                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
1414                             ));
1415
1416         _ltc_send_continuously = new BoolOption (
1417                             "ltc-send-continuously",
1418                             _("send LTC while stopped"),
1419                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
1420                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
1421                             );
1422         Gtkmm2ext::UI::instance()->set_tip
1423                 (_ltc_send_continuously->tip_widget(),
1424                  string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
1425         add_option (_("Transport"), _ltc_send_continuously);
1426
1427         _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
1428         _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
1429         _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
1430         _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
1431
1432         Gtkmm2ext::UI::instance()->set_tip
1433                 (_ltc_volume_slider->tip_widget(),
1434                  _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is  0dBu ^= -18dbFS in an EBU calibrated system"));
1435
1436         add_option (_("Transport"), _ltc_volume_slider);
1437         parameter_changed ("send-ltc");
1438
1439         parameter_changed ("sync-source");
1440
1441         /* EDITOR */
1442
1443         add_option (_("Editor"),
1444              new BoolOption (
1445                      "link-region-and-track-selection",
1446                      _("Link selection of regions and tracks"),
1447                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_region_and_track_selection),
1448                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_region_and_track_selection)
1449                      ));
1450
1451         add_option (_("Editor"),
1452              new BoolOption (
1453                      "automation-follows-regions",
1454                      _("Move relevant automation when audio regions are moved"),
1455                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
1456                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
1457                      ));
1458
1459         add_option (_("Editor"),
1460              new BoolOption (
1461                      "show-track-meters",
1462                      _("Show meters on tracks in the editor"),
1463                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_track_meters),
1464                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_track_meters)
1465                      ));
1466
1467         add_option (_("Editor"),
1468              new BoolOption (
1469                      "show-editor-meter",
1470                      _("Display master-meter in the toolbar"),
1471                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_editor_meter),
1472                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_editor_meter)
1473                      ));
1474
1475         bco = new BoolComboOption (
1476                      "use-overlap-equivalency",
1477                      _("Regions in active edit groups are edited together"),
1478                      _("whenever they overlap in time"),
1479                      _("only if they have identical length, position and origin"),
1480                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
1481                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
1482                      );
1483
1484         add_option (_("Editor"), bco);
1485
1486         add_option (_("Editor"),
1487              new BoolOption (
1488                      "rubberbanding-snaps-to-grid",
1489                      _("Make rubberband selection rectangle snap to the grid"),
1490                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_rubberbanding_snaps_to_grid),
1491                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_rubberbanding_snaps_to_grid)
1492                      ));
1493
1494         add_option (_("Editor"),
1495              new BoolOption (
1496                      "show-waveforms",
1497                      _("Show waveforms in regions"),
1498                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms),
1499                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms)
1500                      ));
1501
1502         add_option (_("Editor"),
1503              new BoolComboOption (
1504                      "show-region-gain-envelopes",
1505                      _("Show gain envelopes in audio regions"),
1506                      _("in all modes"),
1507                      _("only in region gain mode"),
1508                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_region_gain),
1509                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_region_gain)
1510                      ));
1511
1512         ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
1513                 "waveform-scale",
1514                 _("Waveform scale"),
1515                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_scale),
1516                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_scale)
1517                 );
1518
1519         wfs->add (Linear, _("linear"));
1520         wfs->add (Logarithmic, _("logarithmic"));
1521
1522         add_option (_("Editor"), wfs);
1523
1524         ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
1525                 "waveform-shape",
1526                 _("Waveform shape"),
1527                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_shape),
1528                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_shape)
1529                 );
1530
1531         wfsh->add (Traditional, _("traditional"));
1532         wfsh->add (Rectified, _("rectified"));
1533
1534         add_option (_("Editor"), wfsh);
1535
1536         add_option (_("Editor"), new ClipLevelOptions (_rc_config));
1537
1538         add_option (_("Editor"),
1539              new BoolOption (
1540                      "show-waveforms-while-recording",
1541                      _("Show waveforms for audio while it is being recorded"),
1542                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms_while_recording),
1543                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms_while_recording)
1544                      ));
1545
1546         add_option (_("Editor"),
1547                     new BoolOption (
1548                             "show-zoom-tools",
1549                             _("Show zoom toolbar"),
1550                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_zoom_tools),
1551                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_zoom_tools)
1552                             ));
1553
1554         add_option (_("Editor"),
1555                     new BoolOption (
1556                             "update-editor-during-summary-drag",
1557                             _("Update editor window during drags of the summary"),
1558                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_update_editor_during_summary_drag),
1559                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_update_editor_during_summary_drag)
1560                             ));
1561
1562         add_option (_("Editor"),
1563              new BoolOption (
1564                      "link-editor-and-mixer-selection",
1565                      _("Synchronise editor and mixer selection"),
1566                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_editor_and_mixer_selection),
1567                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_editor_and_mixer_selection)
1568                      ));
1569
1570         bo = new BoolOption (
1571                      "name-new-markers",
1572                      _("Name new markers"),
1573                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_name_new_markers),
1574                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_name_new_markers)
1575                 );
1576         
1577         add_option (_("Editor"), bo);
1578         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."
1579                                                                 "\n\nYou can always rename markers by right-clicking on them"));
1580
1581         add_option (_("Editor"),
1582             new BoolOption (
1583                     "autoscroll-editor",
1584                     _("Auto-scroll editor window when dragging near its edges"),
1585                     sigc::mem_fun (*_rc_config, &RCConfiguration::get_autoscroll_editor),
1586                     sigc::mem_fun (*_rc_config, &RCConfiguration::set_autoscroll_editor)
1587                     ));
1588
1589         /* AUDIO */
1590
1591         add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
1592
1593         add_option (_("Audio"), new BufferingOptions (_rc_config));
1594
1595         add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
1596
1597         ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
1598                 "monitoring-model",
1599                 _("Record monitoring handled by"),
1600                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
1601                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
1602                 );
1603
1604         if (AudioEngine::instance()->port_engine().can_monitor_input()) {
1605                 mm->add (HardwareMonitoring, _("via Audio Driver"));
1606         }
1607
1608         string prog (PROGRAM_NAME);
1609         boost::algorithm::to_lower (prog);
1610         mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
1611         mm->add (ExternalMonitoring, _("audio hardware"));
1612
1613         add_option (_("Audio"), mm);
1614
1615         add_option (_("Audio"),
1616              new BoolOption (
1617                      "tape-machine-mode",
1618                      _("Tape machine mode"),
1619                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
1620                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
1621                      ));
1622
1623         add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
1624
1625         add_option (_("Audio"),
1626                     new BoolOption (
1627                             "auto-connect-standard-busses",
1628                             _("Auto-connect master/monitor busses"),
1629                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
1630                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
1631                             ));
1632
1633         ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
1634                 "input-auto-connect",
1635                 _("Connect track inputs"),
1636                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
1637                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
1638                 );
1639
1640         iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
1641         iac->add (ManualConnect, _("manually"));
1642
1643         add_option (_("Audio"), iac);
1644
1645         ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
1646                 "output-auto-connect",
1647                 _("Connect track and bus outputs"),
1648                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
1649                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
1650                 );
1651
1652         oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
1653         oac->add (AutoConnectMaster, _("automatically to master bus"));
1654         oac->add (ManualConnect, _("manually"));
1655
1656         add_option (_("Audio"), oac);
1657
1658         add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
1659
1660         add_option (_("Audio"),
1661              new BoolOption (
1662                      "denormal-protection",
1663                      _("Use DC bias to protect against denormals"),
1664                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
1665                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
1666                      ));
1667
1668         ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
1669                 "denormal-model",
1670                 _("Processor handling"),
1671                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
1672                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
1673                 );
1674
1675         dm->add (DenormalNone, _("no processor handling"));
1676
1677         FPU fpu;
1678
1679         if (fpu.has_flush_to_zero()) {
1680                 dm->add (DenormalFTZ, _("use FlushToZero"));
1681         }
1682
1683         if (fpu.has_denormals_are_zero()) {
1684                 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
1685         }
1686
1687         if (fpu.has_flush_to_zero() && fpu.has_denormals_are_zero()) {
1688                 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
1689         }
1690
1691         add_option (_("Audio"), dm);
1692
1693         add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
1694
1695         add_option (_("Audio"),
1696              new BoolOption (
1697                      "plugins-stop-with-transport",
1698                      _("Silence plugins when the transport is stopped"),
1699                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
1700                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
1701                      ));
1702
1703         add_option (_("Audio"),
1704              new BoolOption (
1705                      "new-plugins-active",
1706                      _("Make new plugins active"),
1707                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
1708                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
1709                      ));
1710
1711         add_option (_("Audio"),
1712              new BoolOption (
1713                      "auto-analyse-audio",
1714                      _("Enable automatic analysis of audio"),
1715                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
1716                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
1717                      ));
1718
1719         add_option (_("Audio"),
1720              new BoolOption (
1721                      "replicate-missing-region-channels",
1722                      _("Replicate missing region channels"),
1723                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
1724                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
1725                      ));
1726
1727         /* SOLO AND MUTE */
1728
1729         add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
1730
1731         add_option (_("Solo / mute"),
1732              new FaderOption (
1733                      "solo-mute-gain",
1734                      _("Solo-in-place mute cut (dB)"),
1735                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
1736                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
1737                      ));
1738
1739         _solo_control_is_listen_control = new BoolOption (
1740                 "solo-control-is-listen-control",
1741                 _("Solo controls are Listen controls"),
1742                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
1743                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
1744                 );
1745
1746         add_option (_("Solo / mute"), _solo_control_is_listen_control);
1747
1748         _listen_position = new ComboOption<ListenPosition> (
1749                 "listen-position",
1750                 _("Listen Position"),
1751                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
1752                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
1753                 );
1754
1755         _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
1756         _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
1757
1758         add_option (_("Solo / mute"), _listen_position);
1759
1760         ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
1761                 "pfl-position",
1762                 _("PFL signals come from"),
1763                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
1764                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
1765                 );
1766
1767         pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
1768         pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
1769
1770         add_option (_("Solo / mute"), pp);
1771
1772         ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
1773                 "afl-position",
1774                 _("AFL signals come from"),
1775                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
1776                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
1777                 );
1778
1779         pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
1780         pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
1781
1782         add_option (_("Solo / mute"), pa);
1783
1784         parameter_changed ("use-monitor-bus");
1785
1786         add_option (_("Solo / mute"),
1787              new BoolOption (
1788                      "exclusive-solo",
1789                      _("Exclusive solo"),
1790                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
1791                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
1792                      ));
1793
1794         add_option (_("Solo / mute"),
1795              new BoolOption (
1796                      "show-solo-mutes",
1797                      _("Show solo muting"),
1798                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
1799                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
1800                      ));
1801
1802         add_option (_("Solo / mute"),
1803              new BoolOption (
1804                      "solo-mute-override",
1805                      _("Soloing overrides muting"),
1806                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
1807                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
1808                      ));
1809
1810         add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
1811
1812         add_option (_("Solo / mute"),
1813              new BoolOption (
1814                      "mute-affects-pre-fader",
1815                      _("Mute affects pre-fader sends"),
1816                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
1817                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
1818                      ));
1819
1820         add_option (_("Solo / mute"),
1821              new BoolOption (
1822                      "mute-affects-post-fader",
1823                      _("Mute affects post-fader sends"),
1824                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
1825                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
1826                      ));
1827
1828         add_option (_("Solo / mute"),
1829              new BoolOption (
1830                      "mute-affects-control-outs",
1831                      _("Mute affects control outputs"),
1832                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
1833                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
1834                      ));
1835
1836         add_option (_("Solo / mute"),
1837              new BoolOption (
1838                      "mute-affects-main-outs",
1839                      _("Mute affects main outputs"),
1840                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
1841                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
1842                      ));
1843
1844         add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
1845
1846         add_option (_("Solo / mute"),
1847              new BoolOption (
1848                      "link-send-and-route-panner",
1849                      _("Link panners of Aux and External Sends with main panner by default"),
1850                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
1851                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
1852                      ));
1853
1854         add_option (_("MIDI"),
1855                     new BoolOption (
1856                             "send-midi-clock",
1857                             _("Send MIDI Clock"),
1858                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
1859                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
1860                             ));
1861
1862         add_option (_("MIDI"),
1863                     new BoolOption (
1864                             "send-mtc",
1865                             _("Send MIDI Time Code"),
1866                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
1867                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
1868                             ));
1869
1870         add_option (_("MIDI"),
1871                     new SpinOption<int> (
1872                             "mtc-qf-speed-tolerance",
1873                             _("Percentage either side of normal transport speed to transmit MTC"),
1874                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
1875                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
1876                             0, 20, 1, 5
1877                             ));
1878
1879         add_option (_("MIDI"),
1880                     new BoolOption (
1881                             "mmc-control",
1882                             _("Obey MIDI Machine Control commands"),
1883                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
1884                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
1885                             ));
1886
1887         add_option (_("MIDI"),
1888                     new BoolOption (
1889                             "send-mmc",
1890                             _("Send MIDI Machine Control commands"),
1891                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
1892                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
1893                             ));
1894
1895         add_option (_("MIDI"),
1896                     new BoolOption (
1897                             "midi-feedback",
1898                             _("Send MIDI control feedback"),
1899                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
1900                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
1901                             ));
1902
1903         add_option (_("MIDI"),
1904              new SpinOption<uint8_t> (
1905                      "mmc-receive-device-id",
1906                      _("Inbound MMC device ID"),
1907                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
1908                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
1909                      0, 128, 1, 10
1910                      ));
1911
1912         add_option (_("MIDI"),
1913              new SpinOption<uint8_t> (
1914                      "mmc-send-device-id",
1915                      _("Outbound MMC device ID"),
1916                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
1917                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
1918                      0, 128, 1, 10
1919                      ));
1920
1921         add_option (_("MIDI"),
1922              new SpinOption<int32_t> (
1923                      "initial-program-change",
1924                      _("Initial program change"),
1925                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
1926                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
1927                      -1, 65536, 1, 10
1928                      ));
1929
1930         add_option (_("MIDI"),
1931                     new BoolOption (
1932                             "diplay-first-midi-bank-as-zero",
1933                             _("Display first MIDI bank/program as 0"),
1934                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
1935                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
1936                             ));
1937
1938         add_option (_("MIDI"),
1939              new BoolOption (
1940                      "never-display-periodic-midi",
1941                      _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
1942                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_never_display_periodic_midi),
1943                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_never_display_periodic_midi)
1944                      ));
1945
1946         add_option (_("MIDI"),
1947              new BoolOption (
1948                      "sound-midi-notes",
1949                      _("Sound MIDI notes as they are selected"),
1950                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_sound_midi_notes),
1951                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_sound_midi_notes)
1952                      ));
1953
1954         add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
1955
1956         ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
1957                 "midi-audition-synth-uri",
1958                 _("Midi Audition Synth (LV2)"),
1959                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
1960                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
1961                 );
1962
1963         audition_synth->add(X_(""), _("None"));
1964         PluginInfoList all_plugs;
1965         PluginManager& manager (PluginManager::instance());
1966 #ifdef LV2_SUPPORT
1967         all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
1968
1969         for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
1970                 if (manager.get_status (*i) == PluginManager::Hidden) continue;
1971                 if (!(*i)->is_instrument()) continue;
1972                 if ((*i)->type != ARDOUR::LV2) continue;
1973                 audition_synth->add((*i)->unique_id, (*i)->name);
1974         }
1975 #endif
1976
1977         add_option (_("MIDI"), audition_synth);
1978
1979         /* USER INTERACTION */
1980
1981         if (getenv ("ARDOUR_BUNDLED")) {
1982                 add_option (_("User interaction"), 
1983                             new BoolOption (
1984                                     "enable-translation",
1985                                     string_compose (_("Use translations of %1 messages\n"
1986                                                       "   <i>(requires a restart of %1 to take effect)</i>\n"
1987                                                       "   <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
1988                                     sigc::ptr_fun (ARDOUR::translations_are_enabled),
1989                                     sigc::ptr_fun (ARDOUR::set_translations_enabled)));
1990         }
1991
1992         add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
1993
1994         add_option (_("User interaction"), new KeyboardOptions);
1995
1996         /* Control Surfaces */
1997
1998         add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
1999
2000         ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2001                 "remote-model",
2002                 _("Control surface remote ID"),
2003                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2004                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2005                 );
2006
2007         rm->add (UserOrdered, _("assigned by user"));
2008         rm->add (MixerOrdered, _("follows order of mixer"));
2009
2010         add_option (_("Control Surfaces"), rm);
2011
2012         /* VIDEO Timeline */
2013         add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2014
2015 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
2016         /* Plugin options (currrently VST only) */
2017         add_option (_("Plugin"), new PluginOptions (_rc_config));
2018 #endif
2019
2020         /* INTERFACE */
2021
2022         add_option (S_("Preferences|GUI"),
2023              new BoolOption (
2024                      "widget-prelight",
2025                      _("Graphically indicate mouse pointer hovering over various widgets"),
2026                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_widget_prelight),
2027                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_widget_prelight)
2028                      ));
2029
2030         add_option (S_("Preferences|GUI"),
2031              new BoolOption (
2032                      "use-tooltips",
2033                      _("Show tooltips if mouse hovers over a control"),
2034                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_tooltips),
2035                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_tooltips)
2036                      ));
2037
2038 #ifndef GTKOSX
2039         /* font scaling does nothing with GDK/Quartz */
2040         add_option (S_("Preferences|GUI"), new FontScalingOptions (_rc_config));
2041 #endif
2042
2043         add_option (S_("GUI"),
2044                     new BoolOption (
2045                             "super-rapid-clock-update",
2046                             _("update transport clock display every 40ms instead of every 100ms"),
2047                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_super_rapid_clock_update),
2048                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_super_rapid_clock_update)
2049                             ));
2050
2051         /* The names of these controls must be the same as those given in MixerStrip
2052            for the actual widgets being controlled.
2053         */
2054         _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2055         _mixer_strip_visibility.add (0, X_("SoloSafe"), _("Solo Safe"));
2056         _mixer_strip_visibility.add (0, X_("SoloIsolated"), _("Solo Isolated"));
2057         _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2058         _mixer_strip_visibility.add (0, X_("MeterPoint"), _("Meter Point"));
2059         
2060         add_option (
2061                 S_("Preferences|GUI"),
2062                 new VisibilityOption (
2063                         _("Mixer Strip"),
2064                         &_mixer_strip_visibility,
2065                         sigc::mem_fun (*_rc_config, &RCConfiguration::get_mixer_strip_visibility),
2066                         sigc::mem_fun (*_rc_config, &RCConfiguration::set_mixer_strip_visibility)
2067                         )
2068                 );
2069
2070         add_option (S_("Preferences|GUI"),
2071              new BoolOption (
2072                      "default-narrow_ms",
2073                      _("Use narrow strips in the mixer by default"),
2074                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_narrow_ms),
2075                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_narrow_ms)
2076                      ));
2077
2078         add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Metering")));
2079
2080         ComboOption<float>* mht = new ComboOption<float> (
2081                 "meter-hold",
2082                 _("Peak hold time"),
2083                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_hold),
2084                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_hold)
2085                 );
2086
2087         mht->add (MeterHoldOff, _("off"));
2088         mht->add (MeterHoldShort, _("short"));
2089         mht->add (MeterHoldMedium, _("medium"));
2090         mht->add (MeterHoldLong, _("long"));
2091
2092         add_option (S_("Preferences|GUI"), mht);
2093
2094         ComboOption<float>* mfo = new ComboOption<float> (
2095                 "meter-falloff",
2096                 _("DPM fall-off"),
2097                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2098                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2099                 );
2100
2101         mfo->add (METER_FALLOFF_OFF,      _("off"));
2102         mfo->add (METER_FALLOFF_SLOWEST,  _("slowest [6.6dB/sec]"));
2103         mfo->add (METER_FALLOFF_SLOW,     _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2104         mfo->add (METER_FALLOFF_SLOWISH,  _("slowish [12.0dB/sec] (DIN)"));
2105         mfo->add (METER_FALLOFF_MODERATE, _("moderate [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2106         mfo->add (METER_FALLOFF_MEDIUM,   _("medium [20dB/sec]"));
2107         mfo->add (METER_FALLOFF_FAST,     _("fast [32dB/sec]"));
2108         mfo->add (METER_FALLOFF_FASTER,   _("faster [46dB/sec]"));
2109         mfo->add (METER_FALLOFF_FASTEST,  _("fastest [70dB/sec]"));
2110
2111         add_option (S_("Preferences|GUI"), mfo);
2112
2113         ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2114                 "meter-line-up-level",
2115                 _("Meter line-up level; 0dBu"),
2116                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_line_up_level),
2117                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_line_up_level)
2118                 );
2119
2120         mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2121         mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2122         mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2123         mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2124
2125         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."));
2126
2127         add_option (S_("Preferences|GUI"), mlu);
2128
2129         ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2130                 "meter-line-up-din",
2131                 _("IEC1/DIN Meter line-up level; 0dBu"),
2132                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_line_up_din),
2133                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_line_up_din)
2134                 );
2135
2136         mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2137         mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2138         mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2139         mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2140
2141         Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2142
2143         add_option (S_("Preferences|GUI"), mld);
2144
2145         ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2146                 "meter-vu-standard",
2147                 _("VU Meter standard"),
2148                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_vu_standard),
2149                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_vu_standard)
2150                 );
2151
2152         mvu->add (MeteringVUfrench,   _("0VU = -2dBu (France)"));
2153         mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2154         mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2155         mvu->add (MeteringVUeight,    _("0VU = +8dBu"));
2156
2157         add_option (S_("Preferences|GUI"), mvu);
2158
2159         Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
2160         HSliderOption *mpks = new HSliderOption("meter-peak",
2161                         _("Peak threshold [dBFS]"),
2162                         mpk,
2163                         sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_peak),
2164                         sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_peak)
2165                         );
2166
2167         Gtkmm2ext::UI::instance()->set_tip
2168                 (mpks->tip_widget(),
2169                  _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
2170
2171         add_option (S_("Preferences|GUI"), mpks);
2172
2173         add_option (S_("Preferences|GUI"),
2174              new BoolOption (
2175                      "meter-style-led",
2176                      _("LED meter style"),
2177                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_style_led),
2178                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_style_led)
2179                      ));
2180
2181 }
2182
2183 void
2184 RCOptionEditor::parameter_changed (string const & p)
2185 {
2186         OptionEditor::parameter_changed (p);
2187
2188         if (p == "use-monitor-bus") {
2189                 bool const s = Config->get_use_monitor_bus ();
2190                 if (!s) {
2191                         /* we can't use this if we don't have a monitor bus */
2192                         Config->set_solo_control_is_listen_control (false);
2193                 }
2194                 _solo_control_is_listen_control->set_sensitive (s);
2195                 _listen_position->set_sensitive (s);
2196         } else if (p == "sync-source") {
2197                 _sync_source->set_sensitive (true);
2198                 if (_session) {
2199                         _sync_source->set_sensitive (!_session->config.get_external_sync());
2200                 }
2201                 switch(Config->get_sync_source()) {
2202                 case ARDOUR::MTC:
2203                 case ARDOUR::LTC:
2204                         _sync_genlock->set_sensitive (true);
2205                         _sync_framerate->set_sensitive (true);
2206                         _sync_source_2997->set_sensitive (true);
2207                         break;
2208                 default:
2209                         _sync_genlock->set_sensitive (false);
2210                         _sync_framerate->set_sensitive (false);
2211                         _sync_source_2997->set_sensitive (false);
2212                         break;
2213                 }
2214         } else if (p == "send-ltc") {
2215                 bool const s = Config->get_send_ltc ();
2216                 _ltc_send_continuously->set_sensitive (s);
2217                 _ltc_volume_slider->set_sensitive (s);
2218         }
2219 }
2220
2221 void RCOptionEditor::ltc_generator_volume_changed () {
2222         _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
2223 }
2224
2225 void
2226 RCOptionEditor::populate_sync_options ()
2227 {
2228         vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
2229
2230         _sync_source->clear ();
2231
2232         for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
2233                 _sync_source->add (*i, sync_source_to_string (*i));
2234         }
2235 }