]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/xforms/FormPreferences.C
fix crash with "save as"
[lyx.git] / src / frontends / xforms / FormPreferences.C
index 4e174dd294ecd7651e8d6455ffe6fe9698b7d7a2..302712e24073f08da4df2149c0d23f842f8b9d8c 100644 (file)
-// -*- C++ -*-
-/* This file is part of
- * ======================================================
- * 
- *           LyX, The Document Processor
- *      
- *         Copyright 1995 Matthias Ettrich
- *          Copyright 1995-2000 The LyX Team.
+/**
+ * \file FormPreferences.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
  *
- *======================================================*/
-/* FormPreferences.C
- * FormPreferences Interface Class Implementation
+ * \author Angus Leeming
+ *
+ * Full author contact details are available in file CREDITS
  */
 
 #include <config.h>
 
-#include <utility>
-#include <X11/Xlib.h>
-
-#include FORMS_H_LOCATION
-
-#ifdef __GNUG_
+#ifdef __GNUG__
 #pragma implementation
 #endif
 
-#include "Color.h"
-#include "LColor.h"
-#include "Lsstream.h"
+#include "ControlPrefs.h"
 #include "FormPreferences.h"
-#include "form_preferences.h"
-#include "input_validators.h"
-#include "LyXView.h"
-#include "language.h"
-#include "lyxfunc.h"
-#include "Dialogs.h"
-#include "lyxrc.h"
+#include "forms/form_preferences.h"
+#include "xformsBC.h"
+
 #include "combox.h"
-#include "debug.h"
-#include "support/filetools.h"
-#include "lyx_gui_misc.h" // idex, scex
-#include "lyxlex.h"
+#include "Color.h"
 #include "input_validators.h"
-#include "xform_helpers.h"
-#include "xform_macros.h"
+#include "forms_gettext.h"
+#include "xforms_helpers.h"
+#include "helper_funcs.h" // getSecond
+
+#include "buffer.h"
 #include "converter.h"
+#include "debug.h"
+#include "language.h"
+#include "frnt_lang.h"
+#include "lyxlex.h"
+#include "lyxrc.h"
+#include "LColor.h"
+#include "Lsstream.h"
+#include "funcrequest.h"
+
 #include "support/lyxfunctional.h"
 #include "support/lyxmanip.h"
+#include "support/filetools.h"
+#include "support/LAssert.h"
+
+#include "graphics/GraphicsCache.h"
+#include "graphics/GraphicsTypes.h"
+
+#include <boost/bind.hpp>
+
+#include FORMS_H_LOCATION
+#include <utility>
+#include <iomanip>
+#include <X11/Xlib.h>
 
 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::setw;
+using std::setfill;
 
 extern string system_lyxdir;
 extern string user_lyxdir;
-extern Languages languages;
-
-// These should probably go inside the class definition...
-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),  lang_opts_tab_(0),
-         warningPosted(false),
-         colors_(*this), converters_(*this), inputs_misc_(*this),
-         formats_(*this), interface_(*this), language_(*this), 
-         lnf_misc_(*this), outputs_misc_(*this), paths_(*this),
-         printer_(*this), screen_fonts_(*this), spellchecker_(*this)
-{
-       // let the dialog be shown
-       // This is a permanent connection so we won't bother
-       // storing a copy because we won't be disconnecting.
-       d->showPreferences.connect(slot(this, &FormPreferences::show));
-}
 
+namespace {
 
-FormPreferences::~FormPreferences()
-{
-       delete converters_tab_;
-       delete inputs_tab_;
-       delete look_n_feel_tab_;
-       delete outputs_tab_;
-       delete lang_opts_tab_;
-
-       delete dialog_;
-}
-
+// These should probably go inside the class definition...
+Formats    local_formats;
+Converters local_converters;
 
-void FormPreferences::connect()
-{
-       fl_set_form_maxsize( dialog_->form, minw_, minh_ );
+} // namespace anon
 
-       FormBaseBI::connect();
-}
 
+typedef FormCB<ControlPrefs, FormDB<FD_preferences> > base_class;
 
-void FormPreferences::disconnect()
+FormPreferences::FormPreferences()
+       : base_class(_("Preferences"), false),
+         colors_(*this), converters_(*this), inputs_misc_(*this),
+         formats_(*this), interface_(*this), language_(*this),
+         lnf_misc_(*this), outputs_misc_(*this), paths_(*this),
+         printer_(*this), screen_fonts_(*this), spelloptions_(*this)
 {
-       // colors_->disconnect();
-       // converters_->disconnect(); //local_converters.Clear();
-       // formats_->disconnect();    //local_formats.Clear();
-
-       FormBaseBI::disconnect();
 }
 
 
@@ -129,80 +98,73 @@ void FormPreferences::redraw()
 
        FL_FORM * form3 = 0;
        if (form2 == converters_tab_->form)
-               form3 = fl_get_active_folder(converters_tab_->tabfolder_outer);
+               form3 = fl_get_active_folder(converters_tab_->tabfolder_inner);
 
        else if (form2 == look_n_feel_tab_->form)
-               form3 = fl_get_active_folder(look_n_feel_tab_->tabfolder_outer);
+               form3 = fl_get_active_folder(look_n_feel_tab_->tabfolder_inner);
 
        else if (form2 == inputs_tab_->form)
-               form3 = fl_get_active_folder(inputs_tab_->tabfolder_outer);
+               form3 = fl_get_active_folder(inputs_tab_->tabfolder_inner);
 
        else if (form2 == outputs_tab_->form)
-               form3 = fl_get_active_folder(outputs_tab_->tabfolder_outer);
+               form3 = fl_get_active_folder(outputs_tab_->tabfolder_inner);
 
        else if (form2 == lang_opts_tab_->form)
-               form3 = fl_get_active_folder(lang_opts_tab_->tabfolder_outer);
+               form3 = fl_get_active_folder(lang_opts_tab_->tabfolder_inner);
 
        if (form3 && form3->visible)
                fl_redraw_form(form3);
 }
 
 
