display policy of plugin-scan progress popup-window
[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 #include <gtkmm2ext/paths_dialog.h>
34
35 #include "pbd/fpu.h"
36 #include "pbd/cpus.h"
37
38 #include "ardour/audioengine.h"
39 #include "ardour/dB.h"
40 #include "ardour/rc_configuration.h"
41 #include "ardour/control_protocol_manager.h"
42 #include "ardour/plugin_manager.h"
43 #include "control_protocol/control_protocol.h"
44
45 #include "canvas/wave_view.h"
46
47 #include "ardour_window.h"
48 #include "ardour_dialog.h"
49 #include "gui_thread.h"
50 #include "midi_tracer.h"
51 #include "rc_option_editor.h"
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 (RCConfiguration* c)
1001                 : _rc_config (c)
1002                 , _display_plugin_scan_progress (_("Always Display Plugin Scan Progress"))
1003                 , _discover_vst_on_start (_("Scan for new VST Plugins on Application Start"))
1004         {
1005                 Label *l;
1006                 std::stringstream ss;
1007                 Table* t = manage (new Table (2, 6));
1008                 t->set_spacings (4);
1009                 Button* b;
1010                 int n = 0;
1011
1012                 ss << "<b>" << _("General") << "</b>";
1013                 l = manage (left_aligned_label (ss.str()));
1014                 l->set_use_markup (true);
1015                 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1016                 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1017
1018                 b = manage (new Button (_("Scan for Plugins")));
1019                 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1020                 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1021
1022                 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1023                 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1024                 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1025                                             _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
1026
1027
1028                 ss.str("");
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> new VST plugins are searched, tested and added to the cache index on application start. When disabled new plugins will only be available after triggering a 'Scan' manually"));
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         CheckButton _display_plugin_scan_progress;
1085         CheckButton _discover_vst_on_start;
1086
1087         void display_plugin_scan_progress_toggled () {
1088                 bool const x = _display_plugin_scan_progress.get_active();
1089                 _rc_config->set_show_plugin_scan_window(x);
1090         }
1091
1092         void discover_vst_on_start_toggled () {
1093                 bool const x = _discover_vst_on_start.get_active();
1094                 _rc_config->set_discover_vst_on_start(x);
1095         }
1096
1097         void clear_vst_cache_clicked () {
1098                 PluginManager::instance().clear_vst_cache();
1099         }
1100
1101         void clear_vst_blacklist_clicked () {
1102                 PluginManager::instance().clear_vst_blacklist();
1103         }
1104
1105         void edit_vst_path_clicked () {
1106                 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1107                                 _("Set Windows VST Search Path"),
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                 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1122                                 _("Set Linux VST Search Path"),
1123                                 _rc_config->get_plugin_path_lxvst(),
1124                                 PluginManager::instance().get_lxvst_path()
1125                                 );
1126                 ResponseType r = (ResponseType) pd->run ();
1127                 pd->hide();
1128                 if (r == RESPONSE_ACCEPT) {
1129                         printf("%s", pd->get_serialized_paths().c_str());
1130                 }
1131                 delete pd;
1132         }
1133
1134         void refresh_clicked () {
1135                 PluginManager::instance().refresh();
1136         }
1137 };
1138
1139
1140 /** A class which allows control of visibility of some editor components usign
1141  *  a VisibilityGroup.  The caller should pass in a `dummy' VisibilityGroup
1142  *  which has the correct members, but with null widget pointers.  This
1143  *  class allows the user to set visibility of the members, the details
1144  *  of which are stored in a configuration variable which can be watched
1145  *  by parts of the editor that actually contain the widgets whose visibility
1146  *  is being controlled.
1147  */
1148
1149 class VisibilityOption : public Option
1150 {
1151 public:
1152         /** @param name User-visible name for this group.
1153          *  @param g `Dummy' VisibilityGroup (as described above).
1154          *  @param get Method to get the value of the appropriate configuration variable.
1155          *  @param set Method to set the value of the appropriate configuration variable.
1156          */
1157         VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1158                 : Option (g->get_state_name(), name)
1159                 , _heading (name)
1160                 , _visibility_group (g)
1161                 , _get (get)
1162                 , _set (set)
1163         {
1164                 /* Watch for changes made by the user to our members */
1165                 _visibility_group->VisibilityChanged.connect_same_thread (
1166                         _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1167                         );
1168         }
1169
1170         void set_state_from_config ()
1171         {
1172                 /* Set our state from the current configuration */
1173                 _visibility_group->set_state (_get ());
1174         }
1175
1176         void add_to_page (OptionEditorPage* p)
1177         {
1178                 _heading.add_to_page (p);
1179                 add_widget_to_page (p, _visibility_group->list_view ());
1180         }
1181
1182         Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1183
1184 private:
1185         void changed ()
1186         {
1187                 /* The user has changed something, so reflect this change
1188                    in the RCConfiguration.
1189                 */
1190                 _set (_visibility_group->get_state_value ());
1191         }
1192         
1193         OptionEditorHeading _heading;
1194         VisibilityGroup* _visibility_group;
1195         sigc::slot<std::string> _get;
1196         sigc::slot<bool, std::string> _set;
1197         PBD::ScopedConnection _visibility_group_connection;
1198 };
1199
1200
1201
1202 RCOptionEditor::RCOptionEditor ()
1203         : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1204         , _rc_config (Config)
1205         , _mixer_strip_visibility ("mixer-strip-visibility")
1206 {
1207         /* MISC */
1208
1209         uint32_t hwcpus = hardware_concurrency ();
1210         BoolOption* bo;
1211         BoolComboOption* bco;
1212
1213         if (hwcpus > 1) {
1214                 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1215
1216                 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1217                         "processor-usage",
1218                         _("Signal processing uses"),
1219                         sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1220                         sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1221                         );
1222
1223                 procs->add (-1, _("all but one processor"));
1224                 procs->add (0, _("all available processors"));
1225
1226                 for (uint32_t i = 1; i <= hwcpus; ++i) {
1227                         procs->add (i, string_compose (_("%1 processors"), i));
1228                 }
1229
1230                 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1231
1232                 add_option (_("Misc"), procs);
1233         }
1234
1235         add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1236
1237         add_option (_("Misc"), new UndoOptions (_rc_config));
1238
1239         add_option (_("Misc"),
1240              new BoolOption (
1241                      "verify-remove-last-capture",
1242                      _("Verify removal of last capture"),
1243                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1244                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1245                      ));
1246
1247         add_option (_("Misc"),
1248              new BoolOption (
1249                      "periodic-safety-backups",
1250                      _("Make periodic backups of the session file"),
1251                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1252                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1253                      ));
1254
1255         add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1256
1257         add_option (_("Misc"),
1258              new BoolOption (
1259                      "only-copy-imported-files",
1260                      _("Always copy imported files"),
1261                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_only_copy_imported_files),
1262                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_only_copy_imported_files)
1263                      ));
1264
1265         add_option (_("Misc"), new DirectoryOption (
1266                             X_("default-session-parent-dir"),
1267                             _("Default folder for new sessions:"),
1268                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1269                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1270                             ));
1271
1272         add_option (_("Misc"),
1273              new SpinOption<uint32_t> (
1274                      "max-recent-sessions",
1275                      _("Maximum number of recent sessions"),
1276                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1277                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1278                      0, 1000, 1, 20
1279                      ));
1280
1281         add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1282
1283         add_option (_("Misc"), new ClickOptions (_rc_config, this));
1284
1285         add_option (_("Misc"),
1286              new FaderOption (
1287                      "click-gain",
1288                      _("Click gain level"),
1289                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1290                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1291                      ));
1292
1293         add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1294
1295         add_option (_("Misc"),
1296              new SpinOption<double> (
1297                      "automation-thinning-factor",
1298                      _("Thinning factor (larger value => less data)"),
1299                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1300                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1301                      0, 1000, 1, 20
1302                      ));
1303
1304         add_option (_("Misc"),
1305              new SpinOption<double> (
1306                      "automation-interval-msecs",
1307                      _("Automation sampling interval (milliseconds)"),
1308                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1309                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1310                      1, 1000, 1, 20
1311                      ));
1312
1313         /* TRANSPORT */
1314
1315         BoolOption* tsf;
1316
1317         tsf = new BoolOption (
1318                      "latched-record-enable",
1319                      _("Keep record-enable engaged on stop"),
1320                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1321                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1322                      );
1323         // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1324         add_option (_("Transport"), tsf);
1325
1326         tsf = new BoolOption (
1327                      "stop-recording-on-xrun",
1328                      _("Stop recording when an xrun occurs"),
1329                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1330                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1331                      );
1332         Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), 
1333                                             string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
1334                                                             PROGRAM_NAME));
1335         add_option (_("Transport"), tsf);
1336
1337         tsf = new BoolOption (
1338                      "create-xrun-marker",
1339                      _("Create markers where xruns occur"),
1340                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1341                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1342                      );
1343         // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1344         add_option (_("Transport"), tsf);
1345
1346         tsf = new BoolOption (
1347                      "stop-at-session-end",
1348                      _("Stop at the end of the session"),
1349                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1350                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1351                      );
1352         Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), 
1353                                             string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
1354                                                               "when it reaches the current session end marker\n\n"
1355                                                               "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
1356                                                             PROGRAM_NAME));
1357         add_option (_("Transport"), tsf);
1358
1359         tsf = new BoolOption (
1360                      "seamless-loop",
1361                      _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
1362                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1363                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1364                      );
1365         Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), 
1366                                             string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1367                                                               "preventing any need to do a transport locate at the end of the loop\n\n"
1368                                                               "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
1369                                                               "which will often cause a small click or delay"), PROGRAM_NAME));
1370         add_option (_("Transport"), tsf);
1371
1372         tsf = new BoolOption (
1373                      "disable-disarm-during-roll",
1374                      _("Disable per-track record disarm while rolling"),
1375                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
1376                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
1377                      );
1378         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"));
1379         add_option (_("Transport"), tsf);
1380
1381         tsf = new BoolOption (
1382                      "quieten_at_speed",
1383                      _("12dB gain reduction during fast-forward and fast-rewind"),
1384                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
1385                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
1386                      );
1387         Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
1388                                                    "that occurs when fast-forwarding or rewinding through some kinds of audio"));
1389         add_option (_("Transport"), tsf);
1390
1391         add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
1392
1393         _sync_source = new ComboOption<SyncSource> (
1394                 "sync-source",
1395                 _("External timecode source"),
1396                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
1397                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
1398                 );
1399
1400         populate_sync_options ();
1401         add_option (_("Transport"), _sync_source);
1402
1403         _sync_framerate = new BoolOption (
1404                      "timecode-sync-frame-rate",
1405                      _("Match session video frame rate to external timecode"),
1406                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
1407                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
1408                      );
1409         Gtkmm2ext::UI::instance()->set_tip 
1410                 (_sync_framerate->tip_widget(),
1411                  string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
1412                                    "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
1413                                    "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
1414                                    "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
1415                                    "timecode standard and the session standard."), PROGRAM_NAME));
1416
1417         add_option (_("Transport"), _sync_framerate);
1418
1419         _sync_genlock = new BoolOption (
1420                 "timecode-source-is-synced",
1421                 _("External timecode is sync locked"),
1422                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
1423                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
1424                 );
1425         Gtkmm2ext::UI::instance()->set_tip 
1426                 (_sync_genlock->tip_widget(), 
1427                  _("<b>When enabled</b> indicates that the selected external timecode source shares sync (Black &amp; Burst, Wordclock, etc) with the audio interface."));
1428
1429
1430         add_option (_("Transport"), _sync_genlock);
1431
1432         _sync_source_2997 = new BoolOption (
1433                 "timecode-source-2997",
1434                 _("Lock to 29.9700 fps instead of 30000/1001"),
1435                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
1436                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
1437                 );
1438         Gtkmm2ext::UI::instance()->set_tip
1439                 (_sync_source_2997->tip_widget(),
1440                  _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
1441                          "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
1442                          "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
1443                          "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
1444                          "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
1445                          "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
1446                          ));
1447
1448         add_option (_("Transport"), _sync_source_2997);
1449
1450         add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
1451
1452         _ltc_port = new ComboStringOption (
1453                 "ltc-source-port",
1454                 _("LTC incoming port"),
1455                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
1456                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
1457                 );
1458
1459         vector<string> physical_inputs;
1460         physical_inputs.push_back (_("None"));
1461         AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
1462         _ltc_port->set_popdown_strings (physical_inputs);
1463
1464         add_option (_("Transport"), _ltc_port);
1465
1466         // TODO; rather disable this button than not compile it..
1467         add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
1468
1469         add_option (_("Transport"),
1470                     new BoolOption (
1471                             "send-ltc",
1472                             _("Enable LTC generator"),
1473                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
1474                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
1475                             ));
1476
1477         _ltc_send_continuously = new BoolOption (
1478                             "ltc-send-continuously",
1479                             _("send LTC while stopped"),
1480                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
1481                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
1482                             );
1483         Gtkmm2ext::UI::instance()->set_tip
1484                 (_ltc_send_continuously->tip_widget(),
1485                  string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
1486         add_option (_("Transport"), _ltc_send_continuously);
1487
1488         _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
1489         _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
1490         _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
1491         _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
1492
1493         Gtkmm2ext::UI::instance()->set_tip
1494                 (_ltc_volume_slider->tip_widget(),
1495                  _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is  0dBu ^= -18dbFS in an EBU calibrated system"));
1496
1497         add_option (_("Transport"), _ltc_volume_slider);
1498         parameter_changed ("send-ltc");
1499
1500         parameter_changed ("sync-source");
1501
1502         /* EDITOR */
1503
1504         add_option (_("Editor"),
1505              new BoolOption (
1506                      "link-region-and-track-selection",
1507                      _("Link selection of regions and tracks"),
1508                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_region_and_track_selection),
1509                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_region_and_track_selection)
1510                      ));
1511
1512         add_option (_("Editor"),
1513              new BoolOption (
1514                      "automation-follows-regions",
1515                      _("Move relevant automation when audio regions are moved"),
1516                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
1517                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
1518                      ));
1519
1520         add_option (_("Editor"),
1521              new BoolOption (
1522                      "show-track-meters",
1523                      _("Show meters on tracks in the editor"),
1524                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_track_meters),
1525                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_track_meters)
1526                      ));
1527
1528         add_option (_("Editor"),
1529              new BoolOption (
1530                      "show-editor-meter",
1531                      _("Display master-meter in the toolbar"),
1532                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_editor_meter),
1533                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_editor_meter)
1534                      ));
1535
1536         bco = new BoolComboOption (
1537                      "use-overlap-equivalency",
1538                      _("Regions in active edit groups are edited together"),
1539                      _("whenever they overlap in time"),
1540                      _("only if they have identical length, position and origin"),
1541                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
1542                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
1543                      );
1544
1545         add_option (_("Editor"), bco);
1546
1547         add_option (_("Editor"),
1548              new BoolOption (
1549                      "rubberbanding-snaps-to-grid",
1550                      _("Make rubberband selection rectangle snap to the grid"),
1551                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_rubberbanding_snaps_to_grid),
1552                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_rubberbanding_snaps_to_grid)
1553                      ));
1554
1555         add_option (_("Editor"),
1556              new BoolOption (
1557                      "show-waveforms",
1558                      _("Show waveforms in regions"),
1559                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms),
1560                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms)
1561                      ));
1562
1563         add_option (_("Editor"),
1564              new BoolComboOption (
1565                      "show-region-gain-envelopes",
1566                      _("Show gain envelopes in audio regions"),
1567                      _("in all modes"),
1568                      _("only in region gain mode"),
1569                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_region_gain),
1570                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_region_gain)
1571                      ));
1572
1573         ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
1574                 "waveform-scale",
1575                 _("Waveform scale"),
1576                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_scale),
1577                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_scale)
1578                 );
1579
1580         wfs->add (Linear, _("linear"));
1581         wfs->add (Logarithmic, _("logarithmic"));
1582
1583         add_option (_("Editor"), wfs);
1584
1585         ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
1586                 "waveform-shape",
1587                 _("Waveform shape"),
1588                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_shape),
1589                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_shape)
1590                 );
1591
1592         wfsh->add (Traditional, _("traditional"));
1593         wfsh->add (Rectified, _("rectified"));
1594
1595         add_option (_("Editor"), wfsh);
1596
1597         add_option (_("Editor"), new ClipLevelOptions (_rc_config));
1598
1599         add_option (_("Editor"),
1600              new BoolOption (
1601                      "show-waveforms-while-recording",
1602                      _("Show waveforms for audio while it is being recorded"),
1603                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms_while_recording),
1604                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms_while_recording)
1605                      ));
1606
1607         add_option (_("Editor"),
1608                     new BoolOption (
1609                             "show-zoom-tools",
1610                             _("Show zoom toolbar"),
1611                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_zoom_tools),
1612                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_zoom_tools)
1613                             ));
1614
1615         add_option (_("Editor"),
1616                     new BoolOption (
1617                             "update-editor-during-summary-drag",
1618                             _("Update editor window during drags of the summary"),
1619                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_update_editor_during_summary_drag),
1620                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_update_editor_during_summary_drag)
1621                             ));
1622
1623         add_option (_("Editor"),
1624              new BoolOption (
1625                      "link-editor-and-mixer-selection",
1626                      _("Synchronise editor and mixer selection"),
1627                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_editor_and_mixer_selection),
1628                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_editor_and_mixer_selection)
1629                      ));
1630
1631         bo = new BoolOption (
1632                      "name-new-markers",
1633                      _("Name new markers"),
1634                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_name_new_markers),
1635                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_name_new_markers)
1636                 );
1637         
1638         add_option (_("Editor"), bo);
1639         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."
1640                                                                 "\n\nYou can always rename markers by right-clicking on them"));
1641
1642         add_option (_("Editor"),
1643             new BoolOption (
1644                     "autoscroll-editor",
1645                     _("Auto-scroll editor window when dragging near its edges"),
1646                     sigc::mem_fun (*_rc_config, &RCConfiguration::get_autoscroll_editor),
1647                     sigc::mem_fun (*_rc_config, &RCConfiguration::set_autoscroll_editor)
1648                     ));
1649
1650         /* AUDIO */
1651
1652         add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
1653
1654         add_option (_("Audio"), new BufferingOptions (_rc_config));
1655
1656         add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
1657
1658         ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
1659                 "monitoring-model",
1660                 _("Record monitoring handled by"),
1661                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
1662                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
1663                 );
1664
1665         if (AudioEngine::instance()->port_engine().can_monitor_input()) {
1666                 mm->add (HardwareMonitoring, _("via Audio Driver"));
1667         }
1668
1669         string prog (PROGRAM_NAME);
1670         boost::algorithm::to_lower (prog);
1671         mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
1672         mm->add (ExternalMonitoring, _("audio hardware"));
1673
1674         add_option (_("Audio"), mm);
1675
1676         add_option (_("Audio"),
1677              new BoolOption (
1678                      "tape-machine-mode",
1679                      _("Tape machine mode"),
1680                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
1681                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
1682                      ));
1683
1684         add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
1685
1686         add_option (_("Audio"),
1687                     new BoolOption (
1688                             "auto-connect-standard-busses",
1689                             _("Auto-connect master/monitor busses"),
1690                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
1691                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
1692                             ));
1693
1694         ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
1695                 "input-auto-connect",
1696                 _("Connect track inputs"),
1697                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
1698                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
1699                 );
1700
1701         iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
1702         iac->add (ManualConnect, _("manually"));
1703
1704         add_option (_("Audio"), iac);
1705
1706         ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
1707                 "output-auto-connect",
1708                 _("Connect track and bus outputs"),
1709                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
1710                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
1711                 );
1712
1713         oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
1714         oac->add (AutoConnectMaster, _("automatically to master bus"));
1715         oac->add (ManualConnect, _("manually"));
1716
1717         add_option (_("Audio"), oac);
1718
1719         add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
1720
1721         add_option (_("Audio"),
1722              new BoolOption (
1723                      "denormal-protection",
1724                      _("Use DC bias to protect against denormals"),
1725                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
1726                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
1727                      ));
1728
1729         ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
1730                 "denormal-model",
1731                 _("Processor handling"),
1732                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
1733                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
1734                 );
1735
1736         dm->add (DenormalNone, _("no processor handling"));
1737
1738         FPU fpu;
1739
1740         if (fpu.has_flush_to_zero()) {
1741                 dm->add (DenormalFTZ, _("use FlushToZero"));
1742         }
1743
1744         if (fpu.has_denormals_are_zero()) {
1745                 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
1746         }
1747
1748         if (fpu.has_flush_to_zero() && fpu.has_denormals_are_zero()) {
1749                 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
1750         }
1751
1752         add_option (_("Audio"), dm);
1753
1754         add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
1755
1756         add_option (_("Audio"),
1757              new BoolOption (
1758                      "plugins-stop-with-transport",
1759                      _("Silence plugins when the transport is stopped"),
1760                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
1761                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
1762                      ));
1763
1764         add_option (_("Audio"),
1765              new BoolOption (
1766                      "new-plugins-active",
1767                      _("Make new plugins active"),
1768                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
1769                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
1770                      ));
1771
1772         add_option (_("Audio"),
1773              new BoolOption (
1774                      "auto-analyse-audio",
1775                      _("Enable automatic analysis of audio"),
1776                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
1777                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
1778                      ));
1779
1780         add_option (_("Audio"),
1781              new BoolOption (
1782                      "replicate-missing-region-channels",
1783                      _("Replicate missing region channels"),
1784                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
1785                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
1786                      ));
1787
1788         /* SOLO AND MUTE */
1789
1790         add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
1791
1792         add_option (_("Solo / mute"),
1793              new FaderOption (
1794                      "solo-mute-gain",
1795                      _("Solo-in-place mute cut (dB)"),
1796                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
1797                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
1798                      ));
1799
1800         _solo_control_is_listen_control = new BoolOption (
1801                 "solo-control-is-listen-control",
1802                 _("Solo controls are Listen controls"),
1803                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
1804                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
1805                 );
1806
1807         add_option (_("Solo / mute"), _solo_control_is_listen_control);
1808
1809         _listen_position = new ComboOption<ListenPosition> (
1810                 "listen-position",
1811                 _("Listen Position"),
1812                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
1813                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
1814                 );
1815
1816         _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
1817         _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
1818
1819         add_option (_("Solo / mute"), _listen_position);
1820
1821         ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
1822                 "pfl-position",
1823                 _("PFL signals come from"),
1824                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
1825                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
1826                 );
1827
1828         pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
1829         pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
1830
1831         add_option (_("Solo / mute"), pp);
1832
1833         ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
1834                 "afl-position",
1835                 _("AFL signals come from"),
1836                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
1837                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
1838                 );
1839
1840         pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
1841         pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
1842
1843         add_option (_("Solo / mute"), pa);
1844
1845         parameter_changed ("use-monitor-bus");
1846
1847         add_option (_("Solo / mute"),
1848              new BoolOption (
1849                      "exclusive-solo",
1850                      _("Exclusive solo"),
1851                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
1852                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
1853                      ));
1854
1855         add_option (_("Solo / mute"),
1856              new BoolOption (
1857                      "show-solo-mutes",
1858                      _("Show solo muting"),
1859                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
1860                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
1861                      ));
1862
1863         add_option (_("Solo / mute"),
1864              new BoolOption (
1865                      "solo-mute-override",
1866                      _("Soloing overrides muting"),
1867                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
1868                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
1869                      ));
1870
1871         add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
1872
1873         add_option (_("Solo / mute"),
1874              new BoolOption (
1875                      "mute-affects-pre-fader",
1876                      _("Mute affects pre-fader sends"),
1877                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
1878                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
1879                      ));
1880
1881         add_option (_("Solo / mute"),
1882              new BoolOption (
1883                      "mute-affects-post-fader",
1884                      _("Mute affects post-fader sends"),
1885                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
1886                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
1887                      ));
1888
1889         add_option (_("Solo / mute"),
1890              new BoolOption (
1891                      "mute-affects-control-outs",
1892                      _("Mute affects control outputs"),
1893                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
1894                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
1895                      ));
1896
1897         add_option (_("Solo / mute"),
1898              new BoolOption (
1899                      "mute-affects-main-outs",
1900                      _("Mute affects main outputs"),
1901                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
1902                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
1903                      ));
1904
1905         add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
1906
1907         add_option (_("Solo / mute"),
1908              new BoolOption (
1909                      "link-send-and-route-panner",
1910                      _("Link panners of Aux and External Sends with main panner by default"),
1911                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
1912                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
1913                      ));
1914
1915         add_option (_("MIDI"),
1916                     new BoolOption (
1917                             "send-midi-clock",
1918                             _("Send MIDI Clock"),
1919                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
1920                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
1921                             ));
1922
1923         add_option (_("MIDI"),
1924                     new BoolOption (
1925                             "send-mtc",
1926                             _("Send MIDI Time Code"),
1927                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
1928                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
1929                             ));
1930
1931         add_option (_("MIDI"),
1932                     new SpinOption<int> (
1933                             "mtc-qf-speed-tolerance",
1934                             _("Percentage either side of normal transport speed to transmit MTC"),
1935                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
1936                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
1937                             0, 20, 1, 5
1938                             ));
1939
1940         add_option (_("MIDI"),
1941                     new BoolOption (
1942                             "mmc-control",
1943                             _("Obey MIDI Machine Control commands"),
1944                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
1945                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
1946                             ));
1947
1948         add_option (_("MIDI"),
1949                     new BoolOption (
1950                             "send-mmc",
1951                             _("Send MIDI Machine Control commands"),
1952                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
1953                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
1954                             ));
1955
1956         add_option (_("MIDI"),
1957                     new BoolOption (
1958                             "midi-feedback",
1959                             _("Send MIDI control feedback"),
1960                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
1961                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
1962                             ));
1963
1964         add_option (_("MIDI"),
1965              new SpinOption<uint8_t> (
1966                      "mmc-receive-device-id",
1967                      _("Inbound MMC device ID"),
1968                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
1969                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
1970                      0, 128, 1, 10
1971                      ));
1972
1973         add_option (_("MIDI"),
1974              new SpinOption<uint8_t> (
1975                      "mmc-send-device-id",
1976                      _("Outbound MMC device ID"),
1977                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
1978                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
1979                      0, 128, 1, 10
1980                      ));
1981
1982         add_option (_("MIDI"),
1983              new SpinOption<int32_t> (
1984                      "initial-program-change",
1985                      _("Initial program change"),
1986                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
1987                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
1988                      -1, 65536, 1, 10
1989                      ));
1990
1991         add_option (_("MIDI"),
1992                     new BoolOption (
1993                             "diplay-first-midi-bank-as-zero",
1994                             _("Display first MIDI bank/program as 0"),
1995                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
1996                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
1997                             ));
1998
1999         add_option (_("MIDI"),
2000              new BoolOption (
2001                      "never-display-periodic-midi",
2002                      _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2003                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_never_display_periodic_midi),
2004                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_never_display_periodic_midi)
2005                      ));
2006
2007         add_option (_("MIDI"),
2008              new BoolOption (
2009                      "sound-midi-notes",
2010                      _("Sound MIDI notes as they are selected"),
2011                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_sound_midi_notes),
2012                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_sound_midi_notes)
2013                      ));
2014
2015         add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2016
2017         ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2018                 "midi-audition-synth-uri",
2019                 _("Midi Audition Synth (LV2)"),
2020                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2021                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2022                 );
2023
2024         audition_synth->add(X_(""), _("None"));
2025         PluginInfoList all_plugs;
2026         PluginManager& manager (PluginManager::instance());
2027 #ifdef LV2_SUPPORT
2028         all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2029
2030         for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2031                 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2032                 if (!(*i)->is_instrument()) continue;
2033                 if ((*i)->type != ARDOUR::LV2) continue;
2034                 audition_synth->add((*i)->unique_id, (*i)->name);
2035         }
2036 #endif
2037
2038         add_option (_("MIDI"), audition_synth);
2039
2040         /* USER INTERACTION */
2041
2042         if (getenv ("ARDOUR_BUNDLED")) {
2043                 add_option (_("User interaction"), 
2044                             new BoolOption (
2045                                     "enable-translation",
2046                                     string_compose (_("Use translations of %1 messages\n"
2047                                                       "   <i>(requires a restart of %1 to take effect)</i>\n"
2048                                                       "   <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2049                                     sigc::ptr_fun (ARDOUR::translations_are_enabled),
2050                                     sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2051         }
2052
2053         add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2054
2055         add_option (_("User interaction"), new KeyboardOptions);
2056
2057         /* Control Surfaces */
2058
2059         add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2060
2061         ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2062                 "remote-model",
2063                 _("Control surface remote ID"),
2064                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2065                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2066                 );
2067
2068         rm->add (UserOrdered, _("assigned by user"));
2069         rm->add (MixerOrdered, _("follows order of mixer"));
2070
2071         add_option (_("Control Surfaces"), rm);
2072
2073         /* VIDEO Timeline */
2074         add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2075
2076 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
2077         /* Plugin options (currrently VST only) */
2078         add_option (_("Plugins"), new PluginOptions (_rc_config));
2079 #endif
2080
2081         /* INTERFACE */
2082
2083         add_option (S_("Preferences|GUI"),
2084              new BoolOption (
2085                      "widget-prelight",
2086                      _("Graphically indicate mouse pointer hovering over various widgets"),
2087                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_widget_prelight),
2088                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_widget_prelight)
2089                      ));
2090
2091         add_option (S_("Preferences|GUI"),
2092              new BoolOption (
2093                      "use-tooltips",
2094                      _("Show tooltips if mouse hovers over a control"),
2095                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_tooltips),
2096                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_tooltips)
2097                      ));
2098
2099 #ifndef GTKOSX
2100         /* font scaling does nothing with GDK/Quartz */
2101         add_option (S_("Preferences|GUI"), new FontScalingOptions (_rc_config));
2102 #endif
2103
2104         add_option (S_("GUI"),
2105                     new BoolOption (
2106                             "super-rapid-clock-update",
2107                             _("update transport clock display every 40ms instead of every 100ms"),
2108                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_super_rapid_clock_update),
2109                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_super_rapid_clock_update)
2110                             ));
2111
2112         /* The names of these controls must be the same as those given in MixerStrip
2113            for the actual widgets being controlled.
2114         */
2115         _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2116         _mixer_strip_visibility.add (0, X_("SoloSafe"), _("Solo Safe"));
2117         _mixer_strip_visibility.add (0, X_("SoloIsolated"), _("Solo Isolated"));
2118         _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2119         _mixer_strip_visibility.add (0, X_("MeterPoint"), _("Meter Point"));
2120         
2121         add_option (
2122                 S_("Preferences|GUI"),
2123                 new VisibilityOption (
2124                         _("Mixer Strip"),
2125                         &_mixer_strip_visibility,
2126                         sigc::mem_fun (*_rc_config, &RCConfiguration::get_mixer_strip_visibility),
2127                         sigc::mem_fun (*_rc_config, &RCConfiguration::set_mixer_strip_visibility)
2128                         )
2129                 );
2130
2131         add_option (S_("Preferences|GUI"),
2132              new BoolOption (
2133                      "default-narrow_ms",
2134                      _("Use narrow strips in the mixer by default"),
2135                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_narrow_ms),
2136                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_narrow_ms)
2137                      ));
2138
2139         add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Metering")));
2140
2141         ComboOption<float>* mht = new ComboOption<float> (
2142                 "meter-hold",
2143                 _("Peak hold time"),
2144                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_hold),
2145                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_hold)
2146                 );
2147
2148         mht->add (MeterHoldOff, _("off"));
2149         mht->add (MeterHoldShort, _("short"));
2150         mht->add (MeterHoldMedium, _("medium"));
2151         mht->add (MeterHoldLong, _("long"));
2152
2153         add_option (S_("Preferences|GUI"), mht);
2154
2155         ComboOption<float>* mfo = new ComboOption<float> (
2156                 "meter-falloff",
2157                 _("DPM fall-off"),
2158                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2159                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2160                 );
2161
2162         mfo->add (METER_FALLOFF_OFF,      _("off"));
2163         mfo->add (METER_FALLOFF_SLOWEST,  _("slowest [6.6dB/sec]"));
2164         mfo->add (METER_FALLOFF_SLOW,     _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2165         mfo->add (METER_FALLOFF_SLOWISH,  _("slowish [12.0dB/sec] (DIN)"));
2166         mfo->add (METER_FALLOFF_MODERATE, _("moderate [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2167         mfo->add (METER_FALLOFF_MEDIUM,   _("medium [20dB/sec]"));
2168         mfo->add (METER_FALLOFF_FAST,     _("fast [32dB/sec]"));
2169         mfo->add (METER_FALLOFF_FASTER,   _("faster [46dB/sec]"));
2170         mfo->add (METER_FALLOFF_FASTEST,  _("fastest [70dB/sec]"));
2171
2172         add_option (S_("Preferences|GUI"), mfo);
2173
2174         ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2175                 "meter-line-up-level",
2176                 _("Meter line-up level; 0dBu"),
2177                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_line_up_level),
2178                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_line_up_level)
2179                 );
2180
2181         mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2182         mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2183         mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2184         mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2185
2186         Gtkmm2ext::UI::instance()->set_tip (mlu->tip_widget(), _("Configure meter-marks and color-knee point for dBFS scale DPM, set reference level for IEC1/Nordic, IEC2 PPM and VU meter."));
2187
2188         add_option (S_("Preferences|GUI"), mlu);
2189
2190         ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2191                 "meter-line-up-din",
2192                 _("IEC1/DIN Meter line-up level; 0dBu"),
2193                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_line_up_din),
2194                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_line_up_din)
2195                 );
2196
2197         mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2198         mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2199         mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2200         mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2201
2202         Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2203
2204         add_option (S_("Preferences|GUI"), mld);
2205
2206         ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2207                 "meter-vu-standard",
2208                 _("VU Meter standard"),
2209                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_vu_standard),
2210                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_vu_standard)
2211                 );
2212
2213         mvu->add (MeteringVUfrench,   _("0VU = -2dBu (France)"));
2214         mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2215         mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2216         mvu->add (MeteringVUeight,    _("0VU = +8dBu"));
2217
2218         add_option (S_("Preferences|GUI"), mvu);
2219
2220         Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
2221         HSliderOption *mpks = new HSliderOption("meter-peak",
2222                         _("Peak threshold [dBFS]"),
2223                         mpk,
2224                         sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_peak),
2225                         sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_peak)
2226                         );
2227
2228         Gtkmm2ext::UI::instance()->set_tip
2229                 (mpks->tip_widget(),
2230                  _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
2231
2232         add_option (S_("Preferences|GUI"), mpks);
2233
2234         add_option (S_("Preferences|GUI"),
2235              new BoolOption (
2236                      "meter-style-led",
2237                      _("LED meter style"),
2238                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_style_led),
2239                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_style_led)
2240                      ));
2241
2242 }
2243
2244 void
2245 RCOptionEditor::parameter_changed (string const & p)
2246 {
2247         OptionEditor::parameter_changed (p);
2248
2249         if (p == "use-monitor-bus") {
2250                 bool const s = Config->get_use_monitor_bus ();
2251                 if (!s) {
2252                         /* we can't use this if we don't have a monitor bus */
2253                         Config->set_solo_control_is_listen_control (false);
2254                 }
2255                 _solo_control_is_listen_control->set_sensitive (s);
2256                 _listen_position->set_sensitive (s);
2257         } else if (p == "sync-source") {
2258                 _sync_source->set_sensitive (true);
2259                 if (_session) {
2260                         _sync_source->set_sensitive (!_session->config.get_external_sync());
2261                 }
2262                 switch(Config->get_sync_source()) {
2263                 case ARDOUR::MTC:
2264                 case ARDOUR::LTC:
2265                         _sync_genlock->set_sensitive (true);
2266                         _sync_framerate->set_sensitive (true);
2267                         _sync_source_2997->set_sensitive (true);
2268                         break;
2269                 default:
2270                         _sync_genlock->set_sensitive (false);
2271                         _sync_framerate->set_sensitive (false);
2272                         _sync_source_2997->set_sensitive (false);
2273                         break;
2274                 }
2275         } else if (p == "send-ltc") {
2276                 bool const s = Config->get_send_ltc ();
2277                 _ltc_send_continuously->set_sensitive (s);
2278                 _ltc_volume_slider->set_sensitive (s);
2279         }
2280 }
2281
2282 void RCOptionEditor::ltc_generator_volume_changed () {
2283         _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
2284 }
2285
2286 void
2287 RCOptionEditor::populate_sync_options ()
2288 {
2289         vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
2290
2291         _sync_source->clear ();
2292
2293         for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
2294                 _sync_source->add (*i, sync_source_to_string (*i));
2295         }
2296 }