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