-FL_FORM * FormPreferences::form() const
-{
-       if (dialog_) return dialog_->form;
-       return 0;
-}
-
-
+#if 0 
 void FormPreferences::ok()
 {
-       FormBase::ok();
+       FormBaseDeprecated::ok();
 
-       if (colors_.modifiedXformPrefs) {
+// FIXME !! 
+       if (colors_.modifiedXformsPrefs) {
                string const filename =
                        AddName(user_lyxdir, "preferences.xform");
-               colors_.modifiedXformPrefs = !XformColor::write(filename);
+               colors_.modifiedXformsPrefs = !XformsColor::write(filename);
        }
-       
-       lv_->getLyXFunc()->Dispatch(LFUN_SAVEPREFERENCES);
+
+       lv_.dispatch(FuncRequest(LFUN_SAVEPREFERENCES));
 }
+#endif 
+
 
 
 void FormPreferences::hide()
 {
        // We need to hide the active tabfolder otherwise we get a
-       // BadDrawable error from X windows and LyX crashes without saving.
-       FL_FORM * outer_form = fl_get_active_folder(dialog_->tabfolder_prefs);
-       if (outer_form
-           && outer_form->visible) {
-               fl_hide_form(outer_form);
-       }
+       // BadDrawable error from X window and LyX crashes without saving.
+       FL_FORM * inner_form = fl_get_active_folder(dialog_->tabfolder_prefs);
+       if (inner_form && inner_form->visible)
+               fl_hide_form(inner_form);
        FormBase::hide();
 }
 
 
 void FormPreferences::build()
 {
-       dialog_ = build_preferences();
+       dialog_.reset(build_preferences(this));
 
-       // manage the restore, save, apply and cancel/close buttons
-       bc_.setOK(dialog_->button_ok);
-       bc_.setApply(dialog_->button_apply);
-       bc_.setCancel(dialog_->button_cancel);
-       bc_.setUndoAll(dialog_->button_restore);
-       bc_.refresh();
+       // Manage the restore, save, apply and cancel/close buttons
+       bc().setOK(dialog_->button_ok);
+       bc().setApply(dialog_->button_apply);
+       bc().setCancel(dialog_->button_close);
+       bc().setRestore(dialog_->button_restore);
 
-       // Workaround dumb xforms sizing bug
-       minw_ = form()->w;
-       minh_ = form()->h;
+       // Allow the base class to control messages
+       setMessageWidget(dialog_->text_warning);
 
        // build the tab folders
-       converters_tab_ = build_outer_tab();
-       look_n_feel_tab_ = build_outer_tab();
-       inputs_tab_ = build_outer_tab();
-       outputs_tab_ = build_outer_tab();
-       lang_opts_tab_ = build_outer_tab();
+       converters_tab_.reset(build_preferences_inner_tab(this));
+       look_n_feel_tab_.reset(build_preferences_inner_tab(this));
+       inputs_tab_.reset(build_preferences_inner_tab(this));
+       outputs_tab_.reset(build_preferences_inner_tab(this));
+       lang_opts_tab_.reset(build_preferences_inner_tab(this));
 
        // build actual tabfolder contents
        // these will become nested tabfolders
@@ -217,7 +179,7 @@ void FormPreferences::build()
        paths_.build();
        printer_.build();
        screen_fonts_.build();
-       spellchecker_.build();
+       spelloptions_.build();
 
        // Now add them to the tabfolder
        fl_addto_tabfolder(dialog_->tabfolder_prefs,
@@ -227,7 +189,7 @@ void FormPreferences::build()
                           _("Lang Opts"),
                           lang_opts_tab_->form);
        fl_addto_tabfolder(dialog_->tabfolder_prefs,
-                          _("Converters"),
+                          _("Conversion"),
                           converters_tab_->form);
        fl_addto_tabfolder(dialog_->tabfolder_prefs,
                           _("Inputs"),
@@ -238,51 +200,58 @@ void FormPreferences::build()
 
        // now build the nested tabfolders
        // Starting with look and feel
-       fl_addto_tabfolder(look_n_feel_tab_->tabfolder_outer,
+       fl_addto_tabfolder(look_n_feel_tab_->tabfolder_inner,
                           _("Screen Fonts"),
                           screen_fonts_.dialog()->form);
-       fl_addto_tabfolder(look_n_feel_tab_->tabfolder_outer,
+       fl_addto_tabfolder(look_n_feel_tab_->tabfolder_inner,
                           _("Interface"),
                           interface_.dialog()->form);
-       fl_addto_tabfolder(look_n_feel_tab_->tabfolder_outer,
+       fl_addto_tabfolder(look_n_feel_tab_->tabfolder_inner,
                           _("Colors"),
                           colors_.dialog()->form);
-       fl_addto_tabfolder(look_n_feel_tab_->tabfolder_outer,
+       fl_addto_tabfolder(look_n_feel_tab_->tabfolder_inner,
                           _("Misc"),
                           lnf_misc_.dialog()->form);
 
        // then build converters
-       fl_addto_tabfolder(converters_tab_->tabfolder_outer,
+       fl_addto_tabfolder(converters_tab_->tabfolder_inner,
                           _("Formats"),
                           formats_.dialog()->form);
-       fl_addto_tabfolder(converters_tab_->tabfolder_outer,
+       fl_addto_tabfolder(converters_tab_->tabfolder_inner,
                           _("Converters"),
                           converters_.dialog()->form);
 
        // then build inputs
-       // Paths should probably go in a few outer_tab called Files
-       fl_addto_tabfolder(inputs_tab_->tabfolder_outer,
+       // Paths should probably go in a few inner_tab called Files
+       fl_addto_tabfolder(inputs_tab_->tabfolder_inner,
                           _("Paths"),
                           paths_.dialog()->form);
-       fl_addto_tabfolder(inputs_tab_->tabfolder_outer,
+       fl_addto_tabfolder(inputs_tab_->tabfolder_inner,
                           _("Misc"),
                           inputs_misc_.dialog()->form);
 
        // then building outputs
-       fl_addto_tabfolder(outputs_tab_->tabfolder_outer,
+       fl_addto_tabfolder(outputs_tab_->tabfolder_inner,
                           _("Printer"),
                           printer_.dialog()->form);
-       fl_addto_tabfolder(outputs_tab_->tabfolder_outer,
+       fl_addto_tabfolder(outputs_tab_->tabfolder_inner,
                           _("Misc"),
                           outputs_misc_.dialog()->form);
 
        // then building usage
-       fl_addto_tabfolder(lang_opts_tab_->tabfolder_outer,
+       fl_addto_tabfolder(lang_opts_tab_->tabfolder_inner,
                           _("Spell checker"),
-                          spellchecker_.dialog()->form);
-       fl_addto_tabfolder(lang_opts_tab_->tabfolder_outer,
+                          spelloptions_.dialog()->form);
+       fl_addto_tabfolder(lang_opts_tab_->tabfolder_inner,
                           _("Language"),
                           language_.dialog()->form);
+
+       // work-around xforms bug re update of folder->x, folder->y coords.
+       setPrehandler(look_n_feel_tab_->tabfolder_inner);
+       setPrehandler(converters_tab_->tabfolder_inner);
+       setPrehandler(inputs_tab_->tabfolder_inner);
+       setPrehandler(outputs_tab_->tabfolder_inner);
+       setPrehandler(lang_opts_tab_->tabfolder_inner);
 }
 
 
@@ -299,114 +268,120 @@ void FormPreferences::apply()
        // and other stuff which may cost us a lot on slower/high-load
        // machines.
 
+       lyxerr << "apply in form !" << endl;
+       LyXRC & rc(controller().rc());
        colors_.apply();
        formats_.apply();    // Must be before converters_.apply()
        converters_.apply();
-       inputs_misc_.apply();
-       interface_.apply();
-       language_.apply();
-       lnf_misc_.apply();
-       outputs_misc_.apply();
-       paths_.apply();
-       printer_.apply();
-       screen_fonts_.apply();
-       spellchecker_.apply();
-}
-
-
-void FormPreferences::feedback(FL_OBJECT * ob)
-{
-       Assert(ob);
-
-       string str;
-
-       if (ob->form->fdui == colors_.dialog()) {
-               str = colors_.feedback(ob);
-       } else if (ob->form->fdui == converters_.dialog()) {
-               str = converters_.feedback(ob);
-       } else if (ob->form->fdui == formats_.dialog()) {
-               str = formats_.feedback(ob);
-       } else if (ob->form->fdui == inputs_misc_.dialog()) {
-               str = inputs_misc_.feedback(ob);
-       } else if (ob->form->fdui == interface_.dialog()) {
-               str = interface_.feedback(ob);
-       } else if (ob->form->fdui == language_.dialog()) {
-               str = language_.feedback(ob);
-       } else if (ob->form->fdui == lnf_misc_.dialog()) {
-               str = lnf_misc_.feedback(ob);
-       } else if (ob->form->fdui == outputs_misc_.dialog()) {
-               str = outputs_misc_.feedback(ob);
-       } else if (ob->form->fdui == paths_.dialog()) {
-               str = paths_.feedback(ob);
-       } else if (ob->form->fdui == printer_.dialog()) {
-               str = printer_.feedback(ob);
-       } else if (ob->form->fdui == screen_fonts_.dialog()) {
-               str = screen_fonts_.feedback(ob);
-       } else if (ob->form->fdui == spellchecker_.dialog()) {
-               str = spellchecker_.feedback(ob);
-       }
-
-       str = formatted(str, dialog_->text_warning->w-10,
-                       FL_SMALL_SIZE, FL_NORMAL_STYLE);
-
-       fl_set_object_label(dialog_->text_warning, str.c_str());
-       fl_set_object_lsize(dialog_->text_warning, FL_SMALL_SIZE);
-}
-
-
-bool FormPreferences::input(FL_OBJECT * ob, long)
-{
-       Assert(ob);
-       
+       inputs_misc_.apply(rc);
+       interface_.apply(rc);
+       language_.apply(rc);
+       lnf_misc_.apply(rc);
+       outputs_misc_.apply(rc);
+       paths_.apply(rc);
+       printer_.apply(rc);
+       screen_fonts_.apply(rc);
+       spelloptions_.apply(rc);
+}
+
+
+string const FormPreferences::getFeedback(FL_OBJECT * ob)
+{
+       lyx::Assert(ob);
+
+       if (ob->form->fdui == colors_.dialog())
+               return colors_.feedback(ob);
+       if (ob->form->fdui == converters_.dialog())
+               return converters_.feedback(ob);
+       if (ob->form->fdui == formats_.dialog())
+               return formats_.feedback(ob);
+       if (ob->form->fdui == inputs_misc_.dialog())
+               return inputs_misc_.feedback(ob);
+       if (ob->form->fdui == interface_.dialog())
+               return interface_.feedback(ob);
+       if (ob->form->fdui == language_.dialog())
+               return language_.feedback(ob);
+       if (ob->form->fdui == lnf_misc_.dialog())
+               return lnf_misc_.feedback(ob);
+       if (ob->form->fdui == outputs_misc_.dialog())
+               return outputs_misc_.feedback(ob);
+       if (ob->form->fdui == paths_.dialog())
+               return paths_.feedback(ob);
+       if (ob->form->fdui == printer_.dialog())
+               return printer_.feedback(ob);
+       if (ob->form->fdui == screen_fonts_.dialog())
+               return screen_fonts_.feedback(ob);
+       if (ob->form->fdui == spelloptions_.dialog())
+               return spelloptions_.feedback(ob);
+
+       return string();
+}
+
+
+ButtonPolicy::SMInput FormPreferences::input(FL_OBJECT * ob, long)
+{
+       lyx::Assert(ob);
+
+       bool valid = true;
        // whatever checks you need to ensure the user hasn't entered
        // some totally ridiculous value somewhere.  Change activate to suit.
        // comments before each test describe what is _valid_
 
        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);
-       else if (ob->form->fdui == interface_.dialog())
-               return interface_.input(ob);
-       else if (ob->form->fdui == language_.dialog())
-               return language_.input(ob);
-       else if (ob->form->fdui == paths_.dialog())
-               return paths_.input(ob);
-       else if (ob->form->fdui == screen_fonts_.dialog())
-               return screen_fonts_.input();
-       else if (ob->form->fdui == spellchecker_.dialog())
-               return spellchecker_.input(ob);
+       } else if (ob->form->fdui == converters_.dialog()) {
+               valid = converters_.input(ob);
+       } else if (ob->form->fdui == formats_.dialog()) {
+               valid = formats_.input(ob);
+       } else if  (ob->form->fdui == interface_.dialog()) {
+               valid = interface_.input(ob);
+       } else if  (ob->form->fdui == language_.dialog()) {
+               valid = language_.input(ob);
+       } else if  (ob->form->fdui == paths_.dialog()) {
+               valid = paths_.input(ob);
+       } else if  (ob->form->fdui == screen_fonts_.dialog()) {
+               valid = screen_fonts_.input();
+       } else if  (ob->form->fdui == spelloptions_.dialog()) {
+               valid = spelloptions_.input(ob);
+       }
 
-       return true;
+       return valid ? ButtonPolicy::SMI_VALID : ButtonPolicy::SMI_INVALID;
 }
 
 
 void FormPreferences::update()
 {
-       if (!dialog_) return;
-    
+       if (!dialog_.get()) return;
+
+       LyXRC const & rc(controller().rc());
        // read lyxrc entries
        colors_.update();
        formats_.update();   // Must be before converters_.update()
        converters_.update();
-       inputs_misc_.update();
-       interface_.update();
-       language_.update();
-       lnf_misc_.update();
-       outputs_misc_.update();
-       paths_.update();
-       printer_.update();
-       screen_fonts_.update();
-       spellchecker_.update();
+       inputs_misc_.update(rc);
+       interface_.update(rc);
+       language_.update(rc);
+       lnf_misc_.update(rc);
+       outputs_misc_.update(rc);
+       paths_.update(rc);
+       printer_.update(rc);
+       screen_fonts_.update(rc);
+       spelloptions_.update(rc);
 }
 
 
-FormPreferences::Colors::~Colors()
+FormPreferences::Colors::Colors(FormPreferences & p)
+       : modifiedXformsPrefs(false), parent_(p)
+{}
+
+
+FD_preferences_colors const * FormPreferences::Colors::dialog()
 {
-       delete dialog_;
+       return dialog_.get();
 }
 
 
@@ -415,66 +390,65 @@ void FormPreferences::Colors::apply()
        bool modifiedText = false;
        bool modifiedBackground = false;
 
-       for (vector<XformColor>::const_iterator cit = xformColorDB.begin();
-            cit != xformColorDB.end(); ++cit) {
+       for (vector<XformsColor>::const_iterator cit = xformsColorDB.begin();
+            cit != xformsColorDB.end(); ++cit) {
                RGBColor col;
-               fl_getmcolor((*cit).colorID, &col.r, &col.g, &col.b);
-               if (col != (*cit).color()) {
-                       modifiedXformPrefs = true;
-                       if ((*cit).colorID == FL_BLACK)
+               fl_getmcolor(cit->colorID, &col.r, &col.g, &col.b);
+               if (col != cit->color()) {
+                       modifiedXformsPrefs = true;
+                       if (cit->colorID == FL_BLACK)
                                modifiedText = true;
-                       if ((*cit).colorID == FL_COL1)
+                       if (cit->colorID == FL_COL1)
                                modifiedBackground = true;
                }
        }
 
-       if (modifiedXformPrefs) {
-               for (vector<XformColor>::const_iterator cit =
-                            xformColorDB.begin(); 
-                    cit != xformColorDB.end(); ++cit) {
-                       fl_mapcolor((*cit).colorID,
-                                   (*cit).r, (*cit).g, (*cit).b);
+       if (modifiedXformsPrefs) {
+               for (vector<XformsColor>::const_iterator cit =
+                            xformsColorDB.begin();
+                    cit != xformsColorDB.end(); ++cit) {
+                       fl_mapcolor(cit->colorID, cit->r, cit->g, cit->b);
 
-                       if (modifiedText && (*cit).colorID == FL_BLACK) {
+                       if (modifiedText && cit->colorID == FL_BLACK) {
                                AdjustVal(FL_INACTIVE, FL_BLACK, 0.5);
                        }
 
-                       if (modifiedBackground && (*cit).colorID == FL_COL1) {
+                       if (modifiedBackground && cit->colorID == FL_COL1) {
                                AdjustVal(FL_MCOL,      FL_COL1, 0.1);
                                AdjustVal(FL_TOP_BCOL,  FL_COL1, 0.1);
                                AdjustVal(FL_LEFT_BCOL, FL_COL1, 0.1);
 
                                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);
+                               setCursorColor(GUI_COLOR_CURSOR);
+                       }
                }
-               Dialogs::redrawGUI();
+               parent_.controller().redrawGUI();
        }
 
        // Now do the same for the LyX LColors...
        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(colorDB.begin(), colorDB.end(), 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);
+               LColor::color lc = lcolor.getFromGUIName(cit->getname());
+               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;
+
+                       parent_.controller().setColor(lc, hexname);
                }
        }
 }
@@ -482,120 +456,93 @@ void FormPreferences::Colors::apply()
 
 void FormPreferences::Colors::build()
 {
-       dialog_ = parent_.build_colors();
+       dialog_.reset(build_preferences_colors(&parent_));
 
-       fl_set_object_color(dialog_->button_color, FL_FREE_COL1, FL_FREE_COL1);
+       fl_set_object_color(dialog_->button_color,
+                           GUI_COLOR_CHOICE, GUI_COLOR_CHOICE);
 
-       fl_set_object_color(dialog_->dial_hue, FL_FREE_COL2, 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);
 
-       // 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);
+       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);
 
-               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_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_object_label(dialog_->text_file_warning, str.c_str());
-               fl_set_object_lsize(dialog_->text_file_warning, FL_SMALL_SIZE);
+       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);
 
-               fl_unfreeze_form(dialog_->form);
-       }
+       // set up the feedback mechanism
+       setPrehandler(dialog_->browser_lyx_objs);
+       setPrehandler(dialog_->button_color);
+       setPrehandler(dialog_->button_modify);
+       setPrehandler(dialog_->dial_hue);
+       setPrehandler(dialog_->slider_saturation);
+       setPrehandler(dialog_->slider_value);
+       setPrehandler(dialog_->slider_red);
+       setPrehandler(dialog_->slider_green);
+       setPrehandler(dialog_->slider_blue);
+       setPrehandler(dialog_->radio_rgb);
+       setPrehandler(dialog_->radio_hsv);
 }
 
+
 string const
 FormPreferences::Colors::feedback(FL_OBJECT const * const ob) const
 {
-       string str;
+       if (ob == dialog_->browser_lyx_objs)
+               return _("LyX objects that can be assigned a color.");
 
-       if (ob == dialog_->browser_x11) {
-               str = N_("The colors listed in the X11 database.");
-       } else 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.");
-       }
+       if (ob == dialog_->button_modify)
+               return _("Modify the LyX object's color. Note: you must then \"Apply\" the change.");
+
+       if (ob == dialog_->dial_hue ||
+                 ob == dialog_->slider_saturation ||
+                 ob == dialog_->slider_value ||
+                 ob == dialog_->slider_red ||
+                 ob == dialog_->slider_green ||
+                 ob == dialog_->slider_blue)
+               return  _("Find a new color.");
 
-       return str;
+       if (ob == dialog_->radio_rgb || ob == dialog_->radio_hsv)
+               return _("Toggle between RGB and HSV color spaces.");
+
+       return string();
 }
 
 
 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 ||
                   ob == dialog_->slider_saturation ||
                   ob == dialog_->slider_value) {
                InputHSV();
 
-       } else if (ob == dialog_->input_name) {
-               LoadDatabase();
-
-       } 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_->slider_red ||
+                  ob == dialog_->slider_green ||
+                  ob == dialog_->slider_blue) {
+               InputRGB();
+
+       } else if (ob == dialog_->radio_rgb ||
+                  ob == dialog_->radio_hsv) {
+               SwitchColorSpace();
 
        } else if (ob == dialog_->button_modify) {
                Modify();
@@ -611,7 +558,7 @@ void FormPreferences::Colors::AdjustVal(int colAdjust, int colParent,
 
        HSVColor hsv(rgb);
        hsv.v += addVal;
-       hsv.v = min( 1.0, max(0.0, hsv.v) );
+       hsv.v = min(1.0, max(0.0, hsv.v));
 
        rgb = RGBColor(hsv);
        fl_mapcolor(colAdjust, rgb.r, rgb.g, rgb.b);
@@ -625,144 +572,159 @@ void FormPreferences::Colors::InputBrowserLyX() const
        if (selLyX < 1) return;
 
        // Is the choice an Xforms color...
-       RGBColor color;
+       RGBColor col;
 
-       if( selLyX-1 < int(xformColorDB.size()) ) {
-               vector<XformColor>::size_type const i = selLyX - 1;
-               color = xformColorDB[i].color();
+       if (selLyX - 1 < xformsColorDB.size()) {
+               vector<XformsColor>::size_type const i = selLyX - 1;
+               col = xformsColorDB[i].color();
        }
        // or a LyX Logical color?
        else {
                vector<NamedColor>::size_type const i = selLyX - 1 -
-                                                       xformColorDB.size();
-               color = lyxColorDB[i].color();
+                       xformsColorDB.size();
+               col = lyxColorDB[i].color();
        }
 
-       vector<NamedColor>::const_iterator cit =
-               find(colorDB.begin(), colorDB.end(), color);
-       if (cit == colorDB.end())  return;
+       fl_freeze_form(dialog_->form);
+
+       fl_mapcolor(GUI_COLOR_CHOICE, col.r, col.g, col.b);
+       fl_redraw_object(dialog_->button_color);
 
-       int const j = static_cast<int>(cit - colorDB.begin());
+       // Display either RGB or HSV but not both!
+       SwitchColorSpace();
 
-       fl_set_browser_topline(dialog_->browser_x11, max(j-5, 1));
-       fl_select_browser_line(dialog_->browser_x11, j+1);
-       InputBrowserX11();
+       // Deactivate the modify button to begin with...
+       setEnabled(dialog_->button_modify, false);
 
-       fl_deactivate_object(dialog_->button_modify);
-       fl_set_object_lcol(dialog_->button_modify, FL_INACTIVE);
+       fl_unfreeze_form(dialog_->form);
 }
 
 
-void FormPreferences::Colors::InputBrowserX11() const
+void FormPreferences::Colors::InputHSV()
 {
-       int const i = fl_get_browser(dialog_->browser_x11);
-       if (i < 1) return;
+       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);
+
+       int const h = int(hue);
+       int const s = int(100.0 * sat);
+       int const v = int(100.0 * val);
+
+       string const label = tostr(h) + string(", ") + tostr(s) + string(", ") +
+               tostr(v);
+       fl_set_object_label(dialog_->text_color_values, label.c_str());
+
+       RGBColor col = HSVColor(hue, sat, val);
 
        fl_freeze_form(dialog_->form);
-       RGBColor const & col = colorDB[i-1].color();
-       
-       fl_mapcolor(FL_FREE_COL1, col.r, col.g, col.b);
-       fl_redraw_object(dialog_->button_color);
 
-       HSVColor hsv(col);
-       
-       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_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_COL2, 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 const isSelected =
-               (line > 0 &&
-                line <= fl_get_browser_maxline(dialog_->browser_lyx_objs));
+       // 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;
 
-       if (isSelected) {
-               fl_activate_object(dialog_->button_modify);
-               fl_set_object_lcol(dialog_->button_modify, FL_BLACK);
+       fl_getmcolor(GUI_COLOR_CHOICE, &col.r, &col.g, &col.b);
+       bool modify = false;
+
+       // Is the choice an Xforms color...
+       if (selLyX - 1 < xformsColorDB.size()) {
+               vector<XformsColor>::size_type const i = selLyX - 1;
+               modify = (xformsColorDB[i].color() != col);
+       }
+       // or a LyX Logical color?
+       else {
+               vector<NamedColor>::size_type const i = selLyX - 1 -
+                       xformsColorDB.size();
+               modify = (lyxColorDB[i].color() != col);
        }
 
-       fl_unfreeze_form(dialog_->form);
+       setEnabled(dialog_->button_modify, modify);
 }
 
 
-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);
-       
-       fl_freeze_form(dialog_->form);
+       string const label = tostr(red) + string(", ") + tostr(green) +
+               string(", ") + tostr(blue);
+       fl_set_object_label(dialog_->text_color_values, label.c_str());
 
-       fl_set_browser_topline(dialog_->browser_x11, max(i-5, 1));
-       fl_select_browser_line(dialog_->browser_x11, i+1);
+       fl_freeze_form(dialog_->form);
 
-       fl_mapcolor(FL_FREE_COL1, 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 const isSelected =
-               (line > 0 &&
-                line <= fl_get_browser_maxline(dialog_->browser_lyx_objs));
+       // Ascertain whether to activate the Modify button.
+       vector<NamedColor>::size_type const selLyX =
+               fl_get_browser(dialog_->browser_lyx_objs);
 
-       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 );
-       }
+       fl_unfreeze_form(dialog_->form);
+       if (selLyX < 1) return;
 
-       // Finally, modify the color of the dial.
-       col = HSVColor(hue, 1.0, 1.0);
-       fl_mapcolor(FL_FREE_COL2, col.r, col.g, col.b);
-       fl_redraw_object(dialog_->dial_hue);
+       bool modify = false;
 
-       fl_unfreeze_form(dialog_->form);
+       // Is the choice an Xforms color...
+       if (selLyX - 1 < xformsColorDB.size()) {
+               vector<XformsColor>::size_type const i = selLyX - 1;
+               modify = (xformsColorDB[i].color() != col);
+       }
+       // or a LyX Logical color?
+       else {
+               vector<NamedColor>::size_type const i = selLyX - 1 -
+                       xformsColorDB.size();
+               modify = (lyxColorDB[i].color() != col);
+       }
+
+       setEnabled(dialog_->button_modify, modify);
 }
 
 
 void FormPreferences::Colors::LoadBrowserLyX()
 {
-       if (!dialog_->browser_lyx_objs->visible) return;
+       if (!dialog_->browser_lyx_objs->visible)
+               return;
 
-       // First, define the modifiable xform colors
-       xformColorDB.clear();
-       XformColor xcol;
+       // First, define the modifiable xforms colors
+       xformsColorDB.clear();
+       XformsColor 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);
+       xformsColorDB.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_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);
+       xformsColorDB.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);
+       xformsColorDB.push_back(xcol);
+
+       xcol.name = _("GUI pointer");
+       xcol.colorID = GUI_COLOR_CURSOR;
+       fl_getmcolor(GUI_COLOR_CURSOR, &xcol.r, &xcol.g, &xcol.b);
+
+       xformsColorDB.push_back(xcol);
 
        // Now create the the LyX LColors database
        lyxColorDB.clear();
@@ -781,123 +743,19 @@ 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;
 
                        string const arg = lcolor.getLyXName(lc) + " black";
-                       parent_.lv_->getLyXFunc()->
-                               Dispatch(LFUN_SET_COLOR, arg);
+                       parent_.controller().setColor(lc, "black");
                        continue;
                }
 
@@ -907,60 +765,46 @@ 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<XformsColor>::const_iterator cit = xformsColorDB.begin();
+            cit != xformsColorDB.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();
 }
 
 
@@ -968,225 +812,200 @@ void FormPreferences::Colors::Modify()
 {
        vector<NamedColor>::size_type const selLyX =
                fl_get_browser(dialog_->browser_lyx_objs);
-       if (selLyX < 1) return;
-       
-       vector<NamedColor>::size_type const selX11 =
-               fl_get_browser(dialog_->browser_x11);
-       if (selX11 < 1) return;
-       
-        // Is the choice an Xforms color...
-       if (selLyX-1 < int(xformColorDB.size())) {
-               vector<XformColor>::size_type const i = selLyX - 1;
-               vector<NamedColor>::size_type const j = selX11 - 1;
-               xformColorDB[i].r  = colorDB[j].r;
-               xformColorDB[i].g  = colorDB[j].g;
-               xformColorDB[i].b  = colorDB[j].b;
-       } else { // or a LyX Logical color?
-               vector<NamedColor>::size_type const i = selLyX - 1 -
-                       xformColorDB.size();
-               vector<NamedColor>::size_type const j = selX11 - 1;
-               lyxColorDB[i].r  = colorDB[j].r;
-               lyxColorDB[i].g  = colorDB[j].g;
-               lyxColorDB[i].b  = colorDB[j].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);
-}
-
-
-int FormPreferences::Colors::SearchEntry(RGBColor const & col) const
-{
-       int mindiff = 0x7fffffff;
-       vector<NamedColor>::const_iterator mincit = colorDB.begin();
-
-       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;
+       if (selLyX < 1)
+               return;
 
-               int d = (2 * (diff.r * diff.r) +
-                        3 * (diff.g * diff.g) +
-                            (diff.b * diff.b));
+       RGBColor col;
+       fl_getmcolor(GUI_COLOR_CHOICE, &col.r, &col.g, &col.b);
 
-               if (mindiff > d) {
-                       mindiff = d;
-                       mincit = cit;
-               }
+       // Is the choice an Xforms color...
+       if (selLyX - 1 < xformsColorDB.size()) {
+               vector<XformsColor>::size_type const i = selLyX - 1;
+               xformsColorDB[i].r  = col.r;
+               xformsColorDB[i].g  = col.g;
+               xformsColorDB[i].b  = col.b;
+       }
+       // or a LyX Logical color?
+       else {
+               vector<NamedColor>::size_type const i = selLyX - 1 -
+                       xformsColorDB.size();
+               lyxColorDB[i].r  = col.r;
+               lyxColorDB[i].g  = col.g;
+               lyxColorDB[i].b  = col.b;
        }
 
-       int sel = 0;
-       if (mincit != colorDB.end())
-               sel = static_cast<int>(mincit - colorDB.begin());
-       
-       return sel;
+       fl_freeze_form(dialog_->form);
+       setEnabled(dialog_->button_modify, false);
+       fl_unfreeze_form(dialog_->form);
 }
 
 
-int FormPreferences::SortColorsByColor::
-operator()(RGBColor const & a, RGBColor const & b) const
+void FormPreferences::Colors::SwitchColorSpace() const
 {
-       RGBColor c1 = a;
-       RGBColor c2 = b;
-               
-       c1.r -= col.r;
-       c1.g -= col.g;
-       c1.b -= col.b;
+       bool const hsv = fl_get_button(dialog_->radio_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;
+       RGBColor col;
+       fl_getmcolor(GUI_COLOR_CHOICE, &col.r, &col.g, &col.b);
 
-       int const l2 = (c2.r * c2.r) + (c2.g * c2.g) + (c2.b * c2.b);
-               
-       return (l1 < l2);
-}
-
-
-void FormPreferences::Colors::Sort()
-{
-       int i = fl_get_browser(dialog_->browser_x11);
-       if (i < 1) return;
+       fl_freeze_form(dialog_->form);
 
-       RGBColor const col = colorDB[i-1].color();
+       if (hsv) {
+               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);
+
+               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) + ", " + tostr(s) +
+                       ", " + tostr(v);
+               fl_set_object_label(dialog_->text_color_values, label.c_str());
 
-       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_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);
 
-       fl_freeze_form(dialog_->form);
-       fl_clear_browser(dialog_->browser_x11);
+               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);
 
-       for (vector<NamedColor>::const_iterator cit = colorDB.begin();
-            cit != colorDB.end(); ++cit) {
-               fl_addto_browser(dialog_->browser_x11,
-                                (*cit).getname().c_str());
+               // 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) + ", " + tostr(g) +
+                       ", " + tostr(b);
+               fl_set_object_label(dialog_->text_color_values, label.c_str());
        }
 
-       vector<NamedColor>::const_iterator cit =
-               find(colorDB.begin(), colorDB.end(), col);
-
-       i = 0;
-       if (cit != colorDB.end())
-               i = static_cast<int>(cit - colorDB.begin());
-
-       fl_set_browser_topline(dialog_->browser_x11, max(i-5, 1));
-       fl_select_browser_line(dialog_->browser_x11, i+1);
        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) << setfill('0')
+            << setw(2) << col.r
+            << setw(2) << col.g
+            << setw(2) << col.b;
+
+       return STRCONV(ostr.str());
 }
 
 
-FormPreferences::Converters::~Converters()
+FormPreferences::Converters::Converters(FormPreferences & p)
+       : parent_(p)
+{}
+
+
+FD_preferences_converters const * FormPreferences::Converters::dialog()
 {
-       delete dialog_;
+       return dialog_.get();
 }
 
 
 void FormPreferences::Converters::apply() const
 {
-       converters = local_converters;
-       converters.Update(formats);
-       converters.BuildGraph();
+       parent_.controller().setConverters(local_converters);
 }
 
 
 void FormPreferences::Converters::build()
 {
-       dialog_ = parent_.build_converters();
+       dialog_.reset(build_preferences_converters(&parent_));
 
        fl_set_input_return(dialog_->input_converter, FL_RETURN_CHANGED);
        fl_set_input_return(dialog_->input_flags, FL_RETURN_CHANGED);
 
        // set up the feedback mechanism
-       setPreHandler(dialog_->browser_all);
-       setPreHandler(dialog_->button_delete);
-       setPreHandler(dialog_->button_add);
-       setPreHandler(dialog_->input_converter);
-       setPreHandler(dialog_->choice_from);
-       setPreHandler(dialog_->choice_to);
-       setPreHandler(dialog_->input_flags);
+       setPrehandler(dialog_->browser_all);
+       setPrehandler(dialog_->button_delete);
+       setPrehandler(dialog_->button_add);
+       setPrehandler(dialog_->input_converter);
+       setPrehandler(dialog_->choice_from);
+       setPrehandler(dialog_->choice_to);
+       setPrehandler(dialog_->input_flags);
 }
 
 
 string const
 FormPreferences::Converters::feedback(FL_OBJECT const * const ob) const
 {
-       string str;
+       if (ob == dialog_->browser_all)
+               return _("All the currently defined converters known to LyX.");
+
+       if (ob == dialog_->choice_from)
+               return _("Convert \"from\" this format");
+
+       if (ob == dialog_->choice_to)
+               return _("Convert \"to\" this format");
+
+       if (ob == dialog_->input_converter)
+               return _("The conversion command. $$i is the input file name, "
+                        "$$b is the file name without its extension and $$o is "
+                        "the name of the output file. $$s can be used as path to "
+                        "LyX's own collection of conversion scripts.");
 
-       if (ob == dialog_->browser_all) {
-               str = N_("All the currently defined converters known to LyX.");
-       } else if (ob == dialog_->choice_from) {
-               str = N_("Convert \"from\" this format");
-       } else if (ob == dialog_->choice_to) {
-               str = N_("Convert \"to\" this format");
-       } else if (ob == dialog_->input_converter) {
-               str = N_("The conversion command. $$i is the input file name, $$b is the file name without its extension and $$o is the name of the output file.");
-       } 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. Note: you must then \"Apply\" the change.");
-       } else if (ob == dialog_->button_add) {
+       if (ob == dialog_->input_flags)
+               return _("Extra information for the Converter class, whether and "
+                        "how to parse the result, and various other things.");
+
+       if (ob == dialog_->button_delete)
+               return _("Remove the current converter from the list of available "
+                        "converters. Note: you must then \"Apply\" the change.");
+
+       if (ob == dialog_->button_add) {
                if (string(ob->label) == _("Add"))
-                       str = N_("Add the current converter to the list of available converters. Note: you must then \"Apply\" the change.");
+                       return _("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 _("Modify the contents of the current converter. "
+                                "Note: you must then \"Apply\" the change.");
        }
 
-       return str;
+       return string();
 }
 
 
 bool FormPreferences::Converters::input(FL_OBJECT const * const ob)
 {
-       if (ob == dialog_->browser_all) {
+       if (ob == dialog_->browser_all)
                return Browser();
 
-       } else if (ob == dialog_->choice_from
+       if (ob == dialog_->choice_from
                   || ob == dialog_->choice_to
                   || ob == dialog_->input_converter
-                  || ob == dialog_->input_flags) {
+                  || ob == dialog_->input_flags)
                return Input();
 
-       } else if (ob == dialog_->button_add) {
+       if (ob == dialog_->button_add)
                return Add();
 
-       } else if (ob == dialog_->button_delete) {
-               return Delete();
-       }
+       if (ob == dialog_->button_delete)
+               return erase();
 
        return true;
 }
