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