allow the use of static_cast for MGR ghost events (speeds things up a bit).
[ardour.git] / gtk2_ardour / rc_option_editor.cc
index 3428125bf9260d10da69f70053d823de0c6c380c..30b55259bd89c8b585a481e47625a3d64e740c6a 100644 (file)
 
 #include "pbd/fpu.h"
 #include "pbd/cpus.h"
+#include "pbd/i18n.h"
 
+#include "ardour/audio_backend.h"
 #include "ardour/audioengine.h"
 #include "ardour/profile.h"
 #include "ardour/dB.h"
 #include "ardour/rc_configuration.h"
 #include "ardour/control_protocol_manager.h"
+#include "ardour/port_manager.h"
 #include "ardour/plugin_manager.h"
 #include "control_protocol/control_protocol.h"
 
 #include "canvas/wave_view.h"
 
-#include "ardour_window.h"
 #include "ardour_dialog.h"
 #include "ardour_ui.h"
+#include "ardour_window.h"
+#include "color_theme_manager.h"
 #include "gui_thread.h"
+#include "keyboard.h"
 #include "meter_patterns.h"
 #include "midi_tracer.h"
 #include "rc_option_editor.h"
-#include "utils.h"
-#include "midi_port_dialog.h"
 #include "sfdb_ui.h"
-#include "keyboard.h"
 #include "theme_manager.h"
+#include "tooltips.h"
 #include "ui_config.h"
-#include "i18n.h"
+#include "utils.h"
 
 using namespace std;
 using namespace Gtk;
@@ -74,7 +77,7 @@ using namespace PBD;
 using namespace ARDOUR;
 using namespace ARDOUR_UI_UTILS;
 