@@ -1195,21 +1014,21 @@ bool FormPreferences::Converters::input(FL_OBJECT const * const ob)
 void FormPreferences::Converters::update()
 {
        local_converters = converters;
-       local_converters.Update(local_formats);
+       local_converters.update(local_formats);
        UpdateBrowser();
 }
 
 
 void FormPreferences::Converters::UpdateBrowser()
 {
-       local_converters.Sort();
+       local_converters.sort();
 
        fl_freeze_form(dialog_->form);
        fl_clear_browser(dialog_->browser_all);
        for (::Converters::const_iterator cit = local_converters.begin();
             cit != local_converters.end(); ++cit) {
-               string const name = (*cit).From->prettyname() + " -> "
-                       + (*cit).To->prettyname();
+               string const name = cit->From->prettyname() + " -> "
+                       + cit->To->prettyname();
                fl_addto_browser(dialog_->browser_all, name.c_str());
        }
        Input();
@@ -1224,59 +1043,54 @@ bool FormPreferences::Converters::Add()
        string const command = fl_get_input(dialog_->input_converter);
        string const flags = fl_get_input(dialog_->input_flags);
 
-       Converter const * old = local_converters.GetConverter(from, to);
-       local_converters.Add(from, to, command, flags);
+       Converter const * old = local_converters.getConverter(from, to);
+       local_converters.add(from, to, command, flags);
        if (!old) {
-               local_converters.UpdateLast(local_formats);
+               local_converters.updateLast(local_formats);
                UpdateBrowser();
        }
-       fl_deactivate_object(dialog_->button_add);
-       fl_set_object_lcol(dialog_->button_add, FL_INACTIVE);
+       setEnabled(dialog_->button_add, false);
 
        return true;
 }
 
 
-bool FormPreferences::Converters::Browser() 
+bool FormPreferences::Converters::Browser()
 {
        int const i = fl_get_browser(dialog_->browser_all);
        if (i <= 0) return false;
 
        fl_freeze_form(dialog_->form);
 
-       Converter const & c = local_converters.Get(i-1);
-       int j = local_formats.GetNumber(c.from);
+       Converter const & c = local_converters.get(i - 1);
+       int j = local_formats.getNumber(c.from);
        if (j >= 0)
-               fl_set_choice(dialog_->choice_from, j+1);
+               fl_set_choice(dialog_->choice_from, j + 1);
 
-       j = local_formats.GetNumber(c.to);
+       j = local_formats.getNumber(c.to);
        if (j >= 0)
-               fl_set_choice(dialog_->choice_to, j+1);
+               fl_set_choice(dialog_->choice_to, j + 1);
 
        fl_set_input(dialog_->input_converter, c.command.c_str());
        fl_set_input(dialog_->input_flags, c.flags.c_str());
 
        fl_set_object_label(dialog_->button_add, idex(_("Modify|#M")));
-       fl_set_button_shortcut(dialog_->button_add,
-                               scex(_("Modify|#M")), 1);
+       fl_set_button_shortcut(dialog_->button_add, scex(_("Modify|#M")), 1);
 
-       fl_deactivate_object(dialog_->button_add);
-       fl_set_object_lcol(dialog_->button_add, FL_INACTIVE);
+       setEnabled(dialog_->button_add,    false);
+       setEnabled(dialog_->button_delete, true);
 
-       fl_activate_object(dialog_->button_delete);
-       fl_set_object_lcol(dialog_->button_delete, FL_BLACK);
-                               
        fl_unfreeze_form(dialog_->form);
        return false;
 }
 
 
-bool FormPreferences::Converters::Delete()
+bool FormPreferences::Converters::erase()
 {
        string const from = GetFrom();
        string const to = GetTo();
 
-       local_converters.Delete(from, to);
+       local_converters.erase(from, to);
        UpdateBrowser();
        return true;
 }
@@ -1286,43 +1100,32 @@ bool FormPreferences::Converters::Input()
 {
        string const from = GetFrom();
        string const to = GetTo();
-       int const sel = local_converters.GetNumber(from, to);
-       
+       int const sel = local_converters.getNumber(from, to);
+
        fl_freeze_form(dialog_->form);
 
        if (sel < 0) {
-               fl_set_object_label(dialog_->button_add,
-                                    idex(_("Add|#A")));
+               fl_set_object_label(dialog_->button_add, idex(_("Add|#A")));
                fl_set_button_shortcut(dialog_->button_add,
-                                       scex(_("Add|#A")), 1);
+                                      scex(_("Add|#A")), 1);
 
                fl_deselect_browser(dialog_->browser_all);
-
-               fl_deactivate_object(dialog_->button_delete);
-               fl_set_object_lcol(dialog_->button_delete, FL_INACTIVE);
+               setEnabled(dialog_->button_delete, false);
 
        } else {
-               fl_set_object_label(dialog_->button_add,
-                                    idex(_("Modify|#M")));
+               fl_set_object_label(dialog_->button_add, idex(_("Modify|#M")));
                fl_set_button_shortcut(dialog_->button_add,
-                                       scex(_("Modify|#M")), 1);
-               
+                                      scex(_("Modify|#M")), 1);
+
                int top = max(sel-5, 0);
                fl_set_browser_topline(dialog_->browser_all, top);
                fl_select_browser_line(dialog_->browser_all, sel+1);
-               
-               fl_activate_object(dialog_->button_delete);
-               fl_set_object_lcol(dialog_->button_delete, FL_BLACK);
+               setEnabled(dialog_->button_delete, true);
        }
 
-       string const command = fl_get_input(dialog_->input_converter);
-       if (command.empty() || from == to) {
-               fl_deactivate_object(dialog_->button_add);
-               fl_set_object_lcol(dialog_->button_add, FL_INACTIVE);
-       } else {
-               fl_activate_object(dialog_->button_add);
-               fl_set_object_lcol(dialog_->button_add, FL_BLACK);
-       }
+       string const command = rtrim(fl_get_input(dialog_->input_converter));
+       bool const enable = !(command.empty() || from == to);
+       setEnabled(dialog_->button_add, enable);
 
        fl_unfreeze_form(dialog_->form);
        return false;
@@ -1331,27 +1134,27 @@ 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();
-       else {
-               lyxerr << "FormPreferences::Converters::GetFrom: No choice!"
-                      << endl;
-               return "???";
-       }
+       ::Formats::FormatList::size_type const i =
+               fl_get_choice(dialog_->choice_from);
+
+       if (i > 0 && i <= local_formats.size())
+               return local_formats.get(i - 1).name();
+
+       lyxerr << "FormPreferences::Converters::GetFrom: No choice!" << endl;
+       return "???";
 }
 
 
 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();
-       else {
-               lyxerr << "FormPreferences::Converters::GetTo: No choice!"
-                      << endl;
-               return "???";
-       }
+       ::Formats::FormatList::size_type const i =
+               fl_get_choice(dialog_->choice_to);
+
+       if (i > 0 && i <= local_formats.size())
+               return local_formats.get(i - 1).name();
+
+       lyxerr << "FormPreferences::Converters::GetTo: No choice!" << endl;
+       return "???";
 }
 
 
@@ -1364,7 +1167,7 @@ void FormPreferences::Converters::UpdateChoices() const
                        choice += " | ";
                else
                        choice += " ";
-               choice += (*cit).prettyname();
+               choice += cit->prettyname();
        }
        choice += " ";
 
@@ -1376,21 +1179,26 @@ void FormPreferences::Converters::UpdateChoices() const
 }
 
 
-FormPreferences::Formats::~Formats()
+FormPreferences::Formats::Formats(FormPreferences &  p)
+       : parent_(p)
+{}
+
+
+FD_preferences_formats const * FormPreferences::Formats::dialog()
 {
-       delete dialog_;
+       return dialog_.get();
 }
 
 
 void FormPreferences::Formats::apply() const
 {
-       formats = local_formats;
+       parent_.controller().setFormats(local_formats);
 }
 
 
 void FormPreferences::Formats::build()
 {
-       dialog_ = parent_.build_formats();
+       dialog_.reset(build_preferences_formats(&parent_));
 
        fl_set_input_return(dialog_->input_format, FL_RETURN_CHANGED);
        fl_set_input_return(dialog_->input_viewer, FL_RETURN_CHANGED);
@@ -1401,65 +1209,73 @@ void FormPreferences::Formats::build()
        fl_set_input_filter(dialog_->input_format, fl_lowercase_filter);
 
        // set up the feedback mechanism
-       setPreHandler(dialog_->browser_all);
-       setPreHandler(dialog_->input_format);
-       setPreHandler(dialog_->input_gui_name);
-       setPreHandler(dialog_->button_delete);
-       setPreHandler(dialog_->button_add);
-       setPreHandler(dialog_->input_extension);
-       setPreHandler(dialog_->input_viewer);
-       setPreHandler(dialog_->input_shrtcut);
+       setPrehandler(dialog_->browser_all);
+       setPrehandler(dialog_->input_format);
+       setPrehandler(dialog_->input_gui_name);
+       setPrehandler(dialog_->button_delete);
+       setPrehandler(dialog_->button_add);
+       setPrehandler(dialog_->input_extension);
+       setPrehandler(dialog_->input_viewer);
+       setPrehandler(dialog_->input_shrtcut);
 }
 
 
 string const
 FormPreferences::Formats::feedback(FL_OBJECT const * const ob) const
 {
-       string str;
+       if (ob == dialog_->browser_all)
+               return  _("All the currently defined formats known to LyX.");
+
+       if (ob == dialog_->input_format)
+               return  _("The format identifier.");
+
+       if (ob == dialog_->input_gui_name)
+               return  _("The format name as it will appear in the menus.");
+
+       if (ob == dialog_->input_shrtcut)
+               return  _("The keyboard accelerator. Use a letter in the GUI name. "
+                         "Case sensitive.");
+
+       if (ob == dialog_->input_extension)
+               return  _("Used to recognize the file. E.g., ps, pdf, tex.");
 
-       if (ob == dialog_->browser_all) {
-               str = N_("All the currently defined formats known to LyX.");
-       } else if (ob == dialog_->input_format) {
-               str = N_("The format identifier.");
-       } else if (ob == dialog_->input_gui_name) {
-               str = N_("The format name as it will appear in the menus.");
-       } else if (ob == dialog_->input_shrtcut) {
-               str = N_("The keyboard accelerator. Use a letter in the GUI name. Case sensitive.");
-       } else if (ob == dialog_->input_extension) {
-               str = N_("Used to recognize the file. E.g., ps, pdf, tex.");
-       } 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. Note: you must then \"Apply\" the change.");
-       } else if (ob == dialog_->button_add) {
+       if (ob == dialog_->input_viewer)
+               return  _("The command used to launch the viewer application.");
+
+       if (ob == dialog_->button_delete)
+               return  _("Remove the current format from the list of available "
+                         "formats. Note: you must then \"Apply\" the change.");
+
+       if (ob == dialog_->button_add) {
                if (string(ob->label) == _("Add"))
-                       str = N_("Add the current format to the list of available formats. Note: you must then \"Apply\" the change.");
+                       return  _("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  _("Modify the contents of the current format. Note: "
+                                 "you must then \"Apply\" the change.");
        }
 
-       return str;
+       return string();
 }
 
 
 bool FormPreferences::Formats::input(FL_OBJECT const * const ob)
 {
-       if (ob == dialog_->browser_all) {
+       if (ob == dialog_->browser_all)
                return Browser();
 
-       } else if (ob == dialog_->input_format
-                  || ob == dialog_->input_gui_name
-                  || ob == dialog_->input_shrtcut
-                  || ob == dialog_->input_extension
-                  || ob == dialog_->input_viewer) {
+       if (ob == dialog_->input_format
+        || ob == dialog_->input_gui_name
+        || ob == dialog_->input_shrtcut
+        || ob == dialog_->input_extension
+        || ob == dialog_->input_viewer)
                return Input();
 
-       } else if (ob == dialog_->button_add) {
+       if (ob == dialog_->button_add)
                return Add();
 
-       } else if (ob == dialog_->button_delete) {
-               return Delete();
-       }
+       if (ob == dialog_->button_delete)
+               return erase();
 
        return false;
 }
@@ -1474,7 +1290,7 @@ void FormPreferences::Formats::update()
 
 void FormPreferences::Formats::UpdateBrowser()
 {
-       local_formats.Sort();
+       local_formats.sort();
 
        fl_freeze_form(dialog_->form);
        fl_deselect_browser(dialog_->browser_all);
@@ -1482,14 +1298,14 @@ void FormPreferences::Formats::UpdateBrowser()
        for (::Formats::const_iterator cit = local_formats.begin();
             cit != local_formats.end(); ++cit)
                fl_addto_browser(dialog_->browser_all,
-                                (*cit).prettyname().c_str());
+                                cit->prettyname().c_str());
 
        Input();
        fl_unfreeze_form(dialog_->form);
 
        // Mustn't forget to update the Formats available to the converters_
        parent_.converters_.UpdateChoices();
-       local_converters.Update(local_formats);
+       local_converters.update(local_formats);
 }
 
 
@@ -1501,30 +1317,30 @@ bool FormPreferences::Formats::Add()
        string const shortcut =  fl_get_input(dialog_->input_shrtcut);
        string const viewer =  fl_get_input(dialog_->input_viewer);
 
-       Format const * old = local_formats.GetFormat(name);
+       Format const * old = local_formats.getFormat(name);
        string const old_prettyname = old ? old->prettyname() : string();
-       local_formats.Add(name, extension, prettyname, shortcut);
-       local_formats.SetViewer(name, viewer);
+       local_formats.add(name, extension, prettyname, shortcut);
+       local_formats.setViewer(name, viewer);
        if (!old || prettyname != old_prettyname) {
                UpdateBrowser();
                if (old)
                        parent_.converters_.UpdateBrowser();
        }
-       fl_deactivate_object(dialog_->button_add);
-       fl_set_object_lcol(dialog_->button_add, FL_INACTIVE);
+       setEnabled(dialog_->button_add, false);
 
        return true;
 }
 
 
-bool FormPreferences::Formats::Browser() 
+bool FormPreferences::Formats::Browser()
 {
        int const i = fl_get_browser(dialog_->browser_all);
-       if (i <= 0) return false;
+       if (i <= 0)
+               return false;
 
        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());
@@ -1535,29 +1351,26 @@ bool FormPreferences::Formats::Browser()
        fl_set_object_label(dialog_->button_add, idex(_("Modify|#M")));
        fl_set_button_shortcut(dialog_->button_add, scex(_("Modify|#M")), 1);
 
-       fl_deactivate_object(dialog_->button_add);
-       fl_set_object_lcol(dialog_->button_add, FL_INACTIVE);
+       setEnabled(dialog_->button_add,    false);
+       setEnabled(dialog_->button_delete, true);
 
-       fl_activate_object(dialog_->button_delete);
-       fl_set_object_lcol(dialog_->button_delete, FL_BLACK);
-                               
        fl_unfreeze_form(dialog_->form);
        return false;
 }
 
 
-bool FormPreferences::Formats::Delete()
+bool FormPreferences::Formats::erase()
 {
        string const name = fl_get_input(dialog_->input_format);
 
-       if (local_converters.FormatIsUsed(name)) {
-               parent_.printWarning(_("Cannot remove a Format used by a Converter. Remove the converter first."));
-               fl_deactivate_object(dialog_->button_delete);
-               fl_set_object_lcol(dialog_->button_delete, FL_INACTIVE);
+       if (local_converters.formatIsUsed(name)) {
+               parent_.postWarning(_("Cannot remove a Format used by a Converter. "
+                                     "Remove the converter first."));
+               setEnabled(dialog_->button_delete, false);
                return false;
        }
 
-       local_formats.Delete(name);
+       local_formats.erase(name);
        UpdateBrowser();
        return true;
 }
@@ -1566,295 +1379,296 @@ bool FormPreferences::Formats::Delete()
 bool FormPreferences::Formats::Input()
 {
        string const name = fl_get_input(dialog_->input_format);
-       int const sel = local_formats.GetNumber(name);
+       int const sel = local_formats.getNumber(name);
        fl_freeze_form(dialog_->form);
 
        if (sel < 0) {
                fl_set_object_label(dialog_->button_add,
-                                    idex(_("Add|#A")));
+                                   idex(_("Add|#A")));
                fl_set_button_shortcut(dialog_->button_add,
-                                       scex(_("Add|#A")), 1);
+                                      scex(_("Add|#A")), 1);
 
                fl_deselect_browser(dialog_->browser_all);
-
-               fl_deactivate_object(dialog_->button_delete);
-               fl_set_object_lcol(dialog_->button_delete, FL_INACTIVE);
+               setEnabled(dialog_->button_delete, false);
 
        } else {
                fl_set_object_label(dialog_->button_add,
-                                    idex(_("Modify|#M")));
+                                   idex(_("Modify|#M")));
                fl_set_button_shortcut(dialog_->button_add,
-                                       scex(_("Modify|#M")), 1);
+                                      scex(_("Modify|#M")), 1);
 
                int const top = max(sel-5, 0);
                fl_set_browser_topline(dialog_->browser_all, top);
                fl_select_browser_line(dialog_->browser_all, sel+1);
-               
-               fl_activate_object(dialog_->button_add);
-               fl_set_object_lcol(dialog_->button_add, FL_BLACK);
 
-               fl_activate_object(dialog_->button_delete);
-               fl_set_object_lcol(dialog_->button_delete, FL_BLACK);
+               setEnabled(dialog_->button_add, true);
+               setEnabled(dialog_->button_delete, true);
        }
 
        string const prettyname = fl_get_input(dialog_->input_gui_name);
-       if (name.empty() || prettyname.empty()) {
-               fl_deactivate_object(dialog_->button_add);
-               fl_set_object_lcol(dialog_->button_add, FL_INACTIVE);
-       } else {
-               fl_activate_object(dialog_->button_add);
-               fl_set_object_lcol(dialog_->button_add, FL_BLACK);
-       }
+       bool const enable = !(name.empty() || prettyname.empty());
+       setEnabled(dialog_->button_add, enable);
 
        fl_unfreeze_form(dialog_->form);
        return false;
 }
 
 
-FormPreferences::InputsMisc::~InputsMisc()
+FormPreferences::InputsMisc::InputsMisc(FormPreferences &  p)
+       : parent_(p)
+{}
+
+
+FD_preferences_inputs_misc const * FormPreferences::InputsMisc::dialog()
 {
-       delete dialog_;
+       return dialog_.get();
 }
 
 
