]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/xforms/FormPreferences.C
try this for distinguishing inner and outer tabs
[lyx.git] / src / frontends / xforms / FormPreferences.C
index 5e2a5ce83b58240c49f522ed305dfef418c432f1..e03fed575347184260f7e18f234c44daa438e5df 100644 (file)
@@ -15,6 +15,7 @@
 #include <config.h>
 
 #include <utility>
+#include <iomanip>
 #include <X11/Xlib.h>
 
 #include FORMS_H_LOCATION
@@ -41,7 +42,6 @@
 #include "lyxlex.h"
 #include "input_validators.h"
 #include "xform_helpers.h"
-#include "xform_macros.h"
 #include "converter.h"
 #include "support/lyxfunctional.h"
 #include "support/lyxmanip.h"
@@ -50,10 +50,11 @@ using std::endl;
 using std::find;
 using std::find_if;
 using std::pair;
+using std::make_pair;
 using std::max;
+using std::min;
 using std::sort;
 using std::vector;
-using std::make_pair;
 
 extern string system_lyxdir;
 extern string user_lyxdir;
@@ -63,15 +64,11 @@ extern Languages languages;
 static Formats    local_formats;
 static Converters local_converters;
 
-// Instantiate static data
-string const FormPreferences::Colors::colorFile = "/usr/lib/X11/rgb.txt";
-vector<NamedColor> FormPreferences::Colors::colorDB;
-
 FormPreferences::FormPreferences(LyXView * lv, Dialogs * d)
        : FormBaseBI(lv, d, _("Preferences"), new PreferencesPolicy),
          dialog_(0),
          converters_tab_(0), inputs_tab_(0), look_n_feel_tab_(0),
-         outputs_tab_(0),  usage_tab_(0),
+         outputs_tab_(0),  lang_opts_tab_(0),
          warningPosted(false),
          colors_(*this), converters_(*this), inputs_misc_(*this),
          formats_(*this), interface_(*this), language_(*this), 
@@ -91,12 +88,30 @@ FormPreferences::~FormPreferences()
        delete inputs_tab_;
        delete look_n_feel_tab_;
        delete outputs_tab_;
-       delete usage_tab_;
+       delete lang_opts_tab_;
 
        delete dialog_;
 }
 
 
+void FormPreferences::connect()
+{
+       fl_set_form_maxsize( dialog_->form, minw_, minh_ );
+
+       FormBaseBI::connect();
+}
+
+
+void FormPreferences::disconnect()
+{
+       // colors_->disconnect();
+       // converters_->disconnect(); //local_converters.Clear();
+       // formats_->disconnect();    //local_formats.Clear();
+
+       FormBaseBI::disconnect();
+}
+
+
 void FormPreferences::redraw()
 {
        if (!(form() && form()->visible))
@@ -121,8 +136,8 @@ void FormPreferences::redraw()
        else if (form2 == outputs_tab_->form)
                form3 = fl_get_active_folder(outputs_tab_->tabfolder_outer);
 
-       else if (form2 == usage_tab_->form)
-               form3 = fl_get_active_folder(usage_tab_->tabfolder_outer);
+       else if (form2 == lang_opts_tab_->form)
+               form3 = fl_get_active_folder(lang_opts_tab_->tabfolder_outer);
 
        if (form3 && form3->visible)
                fl_redraw_form(form3);
@@ -167,7 +182,7 @@ void FormPreferences::build()
 {
        dialog_ = build_preferences();
 
-       // manage the restore, save, apply and cancel/close buttons
+       // Manage the restore, save, apply and cancel/close buttons
        bc_.setOK(dialog_->button_ok);
        bc_.setApply(dialog_->button_apply);
        bc_.setCancel(dialog_->button_cancel);
@@ -183,7 +198,7 @@ void FormPreferences::build()
        look_n_feel_tab_ = build_outer_tab();
        inputs_tab_ = build_outer_tab();
        outputs_tab_ = build_outer_tab();
-       usage_tab_ = build_outer_tab();
+       lang_opts_tab_ = build_outer_tab();
 
        // build actual tabfolder contents
        // these will become nested tabfolders
@@ -202,11 +217,11 @@ void FormPreferences::build()
 
        // Now add them to the tabfolder
        fl_addto_tabfolder(dialog_->tabfolder_prefs,
-                          _("Look and Feel"),
+                          _("Look & Feel"),
                           look_n_feel_tab_->form);
        fl_addto_tabfolder(dialog_->tabfolder_prefs,
-                          _("Usage"),
-                          usage_tab_->form);
+                          _("Lang Opts"),
+                          lang_opts_tab_->form);
        fl_addto_tabfolder(dialog_->tabfolder_prefs,
                           _("Converters"),
                           converters_tab_->form);
@@ -258,10 +273,10 @@ void FormPreferences::build()
                           outputs_misc_.dialog()->form);
 
        // then building usage
-       fl_addto_tabfolder(usage_tab_->tabfolder_outer,
+       fl_addto_tabfolder(lang_opts_tab_->tabfolder_outer,
                           _("Spell checker"),
                           spellchecker_.dialog()->form);
-       fl_addto_tabfolder(usage_tab_->tabfolder_outer,
+       fl_addto_tabfolder(lang_opts_tab_->tabfolder_outer,
                           _("Language"),
                           language_.dialog()->form);
 }
@@ -327,7 +342,7 @@ void FormPreferences::feedback(FL_OBJECT * ob)
                str = spellchecker_.feedback(ob);
        }
 
-       str = formatted(str, dialog_->text_warning->w-10,
+       str = formatted(_(str), dialog_->text_warning->w-10,
                        FL_SMALL_SIZE, FL_NORMAL_STYLE);
 
        fl_set_object_label(dialog_->text_warning, str.c_str());
@@ -343,9 +358,10 @@ bool FormPreferences::input(FL_OBJECT * ob, long)
        // some totally ridiculous value somewhere.  Change activate to suit.
        // comments before each test describe what is _valid_
 
-       if (ob->form->fdui == colors_.dialog())
-               return colors_.input(ob);
-       else if (ob->form->fdui == converters_.dialog())
+       if (ob->form->fdui == colors_.dialog()) {
+               colors_.input(ob);
+               return true;
+       } else if (ob->form->fdui == converters_.dialog())
                return converters_.input(ob);
        else if (ob->form->fdui == formats_.dialog())
                return formats_.input(ob);
@@ -426,7 +442,14 @@ void FormPreferences::Colors::apply()
 
                                AdjustVal(FL_RIGHT_BCOL,  FL_COL1, -0.5);
                                AdjustVal(FL_BOTTOM_BCOL, FL_COL1, -0.5);
-                       }       
+                       }
+
+                       if ((*cit).colorID == GUI_COLOR_CURSOR) {
+                               fl_mapcolor(GUI_COLOR_CURSOR,
+                                           (*cit).r, (*cit).g, (*cit).b);
+                               fl_set_cursor_color(FL_DEFAULT_CURSOR,
+                                                   GUI_COLOR_CURSOR, FL_WHITE);
+                       }
                }
                Dialogs::redrawGUI();
        }
@@ -435,27 +458,22 @@ void FormPreferences::Colors::apply()
        for (vector<NamedColor>::const_iterator cit = lyxColorDB.begin();
             cit != lyxColorDB.end(); ++cit) {
                LColor::color lc = lcolor.getFromGUIName((*cit).getname());
-               if (lc == LColor::ignore) continue;
-
-               // Ascertain the X11 name
-               RGBColor const & col = (*cit).color();
-               vector<NamedColor>::const_iterator cit2 =
-                       find_if(colorDB.begin(), colorDB.end(),
-                               compare_memfun(&NamedColor::color, col));
-               if (cit2 == colorDB.end()) continue;
-
-               if (lcolor.getX11Name(lc) != (*cit2).getname()) {
-                       lyxerr << "FormPreferences::Colors::apply: "
-                              << "resetting LColor " << lcolor.getGUIName(lc)
-                              << " from \"" << lcolor.getX11Name(lc)
-                              << "\" to \"" << (*cit2).getname() << "\"."
-                              << endl;
-
-                       string const arg =
-                               lcolor.getLyXName(lc) + string(" ") +
-                               (*cit2).getname();
-                       parent_.lv_->getLyXFunc()->
-                               Dispatch(LFUN_SET_COLOR, arg);
+               if (lc == LColor::inherit) continue;
+
+               // Create a valid X11 name of the form "#rrggbb"
+               string const hexname = X11hexname((*cit).color());
+               
+               if (lcolor.getX11Name(lc) != hexname) {
+                       lyxerr[Debug::GUI]
+                               << "FormPreferences::Colors::apply: "
+                               << "resetting LColor " << lcolor.getGUIName(lc)
+                               << " from \"" << lcolor.getX11Name(lc)
+                               << "\" to \"" << hexname << "\"."
+                               << endl;
+
+                       string const s = lcolor.getLyXName(lc) + string(" ") +
+                               hexname;
+                       parent_.lv_->getLyXFunc()->Dispatch(LFUN_SET_COLOR, s);
                }
        }
 }