-class ClickOptions : public OptionEditorBox
+class ClickOptions : public OptionEditorPageBox, public OptionEditorPage
 {
 public:
        ClickOptions (RCConfiguration* c)
@@ -82,36 +85,45 @@ public:
                , _click_browse_button (_("Browse..."))
                , _click_emphasis_browse_button (_("Browse..."))
        {
-               Table* t = manage (new Table (4, 3));
-               t->set_spacings (4);
+               Table* t = &table;
 
                Label* l = manage (left_aligned_label (_("Emphasis on first beat:")));
-               t->attach (*l, 0, 1, 1, 2, FILL);
-               t->attach (_use_emphasis_on_click_check_button, 1, 2, 1, 2, FILL);
+               _use_emphasis_on_click_check_button.add (*l);
+               t->attach (_use_emphasis_on_click_check_button, 1, 3, 0, 1, FILL);
                _use_emphasis_on_click_check_button.signal_toggled().connect (
                    sigc::mem_fun (*this, &ClickOptions::use_emphasis_on_click_toggled));
 
                l = manage (left_aligned_label (_("Use default Click:")));
-               t->attach (*l, 0, 1, 0, 1, FILL);
-               t->attach (_use_default_click_check_button, 1, 2, 0, 1, FILL);
+               _use_default_click_check_button.add (*l);
+               t->attach (_use_default_click_check_button, 1, 3, 1, 2, FILL);
                _use_default_click_check_button.signal_toggled().connect (
                    sigc::mem_fun (*this, &ClickOptions::use_default_click_toggled));
 
                l = manage (left_aligned_label (_("Click audio file:")));
-               t->attach (*l, 0, 1, 2, 3, FILL);
-               t->attach (_click_path_entry, 1, 2, 2, 3, FILL);
+               t->attach (*l, 1, 2, 2, 3, FILL);
+               t->attach (_click_path_entry, 2, 3, 2, 3, FILL);
                _click_browse_button.signal_clicked ().connect (
                    sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
-               t->attach (_click_browse_button, 2, 3, 2, 3, FILL);
+               t->attach (_click_browse_button, 3, 4, 2, 3, FILL);
 
                l = manage (left_aligned_label (_("Click emphasis audio file:")));
-               t->attach (*l, 0, 1, 3, 4, FILL);
-               t->attach (_click_emphasis_path_entry, 1, 2, 3, 4, FILL);
+               t->attach (*l, 1, 2, 3, 4, FILL);
+               t->attach (_click_emphasis_path_entry, 2, 3, 3, 4, FILL);
                _click_emphasis_browse_button.signal_clicked ().connect (
                    sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
-               t->attach (_click_emphasis_browse_button, 2, 3, 3, 4, FILL);
+               t->attach (_click_emphasis_browse_button, 3, 4, 3, 4, FILL);
 
-               _box->pack_start (*t, false, false);
+               FaderOption* fo = new FaderOption (
+                               "click-gain",
+                               _("Click gain level"),
+                               sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
+                               sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
+                               );
+
+               fo->add_to_page (this);
+               fo->set_state_from_config ();
+
+               _box->pack_start (table, true, true);
 
                _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
                _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
@@ -321,8 +333,8 @@ private:
 
 
 static const struct {
-    const char *name;
-    guint modifier;
+       const char *name;
+       guint modifier;
 } modifiers[] = {
 
        { "Unmodified", 0 },
@@ -338,6 +350,7 @@ static const struct {
        { "Option", GDK_MOD1_MASK },
        { "Command-Shift", GDK_MOD2_MASK|GDK_SHIFT_MASK },
        { "Command-Option", GDK_MOD2_MASK|GDK_MOD1_MASK },
+       { "Command-Control", GDK_MOD2_MASK|GDK_CONTROL_MASK },
        { "Command-Option-Control", GDK_MOD2_MASK|GDK_MOD1_MASK|GDK_CONTROL_MASK },
        { "Option-Control", GDK_MOD1_MASK|GDK_CONTROL_MASK },
        { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
@@ -350,6 +363,7 @@ static const struct {
        { "Alt", GDK_MOD1_MASK },
        { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
        { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
+       { "Control-Windows", GDK_CONTROL_MASK|GDK_MOD4_MASK },
        { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
        { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
        { "Alt-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
@@ -540,12 +554,13 @@ public:
                /* constraint modifier */
                set_popdown_strings (_constraint_modifier_combo, dumb);
                _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
+               std::string mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
                Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo,
                                                    (string_compose (_("<b>Recommended Setting: %1</b>%2"),
 #ifdef __APPLE__
                                                                     Keyboard::primary_modifier_name (),
 #else
-                                                                    Keyboard::secondary_modifier_name (),
+                                                                    Keyboard::tertiary_modifier_name (),
 #endif
                                                                     restart_msg)));
                for (int x = 0; modifiers[x].name; ++x) {
@@ -561,6 +576,29 @@ public:
                t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
                t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
 
+               ++row;
+               col = 1;
+
+               /* push points */
+               set_popdown_strings (_push_points_combo, dumb);
+               _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
+
+               mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
+               Gtkmm2ext::UI::instance()->set_tip (_push_points_combo,
+                                                   (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
+               for (int x = 0; modifiers[x].name; ++x) {
+                       if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
+                               _push_points_combo.set_active_text (S_(modifiers[x].name));
+                               break;
+                       }
+               }
+
+               l = manage (left_aligned_label (_("Push points using:")));
+               l->set_name ("OptionsLabel");
+
+               t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
+               t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
+
                ++row;
 
                l = manage (left_aligned_label (_("When Beginning a Trim:")));
@@ -594,8 +632,10 @@ public:
                /* anchored trim */
                set_popdown_strings (_trim_anchored_combo, dumb);
                _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
+
+               mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::tertiary_modifier_name ());
                Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo,
-                                                   (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
+                                                   (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
                for (int x = 0; modifiers[x].name; ++x) {
                        if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
                                _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
@@ -639,7 +679,7 @@ public:
                set_popdown_strings (_note_size_relative_combo, dumb);
                _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
                Gtkmm2ext::UI::instance()->set_tip (_note_size_relative_combo,
-                                                   (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
+                                                   (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
                for (int x = 0; modifiers[x].name; ++x) {
                        if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
                                _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
@@ -667,9 +707,9 @@ public:
                set_popdown_strings (_snap_modifier_combo, dumb);
                _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
 #ifdef __APPLE__
-               std::string mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ());
+               mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ());
 #else
-               std::string mod_str = Keyboard::secondary_modifier_name();
+               mod_str = Keyboard::secondary_modifier_name();
 #endif
                Gtkmm2ext::UI::instance()->set_tip (_snap_modifier_combo,
                                                    (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
@@ -753,7 +793,7 @@ public:
                set_popdown_strings (_fine_adjust_combo, dumb);
                _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
 
-               mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::tertiary_modifier_name ());
+               mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::secondary_modifier_name ());
                Gtkmm2ext::UI::instance()->set_tip (_fine_adjust_combo,
                                                    (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
                for (int x = 0; modifiers[x].name; ++x) {
@@ -769,28 +809,6 @@ public:
                t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
                t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
 
-               ++row;
-               col = 1;
-
-               /* push points */
-               set_popdown_strings (_push_points_combo, dumb);
-               _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
-
-               Gtkmm2ext::UI::instance()->set_tip (_push_points_combo,
-                                                   (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
-               for (int x = 0; modifiers[x].name; ++x) {
-                       if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
-                               _push_points_combo.set_active_text (S_(modifiers[x].name));
-                               break;
-                       }
-               }
-
-               l = manage (left_aligned_label (_("Push points using:")));
-               l->set_name ("OptionsLabel");
-
-               t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
-               t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
-
                _box->pack_start (*t, false, false);
        }
 
@@ -826,7 +844,7 @@ private:
                string const txt = _edit_modifier_combo.get_active_text();
 
                for (int i = 0; modifiers[i].name; ++i) {
-                       if (txt == _(modifiers[i].name)) {
+                       if (txt == S_(modifiers[i].name)) {
                                Keyboard::set_edit_modifier (modifiers[i].modifier);
                                break;
                        }
@@ -838,7 +856,7 @@ private:
                string const txt = _delete_modifier_combo.get_active_text();
 
                for (int i = 0; modifiers[i].name; ++i) {
-                       if (txt == _(modifiers[i].name)) {
+                       if (txt == S_(modifiers[i].name)) {
                                Keyboard::set_delete_modifier (modifiers[i].modifier);
                                break;
                        }
@@ -850,7 +868,7 @@ private:
                string const txt = _copy_modifier_combo.get_active_text();
 
                for (int i = 0; modifiers[i].name; ++i) {
-                       if (txt == _(modifiers[i].name)) {
+                       if (txt == S_(modifiers[i].name)) {
                                Keyboard::set_copy_modifier (modifiers[i].modifier);
                                break;
                        }
@@ -862,7 +880,7 @@ private:
                string const txt = _insert_note_modifier_combo.get_active_text();
 
                for (int i = 0; modifiers[i].name; ++i) {
-                       if (txt == _(modifiers[i].name)) {
+                       if (txt == S_(modifiers[i].name)) {
                                Keyboard::set_insert_note_modifier (modifiers[i].modifier);
                                break;
                        }
@@ -874,7 +892,7 @@ private:
                string const txt = _snap_modifier_combo.get_active_text();
 
                for (int i = 0; modifiers[i].name; ++i) {
-                       if (txt == _(modifiers[i].name)) {
+                       if (txt == S_(modifiers[i].name)) {
                                Keyboard::set_snap_modifier (modifiers[i].modifier);
                                break;
                        }
@@ -886,7 +904,7 @@ private:
                string const txt = _snap_delta_combo.get_active_text();
 
                for (int i = 0; modifiers[i].name; ++i) {
-                       if (txt == _(modifiers[i].name)) {
+                       if (txt == S_(modifiers[i].name)) {
                                Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
                                break;
                        }
@@ -898,7 +916,7 @@ private:
                string const txt = _constraint_modifier_combo.get_active_text();
 
                for (int i = 0; modifiers[i].name; ++i) {
-                       if (txt == _(modifiers[i].name)) {
+                       if (txt == S_(modifiers[i].name)) {
                                ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
                                break;
                        }
@@ -910,7 +928,7 @@ private:
                string const txt = _trim_contents_combo.get_active_text();
 
                for (int i = 0; modifiers[i].name; ++i) {
-                       if (txt == _(modifiers[i].name)) {
+                       if (txt == S_(modifiers[i].name)) {
                                ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
                                break;
                        }
@@ -922,7 +940,7 @@ private:
                string const txt = _trim_overlap_combo.get_active_text();
 
                for (int i = 0; modifiers[i].name; ++i) {
-                       if (txt == _(modifiers[i].name)) {
+                       if (txt == S_(modifiers[i].name)) {
                                ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
                                break;
                        }
@@ -934,7 +952,7 @@ private:
                string const txt = _trim_anchored_combo.get_active_text();
 
                for (int i = 0; modifiers[i].name; ++i) {
-                       if (txt == _(modifiers[i].name)) {
+                       if (txt == S_(modifiers[i].name)) {
                                ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
                                break;
                        }
@@ -946,7 +964,7 @@ private:
                string const txt = _fine_adjust_combo.get_active_text();
 
                for (int i = 0; modifiers[i].name; ++i) {
-                       if (txt == _(modifiers[i].name)) {
+                       if (txt == S_(modifiers[i].name)) {
                                ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
                                break;
                        }
@@ -958,7 +976,7 @@ private:
                string const txt = _push_points_combo.get_active_text();
 
                for (int i = 0; modifiers[i].name; ++i) {
-                       if (txt == _(modifiers[i].name)) {
+                       if (txt == S_(modifiers[i].name)) {
                                ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
                                break;
                        }
@@ -970,7 +988,7 @@ private:
                string const txt = _note_size_relative_combo.get_active_text();
 
                for (int i = 0; modifiers[i].name; ++i) {
-                       if (txt == _(modifiers[i].name)) {
+                       if (txt == S_(modifiers[i].name)) {
                                ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
                                break;
                        }
@@ -1196,13 +1214,13 @@ private:
 
 class BufferingOptions : public OptionEditorBox
 {
-public:
-       BufferingOptions (RCConfiguration* c)
-                : _rc_config (c)
-               , _playback_adjustment (5, 1, 60, 1, 4)
-                , _capture_adjustment (5, 1, 60, 1, 4)
-                , _playback_slider (_playback_adjustment)
-               , _capture_slider (_capture_adjustment)
+       public:
+               BufferingOptions (RCConfiguration* c)
+                       : _rc_config (c)
+                       , _playback_adjustment (5, 1, 60, 1, 4)
+                       , _capture_adjustment (5, 1, 60, 1, 4)
+                       , _playback_slider (_playback_adjustment)
+                       , _capture_slider (_capture_adjustment)
        {
                vector<string> presets;
 
@@ -1255,467 +1273,460 @@ public:
                _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
        }
 
-       void parameter_changed (string const & p)
-       {
-               if (p == "buffering-preset") {
-                       switch (_rc_config->get_buffering_preset()) {
-                       case Small:
-                               _playback_slider.set_sensitive (false);
-                               _capture_slider.set_sensitive (false);
-                               _buffering_presets_combo.set_active (0);
-                               break;
-                       case Medium:
-                               _playback_slider.set_sensitive (false);
-                               _capture_slider.set_sensitive (false);
-                               _buffering_presets_combo.set_active (1);
-                               break;
-                       case Large:
-                               _playback_slider.set_sensitive (false);
-                               _capture_slider.set_sensitive (false);
-                               _buffering_presets_combo.set_active (2);
-                               break;
-                       case Custom:
-                               _playback_slider.set_sensitive (true);
-                               _capture_slider.set_sensitive (true);
-                               _buffering_presets_combo.set_active (3);
-                               break;
+               void parameter_changed (string const & p)
+               {
+                       if (p == "buffering-preset") {
+                               switch (_rc_config->get_buffering_preset()) {
+                                       case Small:
+                                               _playback_slider.set_sensitive (false);
+                                               _capture_slider.set_sensitive (false);
+                                               _buffering_presets_combo.set_active (0);
+                                               break;
+                                       case Medium:
+                                               _playback_slider.set_sensitive (false);
+                                               _capture_slider.set_sensitive (false);
+                                               _buffering_presets_combo.set_active (1);
+                                               break;
+                                       case Large:
+                                               _playback_slider.set_sensitive (false);
+                                               _capture_slider.set_sensitive (false);
+                                               _buffering_presets_combo.set_active (2);
+                                               break;
+                                       case Custom:
+                                               _playback_slider.set_sensitive (true);
+                                               _capture_slider.set_sensitive (true);
+                                               _buffering_presets_combo.set_active (3);
+                                               break;
+                               }
                        }
-               }
 
-               if (p == "playback-buffer-seconds") {
-                       _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
-               } else if (p == "capture-buffer-seconds") {
-                       _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
-                }
-       }
+                       if (p == "playback-buffer-seconds") {
+                               _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
+                       } else if (p == "capture-buffer-seconds") {
+                               _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
+                       }
+               }
 
-       void set_state_from_config ()
-       {
-               parameter_changed ("buffering-preset");
-               parameter_changed ("playback-buffer-seconds");
-               parameter_changed ("capture-buffer-seconds");
-       }
+               void set_state_from_config ()
+               {
+                       parameter_changed ("buffering-preset");
+                       parameter_changed ("playback-buffer-seconds");
+                       parameter_changed ("capture-buffer-seconds");
+               }
 
-private:
+       private:
 
-       void preset_changed ()
-       {
-               int index = _buffering_presets_combo.get_active_row_number ();
-               if (index < 0) {
-                       return;
-               }
-               switch (index) {
-               case 0:
-                       _rc_config->set_buffering_preset (Small);
-                       break;
-               case 1:
-                       _rc_config->set_buffering_preset (Medium);
-                       break;
-               case 2:
-                       _rc_config->set_buffering_preset (Large);
-                       break;
-               case 3:
-                       _rc_config->set_buffering_preset (Custom);
-                       break;
-               default:
-                       error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
-                       break;
+               void preset_changed ()
+               {
+                       int index = _buffering_presets_combo.get_active_row_number ();
+                       if (index < 0) {
+                               return;
+                       }
+                       switch (index) {
+                               case 0:
+                                       _rc_config->set_buffering_preset (Small);
+                                       break;
+                               case 1:
+                                       _rc_config->set_buffering_preset (Medium);
+                                       break;
+                               case 2:
+                                       _rc_config->set_buffering_preset (Large);
+                                       break;
+                               case 3:
+                                       _rc_config->set_buffering_preset (Custom);
+                                       break;
+                               default:
+                                       error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
+                                       break;
+                       }
                }
-       }
 
-       void playback_changed ()
-       {
-               _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
-       }
+               void playback_changed ()
+               {
+                       _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
+               }
 
-       void capture_changed ()
-       {
-               _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
-       }
+               void capture_changed ()
+               {
+                       _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
+               }
 
-       RCConfiguration* _rc_config;
-       Adjustment _playback_adjustment;
-       Adjustment _capture_adjustment;
-       HScale _playback_slider;
-       HScale _capture_slider;
-       ComboBoxText _buffering_presets_combo;
+               RCConfiguration* _rc_config;
+               Adjustment _playback_adjustment;
+               Adjustment _capture_adjustment;
+               HScale _playback_slider;
+               HScale _capture_slider;
+               ComboBoxText _buffering_presets_combo;
 };
 
-class ControlSurfacesOptions : public OptionEditorBox
+class ControlSurfacesOptions : public OptionEditorPageBox
 {
-public:
-       ControlSurfacesOptions ()
-               : _ignore_view_change (0)
-       {
-               _store = ListStore::create (_model);
-               _view.set_model (_store);
-               _view.append_column (_("Control Surface Protocol"), _model.name);
-               _view.get_column(0)->set_resizable (true);
-               _view.get_column(0)->set_expand (true);
-               _view.append_column_editable (_("Enabled"), _model.enabled);
-               _view.append_column_editable (_("Feedback"), _model.feedback);
-
-               _box->pack_start (_view, false, false);
-
-               Gtk::HBox* edit_box = manage (new Gtk::HBox);
-               edit_box->set_spacing(3);
-               _box->pack_start (*edit_box, false, false);
-               edit_box->show ();
-               
-               Label* label = manage (new Label);
-               label->set_text (_("Click to edit the settings for selected protocol ( it must be ENABLED first ):"));
-               edit_box->pack_start (*label, false, false);
-               label->show ();
-
-               edit_button = manage (new Button(_("Show Protocol Settings")));
-               edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
-               edit_box->pack_start (*edit_button, true, true);
-               edit_button->set_sensitive (false);
-               edit_button->show ();
-
-               ControlProtocolManager& m = ControlProtocolManager::instance ();
-               m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
-                                               boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
-
-               _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
-               _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
-               _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
-       }
-
-       void parameter_changed (std::string const &)
-       {
+       public:
+               ControlSurfacesOptions ()
+                       : _ignore_view_change (0)
+               {
+                       _store = ListStore::create (_model);
+                       _view.set_model (_store);
+                       _view.append_column (_("Control Surface Protocol"), _model.name);
+                       _view.get_column(0)->set_resizable (true);
+                       _view.get_column(0)->set_expand (true);
+                       _view.append_column_editable (_("Enable"), _model.enabled);
+
+                       Label* l = manage (new Label (string_compose ("<b>%1</b>", _("Control Surfaces"))));
+                       l->set_alignment (0, 0.5);
+                       l->set_use_markup (true);
+                       _box->pack_start (*l, false, false);
+                       _box->pack_start (_view, false, false);
+
+                       Gtk::HBox* edit_box = manage (new Gtk::HBox);
+                       edit_box->set_spacing(3);
+                       _box->pack_start (*edit_box, false, false);
+                       edit_box->show ();
+
+                       Label* label = manage (new Label);
+                       label->set_text (_("Edit the settings for selected protocol (it must be ENABLED first):"));
+                       edit_box->pack_start (*label, false, false);
+                       label->show ();
+
+                       edit_button = manage (new Button(_("Show Protocol Settings")));
+                       edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
+                       edit_box->pack_start (*edit_button, true, true);
+                       edit_button->set_sensitive (false);
+                       edit_button->show ();
 
-       }
+                       ControlProtocolManager& m = ControlProtocolManager::instance ();
+                       m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
+                                       boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
 
-       void set_state_from_config ()
-       {
-               _store->clear ();
+                       _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
+                       _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
+                       _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
+               }
 
-               ControlProtocolManager& m = ControlProtocolManager::instance ();
-               for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
+               void parameter_changed (std::string const &)
+               {
 
-                       if (!(*i)->mandatory) {
-                               TreeModel::Row r = *_store->append ();
-                               r[_model.name] = (*i)->name;
-                               r[_model.enabled] = ((*i)->protocol || (*i)->requested);
-                               r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
-                               r[_model.protocol_info] = *i;
-                       }
                }
-       }
-
-private:
 
-        void protocol_status_changed (ControlProtocolInfo* cpi) {
-               /* find the row */
-               TreeModel::Children rows = _store->children();
+               void set_state_from_config ()
+               {
+                       _store->clear ();
 
-               for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
-                       string n = ((*x)[_model.name]);
+                       ControlProtocolManager& m = ControlProtocolManager::instance ();
+                       for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
 
-                       if ((*x)[_model.protocol_info] == cpi) {
-                               _ignore_view_change++;
-                               (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
-                               _ignore_view_change--;
-                               break;
+                               if (!(*i)->mandatory) {
+                                       TreeModel::Row r = *_store->append ();
+                                       r[_model.name] = (*i)->name;
+                                       r[_model.enabled] = ((*i)->protocol || (*i)->requested);
+                                       r[_model.protocol_info] = *i;
+                               }
                        }
                }
-       }
 
-       void selection_changed ()
-       {
-               //enable the Edit button when a row is selected for editing
-               TreeModel::Row row = *(_view.get_selection()->get_selected());
-               if (row && row[_model.enabled])
-                       edit_button->set_sensitive (true);
-               else
-                       edit_button->set_sensitive (false);
-       }
-       
-       void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
-       {
-               TreeModel::Row r = *i;
+       private:
 
-               if (_ignore_view_change) {
-                       return;
-               }
+               void protocol_status_changed (ControlProtocolInfo* cpi) {
+                       /* find the row */
+                       TreeModel::Children rows = _store->children();
+
+                       for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
+                               string n = ((*x)[_model.name]);
 
-               ControlProtocolInfo* cpi = r[_model.protocol_info];
-               if (!cpi) {
-                       return;
+                               if ((*x)[_model.protocol_info] == cpi) {
+                                       _ignore_view_change++;
+                                       (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
+                                       _ignore_view_change--;
+                                       break;
+                               }
+                       }
                }
 
-               bool const was_enabled = (cpi->protocol != 0);
-               bool const is_enabled = r[_model.enabled];
+               void selection_changed ()
+               {
+                       //enable the Edit button when a row is selected for editing
+                       TreeModel::Row row = *(_view.get_selection()->get_selected());
+                       if (row && row[_model.enabled])
+                               edit_button->set_sensitive (true);
+                       else
+                               edit_button->set_sensitive (false);
+               }
 
+               void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
+               {
+                       TreeModel::Row r = *i;
 
-               if (was_enabled != is_enabled) {
+                       if (_ignore_view_change) {
+                               return;
+                       }
 
-                       if (!was_enabled) {
-                               ControlProtocolManager::instance().activate (*cpi);
-                       } else {
-                               ControlProtocolManager::instance().deactivate (*cpi);
+                       ControlProtocolInfo* cpi = r[_model.protocol_info];
+                       if (!cpi) {
+                               return;
                        }
-               }
 
-               bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
-               bool const is_feedback = r[_model.feedback];
+                       bool const was_enabled = (cpi->protocol != 0);
+                       bool const is_enabled = r[_model.enabled];
 
-               if (was_feedback != is_feedback && cpi->protocol) {
-                       cpi->protocol->set_feedback (is_feedback);
-               }
-       }
 
-       void edit_btn_clicked ()
-       {
-               std::string name;
-               ControlProtocolInfo* cpi;
-               TreeModel::Row row;
-
-               row = *(_view.get_selection()->get_selected());
-               if (!row[_model.enabled]) {
-                       return;
-               }
-               cpi = row[_model.protocol_info];
-               if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
-                       return;
-               }
-               Box* box = (Box*) cpi->protocol->get_gui ();
-               if (!box) {
-                       return;
-               }
-               if (box->get_parent()) {
-                       static_cast<ArdourWindow*>(box->get_parent())->present();
-                       return;
-               }
-               WindowTitle title (Glib::get_application_name());
-               title += row[_model.name];
-               title += _("Configuration");
-               /* once created, the window is managed by the surface itself (as ->get_parent())
-                * Surface's tear_down_gui() is called on session close, when de-activating
-                * or re-initializing a surface.
-                * tear_down_gui() hides an deletes the Window if it exists.
-                */
-               ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
-               win->set_title ("Control Protocol Options");
-               win->add (*box);
-               box->show ();
-               win->present ();
-       }
-
-       void edit_clicked (GdkEventButton* ev)
-       {
-               if (ev->type != GDK_2BUTTON_PRESS) {
-                       return;
-               }
+                       if (was_enabled != is_enabled) {
 
-               edit_btn_clicked();
-       }
+                               if (!was_enabled) {
+                                       ControlProtocolManager::instance().activate (*cpi);
+                               } else {
+                                       ControlProtocolManager::instance().deactivate (*cpi);
+                               }
+                       }
 
-        class ControlSurfacesModelColumns : public TreeModelColumnRecord
-       {
-       public:
+                       selection_changed ();
+               }
 
-               ControlSurfacesModelColumns ()
+               void edit_btn_clicked ()
                {
-                       add (name);
-                       add (enabled);
-                       add (feedback);
-                       add (protocol_info);
-               }
+                       std::string name;
+                       ControlProtocolInfo* cpi;
+                       TreeModel::Row row;
 
-               TreeModelColumn<string> name;
-               TreeModelColumn<bool> enabled;
-               TreeModelColumn<bool> feedback;
-               TreeModelColumn<ControlProtocolInfo*> protocol_info;
-       };
+                       row = *(_view.get_selection()->get_selected());
+                       if (!row[_model.enabled]) {
+                               return;
+                       }
+                       cpi = row[_model.protocol_info];
+                       if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
+                               return;
+                       }
+                       Box* box = (Box*) cpi->protocol->get_gui ();
+                       if (!box) {
+                               return;
+                       }
+                       if (box->get_parent()) {
+                               static_cast<ArdourWindow*>(box->get_parent())->present();
+                               return;
+                       }
+                       WindowTitle title (Glib::get_application_name());
+                       title += row[_model.name];
+                       title += _("Configuration");
+                       /* once created, the window is managed by the surface itself (as ->get_parent())
+                        * Surface's tear_down_gui() is called on session close, when de-activating
+                        * or re-initializing a surface.
+                        * tear_down_gui() hides an deletes the Window if it exists.
+                        */
+                       ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
+                       win->set_title ("Control Protocol Options");
+                       win->add (*box);
+                       box->show ();
+                       win->present ();
+               }
+
+               void edit_clicked (GdkEventButton* ev)
+               {
+                       if (ev->type != GDK_2BUTTON_PRESS) {
+                               return;
+                       }
 
-       Glib::RefPtr<ListStore> _store;
-       ControlSurfacesModelColumns _model;
-       TreeView _view;
-        PBD::ScopedConnection protocol_status_connection;
-        uint32_t _ignore_view_change;
-       Gtk::Button* edit_button;
-};
+                       edit_btn_clicked();
+               }
 
-class VideoTimelineOptions : public OptionEditorBox
-{
-public:
-       VideoTimelineOptions (RCConfiguration* c)
-               : _rc_config (c)
-               , _show_video_export_info_button (_("Show Video Export Info before export"))
-               , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
-               , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
-               , _xjadeo_browse_button (_("Browse..."))
+               class ControlSurfacesModelColumns : public TreeModelColumnRecord
        {
-               Table* t = manage (new Table (8, 4));
-               t->set_spacings (4);
+               public:
 
-               std::stringstream s;
-               s << "<b>" << _("Video Server") << "</b>";
-               Label* l = manage (new Label (s.str()));
-               l->set_use_markup (true);
-               l->set_alignment (0, 0.5);
-               t->attach (*l, 0, 4, 0, 1, EXPAND | FILL, FILL | EXPAND, 0, 8);
+                       ControlSurfacesModelColumns ()
+                       {
+                               add (name);
+                               add (enabled);
+                               add (protocol_info);
+                       }
 
-               t->attach (_video_advanced_setup_button, 1, 4, 1, 2);
-               _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
-               Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
-                                           _("<b>When enabled</b> you can speficify a custom video-server URL and docroot. - Do not enable this option unless you know what you are doing."));
+                       TreeModelColumn<string> name;
+                       TreeModelColumn<bool> enabled;
+                       TreeModelColumn<ControlProtocolInfo*> protocol_info;
+       };
 
-               l = manage (new Label (_("Video Server URL:")));
-               l->set_alignment (0, 0.5);
-               t->attach (*l, 1, 2, 2, 3, FILL);
-               t->attach (_video_server_url_entry, 2, 4, 2, 3, FILL);
-               Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
-                                           _("Base URL of the video-server including http prefix. This is usually 'http://hostname.example.org:1554/' and defaults to 'http://localhost:1554/' when the video-server is running locally"));
+               Glib::RefPtr<ListStore> _store;
+               ControlSurfacesModelColumns _model;
+               TreeView _view;
+               PBD::ScopedConnection protocol_status_connection;
+               uint32_t _ignore_view_change;
+               Gtk::Button* edit_button;
+};
 
-               l = manage (new Label (_("Video Folder:")));
-               l->set_alignment (0, 0.5);
-               t->attach (*l, 1, 2, 3, 4, FILL);
-               t->attach (_video_server_docroot_entry, 2, 4, 3, 4);
-               Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
-                                           _("Local path to the video-server document-root. Only files below this directory will be accessible by the video-server. If the server run on a remote host, it should point to a network mounted folder of the server's docroot or be left empty if it is unvailable. It is used for the local video-monitor and file-browsing when opening/adding a video file."));
-
-               t->attach (_show_video_export_info_button, 1, 4, 4, 5);
-               _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
-               Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
-                                           _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
-
-               t->attach (_show_video_server_dialog_button, 1, 4, 5, 6);
-               _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
-               Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
-                                           _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
-
-               s.str (std::string ());
-               s << "<b>" << _("Video Monitor") << "</b>";
-               l = manage (new Label (s.str()));
-               l->set_use_markup (true);
-               l->set_alignment (0, 0.5);
-               t->attach (*l, 0, 4, 6, 7, EXPAND | FILL, FILL | EXPAND, 0, 8);
-
-               l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"),
+class VideoTimelineOptions : public OptionEditorPageBox, public OptionEditorPage
+{
+       public:
+               VideoTimelineOptions (RCConfiguration* c)
+                       : _rc_config (c)
+                       , _show_video_export_info_button (_("Show Video Export Info before export"))
+                       , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
+                       , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
+                       , _xjadeo_browse_button (_("Browse..."))
+               {
+                       Table* t = &table;
+
+                       Label* l = manage (new Label (string_compose ("<b>%1</b>", _("Video Server"))));
+                       l->set_use_markup (true);
+                       l->set_alignment (0, 0.5);
+                       t->attach (*l, 0, 4, 0, 1, EXPAND | FILL, FILL | EXPAND, 0, 0);
+
+                       t->attach (_show_video_export_info_button, 1, 4, 1, 2);
+                       _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
+                       Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
+                                       _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
+
+                       t->attach (_show_video_server_dialog_button, 1, 4, 2, 3);
+                       _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
+                       Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
+                                       _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
+
+                       t->attach (_video_advanced_setup_button, 1, 4, 3, 4, FILL);
+                       _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
+                       Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
+                                       _("<b>When enabled</b> you can speficify a custom video-server URL and docroot. - Do not enable this option unless you know what you are doing."));
+
+                       l = manage (new Label (_("Video Server URL:")));
+                       l->set_alignment (0, 0.5);
+                       t->attach (*l, 1, 2, 4, 5, FILL);
+                       t->attach (_video_server_url_entry, 2, 4, 4, 5, FILL);
+                       Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
+                                       _("Base URL of the video-server including http prefix. This is usually 'http://hostname.example.org:1554/' and defaults to 'http://localhost:1554/' when the video-server is running locally"));
+
+                       l = manage (new Label (_("Video Folder:")));
+                       l->set_alignment (0, 0.5);
+                       t->attach (*l, 1, 2, 5, 6, FILL);
+                       t->attach (_video_server_docroot_entry, 2, 4, 5, 6);
+                       Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
+                                       _("Local path to the video-server document-root. Only files below this directory will be accessible by the video-server. If the server run on a remote host, it should point to a network mounted folder of the server's docroot or be left empty if it is unvailable. It is used for the local video-monitor and file-browsing when opening/adding a video file."));
+
+                       l = manage (new Label (""));
+                       t->attach (*l, 0, 4, 6, 7, EXPAND | FILL);
+
+                       l = manage (new Label (string_compose ("<b>%1</b>", _("Video Monitor"))));
+                       l->set_use_markup (true);
+                       l->set_alignment (0, 0.5);
+                       t->attach (*l, 0, 4, 7, 8, EXPAND | FILL);
+
+                       l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"),
 #ifdef __APPLE__
-                                               "Jadeo.app"
+                                                       "Jadeo.app"
 #elif defined PLATFORM_WINDOWS
-                                               "xjadeo.exe"
+                                                       "xjadeo.exe"
 #else
-                                               "xjadeo"
+                                                       "xjadeo"
 #endif
-                                               )));
-               l->set_alignment (0, 0.5);
-               t->attach (*l, 1, 4, 7, 8, FILL);
-               t->attach (_custom_xjadeo_path, 2, 3, 8, 9);
-               Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart."));
-               t->attach (_xjadeo_browse_button, 3, 4, 8, 9, FILL);
+                                                       )));
+                       l->set_alignment (0, 0.5);
+                       t->attach (*l, 1, 4, 8, 9, FILL);
+                       t->attach (_custom_xjadeo_path, 2, 3, 9, 10, EXPAND|FILL);
+                       Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart."));
+                       t->attach (_xjadeo_browse_button, 3, 4, 9, 10, FILL);
 
-               _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
-               _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
-               _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
-               _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
-               _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed));
-               _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked));
+                       _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
+                       _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
+                       _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
+                       _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
+                       _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed));
+                       _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked));
 
-               // xjadeo-path is a UIConfig parameter
-               UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &VideoTimelineOptions::parameter_changed));
+                       // xjadeo-path is a UIConfig parameter
+                       UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &VideoTimelineOptions::parameter_changed));
 
-               _box->pack_start (*t,true,true);
-       }
+                       _box->pack_start (*t, true, true);
+               }
 
-       void server_url_changed ()
-       {
-               _rc_config->set_video_server_url (_video_server_url_entry.get_text());
-       }
+               void server_url_changed ()
+               {
+                       _rc_config->set_video_server_url (_video_server_url_entry.get_text());
+               }
 
-       void server_docroot_changed ()
-       {
-               _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
-       }
+               void server_docroot_changed ()
+               {
+                       _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
+               }
 
-       void show_video_export_info_toggled ()
-       {
-               bool const x = _show_video_export_info_button.get_active ();
-               _rc_config->set_show_video_export_info (x);
-       }
+               void show_video_export_info_toggled ()
+               {
+                       bool const x = _show_video_export_info_button.get_active ();
+                       _rc_config->set_show_video_export_info (x);
+               }
 
-       void show_video_server_dialog_toggled ()
-       {
-               bool const x = _show_video_server_dialog_button.get_active ();
-               _rc_config->set_show_video_server_dialog (x);
-       }
+               void show_video_server_dialog_toggled ()
+               {
+                       bool const x = _show_video_server_dialog_button.get_active ();
+                       _rc_config->set_show_video_server_dialog (x);
+               }
 
-       void video_advanced_setup_toggled ()
-       {
-               bool const x = _video_advanced_setup_button.get_active ();
-               _rc_config->set_video_advanced_setup(x);
-       }
+               void video_advanced_setup_toggled ()
+               {
+                       bool const x = _video_advanced_setup_button.get_active ();
+                       _rc_config->set_video_advanced_setup(x);
+               }
 
-       void custom_xjadeo_path_changed ()
-       {
-               UIConfiguration::instance().set_xjadeo_binary (_custom_xjadeo_path.get_text());
-       }
+               void custom_xjadeo_path_changed ()
+               {
+                       UIConfiguration::instance().set_xjadeo_binary (_custom_xjadeo_path.get_text());
+               }
 
-       void xjadeo_browse_clicked ()
-       {
-               Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN);
-               dialog.set_filename (UIConfiguration::instance().get_xjadeo_binary());
-               dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
-               dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
-               if (dialog.run () == Gtk::RESPONSE_OK) {
-                       const std::string& filename = dialog.get_filename();
-                       if (!filename.empty() && (
+               void xjadeo_browse_clicked ()
+               {
+                       Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN);
+                       dialog.set_filename (UIConfiguration::instance().get_xjadeo_binary());
+                       dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
+                       dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
+                       if (dialog.run () == Gtk::RESPONSE_OK) {
+                               const std::string& filename = dialog.get_filename();
+                               if (!filename.empty() && (
 #ifdef __APPLE__
-                                       Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) ||
+                                                       Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) ||
 #endif
-                                       Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)
-                                       )) {
-                               UIConfiguration::instance().set_xjadeo_binary (filename);
+                                                       Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)
+                                                       )) {
+                                       UIConfiguration::instance().set_xjadeo_binary (filename);
+                               }
                        }
                }
-       }
 
-       void parameter_changed (string const & p)
-       {
-               if (p == "video-server-url") {
-                       _video_server_url_entry.set_text (_rc_config->get_video_server_url());
-               } else if (p == "video-server-docroot") {
-                       _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
-               } else if (p == "show-video-export-info") {
-                       bool const x = _rc_config->get_show_video_export_info();
-                       _show_video_export_info_button.set_active (x);
-               } else if (p == "show-video-server-dialog") {
-                       bool const x = _rc_config->get_show_video_server_dialog();
-                       _show_video_server_dialog_button.set_active (x);
-               } else if (p == "video-advanced-setup") {
-                       bool const x = _rc_config->get_video_advanced_setup();
-                       _video_advanced_setup_button.set_active(x);
-                       _video_server_docroot_entry.set_sensitive(x);
-                       _video_server_url_entry.set_sensitive(x);
-               } else if (p == "xjadeo-binary") {
-                       _custom_xjadeo_path.set_text (UIConfiguration::instance().get_xjadeo_binary());
+               void parameter_changed (string const & p)
+               {
+                       if (p == "video-server-url") {
+                               _video_server_url_entry.set_text (_rc_config->get_video_server_url());
+                       } else if (p == "video-server-docroot") {
+                               _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
+                       } else if (p == "show-video-export-info") {
+                               bool const x = _rc_config->get_show_video_export_info();
+                               _show_video_export_info_button.set_active (x);
+                       } else if (p == "show-video-server-dialog") {
+                               bool const x = _rc_config->get_show_video_server_dialog();
+                               _show_video_server_dialog_button.set_active (x);
+                       } else if (p == "video-advanced-setup") {
+                               bool const x = _rc_config->get_video_advanced_setup();
+                               _video_advanced_setup_button.set_active(x);
+                               _video_server_docroot_entry.set_sensitive(x);
+                               _video_server_url_entry.set_sensitive(x);
+                       } else if (p == "xjadeo-binary") {
+                               _custom_xjadeo_path.set_text (UIConfiguration::instance().get_xjadeo_binary());
+                       }
                }
-       }
 
-       void set_state_from_config ()
-       {
-               parameter_changed ("video-server-url");
-               parameter_changed ("video-server-docroot");
-               parameter_changed ("video-monitor-setup-dialog");
-               parameter_changed ("show-video-export-info");
-               parameter_changed ("show-video-server-dialog");
-               parameter_changed ("video-advanced-setup");
-               parameter_changed ("xjadeo-binary");
-       }
+               void set_state_from_config ()
+               {
+                       parameter_changed ("video-server-url");
+                       parameter_changed ("video-server-docroot");
+                       parameter_changed ("video-monitor-setup-dialog");
+                       parameter_changed ("show-video-export-info");
+                       parameter_changed ("show-video-server-dialog");
+                       parameter_changed ("video-advanced-setup");
+                       parameter_changed ("xjadeo-binary");
+               }
 
-private:
-       RCConfiguration* _rc_config;
-       Entry _video_server_url_entry;
-       Entry _video_server_docroot_entry;
-       Entry _custom_xjadeo_path;
-       CheckButton _show_video_export_info_button;
-       CheckButton _show_video_server_dialog_button;
-       CheckButton _video_advanced_setup_button;
-       Button _xjadeo_browse_button;
+       private:
+               RCConfiguration* _rc_config;
+               Entry _video_server_url_entry;
+               Entry _video_server_docroot_entry;
+               Entry _custom_xjadeo_path;
+               CheckButton _show_video_export_info_button;
+               CheckButton _show_video_server_dialog_button;
+               CheckButton _video_advanced_setup_button;
+               Button _xjadeo_browse_button;
 };
 
 class ColumVisibilityOption : public Option
@@ -1827,7 +1838,7 @@ public:
                add_widget_to_page (p, _visibility_group->list_view ());
        }
 
-        Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
+       Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
 
 private:
        void changed ()
@@ -1846,43 +1857,342 @@ private:
 };
 
 
+class MidiPortOptions : public OptionEditorPageBox, public sigc::trackable
+{
+       public:
+               MidiPortOptions() {
+
+                       setup_midi_port_view (midi_output_view, false);
+                       setup_midi_port_view (midi_input_view, true);
+
+
+                       _box->pack_start (*manage (new Label("")), false, false);
+                       input_label.set_markup (string_compose ("<span size=\"large\" weight=\"bold\">%1</span>", _("MIDI Inputs")));
+                       _box->pack_start (input_label, false, false);
+
+                       Gtk::ScrolledWindow* scroller = manage (new Gtk::ScrolledWindow);
+                       scroller->add (midi_input_view);
+                       scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
+                       scroller->set_size_request (-1, 180);
+                       _box->pack_start (*scroller, false, false);
+
+                       _box->pack_start (*manage (new Label("")), false, false);
+                       output_label.set_markup (string_compose ("<span size=\"large\" weight=\"bold\">%1</span>", _("MIDI Outputs")));
+                       _box->pack_start (output_label, false, false);
+
+                       scroller = manage (new Gtk::ScrolledWindow);
+                       scroller->add (midi_output_view);
+                       scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
+                       scroller->set_size_request (-1, 180);
+                       _box->pack_start (*scroller, false, false);
+
+                       midi_output_view.show ();
+                       midi_input_view.show ();
+
+                       _box->signal_show().connect (sigc::mem_fun (*this, &MidiPortOptions::on_show));
+               }
+
+               void parameter_changed (string const&) {}
+               void set_state_from_config() {}
+
+               void on_show () {
+                       refill ();
+
+                       AudioEngine::instance()->PortRegisteredOrUnregistered.connect (connections,
+                                       invalidator (*this),
+                                       boost::bind (&MidiPortOptions::refill, this),
+                                       gui_context());
+                       AudioEngine::instance()->MidiPortInfoChanged.connect (connections,
+                                       invalidator (*this),
+                                       boost::bind (&MidiPortOptions::refill, this),
+                                       gui_context());
+                       AudioEngine::instance()->MidiSelectionPortsChanged.connect (connections,
+                                       invalidator (*this),
+                                       boost::bind (&MidiPortOptions::refill, this),
+                                       gui_context());
+               }
+
+               void refill () {
+
+                       if (refill_midi_ports (true, midi_input_view)) {
+                               input_label.show ();
+                       } else {
+                               input_label.hide ();
+                       }
+                       if (refill_midi_ports (false, midi_output_view)) {
+                               output_label.show ();
+                       } else {
+                               output_label.hide ();
+                       }
+               }
+
+       private:
+               PBD::ScopedConnectionList connections;
+
+               /* MIDI port management */
+               struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord {
+
+                       MidiPortColumns () {
+                               add (pretty_name);
+                               add (music_data);
+                               add (control_data);
+                               add (selection);
+                               add (name);
+                               add (filler);
+                       }
+
+                       Gtk::TreeModelColumn<std::string> pretty_name;
+                       Gtk::TreeModelColumn<bool> music_data;
+                       Gtk::TreeModelColumn<bool> control_data;
+                       Gtk::TreeModelColumn<bool> selection;
+                       Gtk::TreeModelColumn<std::string> name;
+                       Gtk::TreeModelColumn<std::string> filler;
+               };
+
+               MidiPortColumns midi_port_columns;
+               Gtk::TreeView midi_input_view;
+               Gtk::TreeView midi_output_view;
+               Gtk::Label input_label;
+               Gtk::Label output_label;
+
+               void setup_midi_port_view (Gtk::TreeView&, bool with_selection);
+               bool refill_midi_ports (bool for_input, Gtk::TreeView&);
+               void pretty_name_edit (std::string const & path, std::string const & new_text, Gtk::TreeView*);
+               void midi_music_column_toggled (std::string const & path, Gtk::TreeView*);
+               void midi_control_column_toggled (std::string const & path, Gtk::TreeView*);
+               void midi_selection_column_toggled (std::string const & path, Gtk::TreeView*);
+};
+
+void
+MidiPortOptions::setup_midi_port_view (Gtk::TreeView& view, bool with_selection)
+{
+       int pretty_name_column;
+       int music_column;
+       int control_column;
+       int selection_column;
+       TreeViewColumn* col;
+       Gtk::Label* l;
+
+       pretty_name_column = view.append_column_editable (_("Name (click to edit)"), midi_port_columns.pretty_name) - 1;
+
+       col = manage (new TreeViewColumn ("", midi_port_columns.music_data));
+       col->set_alignment (ALIGN_CENTER);
+       l = manage (new Label (_("Music Data")));
+       set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of music performance data."), PROGRAM_NAME));
+       col->set_widget (*l);
+       l->show ();
+       music_column = view.append_column (*col) - 1;
+
+       col = manage (new TreeViewColumn ("", midi_port_columns.control_data));
+       col->set_alignment (ALIGN_CENTER);
+       l = manage (new Label (_("Control Data")));
+       set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of control data."), PROGRAM_NAME));
+       col->set_widget (*l);
+       l->show ();
+       control_column = view.append_column (*col) - 1;
+
+       if (with_selection) {
+               col = manage (new TreeViewColumn (_("Follow Selection"), midi_port_columns.selection));
+               selection_column = view.append_column (*col) - 1;
+               l = manage (new Label (_("Follow Selection")));
+               set_tooltip (*l, string_compose (_("If ticked, and \"MIDI input follows selection\" is enabled,\n%1 will automatically connect the first selected MIDI track to this port.\n"), PROGRAM_NAME));
+               col->set_widget (*l);
+               l->show ();
+       }
+
+       /* filler column so that the last real column doesn't expand */
+       view.append_column ("", midi_port_columns.filler);
+
+       CellRendererText* pretty_name_cell = dynamic_cast<CellRendererText*> (view.get_column_cell_renderer (pretty_name_column));
+       pretty_name_cell->property_editable() = true;
+       pretty_name_cell->signal_edited().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::pretty_name_edit), &view));
+
+       CellRendererToggle* toggle_cell;
+
+       toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (music_column));
+       toggle_cell->property_activatable() = true;
+       toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_music_column_toggled), &view));
+
+       toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (control_column));
+       toggle_cell->property_activatable() = true;
+       toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_control_column_toggled), &view));
+
+       if (with_selection) {
+               toggle_cell = dynamic_cast<CellRendererToggle*> (view.get_column_cell_renderer (selection_column));
+               toggle_cell->property_activatable() = true;
+               toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_selection_column_toggled), &view));
+       }
+
+       view.get_selection()->set_mode (SELECTION_NONE);
+       view.set_tooltip_column (4); /* port "real" name */
+       view.get_column(0)->set_resizable (true);
+       view.get_column(0)->set_expand (true);
+}
+
+bool
+MidiPortOptions::refill_midi_ports (bool for_input, Gtk::TreeView& view)
+{
+       using namespace ARDOUR;
+
+       std::vector<string> ports;
+
+       AudioEngine::instance()->get_known_midi_ports (ports);
+
+       if (ports.empty()) {
+               view.hide ();
+               return false;
+       }
+
+       Glib::RefPtr<ListStore> model = Gtk::ListStore::create (midi_port_columns);
+
+       for (vector<string>::const_iterator s = ports.begin(); s != ports.end(); ++s) {
+
+               if (AudioEngine::instance()->port_is_mine (*s)) {
+                       continue;
+               }
+
+               PortManager::MidiPortInformation mpi (AudioEngine::instance()->midi_port_information (*s));
+
+               if (mpi.pretty_name.empty()) {
+                       /* vanished since get_known_midi_ports() */
+                       continue;
+               }
+
+               if (for_input != mpi.input) {
+                       continue;
+               }
+
+               TreeModel::Row row = *(model->append());
+
+               row[midi_port_columns.pretty_name] = mpi.pretty_name;
+               row[midi_port_columns.music_data] = mpi.properties & MidiPortMusic;
+               row[midi_port_columns.control_data] = mpi.properties & MidiPortControl;
+               row[midi_port_columns.selection] = mpi.properties & MidiPortSelection;
+               row[midi_port_columns.name] = *s;
+       }
+
+       view.set_model (model);
+
+       return true;
+}
+
+void
+MidiPortOptions::midi_music_column_toggled (string const & path, TreeView* view)
+{
+       TreeIter iter = view->get_model()->get_iter (path);
+
+       if (!iter) {
+               return;
+       }
+
+       bool new_value = ! bool ((*iter)[midi_port_columns.music_data]);
+
+       /* don't reset model - wait for MidiPortInfoChanged signal */
+
+       if (new_value) {
+               ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
+       } else {
+               ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic);
+       }
+}
+
+void
+MidiPortOptions::midi_control_column_toggled (string const & path, TreeView* view)
+{
+       TreeIter iter = view->get_model()->get_iter (path);
+
+       if (!iter) {
+               return;
+       }
+
+       bool new_value = ! bool ((*iter)[midi_port_columns.control_data]);
+
+       /* don't reset model - wait for MidiPortInfoChanged signal */
+
+       if (new_value) {
+               ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
+       } else {
+               ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl);
+       }
+}
+
+void
+MidiPortOptions::midi_selection_column_toggled (string const & path, TreeView* view)
+{
+       TreeIter iter = view->get_model()->get_iter (path);
+
+       if (!iter) {
+               return;
+       }
+
+       bool new_value = ! bool ((*iter)[midi_port_columns.selection]);
+
+       /* don't reset model - wait for MidiSelectionPortsChanged signal */
+
+       if (new_value) {
+               ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
+       } else {
+               ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection);
+       }
+}
+
+void
+MidiPortOptions::pretty_name_edit (std::string const & path, string const & new_text, Gtk::TreeView* view)
+{
+       TreeIter iter = view->get_model()->get_iter (path);
+
+       if (!iter) {
+               return;
+       }
+
+       boost::shared_ptr<ARDOUR::AudioBackend> backend = ARDOUR::AudioEngine::instance()->current_backend();
+       if (backend) {
+               ARDOUR::PortEngine::PortHandle ph = backend->get_port_by_name ((*iter)[midi_port_columns.name]);
+               if (ph) {
+                       backend->set_port_property (ph, "http://jackaudio.org/metadata/pretty-name", new_text, "");
+                       (*iter)[midi_port_columns.pretty_name] = new_text;
+               }
+       }
+}
+
+/*============*/
+
 
 RCOptionEditor::RCOptionEditor ()
        : OptionEditorContainer (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
        , Tabbable (*this, _("Preferences")) /* pack self-as-vbox into tabbable */
-        , _rc_config (Config)
+       , _rc_config (Config)
        , _mixer_strip_visibility ("mixer-element-visibility")
 {
-
        UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
 
        /* MISC */
 
-        uint32_t hwcpus = hardware_concurrency ();
+       uint32_t hwcpus = hardware_concurrency ();
        BoolOption* bo;
        BoolComboOption* bco;
 
-        if (hwcpus > 1) {
-                add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
+       if (hwcpus > 1) {
+               add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
 
-                ComboOption<int32_t>* procs = new ComboOption<int32_t> (
-                        "processor-usage",
-                        _("Signal processing uses"),
-                        sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
-                        sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
-                        );
+               ComboOption<int32_t>* procs = new ComboOption<int32_t> (
+                               "processor-usage",
+                               _("Signal processing uses"),
+                               sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
+                               sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
+                               );
 
-                procs->add (-1, _("all but one processor"));
-                procs->add (0, _("all available processors"));
+               procs->add (-1, _("all but one processor"));
+               procs->add (0, _("all available processors"));
 
-                for (uint32_t i = 1; i <= hwcpus; ++i) {
-                        procs->add (i, string_compose (_("%1 processors"), i));
-                }
+               for (uint32_t i = 1; i <= hwcpus; ++i) {
+                       procs->add (i, string_compose (P_("%1 processor", "%1 processors", i), i));
+               }
 
                procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
 
-                add_option (_("Misc"), procs);
-        }
+               add_option (_("Misc"), procs);
+       }
 
        add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
 
@@ -1930,17 +2240,9 @@ RCOptionEditor::RCOptionEditor ()
                     0, 1000, 1, 20
                     ));
 
-       add_option (_("Misc"), new OptionEditorHeading (_("Click")));
+       add_option (_("Misc/Click"), new OptionEditorHeading (_("Click")));
 
-       add_option (_("Misc"), new ClickOptions (_rc_config));
-
-       add_option (_("Misc"),
-            new FaderOption (
-                    "click-gain",
-                    _("Click gain level"),
-                    sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
-                    sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
-                    ));
+       add_option (_("Misc/Click"), new ClickOptions (_rc_config));
 
        add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
 
@@ -1962,12 +2264,26 @@ RCOptionEditor::RCOptionEditor ()
                     1, 1000, 1, 20
                     ));
 