-void FormPreferences::InputsMisc::apply() const
+void FormPreferences::InputsMisc::apply(LyXRC & rc) const
 {
-       lyxrc.date_insert_format =
+       rc.date_insert_format =
                fl_get_input(dialog_->input_date_format);
 }
 
 
 void FormPreferences::InputsMisc::build()
 {
-       dialog_ = parent_.build_inputs_misc();
+       dialog_.reset(build_preferences_inputs_misc(&parent_));
 
        fl_set_input_return(dialog_->input_date_format, FL_RETURN_CHANGED);
 
        // set up the feedback mechanism
-       setPreHandler(dialog_->input_date_format);
+       setPrehandler(dialog_->input_date_format);
 }
 
 
 string const
 FormPreferences::InputsMisc::feedback(FL_OBJECT const * const ob) const
 {
-       string str;
-
        if (ob == dialog_->input_date_format)
-               str = lyxrc.getDescription(LyXRC::RC_DATE_INSERT_FORMAT);
-
-       return str;
+               return LyXRC::getDescription(LyXRC::RC_DATE_INSERT_FORMAT);
+       return string();
 }
 
 
-void FormPreferences::InputsMisc::update()
+void FormPreferences::InputsMisc::update(LyXRC const & rc)
 {
        fl_set_input(dialog_->input_date_format,
-                    lyxrc.date_insert_format.c_str());
+                    rc.date_insert_format.c_str());
 }
 
 
-FormPreferences::Interface::~Interface()
+FormPreferences::Interface::Interface(FormPreferences &  p)
+       : parent_(p)
+{}
+
+
+FD_preferences_interface const * FormPreferences::Interface::dialog()
 {
-       delete dialog_;
+       return dialog_.get();
 }
 
 
-void FormPreferences::Interface::apply() const
+void FormPreferences::Interface::apply(LyXRC & rc) const
 {
-       lyxrc.popup_font_name =
-               fl_get_input(dialog_->input_popup_font);
-       lyxrc.menu_font_name = fl_get_input(dialog_->input_menu_font);
-       lyxrc.font_norm_menu =
-               fl_get_input(dialog_->input_popup_encoding);
-       lyxrc.bind_file = fl_get_input(dialog_->input_bind_file);
-       lyxrc.ui_file = fl_get_input(dialog_->input_ui_file);
-       lyxrc.override_x_deadkeys =
+       rc.popup_normal_font =
+               fl_get_input(dialog_->input_popup_normal_font);
+       rc.popup_bold_font = fl_get_input(dialog_->input_popup_bold_font);
+       rc.popup_font_encoding =
+               fl_get_input(dialog_->input_popup_font_encoding);
+       rc.bind_file = fl_get_input(dialog_->input_bind_file);
+       rc.ui_file = fl_get_input(dialog_->input_ui_file);
+       rc.override_x_deadkeys =
                fl_get_button(dialog_->check_override_x_dead_keys);
 }
 
 
 void FormPreferences::Interface::build()
 {
-       dialog_ = parent_.build_interface();
+       dialog_.reset(build_preferences_interface(&parent_));
 
-       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_normal_font, FL_RETURN_CHANGED);
+       fl_set_input_return(dialog_->input_popup_bold_font, FL_RETURN_CHANGED);
+       fl_set_input_return(dialog_->input_popup_font_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);
 
        // set up the feedback mechanism
-       setPreHandler(dialog_->input_popup_font);
-       setPreHandler(dialog_->input_menu_font);
-       setPreHandler(dialog_->input_popup_encoding);
-       setPreHandler(dialog_->input_bind_file);
-       setPreHandler(dialog_->button_bind_file_browse);
-       setPreHandler(dialog_->input_ui_file);
-       setPreHandler(dialog_->button_ui_file_browse);
-       setPreHandler(dialog_->check_override_x_dead_keys);
+       setPrehandler(dialog_->input_popup_normal_font);
+       setPrehandler(dialog_->input_popup_bold_font);
+       setPrehandler(dialog_->input_popup_font_encoding);
+       setPrehandler(dialog_->input_bind_file);
+       setPrehandler(dialog_->button_bind_file_browse);
+       setPrehandler(dialog_->input_ui_file);
+       setPrehandler(dialog_->button_ui_file_browse);
+       setPrehandler(dialog_->check_override_x_dead_keys);
 }
 
 
 string const
 FormPreferences::Interface::feedback(FL_OBJECT const * const ob) const
 {
-       string str;
-
-       if (ob == dialog_->input_popup_font)
-               str = lyxrc.getDescription(LyXRC::RC_SCREEN_FONT_POPUP);
-       else if (ob == dialog_->input_menu_font)
-               str = lyxrc.getDescription(LyXRC::RC_SCREEN_FONT_MENU);
-       else if (ob == dialog_->input_popup_encoding)
-               str = lyxrc.getDescription(LyXRC::RC_SCREEN_FONT_ENCODING_MENU);
-       else if (ob == dialog_->input_bind_file)
-               str = lyxrc.getDescription(LyXRC::RC_BINDFILE);
-       else if (ob == dialog_->input_ui_file)
-               str = lyxrc.getDescription(LyXRC::RC_UIFILE);
-       else if (ob == dialog_->check_override_x_dead_keys)
-               str = lyxrc.getDescription(LyXRC::RC_OVERRIDE_X_DEADKEYS);
-
-       return str;
+       if (ob == dialog_->input_popup_normal_font)
+               return LyXRC::getDescription(LyXRC::RC_POPUP_NORMAL_FONT);
+       if (ob == dialog_->input_popup_bold_font)
+               return LyXRC::getDescription(LyXRC::RC_POPUP_BOLD_FONT);
+       if (ob == dialog_->input_popup_font_encoding)
+               return LyXRC::getDescription(LyXRC::RC_POPUP_FONT_ENCODING);
+       if (ob == dialog_->input_bind_file)
+               return LyXRC::getDescription(LyXRC::RC_BINDFILE);
+       if (ob == dialog_->input_ui_file)
+               return LyXRC::getDescription(LyXRC::RC_UIFILE);
+       if (ob == dialog_->check_override_x_dead_keys)
+               return LyXRC::getDescription(LyXRC::RC_OVERRIDE_X_DEADKEYS);
+       return string();
 }
 
 
 bool FormPreferences::Interface::input(FL_OBJECT const * const ob)
 {
        if (ob == dialog_->button_bind_file_browse) {
-               string dir  = system_lyxdir + string("bind");
-               string name = N_("Sys Bind");
-               pair<string,string> dir1(name, dir);
-
-               dir = user_lyxdir + string("bind");
-               name = N_("User Bind");
-               pair<string,string> dir2(name, dir);
+               string f = parent_.controller().browsebind(
+                       fl_get_input(dialog_->input_bind_file));
 
-               parent_.browse(dialog_->input_bind_file,
-                               _("Bind file"), "*.bind", dir1, dir2);
-               
+               fl_set_input(dialog_->input_bind_file, f.c_str());
        } else if (ob == dialog_->button_ui_file_browse) {
-               string dir  = system_lyxdir + string("ui");
-               string name = N_("Sys UI");
-               pair<string,string> dir1(name, dir);
-
-               dir = user_lyxdir + string("ui");
-               name = N_("User UI");
-               pair<string,string> dir2(name, dir);
+               string f = parent_.controller().browseUI(
+                       fl_get_input(dialog_->input_ui_file));
 
-               parent_.browse(dialog_->input_ui_file,
-                               _("UI file"), "*.ui", dir1, dir2);
+               fl_set_input(dialog_->input_ui_file, f.c_str());
        }
-       
+
        return true;
 }
 
 
-void FormPreferences::Interface::update()
+void FormPreferences::Interface::update(LyXRC const & rc)
 {
-       fl_set_input(dialog_->input_popup_font,
-                    lyxrc.popup_font_name.c_str());
-       fl_set_input(dialog_->input_menu_font,
-                    lyxrc.menu_font_name.c_str());
-       fl_set_input(dialog_->input_popup_encoding,
-                    lyxrc.font_norm_menu.c_str());
+       fl_set_input(dialog_->input_popup_normal_font,
+                    rc.popup_normal_font.c_str());
+       fl_set_input(dialog_->input_popup_bold_font,
+                    rc.popup_bold_font.c_str());
+       fl_set_input(dialog_->input_popup_font_encoding,
+                    rc.popup_font_encoding.c_str());
        fl_set_input(dialog_->input_bind_file,
-                    lyxrc.bind_file.c_str());
+                    rc.bind_file.c_str());
        fl_set_input(dialog_->input_ui_file,
-                    lyxrc.ui_file.c_str());
+                    rc.ui_file.c_str());
        fl_set_button(dialog_->check_override_x_dead_keys,
-                     lyxrc.override_x_deadkeys);
+                     rc.override_x_deadkeys);
 }
 
 
-FormPreferences::Language::~Language()
+FormPreferences::Language::Language(FormPreferences &  p)
+       : parent_(p)
+{}
+
+
+FD_preferences_language const * FormPreferences::Language::dialog()
 {
-       delete combo_default_lang;
-       delete dialog_;
+       return dialog_.get();
 }
 
 
-void FormPreferences::Language::apply()
+void FormPreferences::Language::apply(LyXRC & rc)
 {
-       lyxrc.default_language = combo_default_lang->getline();
+       int const pos = combo_default_lang->get();
+       rc.default_language = lang_[pos-1];
 
        int button = fl_get_button(dialog_->check_use_kbmap);
        string const name_1 = fl_get_input(dialog_->input_kbmap1);
        string const name_2 = fl_get_input(dialog_->input_kbmap2);
        if (button)
                button = !(name_1.empty() && name_2.empty());
-       lyxrc.use_kbmap = static_cast<bool>(button);
+       rc.use_kbmap = static_cast<bool>(button);
 
-       if (lyxrc.use_kbmap) {
-               lyxrc.primary_kbmap = name_1;
-               lyxrc.secondary_kbmap = name_2;
+       if (rc.use_kbmap) {
+               rc.primary_kbmap = name_1;
+               rc.secondary_kbmap = name_2;
        }
-       
+
        button = fl_get_button(dialog_->check_rtl_support);
-       lyxrc.rtl_support = static_cast<bool>(button);
+       rc.rtl_support = static_cast<bool>(button);
+
+       button = fl_get_button(dialog_->check_mark_foreign);
+       rc.mark_foreign_language = static_cast<bool>(button);
 
        button = fl_get_button(dialog_->check_auto_begin);
-       lyxrc.language_auto_begin = static_cast<bool>(button);
+       rc.language_auto_begin = static_cast<bool>(button);
 
        button = fl_get_button(dialog_->check_auto_end);
-       lyxrc.language_auto_end = static_cast<bool>(button);
+       rc.language_auto_end = static_cast<bool>(button);
 
-       button = fl_get_button(dialog_->check_mark_foreign);
-       lyxrc.mark_foreign_language = static_cast<bool>(button);
+       button = fl_get_button(dialog_->check_use_babel);
+       rc.language_use_babel = static_cast<bool>(button);
+
+       button = fl_get_button(dialog_->check_global_options);
+       rc.language_global_options = static_cast<bool>(button);
 
-       lyxrc.language_package = fl_get_input(dialog_->input_package);
-       lyxrc.language_command_begin = fl_get_input(dialog_->input_command_begin);
-       lyxrc.language_command_end = fl_get_input(dialog_->input_command_end);
+       rc.language_package = fl_get_input(dialog_->input_package);
+       rc.language_command_begin = fl_get_input(dialog_->input_command_begin);
+       rc.language_command_end = fl_get_input(dialog_->input_command_end);
 
        // Ensure that all is self-consistent.
-       update();
+       update(rc);
 }
 
 
 void FormPreferences::Language::build()
 {
-       dialog_ = parent_.build_language();
+       dialog_.reset(build_preferences_language(&parent_));
 
        fl_set_input_return(dialog_->input_package, FL_RETURN_CHANGED);
        fl_set_input_return(dialog_->input_command_begin, FL_RETURN_CHANGED);
        fl_set_input_return(dialog_->input_command_end, FL_RETURN_CHANGED);
 
+       // Store the lang identifiers for later
+       vector<frnt::LanguagePair> const langs = frnt::getLanguageData(false);
+       lang_ = getSecond(langs);
+
        // The default_language is a combo-box and has to be inserted manually
        fl_freeze_form(dialog_->form);
        fl_addto_form(dialog_->form);
 
        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.reset(new Combox(FL_COMBOX_DROPLIST));
        combo_default_lang->add(obj->x, obj->y, obj->w, obj->h, 400);
        combo_default_lang->shortcut("#L",1);
        combo_default_lang->setcallback(ComboCB, &parent_);
 
-       for (Languages::const_iterator cit = languages.begin();
-           cit != languages.end(); ++cit) {
-               combo_default_lang->addto((*cit).second.lang());
+       vector<frnt::LanguagePair>::const_iterator lit  = langs.begin();
+       vector<frnt::LanguagePair>::const_iterator lend = langs.end();
+       for (; lit != lend; ++lit) {
+               combo_default_lang->addto(lit->first);
        }
+       combo_default_lang->select(1);
 
        fl_end_form();
        fl_unfreeze_form(dialog_->form);
 
        // set up the feedback mechanism
-       setPreHandler(dialog_->input_package);
-       setPreHandler(dialog_->check_use_kbmap);
+       setPrehandler(dialog_->input_package);
+       setPrehandler(dialog_->check_use_kbmap);
 
        // This is safe, as nothing is done to the pointer, other than
        // to use its address in a block-if statement.
-       // setPreHandler(
-       //              reinterpret_cast<FL_OBJECT *>(combo_default_lang),
+       // No it's not! Leads to crash.
+       // setPrehandler(
+       //              reinterpret_cast<FL_OBJECT *>(combo_default_lang),
        //              C_FormPreferencesFeedbackCB);
 
-       setPreHandler(dialog_->input_kbmap1);
-       setPreHandler(dialog_->input_kbmap2);
-       setPreHandler(dialog_->check_rtl_support);
-       setPreHandler(dialog_->check_mark_foreign);
-       setPreHandler(dialog_->check_auto_begin);
-       setPreHandler(dialog_->check_auto_end);
-       setPreHandler(dialog_->input_command_begin);
-       setPreHandler(dialog_->input_command_end);
+       setPrehandler(dialog_->input_kbmap1);
+       setPrehandler(dialog_->input_kbmap2);
+       setPrehandler(dialog_->check_rtl_support);
+       setPrehandler(dialog_->check_mark_foreign);
+       setPrehandler(dialog_->check_auto_begin);
+       setPrehandler(dialog_->check_auto_end);
+       setPrehandler(dialog_->check_use_babel);
+       setPrehandler(dialog_->check_global_options);
+       setPrehandler(dialog_->input_command_begin);
+       setPrehandler(dialog_->input_command_end);
 
        // Activate/Deactivate the input fields dependent on the state of the
        // buttons.
@@ -1865,32 +1679,33 @@ void FormPreferences::Language::build()
 string const
 FormPreferences::Language::feedback(FL_OBJECT const * const ob) const
 {
-       string str;
-
-       if (reinterpret_cast<Combox const *>(ob) == combo_default_lang)
-               str = lyxrc.getDescription(LyXRC::RC_DEFAULT_LANGUAGE);
-       else if (ob == dialog_->check_use_kbmap)
-               str = lyxrc.getDescription(LyXRC::RC_KBMAP);
-       else if (ob == dialog_->input_kbmap1)
-               str = lyxrc.getDescription(LyXRC::RC_KBMAP_PRIMARY);
-       else if (ob == dialog_->input_kbmap2)
-               str = lyxrc.getDescription(LyXRC::RC_KBMAP_SECONDARY);
-       else if (ob == dialog_->check_rtl_support)
-               str = lyxrc.getDescription(LyXRC::RC_RTL_SUPPORT);
-       else if (ob == dialog_->check_auto_begin)
-               str = lyxrc.getDescription(LyXRC::RC_LANGUAGE_AUTO_BEGIN);
-       else if (ob == dialog_->check_auto_end)
-               str = lyxrc.getDescription(LyXRC::RC_LANGUAGE_AUTO_END);
-       else if (ob == dialog_->check_mark_foreign)
-               str = lyxrc.getDescription(LyXRC::RC_MARK_FOREIGN_LANGUAGE);
-       else if (ob == dialog_->input_package)
-               str = lyxrc.getDescription(LyXRC::RC_LANGUAGE_PACKAGE);
-       else if (ob == dialog_->input_command_begin)
-               str = lyxrc.getDescription(LyXRC::RC_LANGUAGE_COMMAND_BEGIN);
-       else if (ob == dialog_->input_command_end)
-               str = lyxrc.getDescription(LyXRC::RC_LANGUAGE_COMMAND_END);
-
-       return str;
+       if (reinterpret_cast<Combox const *>(ob) == combo_default_lang.get())
+               return LyXRC::getDescription(LyXRC::RC_DEFAULT_LANGUAGE);
+       if (ob == dialog_->check_use_kbmap)
+               return LyXRC::getDescription(LyXRC::RC_KBMAP);
+       if (ob == dialog_->input_kbmap1)
+               return LyXRC::getDescription(LyXRC::RC_KBMAP_PRIMARY);
+       if (ob == dialog_->input_kbmap2)
+               return LyXRC::getDescription(LyXRC::RC_KBMAP_SECONDARY);
+       if (ob == dialog_->check_rtl_support)
+               return LyXRC::getDescription(LyXRC::RC_RTL_SUPPORT);
+       if (ob == dialog_->check_mark_foreign)
+               return LyXRC::getDescription(LyXRC::RC_MARK_FOREIGN_LANGUAGE);
+       if (ob == dialog_->check_auto_begin)
+               return LyXRC::getDescription(LyXRC::RC_LANGUAGE_AUTO_BEGIN);
+       if (ob == dialog_->check_auto_end)
+               return LyXRC::getDescription(LyXRC::RC_LANGUAGE_AUTO_END);
+       if (ob == dialog_->check_use_babel)
+               return LyXRC::getDescription(LyXRC::RC_LANGUAGE_USE_BABEL);
+       if (ob == dialog_->check_global_options)
+               return LyXRC::getDescription(LyXRC::RC_LANGUAGE_GLOBAL_OPTIONS);
+       if (ob == dialog_->input_package)
+               return LyXRC::getDescription(LyXRC::RC_LANGUAGE_PACKAGE);
+       if (ob == dialog_->input_command_begin)
+               return LyXRC::getDescription(LyXRC::RC_LANGUAGE_COMMAND_BEGIN);
+       if (ob == dialog_->input_command_end)
+               return LyXRC::getDescription(LyXRC::RC_LANGUAGE_COMMAND_END);
+       return string();
 }
 
 
@@ -1902,88 +1717,62 @@ bool FormPreferences::Language::input(FL_OBJECT const * const ob)
        // objects,
        // otherwise the function is called by an xforms CB via input().
        if (!ob || ob == dialog_->check_use_kbmap) {
-               if (fl_get_button(dialog_->check_use_kbmap)) {
-                       fl_activate_object(dialog_->button_kbmap1_browse);
-                       fl_set_object_lcol(dialog_->button_kbmap1_browse,
-                                          FL_BLACK);
-
-                       fl_activate_object(dialog_->button_kbmap2_browse);
-                       fl_set_object_lcol(dialog_->button_kbmap2_browse,
-                                          FL_BLACK);
-
-                       fl_activate_object(dialog_->input_kbmap1);
-                       fl_set_object_lcol(dialog_->input_kbmap1, FL_BLACK);
-                       fl_activate_object(dialog_->input_kbmap2);
-                       fl_set_object_lcol(dialog_->input_kbmap2, FL_BLACK);
-               } else {
-                       fl_deactivate_object(dialog_->button_kbmap1_browse);
-                       fl_set_object_lcol(dialog_->button_kbmap1_browse,
-                                          FL_INACTIVE);
-
-                       fl_deactivate_object(dialog_->button_kbmap2_browse);
-                       fl_set_object_lcol(dialog_->button_kbmap2_browse,
-                                          FL_INACTIVE);
-
-                       fl_deactivate_object(dialog_->input_kbmap1);
-                       fl_set_object_lcol(dialog_->input_kbmap1,
-                                          FL_INACTIVE);
-                       fl_deactivate_object(dialog_->input_kbmap2);
-                       fl_set_object_lcol(dialog_->input_kbmap2,
-                                          FL_INACTIVE);
-               }
+               bool const enable = fl_get_button(dialog_->check_use_kbmap);
+               setEnabled(dialog_->button_kbmap1_browse, enable);
+               setEnabled(dialog_->button_kbmap2_browse, enable);
+               setEnabled(dialog_->input_kbmap1, enable);
+               setEnabled(dialog_->input_kbmap2, enable);
        }
 
        if (ob == dialog_->button_kbmap1_browse) {
-               string const dir  = system_lyxdir + string("kbd");
-               string const name = N_("Key maps");
-               pair<string, string> dir1(name, dir);
+               string f = parent_.controller().browsekbmap(
+                       fl_get_input(dialog_->input_kbmap1));
 
-               parent_.browse(dialog_->input_kbmap1,
-                               _("Keyboard map"), "*.kmap", dir1,
-                               make_pair(string(), string()));
+               fl_set_input(dialog_->input_kbmap1, f.c_str());
        } else if (ob == dialog_->button_kbmap2_browse) {
-               string const dir  = system_lyxdir + string("kbd");
-               string const name = N_("Key maps");
-               pair<string, string> dir1(name, dir);
+               string f = parent_.controller().browsekbmap(
+                       fl_get_input(dialog_->input_kbmap2));
 
-               parent_.browse(dialog_->input_kbmap2,
-                               _("Keyboard map"), "*.kmap", dir1,
-                               make_pair(string(), string()));
+               fl_set_input(dialog_->input_kbmap2, f.c_str());
        }
 
        return activate;
 }
 
 
-void FormPreferences::Language::update()
+void FormPreferences::Language::update(LyXRC const & rc)
 {
        fl_set_button(dialog_->check_use_kbmap,
-                     lyxrc.use_kbmap);
+                     rc.use_kbmap);
 
-       combo_default_lang->select_text(lyxrc.default_language);
+       int const pos = int(findPos(lang_, rc.default_language));
+       combo_default_lang->select(pos + 1);
 
-       if (lyxrc.use_kbmap) {
+       if (rc.use_kbmap) {
                fl_set_input(dialog_->input_kbmap1,
-                            lyxrc.primary_kbmap.c_str());
+                            rc.primary_kbmap.c_str());
                fl_set_input(dialog_->input_kbmap2,
-                            lyxrc.secondary_kbmap.c_str());
+                            rc.secondary_kbmap.c_str());
        } else {
                fl_set_input(dialog_->input_kbmap1, "");
                fl_set_input(dialog_->input_kbmap2, "");
        }
-       
-       fl_set_button(dialog_->check_rtl_support, lyxrc.rtl_support);
-       fl_set_button(dialog_->check_auto_begin,  lyxrc.language_auto_begin);
-       fl_set_button(dialog_->check_auto_end,    lyxrc.language_auto_end);
+
+       fl_set_button(dialog_->check_rtl_support, rc.rtl_support);
        fl_set_button(dialog_->check_mark_foreign,
-                     lyxrc.mark_foreign_language);
+                     rc.mark_foreign_language);
+       fl_set_button(dialog_->check_auto_begin, rc.language_auto_begin);
+       fl_set_button(dialog_->check_auto_end, rc.language_auto_end);
+       fl_set_button(dialog_->check_use_babel, rc.language_use_babel);
+       fl_set_button(dialog_->check_global_options,
+                     rc.language_global_options);
 
        fl_set_input(dialog_->input_package,
-                    lyxrc.language_package.c_str());
+                    rc.language_package.c_str());
        fl_set_input(dialog_->input_command_begin,
-                    lyxrc.language_command_begin.c_str());
+                    rc.language_command_begin.c_str());
        fl_set_input(dialog_->input_command_end,
-                    lyxrc.language_command_end.c_str());
+                    rc.language_command_end.c_str());
 
        // Activate/Deactivate the input fields dependent on the state of the
        // buttons.