@@ -466,59 +484,44 @@ void FormPreferences::Colors::build()
        dialog_ = parent_.build_colors();
 
        fl_set_object_color(dialog_->button_color,
-                           FL_FREE_COL4, FL_FREE_COL4);
+                           GUI_COLOR_CHOICE, GUI_COLOR_CHOICE);
 
-       fl_set_object_color(dialog_->dial_hue, FL_FREE_COL4+1, FL_BLACK);
-       fl_set_dial_return(dialog_->dial_hue, FL_RETURN_CHANGED);
+       fl_set_object_color(dialog_->dial_hue, GUI_COLOR_HUE_DIAL, FL_BLACK);
        fl_set_dial_bounds(dialog_->dial_hue, 0.0, 360.0);
+       fl_set_dial_step(dialog_->dial_hue, 1.0);
+       fl_set_dial_return(dialog_->dial_hue, FL_RETURN_CHANGED);
 
        fl_set_slider_bounds(dialog_->slider_saturation, 0.0, 1.0);
+       fl_set_slider_step(dialog_->slider_saturation, 0.01);
        fl_set_slider_return(dialog_->slider_saturation, FL_RETURN_CHANGED);
-       
+
        fl_set_slider_bounds(dialog_->slider_value, 0.0, 1.0);
+       fl_set_slider_step(dialog_->slider_value, 0.01);
        fl_set_slider_return(dialog_->slider_value, FL_RETURN_CHANGED);
        
-       fl_set_input_return(dialog_->input_name, FL_RETURN_END_CHANGED);
-
+       fl_set_slider_bounds(dialog_->slider_red, 0.0, 255.0);
+       fl_set_slider_step(dialog_->slider_red, 1.0);
+       fl_set_slider_return(dialog_->slider_red, FL_RETURN_CHANGED);
+       
+       fl_set_slider_bounds(dialog_->slider_green, 0.0, 255.0);
+       fl_set_slider_step(dialog_->slider_green, 1.0);
+       fl_set_slider_return(dialog_->slider_green, FL_RETURN_CHANGED);
+       
+       fl_set_slider_bounds(dialog_->slider_blue, 0.0, 255.0);
+       fl_set_slider_step(dialog_->slider_blue, 1.0);
+       fl_set_slider_return(dialog_->slider_blue, FL_RETURN_CHANGED);
+       
        // set up the feedback mechanism
-       setPreHandler(dialog_->input_name);
-       setPreHandler(dialog_->button_browse);
-
-       setPreHandler(dialog_->browser_x11);
        setPreHandler(dialog_->browser_lyx_objs);
        setPreHandler(dialog_->button_color);
        setPreHandler(dialog_->button_modify);
-       setPreHandler(dialog_->button_sort);
-       setPreHandler(dialog_->button_type_sort);
        setPreHandler(dialog_->dial_hue);
        setPreHandler(dialog_->slider_saturation);
        setPreHandler(dialog_->slider_value);
-
-       // Load the X11 color data base
-       if (!LoadBrowserX11(colorFile)) {
-               fl_freeze_form(dialog_->form);
-               
-               fl_hide_object(dialog_->browser_x11);
-               fl_hide_object(dialog_->browser_lyx_objs);
-               fl_hide_object(dialog_->button_color);
-               fl_hide_object(dialog_->button_modify);
-               fl_hide_object(dialog_->button_sort);
-               fl_hide_object(dialog_->button_type_sort);
-               fl_hide_object(dialog_->dial_hue);
-               fl_hide_object(dialog_->slider_saturation);
-               fl_hide_object(dialog_->slider_value);
-               fl_hide_object(dialog_->text_0);
-               fl_hide_object(dialog_->text_1);
-
-               string str = N_("Unable to find the X11 name database, usually to be found at /usr/lib/X11/rgb.txt. Cannot modify LyX's colors until this file is input here.");
-               str = formatted(str, dialog_->text_file_warning->w-10,
-                               FL_SMALL_SIZE, FL_NORMAL_STYLE);
-
-               fl_set_object_label(dialog_->text_file_warning, str.c_str());
-               fl_set_object_lsize(dialog_->text_file_warning, FL_SMALL_SIZE);
-
-               fl_unfreeze_form(dialog_->form);
-       }
+       setPreHandler(dialog_->slider_red);
+       setPreHandler(dialog_->slider_green);
+       setPreHandler(dialog_->slider_blue);
+       setPreHandler(dialog_->button_colorspace);
 }
 
 string const
