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