@@ -1993,40 +1782,63 @@ void FormPreferences::Language::update()
 
 void FormPreferences::Language::ComboCB(int, void * v, Combox * combox)
 {
-    FormPreferences * pre = static_cast<FormPreferences*>(v);
-    // This is safe, as nothing is done to the pointer, other than
-    // to use its address in a block-if statement.
-    pre->bc_.valid(pre->input(reinterpret_cast<FL_OBJECT *>(combox), 0));
+       FormPreferences * pre = static_cast<FormPreferences*>(v);
+       // This is safe, as nothing is done to the pointer, other than
+       // to use its address in a block-if statement.
+       pre->bc().valid(pre->input(reinterpret_cast<FL_OBJECT *>(combox), 0));
 }
 
 
-FormPreferences::LnFmisc::~LnFmisc()
+FormPreferences::LnFmisc::LnFmisc(FormPreferences &  p)
+       : parent_(p)
+{}
+
+
+FD_preferences_lnf_misc const * FormPreferences::LnFmisc::dialog()
 {
-       delete dialog_;
+       return dialog_.get();
 }
 
 
-void FormPreferences::LnFmisc::apply() const
+void FormPreferences::LnFmisc::apply(LyXRC & rc) const
 {
-       lyxrc.show_banner = fl_get_button(dialog_->check_banner);
-       lyxrc.auto_region_delete =
+       rc.auto_region_delete =
                fl_get_button(dialog_->check_auto_region_delete);
-       lyxrc.exit_confirmation = fl_get_button(dialog_->check_exit_confirm);
-       lyxrc.display_shortcuts =
-               fl_get_button(dialog_->check_display_shrtcuts);
-       lyxrc.new_ask_filename = fl_get_button(dialog_->check_ask_new_file);
-       lyxrc.cursor_follows_scrollbar =
+       rc.cursor_follows_scrollbar =
                fl_get_button(dialog_->check_cursor_follows_scrollbar);
-       lyxrc.autosave = static_cast<unsigned int>
+       rc.dialogs_iconify_with_main =
+               fl_get_button(dialog_->check_dialogs_iconify_with_main);
+       rc.preview = fl_get_button(dialog_->check_preview_latex);
+       rc.autosave = static_cast<unsigned int>
                (fl_get_counter_value(dialog_->counter_autosave));
-       lyxrc.wheel_jump = static_cast<unsigned int>
+       rc.wheel_jump = static_cast<unsigned int>
                (fl_get_counter_value(dialog_->counter_wm_jump));
+
+       // See FIXME below
+       // grfx::DisplayType old_value = rc.display_graphics;
+       switch (fl_get_choice(dialog_->choice_display)) {
+               case 4: rc.display_graphics = grfx::NoDisplay; break;
+               case 3: rc.display_graphics = grfx::ColorDisplay; break;
+               case 2: rc.display_graphics = grfx::GrayscaleDisplay; break;
+               case 1: rc.display_graphics = grfx::MonochromeDisplay; break;
+               default: rc.display_graphics = grfx::ColorDisplay; break;
+       }
+
+#ifdef WITH_WARNINGS
+#warning FIXME!! The graphics cache no longer has a changeDisplay method.
+#endif
+#if 0
+       if (old_value != rc.display_graphics) {
+               grfx::GCache & gc = grfx::GCache::get();
+               gc.changeDisplay();
+       }
+#endif
 }
 
 
 void FormPreferences::LnFmisc::build()
 {
-       dialog_ = parent_.build_lnf_misc();
+       dialog_.reset(build_preferences_lnf_misc(&parent_));
 
        fl_set_counter_step(dialog_->counter_autosave, 1, 10);
        fl_set_counter_step(dialog_->counter_wm_jump, 1, 10);
@@ -2035,82 +1847,92 @@ void FormPreferences::LnFmisc::build()
        fl_set_counter_return(dialog_->counter_wm_jump, FL_RETURN_CHANGED);
 
        // set up the feedback mechanism
-       setPreHandler(dialog_->check_banner);
-       setPreHandler(dialog_->check_auto_region_delete);
-       setPreHandler(dialog_->check_exit_confirm);
-       setPreHandler(dialog_->check_display_shrtcuts);
-       setPreHandler(dialog_->counter_autosave);
-       setPreHandler(dialog_->check_ask_new_file);
-       setPreHandler(dialog_->check_cursor_follows_scrollbar);
-       setPreHandler(dialog_->counter_wm_jump);
+       setPrehandler(dialog_->check_auto_region_delete);
+       setPrehandler(dialog_->counter_autosave);
+       setPrehandler(dialog_->check_cursor_follows_scrollbar);
+       setPrehandler(dialog_->check_dialogs_iconify_with_main);
+       setPrehandler(dialog_->check_preview_latex);
+       setPrehandler(dialog_->counter_wm_jump);
+
+       fl_addto_choice(dialog_->choice_display, _("Monochrome|Grayscale|Color|Do not display"));
 }
 
 
 string const
 FormPreferences::LnFmisc::feedback(FL_OBJECT const * const ob) const
 {
-       string str;
+       if (ob == dialog_->check_auto_region_delete)
+               return LyXRC::getDescription(LyXRC::RC_AUTOREGIONDELETE);
+       if (ob == dialog_->check_cursor_follows_scrollbar)
+               return LyXRC::getDescription(LyXRC::RC_CURSOR_FOLLOWS_SCROLLBAR);
+       if (ob == dialog_->check_dialogs_iconify_with_main)
+               return LyXRC::getDescription(LyXRC::RC_DIALOGS_ICONIFY_WITH_MAIN);
+       if (ob == dialog_->check_preview_latex)
+               return LyXRC::getDescription(LyXRC::RC_PREVIEW);
+       if (ob == dialog_->counter_autosave)
+               return LyXRC::getDescription(LyXRC::RC_AUTOSAVE);
+       if (ob == dialog_->counter_wm_jump)
+               return LyXRC::getDescription(LyXRC::RC_WHEEL_JUMP);
+       if (ob == dialog_->choice_display)
+               return LyXRC::getDescription(LyXRC::RC_DISPLAY_GRAPHICS);
+       return string();
+}
+
 
-       if (ob == dialog_->check_banner)
-               str = lyxrc.getDescription(LyXRC::RC_SHOW_BANNER);
-       else if (ob == dialog_->check_auto_region_delete)
-               str = lyxrc.getDescription(LyXRC::RC_AUTOREGIONDELETE);
-       else if (ob == dialog_->check_exit_confirm)
-               str = lyxrc.getDescription(LyXRC::RC_EXIT_CONFIRMATION);
-       else if (ob == dialog_->check_display_shrtcuts)
-               str = lyxrc.getDescription(LyXRC::RC_DISPLAY_SHORTCUTS);
-       else if (ob == dialog_->check_ask_new_file)
-               str = lyxrc.getDescription(LyXRC::RC_NEW_ASK_FILENAME);
-       else if (ob == dialog_->check_cursor_follows_scrollbar)
-               str = lyxrc.getDescription(LyXRC::RC_CURSOR_FOLLOWS_SCROLLBAR);
-       else if (ob == dialog_->counter_autosave)
-               str = lyxrc.getDescription(LyXRC::RC_AUTOSAVE);
-       else if (ob == dialog_->counter_wm_jump)
-               str = lyxrc.getDescription(LyXRC::RC_WHEEL_JUMP);
-
-       return str;
-}
-
-
-void FormPreferences::LnFmisc::update()
-{
-       fl_set_button(dialog_->check_banner, lyxrc.show_banner);
-       fl_set_button(dialog_->check_auto_region_delete, 
-                     lyxrc.auto_region_delete);
-       fl_set_button(dialog_->check_exit_confirm, lyxrc.exit_confirmation);
-       fl_set_button(dialog_->check_display_shrtcuts, lyxrc.display_shortcuts);
-       fl_set_button(dialog_->check_ask_new_file, lyxrc.new_ask_filename);
+void FormPreferences::LnFmisc::update(LyXRC const & rc)
+{
+       fl_set_button(dialog_->check_auto_region_delete,
+                     rc.auto_region_delete);
        fl_set_button(dialog_->check_cursor_follows_scrollbar,
-                     lyxrc.cursor_follows_scrollbar);
-       fl_set_counter_value(dialog_->counter_autosave, lyxrc.autosave);
-       fl_set_counter_value(dialog_->counter_wm_jump, lyxrc.wheel_jump);
+                     rc.cursor_follows_scrollbar);
+       fl_set_button(dialog_->check_dialogs_iconify_with_main,
+                     rc.dialogs_iconify_with_main);
+       fl_set_button(dialog_->check_preview_latex,
+                     rc.preview);
+       fl_set_counter_value(dialog_->counter_autosave, rc.autosave);
+       fl_set_counter_value(dialog_->counter_wm_jump, rc.wheel_jump);
+
+       switch (rc.display_graphics) {
+               case grfx::NoDisplay:           fl_set_choice(dialog_->choice_display, 4); break;
+               case grfx::ColorDisplay:        fl_set_choice(dialog_->choice_display, 3); break;
+               case grfx::GrayscaleDisplay:    fl_set_choice(dialog_->choice_display, 2); break;
+               case grfx::MonochromeDisplay:   fl_set_choice(dialog_->choice_display, 1); break;
+               default:                        fl_set_choice(dialog_->choice_display, 3); break;
+       }
 }
 
 
-FormPreferences::OutputsMisc::~OutputsMisc()
+FormPreferences::OutputsMisc::OutputsMisc(FormPreferences &  p)
+       : parent_(p)
+{}
+
+
+FD_preferences_outputs_misc const * FormPreferences::OutputsMisc::dialog()
 {
-       delete dialog_;
+       return dialog_.get();
 }
 
 
-void FormPreferences::OutputsMisc::apply() const
+void FormPreferences::OutputsMisc::apply(LyXRC & rc) const
 {
-       lyxrc.ascii_linelen = static_cast<unsigned int>
+       rc.ascii_linelen = static_cast<unsigned int>
                (fl_get_counter_value(dialog_->counter_line_len));
-       lyxrc.fontenc = fl_get_input(dialog_->input_tex_encoding);
+       rc.fontenc = fl_get_input(dialog_->input_tex_encoding);
 
        int const choice =
                fl_get_choice(dialog_->choice_default_papersize) - 1;
-       lyxrc.default_papersize = static_cast<BufferParams::PAPER_SIZE>(choice);
+       rc.default_papersize = static_cast<BufferParams::PAPER_SIZE>(choice);
 
-       lyxrc.ascii_roff_command = fl_get_input(dialog_->input_ascii_roff);
-       lyxrc.chktex_command = fl_get_input(dialog_->input_checktex);
+       rc.ascii_roff_command = fl_get_input(dialog_->input_ascii_roff);
+       rc.chktex_command = fl_get_input(dialog_->input_checktex);
+       rc.view_dvi_paper_option = fl_get_input(dialog_->input_paperoption);
+       rc.auto_reset_options = fl_get_button(dialog_->check_autoreset_classopt);
 }
 
 
 void FormPreferences::OutputsMisc::build()
 {
-       dialog_ = parent_.build_outputs_misc();
+       dialog_.reset(build_preferences_outputs_misc(&parent_));
 
        fl_set_counter_step(dialog_->counter_line_len, 1, 10);
 
@@ -2118,98 +1940,114 @@ void FormPreferences::OutputsMisc::build()
        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_input_return(dialog_->input_paperoption,  FL_RETURN_CHANGED);
 
        fl_addto_choice(dialog_->choice_default_papersize,
-                       _(" default | US letter | legal | executive | A3 | A4 | A5 | B5 "));
+                       _(" default | US letter | US legal | US executive | A3 | A4 | A5 | B5 "));
 
        // set up the feedback mechanism
-       setPreHandler(dialog_->counter_line_len);
-       setPreHandler(dialog_->input_tex_encoding);
-       setPreHandler(dialog_->choice_default_papersize);
-       setPreHandler(dialog_->input_ascii_roff);
-       setPreHandler(dialog_->input_checktex);
+       setPrehandler(dialog_->counter_line_len);
+       setPrehandler(dialog_->input_tex_encoding);
+       setPrehandler(dialog_->choice_default_papersize);
+       setPrehandler(dialog_->input_ascii_roff);
+       setPrehandler(dialog_->input_checktex);
+       setPrehandler(dialog_->input_paperoption);
+       setPrehandler(dialog_->check_autoreset_classopt);
 }
 
 
 string const
 FormPreferences::OutputsMisc::feedback(FL_OBJECT const * const ob) const
 {
-       string str;
-
        if (ob == dialog_->counter_line_len)
-               str = lyxrc.getDescription(LyXRC::RC_ASCII_LINELEN);
-       else if (ob == dialog_->input_tex_encoding)
-               str = lyxrc.getDescription(LyXRC::RC_FONT_ENCODING);
-       else if (ob == dialog_->input_ascii_roff)
-               str = lyxrc.getDescription(LyXRC::RC_ASCIIROFF_COMMAND);
-       else if (ob == dialog_->input_checktex)
-               str = lyxrc.getDescription(LyXRC::RC_CHKTEX_COMMAND);
-       else if (ob == dialog_->choice_default_papersize)
-               str = lyxrc.getDescription(LyXRC::RC_DEFAULT_PAPERSIZE);
-
-       return str;
+               return LyXRC::getDescription(LyXRC::RC_ASCII_LINELEN);
+       if (ob == dialog_->input_tex_encoding)
+               return LyXRC::getDescription(LyXRC::RC_FONT_ENCODING);
+       if (ob == dialog_->input_ascii_roff)
+               return LyXRC::getDescription(LyXRC::RC_ASCIIROFF_COMMAND);
+       if (ob == dialog_->input_checktex)
+               return LyXRC::getDescription(LyXRC::RC_CHKTEX_COMMAND);
+       if (ob == dialog_->choice_default_papersize)
+               return LyXRC::getDescription(LyXRC::RC_DEFAULT_PAPERSIZE);
+       if (ob == dialog_->input_paperoption)
+               return LyXRC::getDescription(LyXRC::RC_VIEWDVI_PAPEROPTION);
+       if (ob == dialog_->check_autoreset_classopt)
+               return LyXRC::getDescription(LyXRC::RC_AUTORESET_OPTIONS);
+       return string();
 }
 
 
-void FormPreferences::OutputsMisc::update()
+void FormPreferences::OutputsMisc::update(LyXRC const & rc)
 {
        fl_set_counter_value(dialog_->counter_line_len,
-                            lyxrc.ascii_linelen);
+                            rc.ascii_linelen);
        fl_set_input(dialog_->input_tex_encoding,
-                    lyxrc.fontenc.c_str());
+                    rc.fontenc.c_str());
        fl_set_choice(dialog_->choice_default_papersize,
-                     lyxrc.default_papersize+1);
+                     rc.default_papersize + 1);
        fl_set_input(dialog_->input_ascii_roff,
-                    lyxrc.ascii_roff_command.c_str());
+                    rc.ascii_roff_command.c_str());
        fl_set_input(dialog_->input_checktex,
-                    lyxrc.chktex_command.c_str());
+                    rc.chktex_command.c_str());
+       fl_set_input(dialog_->input_paperoption,
+                    rc.view_dvi_paper_option.c_str());
+       fl_set_button(dialog_->check_autoreset_classopt,
+                     rc.auto_reset_options);
+
 }
 
 
-FormPreferences::Paths::~Paths()
+FormPreferences::Paths::Paths(FormPreferences &  p)
+       : parent_(p)
+{}
+
+
+FD_preferences_paths const * FormPreferences::Paths::dialog()
 {
-       delete dialog_;
+       return dialog_.get();
 }
 
 
