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