+       add_option (_("Misc"), new OptionEditorHeading (_("Tempo")));
+
+       BoolOption* tsf;
+
+       tsf = new BoolOption (
+               "allow-non-quarter-pulse",
+               _("Allow non quarter-note pulse"),
+               sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_allow_non_quarter_pulse),
+               sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_allow_non_quarter_pulse)
+               );
+       Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
+                                           string_compose (_("<b>When enabled</b> %1 will allow tempo to be expressed in divisions per minute\n"
+                                                             "<b>When disabled</b> %1 will only allow tempo to be expressed in quarter notes per minute"),
+                                                           PROGRAM_NAME));
+       add_option (_("Misc"), tsf);
+
        /* TRANSPORT */
 
        add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options")));
 
-       BoolOption* tsf;
-
        tsf = new BoolOption (
                     "latched-record-enable",
                     _("Keep record-enable engaged on stop"),
@@ -2175,7 +2491,7 @@ RCOptionEditor::RCOptionEditor ()
        Gtkmm2ext::UI::instance()->set_tip
                (_ltc_send_continuously->tip_widget(),
                 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
-       add_option (_("Transport"), _ltc_send_continuously);
+       add_option (_("Transport/Sync"), _ltc_send_continuously);
 
        _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
        _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
@@ -2184,12 +2500,14 @@ RCOptionEditor::RCOptionEditor ()
 
        Gtkmm2ext::UI::instance()->set_tip
                (_ltc_volume_slider->tip_widget(),
-                _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is  0dBu ^= -18dbFS in an EBU calibrated system"));
+                _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is  0dBu ^= -18dBFS in an EBU calibrated system"));
 
        add_option (_("Transport/Sync"), _ltc_volume_slider);
 
        /* EDITOR */
 
+       add_option (_("Editor"), new OptionEditorHeading (_("Editor Settings")));
+
        add_option (_("Editor"),
             new BoolOption (
                     "rubberbanding-snaps-to-grid",
@@ -2216,14 +2534,6 @@ RCOptionEditor::RCOptionEditor ()
                     sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
                     ));
 
-       add_option (_("Editor"),
-            new BoolOption (
-                    "show-editor-meter",
-                    _("Display master-meter in the toolbar"),
-                    sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
-                    sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
-                    ));
-
 if (!Profile->get_mixbus()) {
        add_option (_("Editor"),
                    new BoolOption (
@@ -2242,6 +2552,22 @@ if (!Profile->get_mixbus()) {
                            ));
 }  // !mixbus
 
+       add_option (_("Editor"),
+                   new BoolOption (
+                           "use-time-rulers-to-zoom-with-vertical-drag",
+                           _("Use time rulers area to zoom when clicking and dragging vertically"),
+                           sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag),
+                           sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag)
+                           ));
+
+       add_option (_("Editor"),
+                   new BoolOption (
+                           "use-double-click-to-zoom-to-selection",
+                           _("Use double mouse click to zoom to selection"),
+                           sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection),
+                           sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection)
+                           ));
+
        add_option (_("Editor"),
                    new BoolOption (
                            "update-editor-during-summary-drag",
@@ -2296,18 +2622,20 @@ if (!Profile->get_mixbus()) {
 
        add_option (_("Editor"), fadeshape);
 
+#if 1
 
        bco = new BoolComboOption (
                     "use-overlap-equivalency",
-                    _("Regions in active edit groups are edited together"),
+                    _("Regions in edit groups are edited together"),
                     _("whenever they overlap in time"),
-                    _("only if they have identical length, position and origin"),
+                    _("only if they have identical length and position"),
                     sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
                     sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
                     );
 
        add_option (_("Editor"), bco);
 
+#endif
        ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
                "layer-model",
                _("Layering model"),
@@ -2336,11 +2664,11 @@ if (!Profile->get_mixbus()) {
        rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
 
        add_option (_("Editor"), rsas);
-       
-       add_option (_("Editor"), new OptionEditorHeading (_("Waveforms")));
+
+       add_option (_("Editor/Waveforms"), new OptionEditorHeading (_("Waveforms")));
 
 if (!Profile->get_mixbus()) {
-       add_option (_("Editor"),
+       add_option (_("Editor/Waveforms"),
             new BoolOption (
                     "show-waveforms",
                     _("Show waveforms in regions"),
@@ -2349,7 +2677,7 @@ if (!Profile->get_mixbus()) {
                     ));
 }  // !mixbus
 
-       add_option (_("Editor"),
+       add_option (_("Editor/Waveforms"),
             new BoolOption (
                     "show-waveforms-while-recording",
                     _("Show waveforms for audio while it is being recorded"),
@@ -2367,7 +2695,7 @@ if (!Profile->get_mixbus()) {
        wfs->add (Linear, _("linear"));
        wfs->add (Logarithmic, _("logarithmic"));
 
-       add_option (_("Editor"), wfs);
+       add_option (_("Editor/Waveforms"), wfs);
 
        ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
                "waveform-shape",
@@ -2379,9 +2707,9 @@ if (!Profile->get_mixbus()) {
        wfsh->add (Traditional, _("traditional"));
        wfsh->add (Rectified, _("rectified"));
 
-       add_option (_("Editor"), wfsh);
+       add_option (_("Editor/Waveforms"), wfsh);
 
-       add_option (_("Editor"), new ClipLevelOptions ());
+       add_option (_("Editor/Waveforms"), new ClipLevelOptions ());
 
 
        /* AUDIO */
@@ -2399,9 +2727,9 @@ if (!Profile->get_mixbus()) {
                sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
                );
 
-        if (AudioEngine::instance()->port_engine().can_monitor_input()) {
-                mm->add (HardwareMonitoring, _("via Audio Driver"));
-        }
+       if (AudioEngine::instance()->port_engine().can_monitor_input()) {
+               mm->add (HardwareMonitoring, _("via Audio Driver"));
+       }
 
        string prog (PROGRAM_NAME);
        boost::algorithm::to_lower (prog);
@@ -2516,24 +2844,6 @@ if (!Profile->get_mixbus()) {
 
        add_option (_("Audio"), dm);
 
-       add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
-
-       add_option (_("Audio"),
-            new BoolOption (
-                    "plugins-stop-with-transport",
-                    _("Silence plugins when the transport is stopped"),
-                    sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
-                    sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
-                    ));
-
-       add_option (_("Audio"),
-            new BoolOption (
-                    "new-plugins-active",
-                    _("Make new plugins active"),
-                    sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
-                    sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
-                    ));
-
        add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
 
        add_option (_("Audio"),
@@ -2732,9 +3042,21 @@ if (!ARDOUR::Profile->get_mixbus()) {
                            sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
                            ));
 
-       add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Clock")));
+       add_option (_("MIDI/Ports"), new OptionEditorHeading (_("MIDI Port Options")));
 
-       add_option (_("MIDI"),
+       add_option (_("MIDI/Ports"),
+                   new BoolOption (
+                           "get-midi-input-follows-selection",
+                           _("MIDI input follows MIDI track selection"),
+                           sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection),
+                           sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection)
+                           ));
+
+       add_option (_("MIDI/Ports"), new MidiPortOptions ());
+
+       add_option (_("MIDI/Sync"), new OptionEditorHeading (_("MIDI Clock")));
+
+       add_option (_("MIDI/Sync"),
                    new BoolOption (
                            "send-midi-clock",
                            _("Send MIDI Clock"),
@@ -2742,9 +3064,9 @@ if (!ARDOUR::Profile->get_mixbus()) {
                            sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
                            ));
 
-       add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC)")));
+       add_option (_("MIDI/Sync"), new OptionEditorHeading (_("MIDI Time Code (MTC)")));
 
-       add_option (_("MIDI"),
+       add_option (_("MIDI/Sync"),
                    new BoolOption (
                            "send-mtc",
                            _("Send MIDI Time Code"),
@@ -2752,7 +3074,7 @@ if (!ARDOUR::Profile->get_mixbus()) {
                            sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
                            ));
 
-       add_option (_("MIDI"),
+       add_option (_("MIDI/Sync"),
                    new SpinOption<int> (
                            "mtc-qf-speed-tolerance",
                            _("Percentage either side of normal transport speed to transmit MTC"),
@@ -2761,9 +3083,9 @@ if (!ARDOUR::Profile->get_mixbus()) {
                            0, 20, 1, 5
                            ));
 
-       add_option (_("MIDI"), new OptionEditorHeading (_("Midi Machine Control (MMC)")));
+       add_option (_("MIDI/Sync"), new OptionEditorHeading (_("Midi Machine Control (MMC)")));
 
-       add_option (_("MIDI"),
+       add_option (_("MIDI/Sync"),
                    new BoolOption (
                            "mmc-control",
                            _("Obey MIDI Machine Control commands"),
@@ -2771,7 +3093,7 @@ if (!ARDOUR::Profile->get_mixbus()) {
                            sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
                            ));
 
-       add_option (_("MIDI"),
+       add_option (_("MIDI/Sync"),
                    new BoolOption (
                            "send-mmc",
                            _("Send MIDI Machine Control commands"),
@@ -2779,7 +3101,7 @@ if (!ARDOUR::Profile->get_mixbus()) {
                            sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
                            ));
 
-       add_option (_("MIDI"),
+       add_option (_("MIDI/Sync"),
             new SpinOption<uint8_t> (
                     "mmc-receive-device-id",
                     _("Inbound MMC device ID"),
@@ -2788,7 +3110,7 @@ if (!ARDOUR::Profile->get_mixbus()) {
                     0, 128, 1, 10
                     ));
 
-       add_option (_("MIDI"),
+       add_option (_("MIDI/Sync"),
             new SpinOption<uint8_t> (
                     "mmc-send-device-id",
                     _("Outbound MMC device ID"),
@@ -2816,62 +3138,34 @@ if (!ARDOUR::Profile->get_mixbus()) {
                if (manager.get_status (*i) == PluginManager::Hidden) continue;
                if (!(*i)->is_instrument()) continue;
                if ((*i)->type != ARDOUR::LV2) continue;
-               audition_synth->add((*i)->unique_id, (*i)->name);
+               if ((*i)->name.length() > 46) {
+                       audition_synth->add((*i)->unique_id, (*i)->name.substr (0, 44) + "...");
+               } else {
+                       audition_synth->add((*i)->unique_id, (*i)->name);
+               }
        }
 #endif
 
        add_option (_("MIDI"), audition_synth);
 
-       /* USER INTERACTION */
-
-       if (
-#ifdef PLATFORM_WINDOWS
-                       true
-#else
-                       getenv ("ARDOUR_BUNDLED")
-#endif
-          )
-       {
-               add_option (_("User interaction"),
-                           new BoolOption (
-                                   "enable-translation",
-                                   string_compose (_("Use translations of %1 messages\n"
-                                                     "   <i>(requires a restart of %1 to take effect)</i>\n"
-                                                     "   <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
-                                   sigc::ptr_fun (ARDOUR::translations_are_enabled),
-                                   sigc::ptr_fun (ARDOUR::set_translations_enabled)));
-       }
-
-       add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
-
-       add_option (_("User interaction"), new KeyboardOptions);
-
        /* Control Surfaces */
 
-       add_option (_("Control Surfaces"), new ControlSurfacesOptions);
-
-       ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
-               "remote-model",
-               _("Control surface remote ID"),
-               sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
-               sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
-               );
-
-       rm->add (UserOrdered, _("assigned by user"));
-       rm->add (MixerOrdered, _("follows order of mixer"));
-
-       add_option (_("Control Surfaces"), rm);
+       add_option (_("Control Surfaces"), new ControlSurfacesOptions ());
 
        /* VIDEO Timeline */
        add_option (_("Video"), new VideoTimelineOptions (_rc_config));
 
-#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
-       add_option (_("Plugins"), new OptionEditorHeading (_("General")));
-
+#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
+       add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover")));
        add_option (_("Plugins"),
                        new RcActionButton (_("Scan for Plugins"),
                                sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
 
+#endif
+
+       add_option (_("Plugins"), new OptionEditorHeading (_("General")));
+
+#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
        bo = new BoolOption (
                        "show-plugin-scan-window",
                        _("Always Display Plugin Scan Progress"),
@@ -2881,11 +3175,43 @@ if (!ARDOUR::Profile->get_mixbus()) {
        add_option (_("Plugins"), bo);
        Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
                        _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
-
 #endif
 
-#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
-       add_option (_("Plugins"), new OptionEditorHeading (_("VST")));
+       bo = new BoolOption (
+               "plugins-stop-with-transport",
+               _("Silence plugins when the transport is stopped"),
+               sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
+               sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
+               );
+       add_option (_("Plugins"), bo);
+       Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
+                                           _("<b>When enabled</b> plugins will be reset at transport stop. When disabled plugins will be left unchanged at transport stop.\n\nThis mostly affects plugins with a \"tail\" like Reverbs."));
+
+       bo = new BoolOption (
+               "new-plugins-active",
+                       _("Make new plugins active"),
+                       sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
+                       sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
+                       );
+       add_option (_("Plugins"), bo);
+       Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
+                                           _("<b>When enabled</b> plugins will be activated when they are added to tracks/busses. When disabled plugins will be left inactive when they are added to tracks/busses"));
+
+#if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT)
+       add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
+       add_option (_("Plugins/VST"),
+                       new RcActionButton (_("Scan for Plugins"),
+                               sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
+
+#if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT)
+       bo = new BoolOption (
+                       "",
+                       _("Enable Mac VST support (requires restart or re-scan)"),
+                       sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst),
+                       sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst)
+                       );
+       add_option (_("Plugins/VST"), bo);
+#endif
 
        bo = new BoolOption (
                        "discover-vst-on-start",
@@ -2893,7 +3219,7 @@ if (!ARDOUR::Profile->get_mixbus()) {
                        sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
                        sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
                        );
-       add_option (_("Plugins"), bo);
+       add_option (_("Plugins/VST"), bo);
        Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
                                            _("<b>When enabled</b> new VST plugins are searched, tested and added to the cache index on application start. When disabled new plugins will only be available after triggering a 'Scan' manually"));
 
@@ -2905,40 +3231,40 @@ if (!ARDOUR::Profile->get_mixbus()) {
                        sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
                        sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
                        );
-       add_option (_("Plugins"), bo);
+       add_option (_("Plugins/VST"), bo);
        Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
                                            _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
 #endif
 
-       add_option (_("Plugins"), new VstTimeOutSliderOption (_rc_config));
+       add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
 
-       add_option (_("Plugins"),
+       add_option (_("Plugins/VST"),
                        new RcActionButton (_("Clear"),
                                sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
                                _("VST Cache:")));
 
-       add_option (_("Plugins"),
+       add_option (_("Plugins/VST"),
                        new RcActionButton (_("Clear"),
                                sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
                                _("VST Blacklist:")));
 #endif
 
 #ifdef LXVST_SUPPORT
-       add_option (_("Plugins"),
+       add_option (_("Plugins/VST"),
                        new RcActionButton (_("Edit"),
                                sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
                        _("Linux VST Path:")));
 
-       add_option (_("Plugins"),
+       add_option (_("Plugins/VST"),
                        new RcConfigDisplay (
                                "plugin-path-lxvst",
                                _("Path:"),
                                sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
-                               ':'));
+                               0));
 #endif
 
 #ifdef WINDOWS_VST_SUPPORT
-       add_option (_("Plugins"),
+       add_option (_("Plugins/VST"),
                        new RcActionButton (_("Edit"),
                                sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
                        _("Windows VST Path:")));
@@ -2951,30 +3277,34 @@ if (!ARDOUR::Profile->get_mixbus()) {
 #endif
 
 #ifdef AUDIOUNIT_SUPPORT
-       add_option (_("Plugins"), new OptionEditorHeading (_("Audio Unit")));
+
+       add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
+       add_option (_("Plugins/Audio Unit"),
+                       new RcActionButton (_("Scan for Plugins"),
+                               sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
 
        bo = new BoolOption (
                        "discover-audio-units",
-                       _("Scan for AudioUnit Plugins on Application Start"),
+                       _("Scan for [new] AudioUnit Plugins on Application Start"),
                        sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
                        sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
                        );
-       add_option (_("Plugins"), bo);
+       add_option (_("Plugins/Audio Unit"), bo);
        Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
                                            _("<b>When enabled</b> Audio Unit Plugins are discovered on application start. When disabled AU plugins will only be available after triggering a 'Scan' manually. The first successful scan will enable AU auto-scan, Any crash during plugin discovery will disable it."));
 
-       add_option (_("Plugins"),
+       add_option (_("Plugins/Audio Unit"),
                        new RcActionButton (_("Clear"),
                                sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
                                _("AU Cache:")));
 
-       add_option (_("Plugins"),
+       add_option (_("Plugins/Audio Unit"),
                        new RcActionButton (_("Clear"),
                                sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
                                _("AU Blacklist:")));
 #endif
 
-#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
+#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
        add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
        add_option (_("Plugins"),
             new BoolOption (
@@ -2984,7 +3314,7 @@ if (!ARDOUR::Profile->get_mixbus()) {
                     sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
                     ));
 
-#ifdef LV2_SUPPORT
+#if (defined LV2_SUPPORT && defined LV2_EXTENDED)
        add_option (_("Plugins"),
             new BoolOption (
                     "show-inline-display-by-default",
@@ -3025,6 +3355,9 @@ if (!ARDOUR::Profile->get_mixbus()) {
 #endif
 
        /* INTERFACE */
+#if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE)
+       add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Graphics Acceleration")));
+#endif
 
 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
        BoolOption* bgc = new BoolOption (
@@ -3051,6 +3384,15 @@ if (!ARDOUR::Profile->get_mixbus()) {
        add_option (S_("Preferences|GUI"), bgo);
 #endif
 
+       add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Graphical User Interface")));
+       add_option (S_("Preferences|GUI"),
+            new BoolOption (
+                    "use-wm-visibility",
+                    _("Use Window Manager/Desktop visibility information"),
+                    sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
+                    sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
+                    ));
+
        add_option (S_("Preferences|GUI"),
             new BoolOption (
                     "widget-prelight",
@@ -3130,6 +3472,7 @@ if (!ARDOUR::Profile->get_mixbus()) {
        _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
        _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
        _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
+       _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
 
        add_option (
                S_("Preferences|GUI"),
@@ -3149,9 +3492,79 @@ if (!ARDOUR::Profile->get_mixbus()) {
                     sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
                     ));
 
-       add_option (S_("Preferences|GUI"),
+#ifdef ENABLE_NLS
+       OptionEditorHeading* i18n_head = new OptionEditorHeading (_("Internationalization"));
+       i18n_head->set_note (string_compose (_("These settings will only take effect after %1 is restarted (if available for your language preferences)."), PROGRAM_NAME));
+
+       add_option (_("GUI/Translation"), i18n_head);
+
+       bo = new BoolOption (
+                       "enable-translation",
+                       _("Use translations"),
+                       sigc::ptr_fun (ARDOUR::translations_are_enabled),
+                       sigc::ptr_fun (ARDOUR::set_translations_enabled)
+                       );
+
+       add_option (_("GUI/Translation"), bo);
+
+       _l10n = new ComboOption<ARDOUR::LocaleMode> (
+               "locale-mode",
+               _("Localization"),
+               sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_locale_mode),
+               sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_locale_mode)
+               );
+
+       _l10n->add (ARDOUR::SET_LC_ALL, _("Set complete locale"));
+       _l10n->add (ARDOUR::SET_LC_MESSAGES, _("Enable only message translation"));
+       _l10n->add (ARDOUR::SET_LC_MESSAGES_AND_LC_NUMERIC, _("Translate messages and format numeric format"));
+       _l10n->set_note (_("This setting is provided for plugin compatibility. e.g. some plugins on some systems expect the decimal point to be a dot."));
+
+       add_option (_("GUI/Translation"), _l10n);
+       parameter_changed ("enable-translation");
+#endif // ENABLE_NLS
+
+       add_option (_("GUI/Keyboard"), new OptionEditorHeading (_("Keyboard")));
+       add_option (_("GUI/Keyboard"), new KeyboardOptions);
+
+       add_option (_("GUI/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items")));
+
+       add_option (_("GUI/Toolbar"),
+            new BoolOption (
+                    "show-toolbar-selclock",
+                    _("Display Selection Clock in the Toolbar"),
+                    sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock),
+                    sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock)
+                    ));
+
+       if (!ARDOUR::Profile->get_small_screen()) {
+               add_option (_("GUI/Toolbar"),
+                               new BoolOption (
+                                       "show-secondary-clock",
+                                       _("Display Secondary Clock in the Toolbar"),
+                                       sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock),
+                                       sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock)
+                                       ));
+       }
+
+       add_option (_("GUI/Toolbar"),
+            new BoolOption (
+                    "show-mini-timeline",
+                    _("Display Navigation Timeline in the Toolbar"),
+                    sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline),
+                    sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline)
+                    ));
+
+       add_option (_("GUI/Toolbar"),
+            new BoolOption (
+                    "show-editor-meter",
+                    _("Display Master Level Meter in the Toolbar"),
+                    sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
+                    sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
+                    ));
+
+       add_option (_("GUI/Toolbar"),
                        new ColumVisibilityOption (
-                               "action-table-columns", _("Action Script Button Visibility"), 3,
+                               "action-table-columns", _("Lua Action Script Button Visibility"), 4,
                                sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
                                sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
                                )
@@ -3294,7 +3707,7 @@ if (!ARDOUR::Profile->get_mixbus()) {
 
        Gtkmm2ext::UI::instance()->set_tip
                (mpks->tip_widget(),
-                _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
+                _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
 
        add_option (S_("Preferences|Metering"), mpks);
 
@@ -3337,12 +3750,26 @@ if (!ARDOUR::Profile->get_mixbus()) {
        /* and now the theme manager */
 
        ThemeManager* tm = manage (new ThemeManager);
+       add_option (_("Theme"), new OptionEditorHeading (_("Theme")));
        add_page (_("Theme"), *tm);
 
+       add_option (_("Theme/Colors"), new ColorThemeManager);
+
+       Widget::show_all ();
+
        //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
        parameter_changed ("send-ltc");
        parameter_changed ("sync-source");
        parameter_changed ("use-monitor-bus");
+       parameter_changed ("open-gui-after-adding-plugin");
+
+       XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
+       if (node) {
+               /* gcc4 complains about ambiguity with Gtk::Widget::set_state
+                  (Gtk::StateType) here !!!
+               */
+               Tabbable::set_state (*node, Stateful::loading_state_version);
+       }
 }
 
 void
@@ -3381,8 +3808,12 @@ RCOptionEditor::parameter_changed (string const & p)
                _ltc_send_continuously->set_sensitive (s);
                _ltc_volume_slider->set_sensitive (s);
        } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
-#ifdef LV2_SUPPORT
+#if (defined LV2_SUPPORT && defined LV2_EXTENDED)
                _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
+#endif
+#ifdef ENABLE_NLS
+       } else if (p == "enable-translation") {
+               _l10n->set_sensitive (ARDOUR::translations_are_enabled ());
 #endif
        }
 }
@@ -3466,7 +3897,7 @@ RCOptionEditor::populate_sync_options ()
 Gtk::Window*
 RCOptionEditor::use_own_window (bool and_fill_it)
 {
-       bool new_window = !own_window();
+       bool new_window = !own_window ();
 
        Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
 
@@ -3477,3 +3908,11 @@ RCOptionEditor::use_own_window (bool and_fill_it)
 
        return win;
 }
+
+XMLNode&
+RCOptionEditor::get_state ()
+{
+       XMLNode* node = new XMLNode (X_("Preferences"));
+       node->add_child_nocopy (Tabbable::get_state());
+       return *node;
+}