-void FormPreferences::Paths::apply()
+void FormPreferences::Paths::apply(LyXRC & rc)
 {
-       lyxrc.document_path = fl_get_input(dialog_->input_default_path);
-       lyxrc.template_path = fl_get_input(dialog_->input_template_path);
+       rc.document_path = fl_get_input(dialog_->input_default_path);
+       rc.template_path = fl_get_input(dialog_->input_template_path);
 
        int button = fl_get_button(dialog_->check_use_temp_dir);
        string str  = fl_get_input(dialog_->input_temp_dir);
-       if (!button) str.erase();
+       if (!button)
+               str.erase();
 
-       lyxrc.use_tempdir = button;
-       lyxrc.tempdir_path = str;
+       rc.use_tempdir = button;
+       rc.tempdir_path = str;
 
        button = fl_get_button(dialog_->check_last_files);
        str = fl_get_input(dialog_->input_lastfiles);
        if (!button) str.erase();
-       
-       lyxrc.check_lastfiles = button;
-       lyxrc.lastfiles = str;
-       lyxrc.num_lastfiles = static_cast<unsigned int>
+
+       rc.check_lastfiles = button;
+       rc.lastfiles = str;
+       rc.num_lastfiles = static_cast<unsigned int>
                (fl_get_counter_value(dialog_->counter_lastfiles));
 
        button = fl_get_button(dialog_->check_make_backups);
        str = fl_get_input(dialog_->input_backup_path);
-       if (!button) str.erase();
+       if (!button)
+               str.erase();
 
-       lyxrc.make_backup = button;
-       lyxrc.backupdir_path = str;
+       rc.make_backup = button;
+       rc.backupdir_path = str;
 
-       lyxrc.lyxpipes = fl_get_input(dialog_->input_serverpipe);
+       rc.lyxpipes = fl_get_input(dialog_->input_serverpipe);
 
        // update view
-       update();
+       update(rc);
 }
 
 
 void FormPreferences::Paths::build()
 {
-       dialog_ = parent_.build_paths();
+       dialog_.reset(build_preferences_paths(&parent_));
 
        fl_set_input_return(dialog_->input_default_path, FL_RETURN_CHANGED);
        fl_set_input_return(dialog_->input_template_path, FL_RETURN_CHANGED);
@@ -2220,106 +2058,80 @@ void FormPreferences::Paths::build()
        fl_set_input_return(dialog_->input_serverpipe, FL_RETURN_CHANGED);
 
        // set up the feedback mechanism
-       setPreHandler(dialog_->input_default_path);
-       setPreHandler(dialog_->counter_lastfiles);
-       setPreHandler(dialog_->input_template_path);
-       setPreHandler(dialog_->check_last_files);
-       setPreHandler(dialog_->input_lastfiles);
-       setPreHandler(dialog_->check_make_backups);
-       setPreHandler(dialog_->input_backup_path);
-       setPreHandler(dialog_->input_serverpipe);
-       setPreHandler(dialog_->input_temp_dir);
-       setPreHandler(dialog_->check_use_temp_dir);
+       setPrehandler(dialog_->input_default_path);
+       setPrehandler(dialog_->counter_lastfiles);
+       setPrehandler(dialog_->input_template_path);
+       setPrehandler(dialog_->check_last_files);
+       setPrehandler(dialog_->input_lastfiles);
+       setPrehandler(dialog_->check_make_backups);
+       setPrehandler(dialog_->input_backup_path);
+       setPrehandler(dialog_->input_serverpipe);
+       setPrehandler(dialog_->input_temp_dir);
+       setPrehandler(dialog_->check_use_temp_dir);
 }
 
 
 string const
 FormPreferences::Paths::feedback(FL_OBJECT const * const ob) const
 {
-       string str;
-
        if (ob == dialog_->input_default_path)
-               str = lyxrc.getDescription(LyXRC::RC_DOCUMENTPATH);
-       else if (ob == dialog_->input_template_path)
-               str = lyxrc.getDescription(LyXRC::RC_TEMPLATEPATH);
-       else if (ob == dialog_->check_use_temp_dir)
-               str = lyxrc.getDescription(LyXRC::RC_USETEMPDIR);
-       else if (ob == dialog_->input_temp_dir)
-               str = lyxrc.getDescription(LyXRC::RC_TEMPDIRPATH);
-       else if (ob == dialog_->check_last_files)
-               str = lyxrc.getDescription(LyXRC::RC_CHECKLASTFILES);
-       else if (ob == dialog_->input_lastfiles)
-               str = lyxrc.getDescription(LyXRC::RC_LASTFILES);
-       else if (ob == dialog_->counter_lastfiles)
-               str = lyxrc.getDescription(LyXRC::RC_NUMLASTFILES);
-       else if (ob == dialog_->check_make_backups)
-               str = lyxrc.getDescription(LyXRC::RC_MAKE_BACKUP);
-       else if (ob == dialog_->input_backup_path)
-               str = lyxrc.getDescription(LyXRC::RC_BACKUPDIR_PATH);
-       else if (ob == dialog_->input_serverpipe) {
-               str = lyxrc.getDescription(LyXRC::RC_SERVERPIPE);
-               str += " Enter either the input pipe, xxx.in, or the output pipe, xxx.out.";
-       }
-
-       return str;
+               return LyXRC::getDescription(LyXRC::RC_DOCUMENTPATH);
+       if (ob == dialog_->input_template_path)
+               return LyXRC::getDescription(LyXRC::RC_TEMPLATEPATH);
+       if (ob == dialog_->check_use_temp_dir)
+               return LyXRC::getDescription(LyXRC::RC_USETEMPDIR);
+       if (ob == dialog_->input_temp_dir)
+               return LyXRC::getDescription(LyXRC::RC_TEMPDIRPATH);
+       if (ob == dialog_->check_last_files)
+               return LyXRC::getDescription(LyXRC::RC_CHECKLASTFILES);
+       if (ob == dialog_->input_lastfiles)
+               return LyXRC::getDescription(LyXRC::RC_LASTFILES);
+       if (ob == dialog_->counter_lastfiles)
+               return LyXRC::getDescription(LyXRC::RC_NUMLASTFILES);
+       if (ob == dialog_->check_make_backups)
+               return LyXRC::getDescription(LyXRC::RC_MAKE_BACKUP);
+       if (ob == dialog_->input_backup_path)
+               return LyXRC::getDescription(LyXRC::RC_BACKUPDIR_PATH);
+       if (ob == dialog_->input_serverpipe)
+               return LyXRC::getDescription(LyXRC::RC_SERVERPIPE);
+       return string();
 }
 
 
 bool FormPreferences::Paths::input(FL_OBJECT const * const ob)
 {
        bool activate = true;
-       
+
        // !ob if function is called from Paths::update() to de/activate
        // objects,
        // otherwise the function is called by an xforms CB via input().
        if (!ob || ob == dialog_->check_use_temp_dir) {
-               if (fl_get_button(dialog_->check_use_temp_dir)) {
-                       fl_activate_object(dialog_->input_temp_dir);
-                       fl_set_object_lcol(dialog_->input_temp_dir,
-                                          FL_BLACK);
-               } else {
-                       fl_deactivate_object(dialog_->input_temp_dir);
-                       fl_set_object_lcol(dialog_->input_temp_dir,
-                                          FL_INACTIVE);
-               }
+               bool const enable = fl_get_button(dialog_->check_use_temp_dir);
+               setEnabled(dialog_->input_temp_dir, enable);
        }
 
        if (!ob || ob == dialog_->check_last_files) {
-               if (fl_get_button(dialog_->check_last_files)) {
-                       fl_activate_object(dialog_->input_lastfiles);
-                       fl_set_object_lcol(dialog_->input_lastfiles,
-                                          FL_BLACK);
-               } else {
-                       fl_deactivate_object(dialog_->input_lastfiles);
-                       fl_set_object_lcol(dialog_->input_lastfiles,
-                                          FL_INACTIVE);
-               }
+               bool const enable = fl_get_button(dialog_->check_last_files);
+               setEnabled(dialog_->input_lastfiles, enable);
        }
 
        if (!ob || ob == dialog_->check_make_backups) {
-               if (fl_get_button(dialog_->check_make_backups)) {
-                       fl_activate_object(dialog_->input_backup_path);
-                       fl_set_object_lcol(dialog_->input_backup_path,
-                                          FL_BLACK);
-               } else {
-                       fl_deactivate_object(dialog_->input_backup_path);
-                       fl_set_object_lcol(dialog_->input_backup_path,
-                                          FL_INACTIVE);
-               }
+               bool const enable = fl_get_button(dialog_->check_make_backups);
+               setEnabled(dialog_->input_backup_path, enable);
        }
 
        if (!ob || ob == dialog_->input_default_path) {
                string const name = fl_get_input(dialog_->input_default_path);
-               if (!RWInfo::WriteableDir(name)) {
-                       parent_.printWarning(RWInfo::ErrorMessage());
+               if (!name.empty() && !RWInfo::WriteableDir(name)) {
+                       parent_.postWarning(RWInfo::ErrorMessage());
                        return false;
                }
        }
 
        if (!ob || ob == dialog_->input_template_path) {
                string const name = fl_get_input(dialog_->input_template_path);
-               if (!RWInfo::ReadableDir(name)) {
-                       parent_.printWarning(RWInfo::ErrorMessage());
+               if (!name.empty() && !RWInfo::ReadableDir(name)) {
+                       parent_.postWarning(RWInfo::ErrorMessage());
                        return false;
                }
        }
@@ -2329,7 +2141,7 @@ bool FormPreferences::Paths::input(FL_OBJECT const * const ob)
                if (fl_get_button(dialog_->check_make_backups)
                    && !name.empty()
                    && !RWInfo::WriteableDir(name)) {
-                       parent_.printWarning(RWInfo::ErrorMessage());
+                       parent_.postWarning(RWInfo::ErrorMessage());
                        return false;
                }
        }
@@ -2339,7 +2151,7 @@ bool FormPreferences::Paths::input(FL_OBJECT const * const ob)
                if (fl_get_button(dialog_->check_make_backups)
                    && !name.empty()
                    && !RWInfo::WriteableDir(name)) {
-                       parent_.printWarning(RWInfo::ErrorMessage());
+                       parent_.postWarning(RWInfo::ErrorMessage());
                        return false;
                }
        }
@@ -2349,7 +2161,7 @@ bool FormPreferences::Paths::input(FL_OBJECT const * const ob)
                if (fl_get_button(dialog_->check_last_files)
                    && !name.empty()
                    && !RWInfo::WriteableFile(name)) {
-                       parent_.printWarning(RWInfo::ErrorMessage());
+                       parent_.postWarning(RWInfo::ErrorMessage());
                        return false;
                }
        }
@@ -2360,84 +2172,80 @@ bool FormPreferences::Paths::input(FL_OBJECT const * const ob)
                        // strip off the extension
                        string const str = ChangeExtension(name, "");
                        if (!RWInfo::WriteableFile(str + ".in")) {
-                               parent_.printWarning(RWInfo::ErrorMessage());
+                               parent_.postWarning(RWInfo::ErrorMessage());
                                return false;
                        }
                        if (!RWInfo::WriteableFile(str + ".out")) {
-                               parent_.printWarning(RWInfo::ErrorMessage());
+                               parent_.postWarning(RWInfo::ErrorMessage());
                                return false;
                        }
                }
        }
 
        if (ob == dialog_->button_default_path_browse) {
-               parent_.browse(dialog_->input_default_path,
-                               _("Default path"), string(),
-                               make_pair(string(), string()),
-                               make_pair(string(), string()));
+               string f = parent_.controller().browse(
+                       fl_get_input(dialog_->input_default_path), _("Default path"));
+               fl_set_input(dialog_->input_default_path, f.c_str());
        } 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()));
+               string f = parent_.controller().browse(
+                       fl_get_input(dialog_->input_template_path), _("Template path"));
+               fl_set_input(dialog_->input_template_path, f.c_str());
        } 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()));
+               string f = parent_.controller().browse(
+                       fl_get_input(dialog_->input_temp_dir), _("Temporary dir"));
+               fl_set_input(dialog_->input_temp_dir, f.c_str());
        } 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()));
+               string f = parent_.controller().browse(
+                       fl_get_input(dialog_->input_lastfiles), _("Last files"));
+               fl_set_input(dialog_->input_lastfiles, f.c_str());
        } 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()));
+               string f = parent_.controller().browse(
+                       fl_get_input(dialog_->input_backup_path), _("Backup path"));
+               fl_set_input(dialog_->input_backup_path, f.c_str());
        } else if (ob == dialog_->button_serverpipe_browse) {
-               parent_.browse(dialog_->input_serverpipe,
-                               _("LyX Server pipes"), string(),
-                               make_pair(string(), string()),
-                               make_pair(string(), string()));
+               string f = parent_.controller().browse(
+                       fl_get_input(dialog_->input_serverpipe), _("LyX server pipes"));
+               fl_set_input(dialog_->input_serverpipe, f.c_str());
        }
-       
+
        return activate;
 }
 
 
-void FormPreferences::Paths::update()
+void FormPreferences::Paths::update(LyXRC const & rc)
 {
        fl_set_input(dialog_->input_default_path,
-                    lyxrc.document_path.c_str());
+                    rc.document_path.c_str());
        fl_set_input(dialog_->input_template_path,
-                    lyxrc.template_path.c_str());
+                    rc.template_path.c_str());
 
        string str;
-       if (lyxrc.make_backup) str = lyxrc.backupdir_path;
+       if (rc.make_backup)
+               str = rc.backupdir_path;
 
        fl_set_button(dialog_->check_make_backups,
-                     lyxrc.make_backup);
+                     rc.make_backup);
        fl_set_input(dialog_->input_backup_path, str.c_str());
 
        str.erase();
-       if (lyxrc.use_tempdir) str = lyxrc.tempdir_path;
+       if (rc.use_tempdir)
+               str = rc.tempdir_path;
 
        fl_set_button(dialog_->check_use_temp_dir,
-                     lyxrc.use_tempdir);
+                     rc.use_tempdir);
        fl_set_input(dialog_->input_temp_dir, str.c_str());
 
        str.erase();
-       if (lyxrc.check_lastfiles) str = lyxrc.lastfiles;
+       if (rc.check_lastfiles)
+               str = rc.lastfiles;
 
        fl_set_button(dialog_->check_last_files,
-                     lyxrc.check_lastfiles);           
+                     rc.check_lastfiles);
        fl_set_input(dialog_->input_lastfiles, str.c_str());
        fl_set_counter_value(dialog_->counter_lastfiles,
-                            lyxrc.num_lastfiles);
+                            rc.num_lastfiles);
 
-       fl_set_input(dialog_->input_serverpipe, lyxrc.lyxpipes.c_str());
+       fl_set_input(dialog_->input_serverpipe, rc.lyxpipes.c_str());
 
        // Activate/Deactivate the input fields dependent on the state of the
        // buttons.
@@ -2445,89 +2253,91 @@ void FormPreferences::Paths::update()
 }
 
 
-FormPreferences::Printer::~Printer()
+FormPreferences::Printer::Printer(FormPreferences &  p)
+       : parent_(p)
+{}
+
+
+FD_preferences_printer const * FormPreferences::Printer::dialog()
 {
-       delete dialog_;
+       return dialog_.get();
 }
 
 