@@ -526,37 +529,31 @@ FormPreferences::Colors::feedback(FL_OBJECT const * const ob) const
 {
        string str;
 
-       if (ob == dialog_->browser_x11) {
-               str = N_("The colors listed in the X11 database.");
-       } else if (ob == dialog_->browser_lyx_objs) {
+       if (ob == dialog_->browser_lyx_objs) {
                str = N_("LyX objects that can be assigned a color.");
-       } else if (ob == dialog_->input_name) {
-               str = N_("The file containing the X11 color database.");
+
        } else if (ob == dialog_->button_modify) {
                str = N_("Modify the LyX object's color. Note: you must then \"Apply\" the change.");
-       } else if (ob == dialog_->button_sort) {
-               if (fl_get_button(dialog_->button_type_sort))
-                       str = N_("Sort the X11 color database alphabetically.");
-               else
-                       str = N_("Sort the X11 color database based on the currently selected color.");
-       } else if (ob == dialog_->button_type_sort) {
-               str = N_("Toggle between sorting alphabetically or based on the currently selected color.");
+
        } else if (ob == dialog_->dial_hue ||
                   ob == dialog_->slider_saturation ||
-                  ob == dialog_->slider_value) {
-               str = N_("Find a new color. You will only be able to modify the color of the LyX object if the X11 browser and coloured rectangle below agree. Force this by clicking on the highlighted browser name.");
+                  ob == dialog_->slider_value ||
+                  ob == dialog_->slider_red ||
+                  ob == dialog_->slider_green ||
+                  ob == dialog_->slider_blue) {
+               str = N_("Find a new color.");
+
+       } else if (ob == dialog_->button_colorspace) {
+               str = N_("Toggle between RGB and HSV color spaces.");
        }
 
        return str;
 }
 
 
-bool FormPreferences::Colors::input(FL_OBJECT const * const ob)
+void FormPreferences::Colors::input(FL_OBJECT const * const ob)
 {
-       if (ob == dialog_->browser_x11) {
-               InputBrowserX11();
-
-       } else if (ob == dialog_->browser_lyx_objs) {
+       if (ob == dialog_->browser_lyx_objs) {
                InputBrowserLyX();
                
        } else if (ob == dialog_->dial_hue ||
@@ -564,26 +561,17 @@ bool FormPreferences::Colors::input(FL_OBJECT const * const ob)
                   ob == dialog_->slider_value) {
                InputHSV();
 
-       } else if (ob == dialog_->input_name) {
-               LoadDatabase();
+       } else if (ob == dialog_->slider_red ||
+                  ob == dialog_->slider_green ||
+                  ob == dialog_->slider_blue) {
+               InputRGB();
 
-       } else if (ob == dialog_->button_sort) {
-               Sort();
-               
-       } else if (ob == dialog_->button_type_sort) {
-               SortType();
-               
-       } else if (ob == dialog_->button_browse) {
-               parent_.browse(dialog_->input_name,
-                              _("X11 color database"), "*.txt",
-                              make_pair(string(), string()),
-                              make_pair(string(), string()));
+       } else if (ob == dialog_->button_colorspace) {
+               SwitchColorSpace();
 
        } else if (ob == dialog_->button_modify) {
                Modify();
        }
-       
-       return true;
 }
 
 
@@ -595,134 +583,151 @@ void FormPreferences::Colors::AdjustVal(int colAdjust, int colParent,
 
        HSVColor hsv(rgb);
        hsv.v += addVal;
-       if (hsv.v > 1.0) 
-               hsv.v = 1.0;
-       else if (hsv.v < 0.0)
-               hsv.v = 0.0;
+       hsv.v = min( 1.0, max(0.0, hsv.v) );
 
        rgb = RGBColor(hsv);
        fl_mapcolor(colAdjust, rgb.r, rgb.g, rgb.b);
 }
 
 
-bool FormPreferences::Colors::InputBrowserLyX() const
+void FormPreferences::Colors::InputBrowserLyX() const
 {
-       int const i = fl_get_browser(dialog_->browser_lyx_objs);
-       if (i < 1)
-               return true;
-
-       string const name = fl_get_browser_line(dialog_->browser_lyx_objs, i);
+       vector<NamedColor>::size_type const selLyX =
+               fl_get_browser(dialog_->browser_lyx_objs);
+       if (selLyX < 1) return;
 
        // Is the choice an Xforms color...
-       vector<NamedColor>::const_iterator cit =
-               find_if(xformColorDB.begin(), xformColorDB.end(),
-                       compare_memfun(&NamedColor::getname, name));
+       RGBColor col;
 
+       if( selLyX-1 < xformColorDB.size() ) {
+               vector<XformColor>::size_type const i = selLyX - 1;
+               col = xformColorDB[i].color();
+       }
        // or a LyX Logical color?
-       if (cit == xformColorDB.end()) {
-               cit = find_if(lyxColorDB.begin(), lyxColorDB.end(),
-                             compare_memfun(&NamedColor::getname, name));
-               if (cit == lyxColorDB.end()) return true;
+       else {
+               vector<NamedColor>::size_type const i = selLyX - 1 -
+                       xformColorDB.size();
+               col = lyxColorDB[i].color();
        }
 
-       RGBColor const & col = (*cit).color();
-       cit = find_if(colorDB.begin(), colorDB.end(),
-                     compare_memfun(&NamedColor::color, col));
-
-       int j = 0;
-       if (cit != colorDB.end())
-               j = static_cast<int>(cit - colorDB.begin());
+       fl_freeze_form(dialog_->form);
 
-       fl_set_browser_topline(dialog_->browser_x11, max(j-5, 1));
-       fl_select_browser_line(dialog_->browser_x11, j+1);
-       InputBrowserX11();
+       fl_mapcolor(GUI_COLOR_CHOICE, col.r, col.g, col.b);
+       fl_redraw_object(dialog_->button_color);
 
+       // Display either RGB or HSV but not both!
+       SwitchColorSpace();
+       
+       // Deactivate the modify button to begin with...
        fl_deactivate_object(dialog_->button_modify);
        fl_set_object_lcol(dialog_->button_modify, FL_INACTIVE);
        
-       return true;
+       fl_unfreeze_form(dialog_->form);
 }
 
 
-bool FormPreferences::Colors::InputBrowserX11() const
+void FormPreferences::Colors::InputHSV()
 {
-       int const i = fl_get_browser(dialog_->browser_x11);
-       if (i < 1)
-               return true;
+       double const hue = fl_get_dial_value(dialog_->dial_hue);
+       double const sat = fl_get_slider_value(dialog_->slider_saturation);
+       double const val = fl_get_slider_value(dialog_->slider_value);
 
-       fl_freeze_form(dialog_->form);
-       RGBColor const & col = colorDB[i - 1].color();
+       int const h = int(hue);
+       int const s = int(100.0 * sat);
+       int const v = int(100.0 * val);
        
-       fl_mapcolor(FL_FREE_COL4, col.r, col.g, col.b);
-       fl_redraw_object(dialog_->button_color);
+       string const label = tostr(h) + string(", ") + tostr(s) + string(", ") +
+               tostr(v);
+       fl_set_object_label(dialog_->text_color_values, label.c_str());
 
-       HSVColor hsv(col);
+       RGBColor col = HSVColor(hue, sat, val);
        
-       fl_set_dial_value(dialog_->dial_hue, hsv.h);
-       fl_set_slider_value(dialog_->slider_saturation, hsv.s);
-       fl_set_slider_value(dialog_->slider_value, hsv.v);
+       fl_freeze_form(dialog_->form);
+
+       fl_mapcolor(GUI_COLOR_CHOICE, col.r, col.g, col.b);
+       fl_redraw_object(dialog_->button_color);
 
-       RGBColor col2 = HSVColor(hsv.h, 1.0, 1.0);
-       fl_mapcolor(FL_FREE_COL4+1, col2.r, col2.g, col2.b);
+       col = HSVColor(hue, 1.0, 1.0);
+       col.r = max(col.r, 0);
+       fl_mapcolor(GUI_COLOR_HUE_DIAL, col.r, col.g, col.b);
        fl_redraw_object(dialog_->dial_hue);
 
-       // Is it valid to activate the "Modify" button?
-       int const line = fl_get_browser(dialog_->browser_lyx_objs);
-       bool isSelected = (line > 0);
-       if (isSelected)
-               if (line > fl_get_browser_maxline(dialog_->browser_lyx_objs))
-                       isSelected = false;     
+       // Ascertain whether to activate the Modify button.
+       vector<NamedColor>::size_type const selLyX =
+               fl_get_browser(dialog_->browser_lyx_objs);
 
-       if (isSelected) {
+       fl_unfreeze_form(dialog_->form);
+       if (selLyX < 1) return;
+       
+       fl_getmcolor(GUI_COLOR_CHOICE, &col.r, &col.g, &col.b);
+       bool modify = false;
+       
+       // Is the choice an Xforms color...
+       if( selLyX-1 < xformColorDB.size() ) {
+               vector<XformColor>::size_type const i = selLyX - 1;
+               modify = (xformColorDB[i].color() != col);
+       }
+       // or a LyX Logical color?
+       else {
+               vector<NamedColor>::size_type const i = selLyX - 1 -
+                       xformColorDB.size();
+               modify = (lyxColorDB[i].color() != col);
+       }
+
+       if (modify) {
                fl_activate_object(dialog_->button_modify);
                fl_set_object_lcol(dialog_->button_modify, FL_BLACK);
+       } else {
+               fl_deactivate_object(dialog_->button_modify);
+               fl_set_object_lcol(dialog_->button_modify, FL_INACTIVE);
        }
-
-       fl_unfreeze_form(dialog_->form);
-       return true;
 }
 
 
-void FormPreferences::Colors::InputHSV()
+void FormPreferences::Colors::InputRGB()
 {
-       double const hue        = fl_get_dial_value(dialog_->dial_hue);
-       double const saturation = fl_get_slider_value(dialog_->slider_saturation);
-       double const value      = fl_get_slider_value(dialog_->slider_value);
+       int const red   = int(fl_get_slider_value(dialog_->slider_red));
+       int const green = int(fl_get_slider_value(dialog_->slider_green));
+       int const blue  = int(fl_get_slider_value(dialog_->slider_blue));
 
-       RGBColor col = HSVColor(hue, saturation, value);
-       
-       int const i = SearchEntry(col);
-       
+       string const label = tostr(red) + string(", ") + tostr(green) +
+               string(", ") + tostr(blue);
+       fl_set_object_label(dialog_->text_color_values, label.c_str());
+               
        fl_freeze_form(dialog_->form);
 
-       fl_set_browser_topline(dialog_->browser_x11, max(i-5, 1));
-       fl_select_browser_line(dialog_->browser_x11, i+1);
-
-       fl_mapcolor(FL_FREE_COL4, col.r, col.g, col.b);
+       RGBColor col = RGBColor(red, green, blue);
+       fl_mapcolor(GUI_COLOR_CHOICE, col.r, col.g, col.b);
        fl_redraw_object(dialog_->button_color);
 
-       // Only activate the "Modify" button if the browser and slider colors
-       // are the same AND if a LyX object is selected.
-       int const line = fl_get_browser(dialog_->browser_lyx_objs);
-       bool isSelected = (line > 0);
-       if (isSelected)
-               if (line > fl_get_browser_maxline(dialog_->browser_lyx_objs))
-                       isSelected = false;     
-
-       if (isSelected && colorDB[i].color() == col) {
-               fl_activate_object( dialog_->button_modify );
-               fl_set_object_lcol( dialog_->button_modify, FL_BLACK );
-       } else {
-               fl_deactivate_object( dialog_->button_modify );
-               fl_set_object_lcol( dialog_->button_modify, FL_INACTIVE );
-       }
-
-       // Finally, modify the color of the dial.
-       col = HSVColor(hue, 1.0, 1.0);
-       fl_mapcolor(FL_FREE_COL4 + 1, col.r, col.g, col.b);
-       fl_redraw_object(dialog_->dial_hue);
+       // Ascertain whether to activate the Modify button.
+       vector<NamedColor>::size_type const selLyX =
+               fl_get_browser(dialog_->browser_lyx_objs);
 
        fl_unfreeze_form(dialog_->form);
+       if (selLyX < 1) return;
+       
+       bool modify = false;
+       
+       // Is the choice an Xforms color...
+       if( selLyX-1 < xformColorDB.size() ) {
+               vector<XformColor>::size_type const i = selLyX - 1;
+               modify = (xformColorDB[i].color() != col);
+       }
+       // or a LyX Logical color?
+       else {
+               vector<NamedColor>::size_type const i = selLyX - 1 -
+                       xformColorDB.size();
+               modify = (lyxColorDB[i].color() != col);
+       }
+
+       if (modify) {
+               fl_activate_object(dialog_->button_modify);
+               fl_set_object_lcol(dialog_->button_modify, FL_BLACK);
+       } else {
+               fl_deactivate_object(dialog_->button_modify);
+               fl_set_object_lcol(dialog_->button_modify, FL_INACTIVE);
+       }
 }
 
 
@@ -734,31 +739,33 @@ void FormPreferences::Colors::LoadBrowserLyX()
        xformColorDB.clear();
        XformColor xcol;
 
-       xcol.name = "GUI background";
+       xcol.name = _("GUI background");
        xcol.colorID = FL_COL1;
        fl_getmcolor(FL_COL1, &xcol.r, &xcol.g, &xcol.b);
 
        xformColorDB.push_back(xcol);
 
-       xcol.name = "GUI text";
+       xcol.name = _("GUI text");
        xcol.colorID = FL_BLACK;
        fl_getmcolor(FL_BLACK, &xcol.r, &xcol.g, &xcol.b);
 
-       xformColorDB.push_back(xcol);
+       fl_mapcolor(GUI_COLOR_CURSOR, xcol.r, xcol.g, xcol.b);
+       fl_set_cursor_color(FL_DEFAULT_CURSOR, GUI_COLOR_CURSOR, FL_WHITE);
 
-       // FL_LIGHTER_COL1 does not exist in xforms 0.88
-       // xcol.name = "GUI active tab";
-       // xcol.colorID = FL_LIGHTER_COL1;
-       // fl_getmcolor(FL_LIGHTER_COL1, &xcol.r, &xcol.g, &xcol.b);
-       // 
-       // xformColorDB.push_back(xcol);
+       xformColorDB.push_back(xcol);
 
-       xcol.name = "GUI selection";
+       xcol.name = _("GUI selection");
        xcol.colorID = FL_YELLOW;
        fl_getmcolor(FL_YELLOW, &xcol.r, &xcol.g, &xcol.b);
 
        xformColorDB.push_back(xcol);
 
+       xcol.name = _("GUI pointer");
+       xcol.colorID = GUI_COLOR_CURSOR;
+       fl_getmcolor(GUI_COLOR_CURSOR, &xcol.r, &xcol.g, &xcol.b);
+
+       xformColorDB.push_back(xcol);
+
        // Now create the the LyX LColors database
        lyxColorDB.clear();
        for (int i=0; i<LColor::ignore; ++i) {
@@ -776,116 +783,13 @@ void FormPreferences::Colors::LoadBrowserLyX()
                    || lc == LColor::ignore) continue;
 
                string const name = lcolor.getX11Name(lc);
-
-               vector<NamedColor>::const_iterator cit =
-                       find_if(colorDB.begin(), colorDB.end(),
-                               compare_memfun(&NamedColor::getname, name));
-
-               if (cit == colorDB.end()) {
-                       lyxerr << "FormPreferences::Colors::LoadBrowserLyX: "
-                              << "can't find color \"" << name
-                              << "\". This shouldn't happen!" << endl;
-                       continue;
-               }
-
-               NamedColor ncol(lcolor.getGUIName(lc), (*cit).color());
-               lyxColorDB.push_back(ncol);
-       }
-
-       // Finally, construct the browser
-       FL_OBJECT * colbr = dialog_->browser_lyx_objs;
-       fl_freeze_form(dialog_->form);
-       fl_clear_browser(colbr);
-       for (vector<XformColor>::const_iterator cit = xformColorDB.begin();
-            cit != xformColorDB.end(); ++cit) {
-               fl_addto_browser(colbr, (*cit).getname().c_str());
-       }
-       for (vector<NamedColor>::const_iterator cit = lyxColorDB.begin();
-            cit != lyxColorDB.end(); ++cit) {
-               fl_addto_browser(colbr, (*cit).getname().c_str());
-       }
-
-       // just to be safe...
-       fl_set_browser_topline(dialog_->browser_lyx_objs, 1);
-       fl_select_browser_line(dialog_->browser_lyx_objs, 1);
-       fl_unfreeze_form(dialog_->form);
-
-       InputBrowserLyX();
-}
-
-
-bool FormPreferences::Colors::LoadBrowserX11(string const & filename)
-{
-       LyXLex lex(0, 0);
-       lex.setCommentChar('!');
-       
-       if (!lex.setFile(filename))
-               return false;
-
-       colorDB.clear();
-
-       while (lex.next()) {
-               RGBColor col;
-               col.r = lex.GetInteger();
-               lex.next();
-               col.g = lex.GetInteger();
-               lex.next();
-               col.b = lex.GetInteger();
-               lex.EatLine();
-               string name = frontStrip(lex.GetString(), " \t");
-
-               // remove redundant entries on the fly
-               bool add = colorDB.empty();
-               if (!add) {
-                       add = (find(colorDB.begin(), colorDB.end(), col) ==
-                               colorDB.end());
-               }
-               
-               if (add) {
-                       if (col == RGBColor(0,0,0))
-                               name = "black";
-                       else if (col == RGBColor(255,255,255))
-                               name = "white";
-                       else
-                               name = lowercase(name);
-
-                       colorDB.push_back(NamedColor(name, col));
-               }
-       }
-       
-       FL_OBJECT * colbr = dialog_->browser_x11;
-       fl_freeze_form(dialog_->form);
-       fl_clear_browser(colbr);
-
-       for (vector<NamedColor>::const_iterator cit = colorDB.begin();
-            cit != colorDB.end(); ++cit) {
-               fl_addto_browser(colbr, (*cit).getname().c_str());
-       }
-       
-       fl_set_browser_topline(colbr, 1);
-       fl_select_browser_line(colbr, 1);
-       fl_unfreeze_form(dialog_->form);
-       
-       InputBrowserX11();
-
-       // The LyX LColors may have names not in the reduced colorDB shown in
-       // the browser (which has one name only for each RGB entry). If so,
-       // replace them with the colorDB name by quering X for the color.
-
-       // This can go here and not in update() because we only need to do it
-       // once.
-       fl_freeze_form(dialog_->form);
-       for (int i = 0; i<LColor::ignore; ++i) {
-               LColor::color lc = static_cast<LColor::color>(i);
-
-               string name = lowercase(lcolor.getX11Name(lc));
                Display * display = fl_get_display();;
                Colormap const colormap = fl_state[fl_get_vclass()].colormap;
                XColor xcol, ccol;
 
                if (XLookupColor(display, colormap, name.c_str(), &xcol, &ccol)
                    == 0) {
-                       lyxerr << "FormPreferences::Colors::LoadBrowserX11:\n"
+                       lyxerr << "FormPreferences::Colors::LoadBrowserLyX:\n"
                               << "LColor " << lcolor.getLyXName(lc)
                               << ": X can't find color \"" << name
                               << "\". Set to \"black\"!" << endl;
@@ -902,211 +806,160 @@ bool FormPreferences::Colors::LoadBrowserX11(string const & filename)
                // Note that X stores the RGB values in the range 0 - 65535
                // whilst we require them in the range 0 - 255.
                RGBColor col;
-               col.r = static_cast<unsigned char>(xcol.red);
-               col.g = static_cast<unsigned char>(xcol.green);
-               col.b = static_cast<unsigned char>(xcol.blue);
-
-               // In the (inprobable) event of this color not being in the
-               // database, find the closest one that is.
-               int const sel = SearchEntry(col);
-               name = colorDB[sel].getname();
-               
-               // Change the LColor X11name. Don't want to trigger a redraw,
-               // as we're just changing the name to an equivalent one
-               // (same RGBColor). Also reset the system_lcolor names, so
-               // that we don't output unnecessary changes.
-               if (lcolor.getX11Name(lc) != name) {
-                       lcolor.setColor(lc, name);
-                       system_lcolor.setColor(lc,name);
+               col.r = xcol.red   / 256;
+               col.g = xcol.green / 256;
+               col.b = xcol.blue  / 256;
+
+               // Create a valid X11 name of the form "#rrggbb" and change the
+               // LColor X11name to this. Don't want to trigger a redraw,
+               // as we're just changing the name not the RGB values.
+               // Also reset the system_lcolor names, so that we don't output
+               // unnecessary changes.
+               string const hexname = X11hexname(col);
+
+               if (lcolor.getX11Name(lc) != hexname) {
+                       lcolor.setColor(lc, hexname);
+                       system_lcolor.setColor(lc, hexname);
                }
-       }
-       
-       fl_hide_object(dialog_->input_name);
-       fl_hide_object(dialog_->button_browse);
-       fl_hide_object(dialog_->text_file_warning);
-
-       fl_show_object(dialog_->browser_x11);
-       fl_show_object(dialog_->browser_lyx_objs);
-       fl_show_object(dialog_->button_color);
-       fl_show_object(dialog_->button_modify);
-       fl_show_object(dialog_->button_sort);
-       fl_show_object(dialog_->button_type_sort);
-       fl_show_object(dialog_->dial_hue);
-       fl_show_object(dialog_->slider_saturation);
-       fl_show_object(dialog_->slider_value);
-       fl_show_object(dialog_->text_0);
-       fl_show_object(dialog_->text_1);
-
-       LoadBrowserLyX();
-
-       fl_unfreeze_form(dialog_->form);
-       return true;
-}
 
+               // Finally, push the color onto the database
+               NamedColor ncol(lcolor.getGUIName(lc), col);
+               lyxColorDB.push_back(ncol);
+       }
 
-bool FormPreferences::Colors::LoadDatabase()
-{
-       string const file = fl_get_input(dialog_->input_name);
-       if (!RWInfo::ReadableFile(file)) {
-               parent_.printWarning(RWInfo::ErrorMessage());
-               return false;
+       // Now construct the browser
+       FL_OBJECT * colbr = dialog_->browser_lyx_objs;
+       fl_freeze_form(dialog_->form);
+       fl_clear_browser(colbr);
+       for (vector<XformColor>::const_iterator cit = xformColorDB.begin();
+            cit != xformColorDB.end(); ++cit) {
+               fl_addto_browser(colbr, (*cit).getname().c_str());
+       }
+       for (vector<NamedColor>::const_iterator cit = lyxColorDB.begin();
+            cit != lyxColorDB.end(); ++cit) {
+               fl_addto_browser(colbr, (*cit).getname().c_str());
        }
 
-       if (LoadBrowserX11(file))
-               return true;
+       // just to be safe...
+       fl_set_browser_topline(dialog_->browser_lyx_objs, 1);
+       fl_select_browser_line(dialog_->browser_lyx_objs, 1);
+       fl_unfreeze_form(dialog_->form);
 
-       return false;
+       InputBrowserLyX();
 }
 
 
-bool FormPreferences::Colors::Modify() const
+void FormPreferences::Colors::Modify()
 {
-       int const i = fl_get_browser(dialog_->browser_lyx_objs);
-       if (i < 1) return true;
+       vector<NamedColor>::size_type const selLyX =
+               fl_get_browser(dialog_->browser_lyx_objs);
+       if (selLyX < 1) return;
 
-       string const name = fl_get_browser_line(dialog_->browser_lyx_objs, i);
+       RGBColor col;
+       fl_getmcolor(GUI_COLOR_CHOICE, &col.r, &col.g, &col.b);
 
        // Is the choice an Xforms color...
-       vector<NamedColor>::iterator it = // non-const; it's modified below
-               const_cast<vector<XformColor>::iterator>(
-                       find_if(xformColorDB.begin(), xformColorDB.end(),
-                               compare_memfun(&NamedColor::getname, name)));
-
+       if( selLyX-1 < xformColorDB.size() ) {
+               vector<XformColor>::size_type const i = selLyX - 1;
+               xformColorDB[i].r  = col.r;
+               xformColorDB[i].g  = col.g;
+               xformColorDB[i].b  = col.b;
+       }
        // or a LyX Logical color?
-       if (it == xformColorDB.end()) {
-               it = const_cast<vector<NamedColor>::iterator>(
-                       find_if(lyxColorDB.begin(), lyxColorDB.end(),
-                               compare_memfun(&NamedColor::getname, name)));
-               if (it == lyxColorDB.end()) return true;
+       else {
+               vector<NamedColor>::size_type const i = selLyX - 1 -
+                       xformColorDB.size();
+               lyxColorDB[i].r  = col.r;
+               lyxColorDB[i].g  = col.g;
+               lyxColorDB[i].b  = col.b;
        }
-       
-       // Ok! Modify the color.
-       int const j = fl_get_browser(dialog_->browser_x11);
-       if (j < 1) return true;
-
-       (*it).r = colorDB[j - 1].r;
-       (*it).g = colorDB[j - 1].g;
-       (*it).b = colorDB[j - 1].b;
 
        fl_freeze_form(dialog_->form);
 
-       fl_deselect_browser(dialog_->browser_x11);
        fl_deactivate_object(dialog_->button_modify);
        fl_set_object_lcol(dialog_->button_modify, FL_INACTIVE);
-
+       
        fl_unfreeze_form(dialog_->form);
-       return true;
 }
 
 
-int FormPreferences::Colors::SearchEntry(RGBColor const & col) const
+void FormPreferences::Colors::SwitchColorSpace() const
 {
-       int mindiff = 0x7fffffff;
-       vector<NamedColor>::const_iterator mincit = colorDB.begin();
+       bool const pressed = fl_get_button(dialog_->button_colorspace);
 
-       for (vector<NamedColor>::const_iterator cit = colorDB.begin();
-            cit != colorDB.end(); ++cit) {
-               RGBColor diff;
-               diff.r = col.r - (*cit).r;
-               diff.g = col.g - (*cit).g;
-               diff.b = col.b - (*cit).b;
-
-               int d = (2 * (diff.r * diff.r) +
-                        3 * (diff.g * diff.g) +
-                            (diff.b * diff.b));
-
-               if (mindiff > d) {
-                       mindiff = d;
-                       mincit = cit;
-               }
-       }
-
-       int sel = 0;
-       if (mincit != colorDB.end())
-               sel = static_cast<int>(mincit - colorDB.begin());
-       
-       return sel;
-}
+       RGBColor col;
+       fl_getmcolor(GUI_COLOR_CHOICE, &col.r, &col.g, &col.b);
 
+       fl_freeze_form(dialog_->form);
 
-int FormPreferences::SortColorsByColor::
-operator()(RGBColor const & a, RGBColor const & b) const
-{
-       RGBColor c1 = a;
-       RGBColor c2 = b;
-               
-       c1.r -= col.r;
-       c1.g -= col.g;
-       c1.b -= col.b;
+       if (pressed) {
+               fl_set_object_label(dialog_->button_colorspace, _("HSV"));
 
-       int const l1 = (c1.r * c1.r) + (c1.g * c1.g) + (c1.b * c1.b);
-               
-       c2.r -= col.r;
-       c2.g -= col.g;
-       c2.b -= col.b;
+               fl_hide_object(dialog_->slider_red);
+               fl_hide_object(dialog_->slider_blue);
+               fl_hide_object(dialog_->slider_green);
+               fl_show_object(dialog_->dial_hue);
+               fl_show_object(dialog_->slider_saturation);
+               fl_show_object(dialog_->slider_value);
 
-       int const l2 = (c2.r * c2.r) + (c2.g * c2.g) + (c2.b * c2.b);
+               HSVColor hsv = HSVColor(col);
+               hsv.h = max(hsv.h, 0.0);
+       
+               fl_set_dial_value(dialog_->dial_hue, hsv.h);
+               fl_set_slider_value(dialog_->slider_saturation, hsv.s);
+               fl_set_slider_value(dialog_->slider_value, hsv.v);
+
+               col = HSVColor(hsv.h, 1.0, 1.0);
+               col.r = max(col.r,0);
+               fl_mapcolor(GUI_COLOR_HUE_DIAL, col.r, col.g, col.b);
+               fl_redraw_object(dialog_->dial_hue);
+
+               // Adjust the label a bit, but not the actual values.
+               // Means that toggling from one space to the other has no
+               // effect on the final color.
+               int const h = int(hsv.h);
+               int const s = int(100*hsv.s);
+               int const v = int(100*hsv.v);
+               string const label = tostr(h) + string(", ") + tostr(s) +
+                       string(", ") + tostr(v);
+               fl_set_object_label(dialog_->text_color_values, label.c_str());
                
-       return (l1 < l2);
-}
-
-
-void FormPreferences::Colors::Sort()
-{
-       int i = fl_get_browser(dialog_->browser_x11);
-       if (i < 1) return;
-
-       RGBColor const col = colorDB[i - 1].color();
-
-       if (fl_get_button(dialog_->button_type_sort)) {
-               sort(colorDB.begin(), colorDB.end(),
-                    FormPreferences::SortColorsByName());
        } else {
-               sort(colorDB.begin(), colorDB.end(),
-                    FormPreferences::SortColorsByColor(col));
-       }
-
-       fl_freeze_form(dialog_->form);
-       fl_clear_browser(dialog_->browser_x11);
-
-       for (vector<NamedColor>::const_iterator cit = colorDB.begin();
-            cit != colorDB.end(); ++cit) {
-               fl_addto_browser(dialog_->browser_x11,
-                                (*cit).getname().c_str());
-       }
+               fl_set_object_label(dialog_->button_colorspace, _("RGB"));
 
-       vector<NamedColor>::const_iterator cit =
-               find_if(colorDB.begin(), colorDB.end(),
-                       compare_memfun(&NamedColor::color, col));
+               fl_show_object(dialog_->slider_red);
+               fl_show_object(dialog_->slider_blue);
+               fl_show_object(dialog_->slider_green);
+               fl_hide_object(dialog_->dial_hue);
+               fl_hide_object(dialog_->slider_saturation);
+               fl_hide_object(dialog_->slider_value);
 
-       i = 0;
-       if (cit != colorDB.end())
-               i = static_cast<int>(cit - colorDB.begin());
+               fl_set_slider_value(dialog_->slider_red,   col.r);
+               fl_set_slider_value(dialog_->slider_green, col.g);
+               fl_set_slider_value(dialog_->slider_blue,  col.b);
 
-       fl_set_browser_topline(dialog_->browser_x11, max(i - 5, 1));
-       fl_select_browser_line(dialog_->browser_x11, i + 1);
+               // Adjust the label a bit. Same reasoning as above.
+               int const r = int(col.r);
+               int const g = int(col.g);
+               int const b = int(col.b);
+               string const label = tostr(r) + string(", ") + tostr(g) +
+                       string(", ") + tostr(b);
+               fl_set_object_label(dialog_->text_color_values, label.c_str());
+       }
+       
        fl_unfreeze_form(dialog_->form);
 }
 
-
-void FormPreferences::Colors::SortType()
+string const FormPreferences::Colors::X11hexname(RGBColor const & col) const
 {
-       fl_freeze_form(dialog_->form);
-       if (fl_get_button(dialog_->button_type_sort)) {
-               fl_set_object_label(dialog_->button_type_sort,
-                                    idex(_("Alphabet|#A")));
-               fl_set_button_shortcut(dialog_->button_type_sort,
-                                       scex(_("Alphabet|#A")), 1);
-       } else {
-               fl_set_object_label(dialog_->button_type_sort,
-                                    idex(_("Color|#C")));
-               fl_set_button_shortcut(dialog_->button_type_sort,
-                                       scex(_("Color|#C")), 1);
-       }
-       // Need to redraw the form or we'll end up with both labels on top of
-       // each other. Another xforms bug associated with nested tab folders.
-       fl_redraw_form(dialog_->form);
-       fl_unfreeze_form(dialog_->form);
+       ostringstream ostr;
+
+       ostr << "#" << std::setbase(16) << std::setfill('0')
+            << std::setw(2) << col.r
+            << std::setw(2) << col.g
+            << std::setw(2) << col.b;
+
+       return ostr.str().c_str();
 }
 
 
@@ -1158,9 +1011,12 @@ FormPreferences::Converters::feedback(FL_OBJECT const * const ob) const
        } else if (ob == dialog_->input_flags) {
                str = N_("Flags that control the converter behavior");
        } else if (ob == dialog_->button_delete) {
-               str = N_("Remove the current converter from the list of available converters.");
+               str = N_("Remove the current converter from the list of available converters. Note: you must then \"Apply\" the change.");
        } else if (ob == dialog_->button_add) {
-               str = N_("Add the current converter to the list of available converters.");
+               if (string(ob->label) == _("Add"))
+                       str = N_("Add the current converter to the list of available converters. Note: you must then \"Apply\" the change.");
+               else
+                       str = N_("Modify the contents of the current converter. Note: you must then \"Apply\" the change.");
        }
 
        return str;
@@ -1329,8 +1185,8 @@ bool FormPreferences::Converters::Input()
 string const FormPreferences::Converters::GetFrom() const
 {
        int const i = fl_get_choice(dialog_->choice_from);
-       if (i > 0)
-               return local_formats.Get(i - 1).name();
+       if (i > 0 && i <= local_formats.size())
+               return local_formats.Get(i-1).name();
        else {
                lyxerr << "FormPreferences::Converters::GetFrom: No choice!"
                       << endl;
@@ -1342,8 +1198,8 @@ string const FormPreferences::Converters::GetFrom() const
 string const FormPreferences::Converters::GetTo() const
 {
        int const i = fl_get_choice(dialog_->choice_to);
-       if (i > 0)
-               return local_formats.Get(i - 1).name();
+       if (i > 0 && i <= local_formats.size())
+               return local_formats.Get(i-1).name();
        else {
                lyxerr << "FormPreferences::Converters::GetTo: No choice!"
                       << endl;
@@ -1427,9 +1283,12 @@ FormPreferences::Formats::feedback(FL_OBJECT const * const ob) const
        } else if (ob == dialog_->input_viewer) {
                str = N_("The command used to launch the viewer application.");
        } else if (ob == dialog_->button_delete) {
-               str = N_("Remove the current format from the list of available formats.");
+               str = N_("Remove the current format from the list of available formats. Note: you must then \"Apply\" the change.");
        } else if (ob == dialog_->button_add) {
-               str = N_("Add the current format to the list of available formats.");
+               if (string(ob->label) == _("Add"))
+                       str = N_("Add the current format to the list of available formats. Note: you must then \"Apply\" the change.");
+               else
+                       str = N_("Modify the contents of the current format. Note: you must then \"Apply\" the change.");
        }
 
        return str;
@@ -1518,7 +1377,7 @@ bool FormPreferences::Formats::Browser()
 
        fl_freeze_form(dialog_->form);
 
-       Format const & f = local_formats.Get(i - 1);
+       Format const & f = local_formats.Get(i-1);
 
        fl_set_input(dialog_->input_format, f.name().c_str());
        fl_set_input(dialog_->input_gui_name, f.prettyname().c_str());
@@ -1580,7 +1439,7 @@ bool FormPreferences::Formats::Input()
                fl_set_button_shortcut(dialog_->button_add,
                                        scex(_("Modify|#M")), 1);
 
-               int const top = max(sel - 5, 0);
+               int const top = max(sel-5, 0);
                fl_set_browser_topline(dialog_->browser_all, top);
                fl_select_browser_line(dialog_->browser_all, sel+1);
                
@@ -1674,8 +1533,7 @@ void FormPreferences::Interface::build()
 
        fl_set_input_return(dialog_->input_popup_font, FL_RETURN_CHANGED);
        fl_set_input_return(dialog_->input_menu_font, FL_RETURN_CHANGED);
-       fl_set_input_return(dialog_->input_popup_encoding, 
-                           FL_RETURN_CHANGED);
+       fl_set_input_return(dialog_->input_popup_encoding, FL_RETURN_CHANGED);
        fl_set_input_return(dialog_->input_bind_file, FL_RETURN_CHANGED);
        fl_set_input_return(dialog_->input_ui_file, FL_RETURN_CHANGED);
 
@@ -1716,28 +1574,28 @@ FormPreferences::Interface::feedback(FL_OBJECT const * const ob) const
 bool FormPreferences::Interface::input(FL_OBJECT const * const ob)
 {
        if (ob == dialog_->button_bind_file_browse) {
-               string dir  = system_lyxdir + string("bind");
+               string dir  = AddName(system_lyxdir, "bind");
                string name = N_("Sys Bind");
                pair<string,string> dir1(name, dir);
 
-               dir = user_lyxdir + string("bind");
+               dir = AddName(user_lyxdir, "bind");
                name = N_("User Bind");
                pair<string,string> dir2(name, dir);
 
                parent_.browse(dialog_->input_bind_file,
-                               _("Bind file"), "*.bind", dir1, dir2);
+                              N_("Bind file"), "*.bind", dir1, dir2);
                
        } else if (ob == dialog_->button_ui_file_browse) {
-               string dir  = system_lyxdir + string("ui");
+               string dir  = AddName(system_lyxdir, "ui");
                string name = N_("Sys UI");
                pair<string,string> dir1(name, dir);
 
-               dir = user_lyxdir + string("ui");
+               dir = AddName(user_lyxdir, "ui");
                name = N_("User UI");
                pair<string,string> dir2(name, dir);
 
                parent_.browse(dialog_->input_ui_file,
-                               _("UI file"), "*.ui", dir1, dir2);
+                              N_("UI file"), "*.ui", dir1, dir2);
        }
        
        return true;
@@ -1820,7 +1678,9 @@ void FormPreferences::Language::build()
        FL_OBJECT * obj = dialog_->choice_default_lang;
        fl_deactivate_object(dialog_->choice_default_lang);
        combo_default_lang = new Combox(FL_COMBOX_DROPLIST);
-       combo_default_lang->add(obj->x, obj->y, obj->w, obj->h, 400);
+       combo_default_lang->add(obj->x, obj->y, obj->w, obj->h, 400,
+                               parent_.lang_opts_tab_->tabfolder_outer,
+                               parent_.dialog_->tabfolder_prefs);
        combo_default_lang->shortcut("#L",1);
        combo_default_lang->setcallback(ComboCB, &parent_);
 
@@ -1838,6 +1698,7 @@ void FormPreferences::Language::build()
 
        // This is safe, as nothing is done to the pointer, other than
        // to use its address in a block-if statement.
+       // No it's not! Leads to crash.
        // setPreHandler(
        //              reinterpret_cast<FL_OBJECT *>(combo_default_lang),
        //              C_FormPreferencesFeedbackCB);
@@ -1929,21 +1790,21 @@ bool FormPreferences::Language::input(FL_OBJECT const * const ob)
        }
 
        if (ob == dialog_->button_kbmap1_browse) {
-               string const dir  = system_lyxdir + string("kbd");
+               string const dir  = AddName(system_lyxdir, "kbd");
                string const name = N_("Key maps");
                pair<string, string> dir1(name, dir);
 
                parent_.browse(dialog_->input_kbmap1,
-                               _("Keyboard map"), "*.kmap", dir1,
-                               make_pair(string(), string()));
+                              N_("Keyboard map"), "*.kmap", dir1,
+                              make_pair(string(), string()));
        } else if (ob == dialog_->button_kbmap2_browse) {
-               string const dir  = system_lyxdir + string("kbd");
+               string const dir  = AddName(system_lyxdir, "kbd");
                string const name = N_("Key maps");
                pair<string, string> dir1(name, dir);
 
                parent_.browse(dialog_->input_kbmap2,
-                               _("Keyboard map"), "*.kmap", dir1,
-                               make_pair(string(), string()));
+                              N_("Keyboard map"), "*.kmap", dir1,
+                              make_pair(string(), string()));
        }
 
        return activate;
@@ -2023,6 +1884,9 @@ void FormPreferences::LnFmisc::build()
 {
        dialog_ = parent_.build_lnf_misc();
 
+       fl_set_counter_step(dialog_->counter_autosave, 1, 10);
+       fl_set_counter_step(dialog_->counter_wm_jump, 1, 10);
+
        fl_set_counter_return(dialog_->counter_autosave, FL_RETURN_CHANGED);
        fl_set_counter_return(dialog_->counter_wm_jump, FL_RETURN_CHANGED);
 
@@ -2104,14 +1968,13 @@ void FormPreferences::OutputsMisc::build()
 {
        dialog_ = parent_.build_outputs_misc();
 
-       fl_set_counter_return(dialog_->counter_line_len,
-                             FL_RETURN_CHANGED);
-       fl_set_input_return(dialog_->input_tex_encoding,
-                           FL_RETURN_CHANGED);
-       fl_set_input_return(dialog_->input_ascii_roff,
-                           FL_RETURN_CHANGED);
-       fl_set_input_return(dialog_->input_checktex,
-                           FL_RETURN_CHANGED);
+       fl_set_counter_step(dialog_->counter_line_len, 1, 10);
+
+       fl_set_counter_return(dialog_->counter_line_len, FL_RETURN_CHANGED);
+       fl_set_input_return(dialog_->input_tex_encoding, FL_RETURN_CHANGED);
+       fl_set_input_return(dialog_->input_ascii_roff,   FL_RETURN_CHANGED);
+       fl_set_input_return(dialog_->input_checktex,     FL_RETURN_CHANGED);
+
        fl_addto_choice(dialog_->choice_default_papersize,
                        _(" default | US letter | legal | executive | A3 | A4 | A5 | B5 "));
 
@@ -2351,7 +2214,7 @@ bool FormPreferences::Paths::input(FL_OBJECT const * const ob)
                string const name = fl_get_input(dialog_->input_serverpipe);
                if (!name.empty()) {
                        // strip off the extension
-                       string str = ChangeExtension(name, "");
+                       string const str = ChangeExtension(name, "");
                        if (!RWInfo::WriteableFile(str + ".in")) {
                                parent_.printWarning(RWInfo::ErrorMessage());
                                return false;
@@ -2365,35 +2228,35 @@ bool FormPreferences::Paths::input(FL_OBJECT const * const ob)
 
        if (ob == dialog_->button_default_path_browse) {
                parent_.browse(dialog_->input_default_path,
-                               _("Default path"), string(),
-                               make_pair(string(), string()),
-                               make_pair(string(), string()));
+                              N_("Default path"), string(),
+                              make_pair(string(), string()),
+                              make_pair(string(), string()));
        } else if (ob == dialog_->button_template_path_browse) {
                parent_.browse(dialog_->input_template_path,
-                               _("Template path"), string(),
-                               make_pair(string(), string()),
-                               make_pair(string(), string()));
+                              N_("Template path"), string(),
+                              make_pair(string(), string()),
+                              make_pair(string(), string()));
        } else if (ob == dialog_->button_temp_dir_browse) {
                parent_.browse(dialog_->input_temp_dir,
-                               _("Temp dir"), string(),
-                               make_pair(string(), string()),
-                               make_pair(string(), string()));
+                              N_("Temp dir"), string(),
+                              make_pair(string(), string()),
+                              make_pair(string(), string()));
        } else if (ob == dialog_->button_lastfiles_browse) {
                pair<string, string> dir(_("User"), user_lyxdir);
 
                parent_.browse(dialog_->input_lastfiles,
-                               _("Lastfiles"), string(), dir,
-                               make_pair(string(), string()));
+                              N_("Lastfiles"), string(), dir,
+                              make_pair(string(), string()));
        } else if (ob == dialog_->button_backup_path_browse) {
                parent_.browse(dialog_->input_backup_path,
-                               _("Backup path"), string(),
-                               make_pair(string(), string()),
-                               make_pair(string(), string()));
+                              N_("Backup path"), string(),
+                              make_pair(string(), string()),
+                              make_pair(string(), string()));
        } else if (ob == dialog_->button_serverpipe_browse) {
                parent_.browse(dialog_->input_serverpipe,
-                               _("LyX Server pipes"), string(),
-                               make_pair(string(), string()),
-                               make_pair(string(), string()));
+                              N_("LyX Server pipes"), string(),
+                              make_pair(string(), string()),
+                              make_pair(string(), string()));
        }
        
        return activate;
@@ -2506,9 +2369,9 @@ FormPreferences::Printer::feedback(FL_OBJECT const * const ob) const
        else if (ob == dialog_->input_landscape)
                str = lyxrc.getDescription(LyXRC::RC_PRINTLANDSCAPEFLAG);
        else if (ob == dialog_->input_copies)
-               str = lyxrc.getDescription(LyXRC::RC_PRINTCOLLCOPIESFLAG);
-       else if (ob == dialog_->input_collated)
                str = lyxrc.getDescription(LyXRC::RC_PRINTCOPIESFLAG);
+       else if (ob == dialog_->input_collated)
+               str = lyxrc.getDescription(LyXRC::RC_PRINTCOLLCOPIESFLAG);
        else if (ob == dialog_->input_paper_type)
                str = lyxrc.getDescription(LyXRC::RC_PRINTPAPERFLAG);
        else if (ob == dialog_->input_paper_size)
@@ -2729,45 +2592,36 @@ void FormPreferences::ScreenFonts::build()
 {
        dialog_ = parent_.build_screen_fonts();
 
-       fl_set_input_return(dialog_->input_roman, FL_RETURN_CHANGED);
-       fl_set_input_return(dialog_->input_sans, FL_RETURN_CHANGED);
-       fl_set_input_return(dialog_->input_typewriter,
-                           FL_RETURN_CHANGED);
-       fl_set_input_return(dialog_->input_screen_encoding,
-                           FL_RETURN_CHANGED);
-       fl_set_counter_return(dialog_->counter_zoom, FL_RETURN_CHANGED);
-       fl_set_counter_return(dialog_->counter_dpi, FL_RETURN_CHANGED);
-       fl_set_input_return(dialog_->input_tiny, FL_RETURN_CHANGED);
-       fl_set_input_return(dialog_->input_script, FL_RETURN_CHANGED);
-       fl_set_input_return(dialog_->input_footnote, FL_RETURN_CHANGED);
-       fl_set_input_return(dialog_->input_small, FL_RETURN_CHANGED);
-       fl_set_input_return(dialog_->input_normal, FL_RETURN_CHANGED);
-       fl_set_input_return(dialog_->input_large, FL_RETURN_CHANGED);
-       fl_set_input_return(dialog_->input_larger, FL_RETURN_CHANGED);
-       fl_set_input_return(dialog_->input_largest, FL_RETURN_CHANGED);
-       fl_set_input_return(dialog_->input_huge, FL_RETURN_CHANGED);
-       fl_set_input_return(dialog_->input_huger, FL_RETURN_CHANGED);
-
-       fl_set_input_filter(dialog_->input_tiny,
-                           fl_unsigned_int_filter);
-       fl_set_input_filter(dialog_->input_script,
-                           fl_unsigned_int_filter);
-       fl_set_input_filter(dialog_->input_footnote,
-                           fl_unsigned_int_filter);
-       fl_set_input_filter(dialog_->input_small,
-                           fl_unsigned_int_filter);
-       fl_set_input_filter(dialog_->input_normal,
-                           fl_unsigned_int_filter);
-       fl_set_input_filter(dialog_->input_large,
-                           fl_unsigned_int_filter);
-       fl_set_input_filter(dialog_->input_larger,
-                           fl_unsigned_int_filter);
-       fl_set_input_filter(dialog_->input_largest,
-                           fl_unsigned_int_filter);
-       fl_set_input_filter(dialog_->input_huge,
-                           fl_unsigned_int_filter);
-       fl_set_input_filter(dialog_->input_huger,
-                           fl_unsigned_int_filter);
+       fl_set_counter_step(dialog_->counter_zoom, 1, 10);
+       fl_set_counter_step(dialog_->counter_dpi,  1, 10);
+
+       fl_set_input_return(dialog_->input_roman,           FL_RETURN_CHANGED);
+       fl_set_input_return(dialog_->input_sans,            FL_RETURN_CHANGED);
+       fl_set_input_return(dialog_->input_typewriter,      FL_RETURN_CHANGED);
+       fl_set_input_return(dialog_->input_screen_encoding, FL_RETURN_CHANGED);
+       fl_set_counter_return(dialog_->counter_zoom,        FL_RETURN_CHANGED);
+       fl_set_counter_return(dialog_->counter_dpi,         FL_RETURN_CHANGED);
+       fl_set_input_return(dialog_->input_tiny,            FL_RETURN_CHANGED);
+       fl_set_input_return(dialog_->input_script,          FL_RETURN_CHANGED);
+       fl_set_input_return(dialog_->input_footnote,        FL_RETURN_CHANGED);
+       fl_set_input_return(dialog_->input_small,           FL_RETURN_CHANGED);
+       fl_set_input_return(dialog_->input_normal,          FL_RETURN_CHANGED);
+       fl_set_input_return(dialog_->input_large,           FL_RETURN_CHANGED);
+       fl_set_input_return(dialog_->input_larger,          FL_RETURN_CHANGED);
+       fl_set_input_return(dialog_->input_largest,         FL_RETURN_CHANGED);
+       fl_set_input_return(dialog_->input_huge,            FL_RETURN_CHANGED);
+       fl_set_input_return(dialog_->input_huger,           FL_RETURN_CHANGED);
+
+       fl_set_input_filter(dialog_->input_tiny,     fl_unsigned_float_filter);
+       fl_set_input_filter(dialog_->input_script,   fl_unsigned_float_filter);
+       fl_set_input_filter(dialog_->input_footnote, fl_unsigned_float_filter);
+       fl_set_input_filter(dialog_->input_small,    fl_unsigned_float_filter);
+       fl_set_input_filter(dialog_->input_normal,   fl_unsigned_float_filter);
+       fl_set_input_filter(dialog_->input_large,    fl_unsigned_float_filter);
+       fl_set_input_filter(dialog_->input_larger,   fl_unsigned_float_filter);
+       fl_set_input_filter(dialog_->input_largest,  fl_unsigned_float_filter);
+       fl_set_input_filter(dialog_->input_huge,     fl_unsigned_float_filter);
+       fl_set_input_filter(dialog_->input_huger,    fl_unsigned_float_filter);
 
        // set up the feedback mechanism
        setPreHandler(dialog_->input_roman);
@@ -2984,12 +2838,9 @@ void FormPreferences::SpellChecker::build()
 
        fl_addto_choice(dialog_->choice_spell_command,
                        _(" none | ispell | aspell "));
-       fl_set_input_return(dialog_->input_alt_lang,
-                           FL_RETURN_CHANGED);
-       fl_set_input_return(dialog_->input_escape_chars,
-                           FL_RETURN_CHANGED);
-       fl_set_input_return(dialog_->input_personal_dict,
-                           FL_RETURN_CHANGED);
+       fl_set_input_return(dialog_->input_alt_lang,      FL_RETURN_CHANGED);
+       fl_set_input_return(dialog_->input_escape_chars,  FL_RETURN_CHANGED);
+       fl_set_input_return(dialog_->input_personal_dict, FL_RETURN_CHANGED);
 
        // set up the feedback mechanism
        setPreHandler(dialog_->choice_spell_command);
@@ -3098,9 +2949,9 @@ bool FormPreferences::SpellChecker::input(FL_OBJECT const * const ob)
 
        if (ob == dialog_->button_personal_dict) {
                parent_.browse(dialog_->input_personal_dict,
-                               _("Personal dictionary"), "*.ispell",
-                               make_pair(string(), string()),
-                               make_pair(string(), string()));
+                              N_("Personal dictionary"), "*.ispell",
+                              make_pair(string(), string()),
+                              make_pair(string(), string()));
        }
        
        return true; // All input is valid!
@@ -3154,7 +3005,7 @@ void FormPreferences::printWarning(string const & warning)
 {
        warningPosted = true;
 
-       string str = N_("WARNING!") + string(" ") + warning;
+       string str = _("WARNING!") + string(" ") + warning;
        str = formatted(str, dialog_->text_warning->w-10,
                         FL_SMALL_SIZE, FL_NORMAL_STYLE);
 
@@ -3185,7 +3036,12 @@ void FormPreferences::browse(FL_OBJECT * inpt,
 
 
 // C function wrapper, required by xforms.
-C_PREPOSTHANDLER(FormPreferences, FeedbackCB)
+extern "C" int C_FormPreferencesFeedbackCB(FL_OBJECT * ob, int event,
+                                          FL_Coord mx, FL_Coord my,
+                                          int key, void * xev)
+{
+       return FormPreferences::FeedbackCB(ob, event, mx, my, key, xev);
+}
 
 int FormPreferences::FeedbackCB(FL_OBJECT * ob, int event,
                                FL_Coord, FL_Coord, int, void *)
@@ -3228,11 +3084,8 @@ void FormPreferences::Feedback(FL_OBJECT * ob, int event)
 }
 
 
-
-
 void FormPreferences::setPreHandler(FL_OBJECT * ob)
 {
        Assert(ob);
        fl_set_object_prehandler(ob, C_FormPreferencesFeedbackCB);
 }
-