978cea87cc7116ea0240384a8cc1a9c963d68c94
[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         _sync_source_2997 = new BoolOption (
1091                 "timecode-source-2997",
1092                 _("Lock to 29.9700 fps instead of 30000/1001"),
1093                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
1094                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
1095                 );
1096         Gtkmm2ext::UI::instance()->set_tip
1097                 (_sync_source_2997->tip_widget(),
1098                  _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
1099                          "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
1100                          "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
1101                          "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
1102                          "That is not the actual rate, however some vendor use that rate - despite it being against the specs - "
1103                          "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
1104                          ));
1105
1106         add_option (_("Transport"), _sync_source_2997);
1107
1108         _ltc_port = new ComboStringOption (
1109                 "ltc-source-port",
1110                 _("LTC incoming port"),
1111                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
1112                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
1113                 );
1114
1115         vector<string> physical_inputs;
1116         physical_inputs.push_back (_("None"));
1117         AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
1118         _ltc_port->set_popdown_strings (physical_inputs);
1119
1120         add_option (_("Transport"), _ltc_port);
1121
1122 #ifdef HAVE_LTC
1123         // TODO; rather disable this button than not compile it..
1124         add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
1125
1126         add_option (_("Transport"),
1127                     new BoolOption (
1128                             "send-ltc",
1129                             _("Enable LTC generator"),
1130                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
1131                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
1132                             ));
1133
1134         _ltc_send_continuously = new BoolOption (
1135                             "ltc-send-continuously",
1136                             _("send LTC while stopped"),
1137                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
1138                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
1139                             );
1140         Gtkmm2ext::UI::instance()->set_tip
1141                 (_ltc_send_continuously->tip_widget(),
1142                  _("<b>When enabled</b> Ardour will continue to send LTC information even when the transport (playhead) is not moving"));
1143         add_option (_("Transport"), _ltc_send_continuously);
1144
1145   _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
1146         _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
1147         _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
1148         _ltc_volume_slider = new HSliderOption("ltcvol", ("LTC generator level:"), *_ltc_volume_adjustment);
1149
1150         Gtkmm2ext::UI::instance()->set_tip
1151                 (_ltc_volume_slider->tip_widget(),
1152                  _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is  0dBu ^= -18dbFS in an EBU calibrated system"));
1153
1154         add_option (_("Transport"), _ltc_volume_slider);
1155         parameter_changed ("send-ltc");
1156 #endif
1157
1158         parameter_changed ("sync-source");
1159
1160         /* EDITOR */
1161
1162         add_option (_("Editor"),
1163              new BoolOption (
1164                      "link-region-and-track-selection",
1165                      _("Link selection of regions and tracks"),
1166                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_region_and_track_selection),
1167                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_region_and_track_selection)
1168                      ));
1169
1170         add_option (_("Editor"),
1171              new BoolOption (
1172                      "automation-follows-regions",
1173                      _("Move relevant automation when audio regions are moved"),
1174                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
1175                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
1176                      ));
1177
1178         add_option (_("Editor"),
1179              new BoolOption (
1180                      "show-track-meters",
1181                      _("Show meters on tracks in the editor"),
1182                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_track_meters),
1183                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_track_meters)
1184                      ));
1185
1186         add_option (_("Editor"),
1187              new BoolOption (
1188                      "use-overlap-equivalency",
1189                      _("Use overlap equivalency for regions"),
1190                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
1191                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
1192                      ));
1193
1194         add_option (_("Editor"),
1195              new BoolOption (
1196                      "rubberbanding-snaps-to-grid",
1197                      _("Make rubberband selection rectangle snap to the grid"),
1198                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_rubberbanding_snaps_to_grid),
1199                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_rubberbanding_snaps_to_grid)
1200                      ));
1201
1202         add_option (_("Editor"),
1203              new BoolOption (
1204                      "show-waveforms",
1205                      _("Show waveforms in regions"),
1206                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms),
1207                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms)
1208                      ));
1209
1210         add_option (_("Editor"),
1211              new BoolComboOption (
1212                      "show-region-gain-envelopes",
1213                      _("Show gain envelopes in audio regions"),
1214                      _("in all modes"),
1215                      _("only in region gain mode"),
1216                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_region_gain),
1217                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_region_gain)
1218                      ));
1219
1220         ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
1221                 "waveform-scale",
1222                 _("Waveform scale"),
1223                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_scale),
1224                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_scale)
1225                 );
1226
1227         wfs->add (Linear, _("linear"));
1228         wfs->add (Logarithmic, _("logarithmic"));
1229
1230         add_option (_("Editor"), wfs);
1231
1232         ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
1233                 "waveform-shape",
1234                 _("Waveform shape"),
1235                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_shape),
1236                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_shape)
1237                 );
1238
1239         wfsh->add (Traditional, _("traditional"));
1240         wfsh->add (Rectified, _("rectified"));
1241
1242         add_option (_("Editor"), wfsh);
1243
1244         add_option (_("Editor"),
1245              new BoolOption (
1246                      "show-waveforms-while-recording",
1247                      _("Show waveforms for audio while it is being recorded"),
1248                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms_while_recording),
1249                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms_while_recording)
1250                      ));
1251
1252         add_option (_("Editor"),
1253                     new BoolOption (
1254                             "show-zoom-tools",
1255                             _("Show zoom toolbar"),
1256                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_zoom_tools),
1257                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_zoom_tools)
1258                             ));
1259
1260         add_option (_("Editor"),
1261                     new BoolOption (
1262                             "color-regions-using-track-color",
1263                             _("Color regions using their track's color"),
1264                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_color_regions_using_track_color),
1265                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_color_regions_using_track_color)
1266                             ));
1267
1268         add_option (_("Editor"),
1269                     new BoolOption (
1270                             "update-editor-during-summary-drag",
1271                             _("Update editor window during drags of the summary"),
1272                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_update_editor_during_summary_drag),
1273                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_update_editor_during_summary_drag)
1274                             ));
1275
1276         add_option (_("Editor"),
1277              new BoolOption (
1278                      "sync-all-route-ordering",
1279                      _("Synchronise editor and mixer track order"),
1280                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_all_route_ordering),
1281                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_all_route_ordering)
1282                      ));
1283
1284         add_option (_("Editor"),
1285              new BoolOption (
1286                      "link-editor-and-mixer-selection",
1287                      _("Synchronise editor and mixer selection"),
1288                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_editor_and_mixer_selection),
1289                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_editor_and_mixer_selection)
1290                      ));
1291
1292         add_option (_("Editor"),
1293              new BoolOption (
1294                      "name-new-markers",
1295                      _("Name new markers"),
1296                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_name_new_markers),
1297                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_name_new_markers)
1298                      ));
1299
1300         add_option (_("Editor"),
1301             new BoolOption (
1302                     "autoscroll-editor",
1303                     _("Auto-scroll editor window when dragging near its edges"),
1304                     sigc::mem_fun (*_rc_config, &RCConfiguration::get_autoscroll_editor),
1305                     sigc::mem_fun (*_rc_config, &RCConfiguration::set_autoscroll_editor)
1306                     ));
1307
1308         /* AUDIO */
1309
1310         add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
1311
1312         add_option (_("Audio"), new BufferingOptions (_rc_config));
1313
1314         add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
1315
1316         add_option (_("Audio"),
1317              new BoolOption (
1318                      "use-monitor-bus",
1319                      _("Use a monitor bus (allows AFL/PFL and more control)"),
1320                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_monitor_bus),
1321                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_monitor_bus)
1322                      ));
1323
1324         ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
1325                 "monitoring-model",
1326                 _("Record monitoring handled by"),
1327                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
1328                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
1329                 );
1330
1331 #ifndef __APPLE__
1332         /* no JACK monitoring on CoreAudio */
1333         if (AudioEngine::instance()->can_request_hardware_monitoring()) {
1334                 mm->add (HardwareMonitoring, _("JACK"));
1335         }
1336 #endif
1337         mm->add (SoftwareMonitoring, _("ardour"));
1338         mm->add (ExternalMonitoring, _("audio hardware"));
1339
1340         add_option (_("Audio"), mm);
1341
1342         add_option (_("Audio"),
1343              new BoolOption (
1344                      "tape-machine-mode",
1345                      _("Tape machine mode"),
1346                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
1347                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
1348                      ));
1349
1350         add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
1351
1352         add_option (_("Audio"),
1353                     new BoolOption (
1354                             "auto-connect-standard-busses",
1355                             _("Auto-connect master/monitor busses"),
1356                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
1357                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
1358                             ));
1359
1360         ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
1361                 "input-auto-connect",
1362                 _("Connect track inputs"),
1363                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
1364                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
1365                 );
1366
1367         iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
1368         iac->add (ManualConnect, _("manually"));
1369
1370         add_option (_("Audio"), iac);
1371
1372         ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
1373                 "output-auto-connect",
1374                 _("Connect track and bus outputs"),
1375                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
1376                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
1377                 );
1378
1379         oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
1380         oac->add (AutoConnectMaster, _("automatically to master bus"));
1381         oac->add (ManualConnect, _("manually"));
1382
1383         add_option (_("Audio"), oac);
1384
1385         add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
1386
1387         add_option (_("Audio"),
1388              new BoolOption (
1389                      "denormal-protection",
1390                      _("Use DC bias to protect against denormals"),
1391                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
1392                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
1393                      ));
1394
1395         ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
1396                 "denormal-model",
1397                 _("Processor handling"),
1398                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
1399                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
1400                 );
1401
1402         dm->add (DenormalNone, _("no processor handling"));
1403
1404         FPU fpu;
1405
1406         if (fpu.has_flush_to_zero()) {
1407                 dm->add (DenormalFTZ, _("use FlushToZero"));
1408         }
1409
1410         if (fpu.has_denormals_are_zero()) {
1411                 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
1412         }
1413
1414         if (fpu.has_flush_to_zero() && fpu.has_denormals_are_zero()) {
1415                 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
1416         }
1417
1418         add_option (_("Audio"), dm);
1419
1420         add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
1421
1422         add_option (_("Audio"),
1423              new BoolOption (
1424                      "plugins-stop-with-transport",
1425                      _("Silence plugins when the transport is stopped"),
1426                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
1427                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
1428                      ));
1429
1430         add_option (_("Audio"),
1431              new BoolOption (
1432                      "do-not-record-plugins",
1433                      _("Disable plugins during recording"),
1434                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_do_not_record_plugins),
1435                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_do_not_record_plugins)
1436                      ));
1437
1438         add_option (_("Audio"),
1439              new BoolOption (
1440                      "new-plugins-active",
1441                      _("Make new plugins active"),
1442                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
1443                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
1444                      ));
1445
1446         add_option (_("Audio"),
1447              new BoolOption (
1448                      "auto-analyse-audio",
1449                      _("Enable automatic analysis of audio"),
1450                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
1451                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
1452                      ));
1453
1454         add_option (_("Audio"),
1455              new BoolOption (
1456                      "replicate-missing-region-channels",
1457                      _("Replicate missing region channels"),
1458                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
1459                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
1460                      ));
1461
1462         /* SOLO AND MUTE */
1463
1464         add_option (_("Solo / mute"),
1465              new FaderOption (
1466                      "solo-mute-gain",
1467                      _("Solo-in-place mute cut (dB)"),
1468                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
1469                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
1470                      ));
1471
1472         _solo_control_is_listen_control = new BoolOption (
1473                 "solo-control-is-listen-control",
1474                 _("Solo controls are Listen controls"),
1475                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
1476                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
1477                 );
1478
1479         add_option (_("Solo / mute"), _solo_control_is_listen_control);
1480
1481         _listen_position = new ComboOption<ListenPosition> (
1482                 "listen-position",
1483                 _("Listen Position"),
1484                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
1485                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
1486                 );
1487
1488         _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
1489         _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
1490
1491         add_option (_("Solo / mute"), _listen_position);
1492
1493         ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
1494                 "pfl-position",
1495                 _("PFL signals come from"),
1496                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
1497                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
1498                 );
1499
1500         pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
1501         pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
1502
1503         add_option (_("Solo / mute"), pp);
1504
1505         ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
1506                 "afl-position",
1507                 _("AFL signals come from"),
1508                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
1509                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
1510                 );
1511
1512         pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
1513         pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
1514
1515         add_option (_("Solo / mute"), pa);
1516
1517         parameter_changed ("use-monitor-bus");
1518
1519         add_option (_("Solo / mute"),
1520              new BoolOption (
1521                      "exclusive-solo",
1522                      _("Exclusive solo"),
1523                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
1524                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
1525                      ));
1526
1527         add_option (_("Solo / mute"),
1528              new BoolOption (
1529                      "show-solo-mutes",
1530                      _("Show solo muting"),
1531                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
1532                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
1533                      ));
1534
1535         add_option (_("Solo / mute"),
1536              new BoolOption (
1537                      "solo-mute-override",
1538                      _("Soloing overrides muting"),
1539                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
1540                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
1541                      ));
1542
1543         add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
1544
1545         add_option (_("Solo / mute"),
1546              new BoolOption (
1547                      "mute-affects-pre-fader",
1548                      _("Mute affects pre-fader sends"),
1549                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
1550                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
1551                      ));
1552
1553         add_option (_("Solo / mute"),
1554              new BoolOption (
1555                      "mute-affects-post-fader",
1556                      _("Mute affects post-fader sends"),
1557                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
1558                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
1559                      ));
1560
1561         add_option (_("Solo / mute"),
1562              new BoolOption (
1563                      "mute-affects-control-outs",
1564                      _("Mute affects control outputs"),
1565                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
1566                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
1567                      ));
1568
1569         add_option (_("Solo / mute"),
1570              new BoolOption (
1571                      "mute-affects-main-outs",
1572                      _("Mute affects main outputs"),
1573                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
1574                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
1575                      ));
1576
1577         add_option (_("MIDI"),
1578                     new BoolOption (
1579                             "send-midi-clock",
1580                             _("Send MIDI Clock"),
1581                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
1582                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
1583                             ));
1584
1585         add_option (_("MIDI"),
1586                     new BoolOption (
1587                             "send-mtc",
1588                             _("Send MIDI Time Code"),
1589                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
1590                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
1591                             ));
1592
1593         add_option (_("MIDI"),
1594                     new SpinOption<int> (
1595                             "mtc-qf-speed-tolerance",
1596                             _("Percentage either side of normal transport speed to transmit MTC"),
1597                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
1598                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
1599                             0, 20, 1, 5
1600                             ));
1601
1602         add_option (_("MIDI"),
1603                     new BoolOption (
1604                             "mmc-control",
1605                             _("Obey MIDI Machine Control commands"),
1606                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
1607                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
1608                             ));
1609
1610         add_option (_("MIDI"),
1611                     new BoolOption (
1612                             "send-mmc",
1613                             _("Send MIDI Machine Control commands"),
1614                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
1615                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
1616                             ));
1617
1618         add_option (_("MIDI"),
1619                     new BoolOption (
1620                             "midi-feedback",
1621                             _("Send MIDI control feedback"),
1622                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
1623                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
1624                             ));
1625
1626         add_option (_("MIDI"),
1627              new SpinOption<uint8_t> (
1628                      "mmc-receive-device-id",
1629                      _("Inbound MMC device ID"),
1630                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
1631                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
1632                      0, 128, 1, 10
1633                      ));
1634
1635         add_option (_("MIDI"),
1636              new SpinOption<uint8_t> (
1637                      "mmc-send-device-id",
1638                      _("Outbound MMC device ID"),
1639                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
1640                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
1641                      0, 128, 1, 10
1642                      ));
1643
1644         add_option (_("MIDI"),
1645              new SpinOption<int32_t> (
1646                      "initial-program-change",
1647                      _("Initial program change"),
1648                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
1649                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
1650                      -1, 65536, 1, 10
1651                      ));
1652
1653         add_option (_("MIDI"),
1654                     new BoolOption (
1655                             "diplay-first-midi-bank-as-zero",
1656                             _("Display first MIDI bank/program as 0"),
1657                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
1658                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
1659                             ));
1660
1661         add_option (_("MIDI"),
1662              new BoolOption (
1663                      "never-display-periodic-midi",
1664                      _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
1665                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_never_display_periodic_midi),
1666                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_never_display_periodic_midi)
1667                      ));
1668
1669         add_option (_("MIDI"),
1670              new BoolOption (
1671                      "sound-midi-notes",
1672                      _("Sound MIDI notes as they are selected"),
1673                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_sound_midi_notes),
1674                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_sound_midi_notes)
1675                      ));
1676
1677         /* USER INTERACTION */
1678
1679         add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
1680
1681         add_option (_("User interaction"), new KeyboardOptions);
1682
1683         add_option (_("User interaction"), new OptionEditorHeading (_("Control surfaces")));
1684
1685         add_option (_("User interaction"), new ControlSurfacesOptions (*this));
1686
1687         ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
1688                 "remote-model",
1689                 _("Control surface remote ID"),
1690                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
1691                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
1692                 );
1693
1694         rm->add (UserOrdered, _("assigned by user"));
1695         rm->add (MixerOrdered, _("follows order of mixer"));
1696         rm->add (EditorOrdered, _("follows order of editor"));
1697
1698         add_option (_("User interaction"), rm);
1699
1700         /* INTERFACE */
1701
1702         add_option (S_("GUI"),
1703              new BoolOption (
1704                      "widget-prelight",
1705                      _("Graphically indicate mouse pointer hovering over various widgets"),
1706                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_widget_prelight),
1707                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_widget_prelight)
1708                      ));
1709
1710 #ifndef GTKOSX
1711         /* font scaling does nothing with GDK/Quartz */
1712         add_option (S_("GUI"), new FontScalingOptions (_rc_config));
1713 #endif
1714         add_option (S_("GUI"),
1715                     new BoolOption (
1716                             "use-own-plugin-gui",
1717                             _("Use plugins' own interfaces instead of Ardour's"),
1718                             sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_plugin_own_gui),
1719                             sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_plugin_own_gui)
1720                             ));
1721
1722         /* The names of these controls must be the same as those given in MixerStrip
1723            for the actual widgets being controlled.
1724         */
1725         _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
1726         _mixer_strip_visibility.add (0, X_("SoloSafe"), _("Solo Safe"));
1727         _mixer_strip_visibility.add (0, X_("SoloIsolated"), _("Solo Isolated"));
1728         _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
1729         _mixer_strip_visibility.add (0, X_("Group"), _("Group"));
1730         _mixer_strip_visibility.add (0, X_("MeterPoint"), _("Meter Point"));
1731         
1732         add_option (
1733                 S_("GUI"),
1734                 new VisibilityOption (
1735                         _("Mixer Strip"),
1736                         &_mixer_strip_visibility,
1737                         sigc::mem_fun (*_rc_config, &RCConfiguration::get_mixer_strip_visibility),
1738                         sigc::mem_fun (*_rc_config, &RCConfiguration::set_mixer_strip_visibility)
1739                         )
1740                 );
1741
1742         add_option (S_("GUI"),
1743              new BoolOption (
1744                      "default-narrow_ms",
1745                      _("Use narrow strips in the mixer by default"),
1746                      sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_narrow_ms),
1747                      sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_narrow_ms)
1748                      ));
1749
1750         add_option (S_("GUI"), new OptionEditorHeading (_("Metering")));
1751
1752         ComboOption<float>* mht = new ComboOption<float> (
1753                 "meter-hold",
1754                 _("Meter hold time"),
1755                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_hold),
1756                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_hold)
1757                 );
1758
1759         mht->add (MeterHoldOff, _("off"));
1760         mht->add (MeterHoldShort, _("short"));
1761         mht->add (MeterHoldMedium, _("medium"));
1762         mht->add (MeterHoldLong, _("long"));
1763
1764         add_option (S_("GUI"), mht);
1765
1766         ComboOption<float>* mfo = new ComboOption<float> (
1767                 "meter-falloff",
1768                 _("Meter fall-off"),
1769                 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
1770                 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
1771                 );
1772
1773         mfo->add (METER_FALLOFF_OFF, _("off"));
1774         mfo->add (METER_FALLOFF_SLOWEST, _("slowest"));
1775         mfo->add (METER_FALLOFF_SLOW, _("slow"));
1776         mfo->add (METER_FALLOFF_MEDIUM, _("medium"));
1777         mfo->add (METER_FALLOFF_FAST, _("fast"));
1778         mfo->add (METER_FALLOFF_FASTER, _("faster"));
1779         mfo->add (METER_FALLOFF_FASTEST, _("fastest"));
1780
1781         add_option (S_("GUI"), mfo);
1782 }
1783
1784 void
1785 RCOptionEditor::parameter_changed (string const & p)
1786 {
1787         OptionEditor::parameter_changed (p);
1788
1789         if (p == "use-monitor-bus") {
1790                 bool const s = Config->get_use_monitor_bus ();
1791                 if (!s) {
1792                         /* we can't use this if we don't have a monitor bus */
1793                         Config->set_solo_control_is_listen_control (false);
1794                 }
1795                 _solo_control_is_listen_control->set_sensitive (s);
1796                 _listen_position->set_sensitive (s);
1797         } else if (p == "sync-source") {
1798                 _sync_source->set_sensitive (true);
1799                 if (_session) {
1800                         _sync_source->set_sensitive (_session->config.get_external_sync());
1801                 }
1802                 switch(Config->get_sync_source()) {
1803                 case ARDOUR::MTC:
1804                 case ARDOUR::LTC:
1805                         _sync_genlock->set_sensitive (true);
1806                         _sync_framerate->set_sensitive (true);
1807                         _sync_source_2997->set_sensitive (true);
1808                         break;
1809                 default:
1810                         _sync_genlock->set_sensitive (false);
1811                         _sync_framerate->set_sensitive (false);
1812                         _sync_source_2997->set_sensitive (false);
1813                         break;
1814                 }
1815 #ifdef HAVE_LTC
1816         } else if (p == "send-ltc") {
1817                 bool const s = Config->get_send_ltc ();
1818                 _ltc_send_continuously->set_sensitive (s);
1819                 _ltc_volume_slider->set_sensitive (s);
1820 #endif /*HAVE_LTC*/
1821         }
1822 }
1823
1824 void RCOptionEditor::ltc_generator_volume_changed () {
1825         _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
1826 }
1827
1828 void
1829 RCOptionEditor::populate_sync_options ()
1830 {
1831         vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
1832
1833         _sync_source->clear ();
1834
1835         for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
1836                 _sync_source->add (*i, sync_source_to_string (*i));
1837         }
1838 }