-void FormPreferences::Printer::apply() const
+void FormPreferences::Printer::apply(LyXRC & rc) const
 {
-       lyxrc.print_adapt_output = fl_get_button(dialog_->check_adapt_output);
-       lyxrc.print_command = fl_get_input(dialog_->input_command);
-       lyxrc.print_pagerange_flag = fl_get_input(dialog_->input_page_range);
-       lyxrc.print_copies_flag = fl_get_input(dialog_->input_copies);
-       lyxrc.print_reverse_flag = fl_get_input(dialog_->input_reverse);
-       lyxrc.print_to_printer = fl_get_input(dialog_->input_to_printer);
-       lyxrc.print_file_extension =
+       rc.print_adapt_output = fl_get_button(dialog_->check_adapt_output);
+       rc.print_command = fl_get_input(dialog_->input_command);
+       rc.print_pagerange_flag = fl_get_input(dialog_->input_page_range);
+       rc.print_copies_flag = fl_get_input(dialog_->input_copies);
+       rc.print_reverse_flag = fl_get_input(dialog_->input_reverse);
+       rc.print_to_printer = fl_get_input(dialog_->input_to_printer);
+       rc.print_file_extension =
                fl_get_input(dialog_->input_file_extension);
-       lyxrc.print_spool_command =
+       rc.print_spool_command =
                fl_get_input(dialog_->input_spool_command);
-       lyxrc.print_paper_flag = fl_get_input(dialog_->input_paper_type);
-       lyxrc.print_evenpage_flag = fl_get_input(dialog_->input_even_pages);
-       lyxrc.print_oddpage_flag = fl_get_input(dialog_->input_odd_pages);
-       lyxrc.print_collcopies_flag = fl_get_input(dialog_->input_collated);
-       lyxrc.print_landscape_flag = fl_get_input(dialog_->input_landscape);
-       lyxrc.print_to_file = fl_get_input(dialog_->input_to_file);
-       lyxrc.print_extra_options =
+       rc.print_paper_flag = fl_get_input(dialog_->input_paper_type);
+       rc.print_evenpage_flag = fl_get_input(dialog_->input_even_pages);
+       rc.print_oddpage_flag = fl_get_input(dialog_->input_odd_pages);
+       rc.print_collcopies_flag = fl_get_input(dialog_->input_collated);
+       rc.print_landscape_flag = fl_get_input(dialog_->input_landscape);
+       rc.print_to_file = fl_get_input(dialog_->input_to_file);
+       rc.print_extra_options =
                fl_get_input(dialog_->input_extra_options);
-       lyxrc.print_spool_printerprefix =
+       rc.print_spool_printerprefix =
                fl_get_input(dialog_->input_spool_prefix);
-       lyxrc.print_paper_dimension_flag =
+       rc.print_paper_dimension_flag =
                fl_get_input(dialog_->input_paper_size);
-       lyxrc.printer = fl_get_input(dialog_->input_name);
+       rc.printer = fl_get_input(dialog_->input_name);
 }
 
 
 string const
 FormPreferences::Printer::feedback(FL_OBJECT const * const ob) const
 {
-       string str;
-
        if (ob == dialog_->input_command)
-               str = lyxrc.getDescription(LyXRC::RC_PRINT_COMMAND);
-       else if (ob == dialog_->check_adapt_output)
-               str = lyxrc.getDescription(LyXRC::RC_PRINT_ADAPTOUTPUT);
-       else if (ob == dialog_->input_to_printer)
-               str = lyxrc.getDescription(LyXRC::RC_PRINTTOPRINTER);
-       else if (ob == dialog_->input_to_file)
-               str = lyxrc.getDescription(LyXRC::RC_PRINTTOFILE);
-       else if (ob == dialog_->input_file_extension)
-               str = lyxrc.getDescription(LyXRC::RC_PRINTFILEEXTENSION);
-       else if (ob == dialog_->input_extra_options)
-               str = lyxrc.getDescription(LyXRC::RC_PRINTEXSTRAOPTIONS);
-       else if (ob == dialog_->input_spool_command)
-               str = lyxrc.getDescription(LyXRC::RC_PRINTSPOOL_COMMAND);
-       else if (ob == dialog_->input_spool_prefix)
-               str = lyxrc.getDescription(LyXRC::RC_PRINTSPOOL_PRINTERPREFIX);
-       else if (ob == dialog_->input_name)
-               str = lyxrc.getDescription(LyXRC::RC_PRINTER);
-       else if (ob == dialog_->input_even_pages)
-               str = lyxrc.getDescription(LyXRC::RC_PRINTEVENPAGEFLAG);
-       else if (ob == dialog_->input_odd_pages)
-               str = lyxrc.getDescription(LyXRC::RC_PRINTODDPAGEFLAG);
-       else if (ob == dialog_->input_page_range)
-               str = lyxrc.getDescription(LyXRC::RC_PRINTPAGERANGEFLAG);
-       else if (ob == dialog_->input_reverse)
-               str = lyxrc.getDescription(LyXRC::RC_PRINTREVERSEFLAG);
-       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_paper_type)
-               str = lyxrc.getDescription(LyXRC::RC_PRINTPAPERFLAG);
-       else if (ob == dialog_->input_paper_size)
-               str = lyxrc.getDescription(LyXRC::RC_PRINTPAPERDIMENSIONFLAG);
-
-       return str;
+               return LyXRC::getDescription(LyXRC::RC_PRINT_COMMAND);
+       if (ob == dialog_->check_adapt_output)
+               return LyXRC::getDescription(LyXRC::RC_PRINT_ADAPTOUTPUT);
+       if (ob == dialog_->input_to_printer)
+               return LyXRC::getDescription(LyXRC::RC_PRINTTOPRINTER);
+       if (ob == dialog_->input_to_file)
+               return LyXRC::getDescription(LyXRC::RC_PRINTTOFILE);
+       if (ob == dialog_->input_file_extension)
+               return LyXRC::getDescription(LyXRC::RC_PRINTFILEEXTENSION);
+       if (ob == dialog_->input_extra_options)
+               return LyXRC::getDescription(LyXRC::RC_PRINTEXSTRAOPTIONS);
+       if (ob == dialog_->input_spool_command)
+               return LyXRC::getDescription(LyXRC::RC_PRINTSPOOL_COMMAND);
+       if (ob == dialog_->input_spool_prefix)
+               return LyXRC::getDescription(LyXRC::RC_PRINTSPOOL_PRINTERPREFIX);
+       if (ob == dialog_->input_name)
+               return LyXRC::getDescription(LyXRC::RC_PRINTER);
+       if (ob == dialog_->input_even_pages)
+               return LyXRC::getDescription(LyXRC::RC_PRINTEVENPAGEFLAG);
+       if (ob == dialog_->input_odd_pages)
+               return LyXRC::getDescription(LyXRC::RC_PRINTODDPAGEFLAG);
+       if (ob == dialog_->input_page_range)
+               return LyXRC::getDescription(LyXRC::RC_PRINTPAGERANGEFLAG);
+       if (ob == dialog_->input_reverse)
+               return LyXRC::getDescription(LyXRC::RC_PRINTREVERSEFLAG);
+       if (ob == dialog_->input_landscape)
+               return LyXRC::getDescription(LyXRC::RC_PRINTLANDSCAPEFLAG);
+       if (ob == dialog_->input_copies)
+               return LyXRC::getDescription(LyXRC::RC_PRINTCOPIESFLAG);
+       if (ob == dialog_->input_collated)
+               return LyXRC::getDescription(LyXRC::RC_PRINTCOLLCOPIESFLAG);
+       if (ob == dialog_->input_paper_type)
+               return LyXRC::getDescription(LyXRC::RC_PRINTPAPERFLAG);
+       if (ob == dialog_->input_paper_size)
+               return LyXRC::getDescription(LyXRC::RC_PRINTPAPERDIMENSIONFLAG);
+       return string();
 }
 
 
 void FormPreferences::Printer::build()
 {
-       dialog_ = parent_.build_printer();
+       dialog_.reset(build_preferences_printer(&parent_));
 
        fl_set_input_return(dialog_->input_command, FL_RETURN_CHANGED);
        fl_set_input_return(dialog_->input_page_range, FL_RETURN_CHANGED);
@@ -2548,193 +2358,198 @@ void FormPreferences::Printer::build()
        fl_set_input_return(dialog_->input_name, FL_RETURN_CHANGED);
 
        // set up the feedback mechanism
-       setPreHandler(dialog_->input_command);
-       setPreHandler(dialog_->input_page_range);
-       setPreHandler(dialog_->input_copies);
-       setPreHandler(dialog_->input_reverse);
-       setPreHandler(dialog_->input_to_printer);
-       setPreHandler(dialog_->input_file_extension);
-       setPreHandler(dialog_->input_spool_command);
-       setPreHandler(dialog_->input_paper_type);
-       setPreHandler(dialog_->input_even_pages);
-       setPreHandler(dialog_->input_odd_pages);
-       setPreHandler(dialog_->input_collated);
-       setPreHandler(dialog_->input_landscape);
-       setPreHandler(dialog_->input_to_file);
-       setPreHandler(dialog_->input_extra_options);
-       setPreHandler(dialog_->input_spool_prefix);
-       setPreHandler(dialog_->input_paper_size);
-       setPreHandler(dialog_->input_name);
-       setPreHandler(dialog_->check_adapt_output);
-}
-
-
-void FormPreferences::Printer::update()
+       setPrehandler(dialog_->input_command);
+       setPrehandler(dialog_->input_page_range);
+       setPrehandler(dialog_->input_copies);
+       setPrehandler(dialog_->input_reverse);
+       setPrehandler(dialog_->input_to_printer);
+       setPrehandler(dialog_->input_file_extension);
+       setPrehandler(dialog_->input_spool_command);
+       setPrehandler(dialog_->input_paper_type);
+       setPrehandler(dialog_->input_even_pages);
+       setPrehandler(dialog_->input_odd_pages);
+       setPrehandler(dialog_->input_collated);
+       setPrehandler(dialog_->input_landscape);
+       setPrehandler(dialog_->input_to_file);
+       setPrehandler(dialog_->input_extra_options);
+       setPrehandler(dialog_->input_spool_prefix);
+       setPrehandler(dialog_->input_paper_size);
+       setPrehandler(dialog_->input_name);
+       setPrehandler(dialog_->check_adapt_output);
+}
+
+
+void FormPreferences::Printer::update(LyXRC const & rc)
 {
        fl_set_button(dialog_->check_adapt_output,
-                     lyxrc.print_adapt_output);
+                     rc.print_adapt_output);
        fl_set_input(dialog_->input_command,
-                    lyxrc.print_command.c_str());
+                    rc.print_command.c_str());
        fl_set_input(dialog_->input_page_range,
-                    lyxrc.print_pagerange_flag.c_str());
+                    rc.print_pagerange_flag.c_str());
        fl_set_input(dialog_->input_copies,
-                    lyxrc.print_copies_flag.c_str());
+                    rc.print_copies_flag.c_str());
        fl_set_input(dialog_->input_reverse,
-                    lyxrc.print_reverse_flag.c_str());
+                    rc.print_reverse_flag.c_str());
        fl_set_input(dialog_->input_to_printer,
-                    lyxrc.print_to_printer.c_str());
+                    rc.print_to_printer.c_str());
        fl_set_input(dialog_->input_file_extension,
-                    lyxrc.print_file_extension.c_str());
+                    rc.print_file_extension.c_str());
        fl_set_input(dialog_->input_spool_command,
-                    lyxrc.print_spool_command.c_str());
+                    rc.print_spool_command.c_str());
        fl_set_input(dialog_->input_paper_type,
-                    lyxrc.print_paper_flag.c_str());
+                    rc.print_paper_flag.c_str());
        fl_set_input(dialog_->input_even_pages,
-                    lyxrc.print_evenpage_flag.c_str());
+                    rc.print_evenpage_flag.c_str());
        fl_set_input(dialog_->input_odd_pages,
-                    lyxrc.print_oddpage_flag.c_str());
+                    rc.print_oddpage_flag.c_str());
        fl_set_input(dialog_->input_collated,
-                    lyxrc.print_collcopies_flag.c_str());
+                    rc.print_collcopies_flag.c_str());
        fl_set_input(dialog_->input_landscape,
-                    lyxrc.print_landscape_flag.c_str());
+                    rc.print_landscape_flag.c_str());
        fl_set_input(dialog_->input_to_file,
-                    lyxrc.print_to_file.c_str());
+                    rc.print_to_file.c_str());
        fl_set_input(dialog_->input_extra_options,
-                    lyxrc.print_extra_options.c_str());
+                    rc.print_extra_options.c_str());
        fl_set_input(dialog_->input_spool_prefix,
-                    lyxrc.print_spool_printerprefix.c_str());
+                    rc.print_spool_printerprefix.c_str());
        fl_set_input(dialog_->input_paper_size,
-                    lyxrc.print_paper_dimension_flag.c_str());
+                    rc.print_paper_dimension_flag.c_str());
        fl_set_input(dialog_->input_name,
-                    lyxrc.printer.c_str());
+                    rc.printer.c_str());
 }
 
 
-FormPreferences::ScreenFonts::~ScreenFonts()
+FormPreferences::ScreenFonts::ScreenFonts(FormPreferences &  p)
+       : parent_(p)
+{}
+
+
+FD_preferences_screen_fonts const * FormPreferences::ScreenFonts::dialog()
 {
-       delete dialog_;
+       return dialog_.get();
 }
 
 
-void FormPreferences::ScreenFonts::apply() const
+void FormPreferences::ScreenFonts::apply(LyXRC & rc) const
 {
        bool changed = false;
 
        string str = fl_get_input(dialog_->input_roman);
-       if (lyxrc.roman_font_name != str) {
+       if (rc.roman_font_name != str) {
                changed = true;
-               lyxrc.roman_font_name = str;
+               rc.roman_font_name = str;
        }
 
        str = fl_get_input(dialog_->input_sans);
-       if (lyxrc.sans_font_name != str) {
+       if (rc.sans_font_name != str) {
                changed = true;
-               lyxrc.sans_font_name = str;
+               rc.sans_font_name = str;
        }
 
        str = fl_get_input(dialog_->input_typewriter);
-       if (lyxrc.typewriter_font_name != str) {
+       if (rc.typewriter_font_name != str) {
                changed = true;
-               lyxrc.typewriter_font_name = str;
+               rc.typewriter_font_name = str;
        }
 
        str = fl_get_input(dialog_->input_screen_encoding);
-       if (lyxrc.font_norm != str) {
+       if (rc.font_norm != str) {
                changed = true;
-               lyxrc.font_norm = str;
+               rc.font_norm = str;
        }
 
        bool button = fl_get_button(dialog_->check_scalable);
-       if (lyxrc.use_scalable_fonts != button) {
+       if (rc.use_scalable_fonts != button) {
                changed = true;
-               lyxrc.use_scalable_fonts = button;
+               rc.use_scalable_fonts = button;
        }
 
        unsigned int ivalue = static_cast<unsigned int>
                (fl_get_counter_value(dialog_->counter_zoom));
-       if (lyxrc.zoom != ivalue) {
+       if (rc.zoom != ivalue) {
                changed = true;
-               lyxrc.zoom = ivalue;
+               rc.zoom = ivalue;
        }
 
        ivalue = static_cast<unsigned int>
                (fl_get_counter_value(dialog_->counter_dpi));
-       if (lyxrc.dpi != ivalue) {
+       if (rc.dpi != ivalue) {
                changed = true;
-               lyxrc.dpi = ivalue;
+               rc.dpi = ivalue;
        }
-       
+
        double dvalue = strToDbl(fl_get_input(dialog_->input_tiny));
-       if (lyxrc.font_sizes[LyXFont::SIZE_TINY] != dvalue) {
+       if (rc.font_sizes[LyXFont::SIZE_TINY] != dvalue) {
                changed = true;
-               lyxrc.font_sizes[LyXFont::SIZE_TINY] = dvalue;
+               rc.font_sizes[LyXFont::SIZE_TINY] = dvalue;
        }
 
        dvalue = strToDbl(fl_get_input(dialog_->input_script));
-       if (lyxrc.font_sizes[LyXFont::SIZE_SCRIPT] != dvalue) {
+       if (rc.font_sizes[LyXFont::SIZE_SCRIPT] != dvalue) {
                changed = true;
-               lyxrc.font_sizes[LyXFont::SIZE_SCRIPT] = dvalue;
+               rc.font_sizes[LyXFont::SIZE_SCRIPT] = dvalue;
        }
 
        dvalue = strToDbl(fl_get_input(dialog_->input_footnote));
-       if (lyxrc.font_sizes[LyXFont::SIZE_FOOTNOTE] != dvalue) {
+       if (rc.font_sizes[LyXFont::SIZE_FOOTNOTE] != dvalue) {
                changed = true;
-               lyxrc.font_sizes[LyXFont::SIZE_FOOTNOTE] = dvalue;
+               rc.font_sizes[LyXFont::SIZE_FOOTNOTE] = dvalue;
        }
 
        dvalue = strToDbl(fl_get_input(dialog_->input_small));
-       if (lyxrc.font_sizes[LyXFont::SIZE_SMALL] != dvalue) {
+       if (rc.font_sizes[LyXFont::SIZE_SMALL] != dvalue) {
                changed = true;
-               lyxrc.font_sizes[LyXFont::SIZE_SMALL] = dvalue;
+               rc.font_sizes[LyXFont::SIZE_SMALL] = dvalue;
        }
 
        dvalue = strToDbl(fl_get_input(dialog_->input_normal));
-       if (lyxrc.font_sizes[LyXFont::SIZE_NORMAL] != dvalue) {
+       if (rc.font_sizes[LyXFont::SIZE_NORMAL] != dvalue) {
                changed = true;
-               lyxrc.font_sizes[LyXFont::SIZE_NORMAL] = dvalue;
+               rc.font_sizes[LyXFont::SIZE_NORMAL] = dvalue;
        }
 
        dvalue = strToDbl(fl_get_input(dialog_->input_large));
-       if (lyxrc.font_sizes[LyXFont::SIZE_LARGE] != dvalue) {
+       if (rc.font_sizes[LyXFont::SIZE_LARGE] != dvalue) {
                changed = true;
-               lyxrc.font_sizes[LyXFont::SIZE_LARGE] = dvalue;
+               rc.font_sizes[LyXFont::SIZE_LARGE] = dvalue;
        }
 
        dvalue = strToDbl(fl_get_input(dialog_->input_larger));
-       if (lyxrc.font_sizes[LyXFont::SIZE_LARGER] != dvalue) {
+       if (rc.font_sizes[LyXFont::SIZE_LARGER] != dvalue) {
                changed = true;
-               lyxrc.font_sizes[LyXFont::SIZE_LARGER] = dvalue;
+               rc.font_sizes[LyXFont::SIZE_LARGER] = dvalue;
        }
 
        dvalue = strToDbl(fl_get_input(dialog_->input_largest));
-       if (lyxrc.font_sizes[LyXFont::SIZE_LARGEST] != dvalue) {
+       if (rc.font_sizes[LyXFont::SIZE_LARGEST] != dvalue) {
                changed = true;
-               lyxrc.font_sizes[LyXFont::SIZE_LARGEST] = dvalue;
+               rc.font_sizes[LyXFont::SIZE_LARGEST] = dvalue;
        }
 
        dvalue = strToDbl(fl_get_input(dialog_->input_huge));
-       if (lyxrc.font_sizes[LyXFont::SIZE_HUGE] != dvalue) {
+       if (rc.font_sizes[LyXFont::SIZE_HUGE] != dvalue) {
                changed = true;
-               lyxrc.font_sizes[LyXFont::SIZE_HUGE] = dvalue;
+               rc.font_sizes[LyXFont::SIZE_HUGE] = dvalue;
        }
 
        dvalue = strToDbl(fl_get_input(dialog_->input_huger));
-       if (lyxrc.font_sizes[LyXFont::SIZE_HUGER] != dvalue) {
+       if (rc.font_sizes[LyXFont::SIZE_HUGER] != dvalue) {
                changed = true;
-               lyxrc.font_sizes[LyXFont::SIZE_HUGER] = dvalue;
+               rc.font_sizes[LyXFont::SIZE_HUGER] = dvalue;
        }
 
        if (changed) {
                // Now update the buffers
                // Can anything below here affect the redraw process?
-               parent_.lv_->getLyXFunc()->Dispatch(LFUN_SCREEN_FONT_UPDATE);
+               parent_.controller().updateScreenFonts();
        }
 }
 
 
 void FormPreferences::ScreenFonts::build()
 {
-       dialog_ = parent_.build_screen_fonts();
+       dialog_.reset(build_preferences_screen_fonts(&parent_));
 
        fl_set_counter_step(dialog_->counter_zoom, 1, 10);
        fl_set_counter_step(dialog_->counter_dpi,  1, 10);
@@ -2756,58 +2571,56 @@ void FormPreferences::ScreenFonts::build()
        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_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);
-       setPreHandler(dialog_->input_sans);
-       setPreHandler(dialog_->input_typewriter);
-       setPreHandler(dialog_->counter_zoom);
-       setPreHandler(dialog_->counter_dpi);
-       setPreHandler(dialog_->check_scalable);
-       setPreHandler(dialog_->input_screen_encoding);
-       setPreHandler(dialog_->input_tiny);
-       setPreHandler(dialog_->input_script);
-       setPreHandler(dialog_->input_footnote);
-       setPreHandler(dialog_->input_small);
-       setPreHandler(dialog_->input_large);
-       setPreHandler(dialog_->input_larger);
-       setPreHandler(dialog_->input_largest);
-       setPreHandler(dialog_->input_normal);
-       setPreHandler(dialog_->input_huge);
-       setPreHandler(dialog_->input_huger);
-}
-
-       
+       setPrehandler(dialog_->input_roman);
+       setPrehandler(dialog_->input_sans);
+       setPrehandler(dialog_->input_typewriter);
+       setPrehandler(dialog_->counter_zoom);
+       setPrehandler(dialog_->counter_dpi);
+       setPrehandler(dialog_->check_scalable);
+       setPrehandler(dialog_->input_screen_encoding);
+       setPrehandler(dialog_->input_tiny);
+       setPrehandler(dialog_->input_script);
+       setPrehandler(dialog_->input_footnote);
+       setPrehandler(dialog_->input_small);
+       setPrehandler(dialog_->input_large);
+       setPrehandler(dialog_->input_larger);
+       setPrehandler(dialog_->input_largest);
+       setPrehandler(dialog_->input_normal);
+       setPrehandler(dialog_->input_huge);
+       setPrehandler(dialog_->input_huger);
+}
+
+
 string const
 FormPreferences::ScreenFonts::feedback(FL_OBJECT const * const ob) const
 {
-       string str;
-
        if (ob == dialog_->input_roman)
-               str = lyxrc.getDescription(LyXRC::RC_SCREEN_FONT_ROMAN);
-       else if (ob == dialog_->input_sans)
-               str = lyxrc.getDescription(LyXRC::RC_SCREEN_FONT_SANS);
-       else if (ob == dialog_->input_typewriter)
-               str = lyxrc.getDescription(LyXRC::RC_SCREEN_FONT_TYPEWRITER);
-       else if (ob == dialog_->check_scalable)
-               str = lyxrc.getDescription(LyXRC::RC_SCREEN_FONT_SCALABLE);
-       else if (ob == dialog_->input_screen_encoding)
-               str = lyxrc.getDescription(LyXRC::RC_SCREEN_FONT_ENCODING);
-       else if (ob == dialog_->counter_zoom)
-               str = lyxrc.getDescription(LyXRC::RC_SCREEN_ZOOM);
-       else if (ob == dialog_->counter_dpi) 
-               str = lyxrc.getDescription(LyXRC::RC_SCREEN_DPI);
-       else if (ob == dialog_->input_tiny
+               return LyXRC::getDescription(LyXRC::RC_SCREEN_FONT_ROMAN);
+       if (ob == dialog_->input_sans)
+               return LyXRC::getDescription(LyXRC::RC_SCREEN_FONT_SANS);
+       if (ob == dialog_->input_typewriter)
+               return LyXRC::getDescription(LyXRC::RC_SCREEN_FONT_TYPEWRITER);
+       if (ob == dialog_->check_scalable)
+               return LyXRC::getDescription(LyXRC::RC_SCREEN_FONT_SCALABLE);
+       if (ob == dialog_->input_screen_encoding)
+               return LyXRC::getDescription(LyXRC::RC_SCREEN_FONT_ENCODING);
+       if (ob == dialog_->counter_zoom)
+               return LyXRC::getDescription(LyXRC::RC_SCREEN_ZOOM);
+       if (ob == dialog_->counter_dpi)
+               return LyXRC::getDescription(LyXRC::RC_SCREEN_DPI);
+       if (ob == dialog_->input_tiny
                 || ob == dialog_->input_script
                 || ob == dialog_->input_footnote
                 || ob == dialog_->input_small
@@ -2818,9 +2631,8 @@ FormPreferences::ScreenFonts::feedback(FL_OBJECT const * const ob) const
                 || ob == dialog_->input_normal
                 || ob == dialog_->input_huge
                 || ob == dialog_->input_huger)
-               str = lyxrc.getDescription(LyXRC::RC_SCREEN_FONT_SIZES);
-
-       return str;
+               return LyXRC::getDescription(LyXRC::RC_SCREEN_FONT_SIZES);
+       return string();
 }
 
 
@@ -2842,10 +2654,10 @@ bool FormPreferences::ScreenFonts::input()
            || 0.0 >= strToDbl(fl_get_input(dialog_->input_huge))
            || 0.0 >= strToDbl(fl_get_input(dialog_->input_huger))) {
                activate = false;
-               str = N_("Fonts must be positive!");
+               str = _("Fonts must be positive!");
 
-       // Fontsizes -- tiny < script < footnote etc.
        } else if (strToDbl(fl_get_input(dialog_->input_tiny)) >
+                  // Fontsizes -- tiny < script < footnote etc.
                   strToDbl(fl_get_input(dialog_->input_script)) ||
                   strToDbl(fl_get_input(dialog_->input_script)) >
                   strToDbl(fl_get_input(dialog_->input_footnote)) ||
@@ -2865,175 +2677,183 @@ bool FormPreferences::ScreenFonts::input()
                   strToDbl(fl_get_input(dialog_->input_huger))) {
                activate = false;
 
-               str = N_("Fonts must be input in the order tiny > script> footnote > small > normal > large > larger > largest > huge > huger.");
+               str = _("Fonts must be input in the order tiny > script> footnote > small > normal > large > larger > largest > huge > huger.");
        }
 
        if (!activate)
-               parent_.printWarning(str);
-       
+               parent_.postWarning(str);
+
        return activate;
 }
 
 
-void FormPreferences::ScreenFonts::update()
+void FormPreferences::ScreenFonts::update(LyXRC const & rc)
 {
        fl_set_input(dialog_->input_roman,
-                    lyxrc.roman_font_name.c_str());
+                    rc.roman_font_name.c_str());
        fl_set_input(dialog_->input_sans,
-                    lyxrc.sans_font_name.c_str());
+                    rc.sans_font_name.c_str());
        fl_set_input(dialog_->input_typewriter,
-                    lyxrc.typewriter_font_name.c_str());
+                    rc.typewriter_font_name.c_str());
        fl_set_input(dialog_->input_screen_encoding,
-                    lyxrc.font_norm.c_str());
+                    rc.font_norm.c_str());
        fl_set_button(dialog_->check_scalable,
-                     lyxrc.use_scalable_fonts);
-       fl_set_counter_value(dialog_->counter_zoom, lyxrc.zoom);
-       fl_set_counter_value(dialog_->counter_dpi,  lyxrc.dpi);
+                     rc.use_scalable_fonts);
+       fl_set_counter_value(dialog_->counter_zoom, rc.zoom);
+       fl_set_counter_value(dialog_->counter_dpi,  rc.dpi);
        fl_set_input(dialog_->input_tiny,
-                    tostr(lyxrc.font_sizes[LyXFont::SIZE_TINY]).c_str());
+                    tostr(rc.font_sizes[LyXFont::SIZE_TINY]).c_str());
        fl_set_input(dialog_->input_script,
-                    tostr(lyxrc.font_sizes[LyXFont::SIZE_SCRIPT]).c_str());
+                    tostr(rc.font_sizes[LyXFont::SIZE_SCRIPT]).c_str());
        fl_set_input(dialog_->input_footnote,
-                    tostr(lyxrc.font_sizes[LyXFont::SIZE_FOOTNOTE]).c_str());
+                    tostr(rc.font_sizes[LyXFont::SIZE_FOOTNOTE]).c_str());
        fl_set_input(dialog_->input_small,
-                    tostr(lyxrc.font_sizes[LyXFont::SIZE_SMALL]).c_str());
+                    tostr(rc.font_sizes[LyXFont::SIZE_SMALL]).c_str());
        fl_set_input(dialog_->input_normal,
-                    tostr(lyxrc.font_sizes[LyXFont::SIZE_NORMAL]).c_str());
+                    tostr(rc.font_sizes[LyXFont::SIZE_NORMAL]).c_str());
        fl_set_input(dialog_->input_large,
-                    tostr(lyxrc.font_sizes[LyXFont::SIZE_LARGE]).c_str());
+                    tostr(rc.font_sizes[LyXFont::SIZE_LARGE]).c_str());
        fl_set_input(dialog_->input_larger,
-                    tostr(lyxrc.font_sizes[LyXFont::SIZE_LARGER]).c_str());
+                    tostr(rc.font_sizes[LyXFont::SIZE_LARGER]).c_str());
        fl_set_input(dialog_->input_largest,
-                    tostr(lyxrc.font_sizes[LyXFont::SIZE_LARGEST]).c_str());
+                    tostr(rc.font_sizes[LyXFont::SIZE_LARGEST]).c_str());
        fl_set_input(dialog_->input_huge,
-                    tostr(lyxrc.font_sizes[LyXFont::SIZE_HUGE]).c_str());
+                    tostr(rc.font_sizes[LyXFont::SIZE_HUGE]).c_str());
        fl_set_input(dialog_->input_huger,
-                    tostr(lyxrc.font_sizes[LyXFont::SIZE_HUGER]).c_str());
+                    tostr(rc.font_sizes[LyXFont::SIZE_HUGER]).c_str());
 }
 
 
-FormPreferences::SpellChecker::~SpellChecker()
+
+FormPreferences::SpellOptions::SpellOptions(FormPreferences &  p)
+       : parent_(p)
+{}
+
+
+FD_preferences_spelloptions const * FormPreferences::SpellOptions::dialog()
 {
-       delete dialog_;
+       return dialog_.get();
 }
 
 
-void FormPreferences::SpellChecker::apply()
+void FormPreferences::SpellOptions::apply(LyXRC & rc)
 {
-
        string choice = fl_get_choice_text(dialog_->choice_spell_command);
-       choice = strip(frontStrip(choice));
-       
-       lyxrc.isp_command = choice;
+       choice = trim(choice);
+
+       rc.isp_command = choice;
 
+#if 0
        // If spell checker == "none", all other input set to off.
        if (fl_get_choice(dialog_->choice_spell_command) == 1) {
-               lyxrc.isp_use_alt_lang = false;
-               lyxrc.isp_alt_lang.erase();
+               rc.isp_use_alt_lang = false;
+               rc.isp_alt_lang.erase();
 
-               lyxrc.isp_use_esc_chars = false;
-               lyxrc.isp_esc_chars.erase();
+               rc.isp_use_esc_chars = false;
+               rc.isp_esc_chars.erase();
 
-               lyxrc.isp_use_pers_dict = false;
-               lyxrc.isp_pers_dict.erase();
+               rc.isp_use_pers_dict = false;
+               rc.isp_pers_dict.erase();
 
-               lyxrc.isp_accept_compound = false;
-               lyxrc.isp_use_input_encoding = false;
+               rc.isp_accept_compound = false;
+               rc.isp_use_input_encoding = false;
        } else {
+#else
                int button = fl_get_button(dialog_->check_alt_lang);
                choice = fl_get_input(dialog_->input_alt_lang);
                if (button && choice.empty()) button = 0;
                if (!button) choice.erase();
 
-               lyxrc.isp_use_alt_lang = static_cast<bool>(button);
-               lyxrc.isp_alt_lang = choice;
+               rc.isp_use_alt_lang = static_cast<bool>(button);
+               rc.isp_alt_lang = choice;
 
                button = fl_get_button(dialog_->check_escape_chars);
                choice = fl_get_input(dialog_->input_escape_chars);
                if (button && choice.empty()) button = 0;
                if (!button) choice.erase();
-       
-               lyxrc.isp_use_esc_chars = static_cast<bool>(button);
-               lyxrc.isp_esc_chars = choice;
+
+               rc.isp_use_esc_chars = static_cast<bool>(button);
+               rc.isp_esc_chars = choice;
 
                button = fl_get_button(dialog_->check_personal_dict);
                choice = fl_get_input(dialog_->input_personal_dict);
                if (button && choice.empty()) button = 0;
                if (!button) choice.erase();
 
-               lyxrc.isp_use_pers_dict = static_cast<bool>(button);
-               lyxrc.isp_pers_dict = choice;
+               rc.isp_use_pers_dict = static_cast<bool>(button);
+               rc.isp_pers_dict = choice;
 
                button = fl_get_button(dialog_->check_compound_words);
-               lyxrc.isp_accept_compound = static_cast<bool>(button);
+               rc.isp_accept_compound = static_cast<bool>(button);
 
                button = fl_get_button(dialog_->check_input_enc);
-               lyxrc.isp_use_input_encoding = static_cast<bool>(button);
+               rc.isp_use_input_encoding = static_cast<bool>(button);
+#endif
+#if 0
        }
+#endif
 
        // Reset view
-       update();
+       update(rc);
 }
 
 
-void FormPreferences::SpellChecker::build()
+void FormPreferences::SpellOptions::build()
 {
-       dialog_ = parent_.build_spellchecker();
+       dialog_.reset(build_preferences_spelloptions(&parent_));
 
        fl_addto_choice(dialog_->choice_spell_command,
-                       _(" none | ispell | aspell "));
+                       _(" 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);
 
        // set up the feedback mechanism
-       setPreHandler(dialog_->choice_spell_command);
-       setPreHandler(dialog_->check_alt_lang);
-       setPreHandler(dialog_->input_alt_lang);
-       setPreHandler(dialog_->check_escape_chars);
-       setPreHandler(dialog_->input_escape_chars);
-       setPreHandler(dialog_->check_personal_dict);
-       setPreHandler(dialog_->input_personal_dict);
-       setPreHandler(dialog_->button_personal_dict);
-       setPreHandler(dialog_->check_compound_words);
-       setPreHandler(dialog_->check_input_enc);
+       setPrehandler(dialog_->choice_spell_command);
+       setPrehandler(dialog_->check_alt_lang);
+       setPrehandler(dialog_->input_alt_lang);
+       setPrehandler(dialog_->check_escape_chars);
+       setPrehandler(dialog_->input_escape_chars);
+       setPrehandler(dialog_->check_personal_dict);
+       setPrehandler(dialog_->input_personal_dict);
+       setPrehandler(dialog_->button_personal_dict);
+       setPrehandler(dialog_->check_compound_words);
+       setPrehandler(dialog_->check_input_enc);
 }
 
 
 string const
-FormPreferences::SpellChecker::feedback(FL_OBJECT const * const ob) const
+FormPreferences::SpellOptions::feedback(FL_OBJECT const * const ob) const
 {
-       string str;
-
        if (ob == dialog_->choice_spell_command)
-               str = lyxrc.getDescription(LyXRC::RC_SPELL_COMMAND);
-       else if (ob == dialog_->check_alt_lang)
-               str = lyxrc.getDescription(LyXRC::RC_USE_ALT_LANG);
-       else if (ob == dialog_->input_alt_lang)
-               str = lyxrc.getDescription(LyXRC::RC_ALT_LANG);
-       else if (ob == dialog_->check_escape_chars)
-               str = lyxrc.getDescription(LyXRC::RC_USE_ESC_CHARS);
-       else if (ob == dialog_->input_escape_chars)
-               str = lyxrc.getDescription(LyXRC::RC_ESC_CHARS);
-       else if (ob == dialog_->check_personal_dict)
-               str = lyxrc.getDescription(LyXRC::RC_USE_PERS_DICT);
-       else if (ob == dialog_->input_personal_dict)
-               str = lyxrc.getDescription(LyXRC::RC_PERS_DICT);
-       else if (ob == dialog_->check_compound_words)
-               str = lyxrc.getDescription(LyXRC::RC_ACCEPT_COMPOUND);
-       else if (ob == dialog_->check_input_enc)
-               str = lyxrc.getDescription(LyXRC::RC_USE_INP_ENC);
-
-       return str;
-}
-
-
-bool FormPreferences::SpellChecker::input(FL_OBJECT const * const ob)
-{
-       // !ob if function is called from updateSpellChecker() to de/activate
+               return LyXRC::getDescription(LyXRC::RC_SPELL_COMMAND);
+       if (ob == dialog_->check_alt_lang)
+               return LyXRC::getDescription(LyXRC::RC_USE_ALT_LANG);
+       if (ob == dialog_->input_alt_lang)
+               return LyXRC::getDescription(LyXRC::RC_ALT_LANG);
+       if (ob == dialog_->check_escape_chars)
+               return LyXRC::getDescription(LyXRC::RC_USE_ESC_CHARS);
+       if (ob == dialog_->input_escape_chars)
+               return LyXRC::getDescription(LyXRC::RC_ESC_CHARS);
+       if (ob == dialog_->check_personal_dict)
+               return LyXRC::getDescription(LyXRC::RC_USE_PERS_DICT);
+       if (ob == dialog_->input_personal_dict)
+               return LyXRC::getDescription(LyXRC::RC_PERS_DICT);
+       if (ob == dialog_->check_compound_words)
+               return LyXRC::getDescription(LyXRC::RC_ACCEPT_COMPOUND);
+       if (ob == dialog_->check_input_enc)
+               return LyXRC::getDescription(LyXRC::RC_USE_INP_ENC);
+       return string();
+}
+
+
+bool FormPreferences::SpellOptions::input(FL_OBJECT const * const ob)
+{
+       // !ob if function is called from updateSpellOptions() to de/activate
        // objects,
        // otherwise the function is called by an xforms CB via input().
 
+#if 0
        // If spell checker == "none", disable all input.
        if (!ob || ob == dialog_->choice_spell_command) {
                if (fl_get_choice(dialog_->choice_spell_command) == 1) {
@@ -3054,177 +2874,81 @@ bool FormPreferences::SpellChecker::input(FL_OBJECT const * const ob)
                        fl_activate_object(dialog_->check_input_enc);
                }
        }
+#endif
 
        if (!ob || ob == dialog_->check_alt_lang) {
-               if (fl_get_button(dialog_->check_alt_lang)) {
-                       fl_activate_object(dialog_->input_alt_lang);
-                       fl_set_object_lcol(dialog_->input_alt_lang,
-                                          FL_BLACK);
-               } else {
-                       fl_deactivate_object(dialog_->input_alt_lang);
-                       fl_set_object_lcol(dialog_->input_alt_lang,
-                                          FL_INACTIVE);
-               }
+               bool const enable = fl_get_button(dialog_->check_alt_lang);
+               setEnabled(dialog_->input_alt_lang, enable);
        }
 
        if (!ob || ob == dialog_->check_escape_chars) {
-               if (fl_get_button(dialog_->check_escape_chars)) {
-                       fl_activate_object(dialog_->input_escape_chars);
-                       fl_set_object_lcol(dialog_->input_escape_chars,
-                                          FL_BLACK);
-               } else {
-                       fl_deactivate_object(dialog_->input_escape_chars);
-                       fl_set_object_lcol(dialog_->input_escape_chars,
-                                          FL_INACTIVE);
-               }
+               bool const enable = fl_get_button(dialog_->check_escape_chars);
+               setEnabled(dialog_->input_escape_chars, enable);
        }
 
        if (!ob || ob == dialog_->check_personal_dict) {
-               if (fl_get_button(dialog_->check_personal_dict)) {
-                       fl_activate_object(dialog_->input_personal_dict);
-                       fl_set_object_lcol(dialog_->input_personal_dict,
-                                          FL_BLACK);
-               } else {
-                       fl_deactivate_object(dialog_->input_personal_dict);
-                       fl_set_object_lcol(dialog_->input_personal_dict,
-                                          FL_INACTIVE);
-               }
+               bool const enable = fl_get_button(dialog_->check_personal_dict);
+               setEnabled(dialog_->input_personal_dict, enable);
        }
 
        if (ob == dialog_->button_personal_dict) {
-               parent_.browse(dialog_->input_personal_dict,
-                               _("Personal dictionary"), "*.ispell",
-                               make_pair(string(), string()),
-                               make_pair(string(), string()));
+               string f = parent_.controller().browsedict(
+                       fl_get_input(dialog_->input_personal_dict));
+               fl_set_input(dialog_->input_personal_dict, f.c_str());
        }
-       
+
        return true; // All input is valid!
 }
 
 
-void FormPreferences::SpellChecker::update()
+void FormPreferences::SpellOptions::update(LyXRC const & rc)
 {
        int choice = 1;
-       if (lyxrc.isp_command == "none")
+#if 0
+       if (rc.isp_command == "none")
                choice = 1;
-       else if (lyxrc.isp_command == "ispell")
+       else if (rc.isp_command == "ispell")
                choice = 2;
-       else if (lyxrc.isp_command == "aspell")
+       else if (rc.isp_command == "aspell")
                choice = 3;
+#else
+       if (rc.isp_command == "ispell")
+               choice = 1;
+       else if (rc.isp_command == "aspell")
+               choice = 2;
+#endif
        fl_set_choice(dialog_->choice_spell_command, choice);
-       
+
        string str;
-       if (lyxrc.isp_use_alt_lang) str = lyxrc.isp_alt_lang;
+       if (rc.isp_use_alt_lang)
+               str = rc.isp_alt_lang;
 
        fl_set_button(dialog_->check_alt_lang,
-                     lyxrc.isp_use_alt_lang);
+                     rc.isp_use_alt_lang);
        fl_set_input(dialog_->input_alt_lang, str.c_str());
-       
+
        str.erase();
-       if (lyxrc.isp_use_esc_chars) str = lyxrc.isp_esc_chars;
+       if (rc.isp_use_esc_chars)
+               str = rc.isp_esc_chars;
 
        fl_set_button(dialog_->check_escape_chars,
-                     lyxrc.isp_use_esc_chars);
+                     rc.isp_use_esc_chars);
        fl_set_input(dialog_->input_escape_chars, str.c_str());
 
        str.erase();
-       if (lyxrc.isp_use_pers_dict) str = lyxrc.isp_pers_dict;
+       if (rc.isp_use_pers_dict)
+               str = rc.isp_pers_dict;
 
        fl_set_button(dialog_->check_personal_dict,
-                     lyxrc.isp_use_pers_dict);
+                     rc.isp_use_pers_dict);
        fl_set_input(dialog_->input_personal_dict, str.c_str());
 
        fl_set_button(dialog_->check_compound_words,
-                     lyxrc.isp_accept_compound);
+                     rc.isp_accept_compound);
        fl_set_button(dialog_->check_input_enc,
-                     lyxrc.isp_use_input_encoding);
+                     rc.isp_use_input_encoding);
 
        // Activate/Deactivate the input fields dependent on the state of the
        // buttons.
        input(0);
 }
-
-
-void FormPreferences::printWarning(string const & warning)
-{
-       warningPosted = true;
-
-       string str = N_("WARNING!") + string(" ") + warning;
-       str = formatted(str, dialog_->text_warning->w-10,
-                        FL_SMALL_SIZE, FL_NORMAL_STYLE);
-
-       fl_set_object_label(dialog_->text_warning, str.c_str());
-       fl_set_object_lsize(dialog_->text_warning, FL_SMALL_SIZE);
-}
-
-
-void FormPreferences::browse(FL_OBJECT * inpt,
-                            string const & title,
-                            string const & pattern, 
-                            pair<string,string> const & dir1,
-                            pair<string,string> const & dir2)
-{
-       // Get the filename from the dialog
-       string const filename = fl_get_input(inpt);
-
-       // Show the file browser dialog
-       string const new_filename =
-               browseFile(filename, title, pattern, dir1, dir2);
-
-       // Save the filename to the dialog
-       if (new_filename != filename && !new_filename.empty()) {
-               fl_set_input(inpt, new_filename.c_str());
-               input(inpt, 0);
-       }
-}
-
-
-// C function wrapper, required by xforms.
-C_PREPOSTHANDLER(FormPreferences, FeedbackCB)
-
-int FormPreferences::FeedbackCB(FL_OBJECT * ob, int event,
-                               FL_Coord, FL_Coord, int, void *)
-{
-       // Note that the return value is important in the pre-emptive handler.
-       // Don't return anything other than 0.
-
-       Assert(ob);
-       // Don't Assert this one, as it can happen quite reasonably when things
-       // are being deleted in the d-tor.
-       //Assert(ob->form);
-       if (!ob->form) return 0;
-
-       FormPreferences * pre =
-               static_cast<FormPreferences*>(ob->form->u_vdata);
-       pre->Feedback(ob, event);
-       return 0;
-}
-
-
-// preemptive handler for feedback messages
-void FormPreferences::Feedback(FL_OBJECT * ob, int event)
-{
-       Assert(ob);
-
-       switch (event) {
-       case FL_ENTER:
-               warningPosted = false;
-               feedback(ob);
-               break;
-
-       case FL_LEAVE:
-               if (!warningPosted)
-                       fl_set_object_label(dialog_->text_warning, "");
-               break;
-
-       default:
-               break;
-       }
-}
-
-
-void FormPreferences::setPreHandler(FL_OBJECT * ob)
-{
-       Assert(ob);
-       fl_set_object_prehandler(ob, C_FormPreferencesFeedbackCB);
-}