]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/QPrefsDialog.C
* MSVC Compilation fix: #warning is not supported.
[lyx.git] / src / frontends / qt4 / QPrefsDialog.C
index 9dded4bef6bd97e7726254abf461aaea2643b9b0..0c9b0485bedd2c0a32411419e61852604443d350 100644 (file)
@@ -13,7 +13,7 @@
 #include "debug.h"
 #include "qt_helpers.h"
 
-#include "lcolorcache.h"
+#include "ColorCache.h"
 #include "Qt2BC.h"
 #include "qt_helpers.h"
 
 #include "QPrefs.h"
 
 #include "panelstack.h"
-#include "qcoloritem.h"
 #include "qfontexample.h"
 
-#include "ui/QPrefAsciiUi.h"
-#include "ui/QPrefDateUi.h"
-#include "ui/QPrefKeyboardUi.h"
-#include "ui/QPrefLatexUi.h"
-#include "ui/QPrefScreenFontsUi.h"
-#include "ui/QPrefColorsUi.h"
-#if defined(__CYGWIN__) || defined(__CYGWIN32__)
-#include "ui/QPrefCygwinPathUi.h"
-#endif
-#include "ui/QPrefDisplayUi.h"
-#include "ui/QPrefPathsUi.h"
-#include "ui/QPrefSpellcheckerUi.h"
-#include "ui/QPrefConvertersUi.h"
-#include "ui/QPrefCopiersUi.h"
-#include "ui/QPrefFileformatsUi.h"
-#include "ui/QPrefLanguageUi.h"
-#include "ui/QPrefPrinterUi.h"
-#include "ui/QPrefUi.h"
-#include "ui/QPrefIdentityUi.h"
-
 #include "gettext.h"
 #include "LColor.h"
-#include "lcolorcache.h"
+#include "ColorCache.h"
 
 #include "controllers/ControlPrefs.h"
 
@@ -90,538 +69,1019 @@ using std::ostringstream;
 using std::pair;
 using std::vector;
 
+
 namespace lyx {
 namespace frontend {
 
-QPrefsDialog::QPrefsDialog(QPrefs * form)
-       : form_(form)
-{
-       setupUi(this);
-
-       connect(savePB, SIGNAL(clicked()),
-               form, SLOT(slotOK()));
-       connect(applyPB, SIGNAL(clicked()),
-               form, SLOT(slotApply()));
-       connect(closePB, SIGNAL(clicked()),
-               form, SLOT(slotClose()));
-       connect(restorePB, SIGNAL(clicked()),
-               form, SLOT(slotRestore()));
-
-
-
-       asciiModule = new UiWidget<Ui::QPrefAsciiUi>;
-       connect(asciiModule->asciiLinelengthSB, SIGNAL(valueChanged(int)), this, SLOT(change_adaptor()));
-       connect(asciiModule->asciiRoffED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-
-
-       dateModule = new UiWidget<Ui::QPrefDateUi>;
-       connect(dateModule->DateED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-
-
-
-       keyboardModule = new UiWidget<Ui::QPrefKeyboardUi>;
-       connect( keyboardModule->keymapCB, SIGNAL( toggled(bool) ),
-                keyboardModule->firstKeymapLA, SLOT( setEnabled(bool) ) );
-       connect( keyboardModule->keymapCB, SIGNAL( toggled(bool) ),
-               keyboardModule->secondKeymapLA, SLOT( setEnabled(bool) ) );
-       connect( keyboardModule->keymapCB, SIGNAL( toggled(bool) ),
-               keyboardModule->firstKeymapED, SLOT( setEnabled(bool) ) );
-       connect( keyboardModule->keymapCB, SIGNAL( toggled(bool) ),
-               keyboardModule->secondKeymapED, SLOT( setEnabled(bool) ) );
-       connect( keyboardModule->keymapCB, SIGNAL( toggled(bool) ),
-               keyboardModule->firstKeymapPB, SLOT( setEnabled(bool) ) );
-       connect( keyboardModule->keymapCB, SIGNAL( toggled(bool) ),
-               keyboardModule->secondKeymapPB, SLOT( setEnabled(bool) ) );
-       connect(keyboardModule->firstKeymapPB, SIGNAL(clicked()), this, SLOT(select_keymap1()));
-       connect(keyboardModule->secondKeymapPB, SIGNAL(clicked()), this, SLOT(select_keymap2()));
-       connect(keyboardModule->keymapCB, SIGNAL(toggled(bool)), this, SLOT(change_adaptor()));
-       connect(keyboardModule->firstKeymapED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(keyboardModule->secondKeymapED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-
-
-
-       latexModule = new UiWidget<Ui::QPrefLatexUi>;
-       connect(latexModule->latexEncodingED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(latexModule->latexChecktexED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(latexModule->latexBibtexED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(latexModule->latexIndexED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(latexModule->latexAutoresetCB, SIGNAL(toggled(bool)), this, SLOT(change_adaptor()));
-       connect(latexModule->latexDviPaperED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(latexModule->latexPaperSizeCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
+string const LookAndFeel = "Look and feel";
+string const LanguageSettings = "Language settings";
+string const Outputs = "Outputs";
 
 
+// FIXME: move to helper_funcs.h
+namespace {
 
+template<class A>
+typename std::vector<A>::size_type
+findPos(std::vector<A> const & vec, A const & val)
+{
+       typedef typename std::vector<A>::const_iterator Cit;
 
-       screenfontsModule = new UiWidget<Ui::QPrefScreenFontsUi>;
-       connect(screenfontsModule->screenRomanCO, SIGNAL(activated(const QString&)), this, SLOT(select_roman(const QString&)));
-       connect(screenfontsModule->screenSansCO, SIGNAL(activated(const QString&)), this, SLOT(select_sans(const QString&)));
-       connect(screenfontsModule->screenTypewriterCO, SIGNAL(activated(const QString&)), this, SLOT(select_typewriter(const QString&)));
+       Cit it = std::find(vec.begin(), vec.end(), val);
+       if (it == vec.end())
+               return 0;
+       return distance(vec.begin(), it);
+}
 
-       QFontDatabase fontdb;
-       QStringList families(fontdb.families());
-       for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
-               screenfontsModule->screenRomanCO->insertItem(*it);
-               screenfontsModule->screenSansCO->insertItem(*it);
-               screenfontsModule->screenTypewriterCO->insertItem(*it);
+void setComboxFont(QComboBox * cb, string const & family, string const & foundry)
+{
+       string const name = makeFontName(family, foundry);
+       for (int i = 0; i < cb->count(); ++i) {
+               if (fromqstr(cb->text(i)) == name) {
+                       cb->setCurrentItem(i);
+                       return;
+               }
        }
-       connect(screenfontsModule->screenRomanCO, SIGNAL(activated(const QString&)), this, SLOT(change_adaptor()));
-       connect(screenfontsModule->screenSansCO, SIGNAL(activated(const QString&)), this, SLOT(change_adaptor()));
-       connect(screenfontsModule->screenTypewriterCO, SIGNAL(activated(const QString&)), this, SLOT(change_adaptor()));
-       connect(screenfontsModule->screenZoomSB, SIGNAL(valueChanged(int)), this, SLOT(change_adaptor()));
-       connect(screenfontsModule->screenDpiSB, SIGNAL(valueChanged(int)), this, SLOT(change_adaptor()));
-       connect(screenfontsModule->screenTinyED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(screenfontsModule->screenSmallestED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(screenfontsModule->screenSmallerED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(screenfontsModule->screenSmallED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(screenfontsModule->screenNormalED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(screenfontsModule->screenLargeED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(screenfontsModule->screenLargerED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(screenfontsModule->screenLargestED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(screenfontsModule->screenHugeED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(screenfontsModule->screenHugerED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-
-       screenfontsModule->screenTinyED->setValidator(new QDoubleValidator(
-               screenfontsModule->screenTinyED));
-       screenfontsModule->screenSmallestED->setValidator(new QDoubleValidator(
-               screenfontsModule->screenSmallestED));
-       screenfontsModule->screenSmallerED->setValidator(new QDoubleValidator(
-               screenfontsModule->screenSmallerED));
-       screenfontsModule->screenSmallED->setValidator(new QDoubleValidator(
-               screenfontsModule->screenSmallED));
-       screenfontsModule->screenNormalED->setValidator(new QDoubleValidator(
-               screenfontsModule->screenNormalED));
-       screenfontsModule->screenLargeED->setValidator(new QDoubleValidator(
-               screenfontsModule->screenLargeED));
-       screenfontsModule->screenLargerED->setValidator(new QDoubleValidator(
-               screenfontsModule->screenLargerED));
-       screenfontsModule->screenLargestED->setValidator(new QDoubleValidator(
-               screenfontsModule->screenLargestED));
-       screenfontsModule->screenHugeED->setValidator(new QDoubleValidator(
-               screenfontsModule->screenHugeED));
-       screenfontsModule->screenHugerED->setValidator(new QDoubleValidator(
-               screenfontsModule->screenHugerED));
-
-
-
-
-       colorsModule = new UiWidget<Ui::QPrefColorsUi>;
-       // FIXME: put in controller
-       for (int i = 0; i < LColor::ignore; ++i) {
-               LColor::color lc = static_cast<LColor::color>(i);
-               if (lc == LColor::none
-                       || lc == LColor::black
-                       || lc == LColor::white
-                       || lc == LColor::red
-                       || lc == LColor::green
-                       || lc == LColor::blue
-                       || lc == LColor::cyan
-                       || lc == LColor::magenta
-                       || lc == LColor::yellow
-                       || lc == LColor::inherit
-                       || lc == LColor::ignore) continue;
 
-               colors_.push_back(lc);
-               string const guiname(lcolor.getGUIName(lc));
-               QColorItem * ci(new QColorItem(lcolorcache.get(lc),
-                               toqstr(guiname)));
-               colorsModule->lyxObjectsLB->insertItem(ci);
-       }
-       connect(colorsModule->colorChangePB, SIGNAL(clicked()), this, SLOT(change_color()));
-       connect(colorsModule->lyxObjectsLB, SIGNAL(selected(int)), this, SLOT(change_color()));
+       // Try matching without foundry name
 
+       // We count in reverse in order to prefer the Xft foundry
+       for (int i = cb->count() - 1; i >= 0; --i) {
+               pair<string, string> tmp = parseFontName(fromqstr(cb->text(i)));
+               if (compare_no_case(tmp.first, family) == 0) {
+                       cb->setCurrentItem(i);
+                       return;
+               }
+       }
 
+       // family alone can contain e.g. "Helvetica [Adobe]"
+       pair<string, string> tmpfam = parseFontName(family);
 
+       // We count in reverse in order to prefer the Xft foundry
+       for (int i = cb->count() - 1; i >= 0; --i) {
+               pair<string, string> tmp = parseFontName(fromqstr(cb->text(i)));
+               if (compare_no_case(tmp.first, tmpfam.first) == 0) {
+                       cb->setCurrentItem(i);
+                       return;
+               }
+       }
 
-#if defined(__CYGWIN__) || defined(__CYGWIN32__)
-       cygwinpathModule = new UiWidget<Ui::QPrefCygwinPathUi>;
-       connect(cygwinpathModule->pathCB, SIGNAL(toggled(bool)), this, SLOT(change_adaptor()));
-#endif
+       // Bleh, default fonts, and the names couldn't be found. Hack
+       // for bug 1063. Qt makes baby Jesus cry.
 
+       QFont font;
 
+       if (family == lyx_gui::roman_font_name()) {
+               font.setStyleHint(QFont::Serif);
+               font.setFamily(family.c_str());
+       } else if (family == lyx_gui::sans_font_name()) {
+               font.setStyleHint(QFont::SansSerif);
+               font.setFamily(family.c_str());
+       } else if (family == lyx_gui::typewriter_font_name()) {
+               font.setStyleHint(QFont::TypeWriter);
+               font.setFamily(family.c_str());
+       } else {
+               lyxerr << "FAILED to find the default font: '"
+                      << foundry << "', '" << family << '\''<< endl;
+               return;
+       }
 
-       displayModule = new UiWidget<Ui::QPrefDisplayUi>;
-       connect(displayModule->instantPreviewCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
-       connect(displayModule->displayGraphicsCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
+       QFontInfo info(font);
+       pair<string, string> tmp = parseFontName(fromqstr(info.family()));
+       string const & default_font_name = tmp.first;
+       lyxerr << "Apparent font is " << default_font_name << endl;
 
+       for (int i = 0; i < cb->count(); ++i) {
+               lyxerr << "Looking at " << fromqstr(cb->text(i)) << endl;
+               if (compare_no_case(fromqstr(cb->text(i)),
+                                   default_font_name) == 0) {
+                       cb->setCurrentItem(i);
+                       return;
+               }
+       }
 
+       lyxerr << "FAILED to find the font: '"
+              << foundry << "', '" << family << '\'' <<endl;
+}
 
-       pathsModule = new UiWidget<Ui::QPrefPathsUi>;
-       connect(pathsModule->templateDirPB, SIGNAL(clicked()), this, SLOT(select_templatedir()));
-       connect(pathsModule->tempDirPB, SIGNAL(clicked()), this, SLOT(select_tempdir()));
-       connect(pathsModule->backupDirPB, SIGNAL(clicked()), this, SLOT(select_backupdir()));
-       connect(pathsModule->workingDirPB, SIGNAL(clicked()), this, SLOT(select_workingdir()));
-       connect(pathsModule->lyxserverDirPB, SIGNAL(clicked()), this, SLOT(select_lyxpipe()));
-       connect(pathsModule->workingDirED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(pathsModule->templateDirED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(pathsModule->backupDirED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(pathsModule->tempDirED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(pathsModule->lyxserverDirED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(pathsModule->pathPrefixED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
 
+QString const external_path(string const & input)
+{
+       return toqstr(lyx::support::os::external_path(input));
+}
 
 
-       spellcheckerModule = new UiWidget<Ui::QPrefSpellcheckerUi>;
-       connect(spellcheckerModule->persDictionaryPB, SIGNAL(clicked()), this, SLOT(select_dict()));
-#if defined (USE_ISPELL)
-       connect(spellcheckerModule->spellCommandCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
-#else
-       spellcheckerModule->spellCommandCO->setEnabled(false);
-#endif
-       connect(spellcheckerModule->altLanguageED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(spellcheckerModule->escapeCharactersED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(spellcheckerModule->persDictionaryED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(spellcheckerModule->compoundWordCB, SIGNAL(toggled(bool)), this, SLOT(change_adaptor()));
-       connect(spellcheckerModule->inputEncodingCB, SIGNAL(toggled(bool)), this, SLOT(change_adaptor()));
-       spellcheckerModule->spellCommandCO->insertItem(qt_("ispell"));
-       spellcheckerModule->spellCommandCO->insertItem(qt_("aspell"));
-       spellcheckerModule->spellCommandCO->insertItem(qt_("hspell"));
-#ifdef USE_PSPELL
-       spellcheckerModule->spellCommandCO->insertItem(qt_("pspell (library)"));
-#else
-#ifdef USE_ASPELL
-       spellcheckerModule->spellCommandCO->insertItem(qt_("aspell (library)"));
-#endif
-#endif
+string const internal_path(QString const & input)
+{
+       return lyx::support::os::internal_path(fromqstr(input));
+}
 
+} // end namespace anon
 
 
-       convertersModule = new UiWidget<Ui::QPrefConvertersUi>;
-       connect(convertersModule->converterNewPB, SIGNAL(clicked()), this, SLOT(new_converter()));
-       connect(convertersModule->converterRemovePB, SIGNAL(clicked()), this, SLOT(remove_converter()));
-       connect(convertersModule->converterModifyPB, SIGNAL(clicked()), this, SLOT(modify_converter()));
-       connect(convertersModule->convertersLB, SIGNAL(highlighted(int)), this, SLOT(switch_converter(int)));
-       connect(convertersModule->converterFromCO, SIGNAL(activated(const QString&)), this, SLOT(converter_changed()));
-       connect(convertersModule->converterToCO, SIGNAL(activated(const QString&)), this, SLOT(converter_changed()));
-       connect(convertersModule->converterED, SIGNAL(textChanged(const QString&)), this, SLOT(converter_changed()));
-       connect(convertersModule->converterFlagED, SIGNAL(textChanged(const QString&)), this, SLOT(converter_changed()));
-       connect(convertersModule->converterNewPB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
-       connect(convertersModule->converterRemovePB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
-       connect(convertersModule->converterModifyPB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
+PrefAscii::PrefAscii(QWidget * parent)
+: PrefModule(_(Outputs), _("Plain text"), 0, parent)
+{
+       setupUi(this);
+       connect(asciiLinelengthSB, SIGNAL(valueChanged(int)),
+               this, SIGNAL(changed()));
+       connect(asciiRoffED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+}
 
 
+void PrefAscii::apply(LyXRC & rc) const
+{
+       rc.ascii_linelen = asciiLinelengthSB->value();
+       rc.ascii_roff_command = fromqstr(asciiRoffED->text());
+}
 
-       copiersModule = new UiWidget<Ui::QPrefCopiersUi>;
-       connect(copiersModule->copierNewPB, SIGNAL(clicked()), this, SLOT(new_copier()));
-       connect(copiersModule->copierRemovePB, SIGNAL(clicked()), this, SLOT(remove_copier()));
-       connect(copiersModule->copierModifyPB, SIGNAL(clicked()), this, SLOT(modify_copier()));
-       connect(copiersModule->AllCopiersLB, SIGNAL(highlighted(int)), this, SLOT(switch_copierLB(int)));
-       connect(copiersModule->copierFormatCO, SIGNAL(activated(int)), this, SLOT(switch_copierCO(int)));
-       connect(copiersModule->copierNewPB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
-       connect(copiersModule->copierRemovePB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
-       connect(copiersModule->copierModifyPB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
-       connect(copiersModule->copierFormatCO, SIGNAL(activated(const QString&)), this, SLOT(copiers_changed()));
-       connect(copiersModule->copierED, SIGNAL(textChanged(const QString&)), this, SLOT(copiers_changed()));
 
+void PrefAscii::update(LyXRC const & rc)
+{
+       asciiLinelengthSB->setValue(rc.ascii_linelen);
+       asciiRoffED->setText(toqstr(rc.ascii_roff_command));
+}
 
 
+PrefDate::PrefDate(QWidget * parent)
+: PrefModule(_(Outputs), _("Date format"), 0, parent)
+{
+       setupUi(this);
+       connect(DateED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+}
 
-       fileformatsModule = new UiWidget<Ui::QPrefFileformatsUi>;
-       connect(fileformatsModule->formatNewPB, SIGNAL(clicked()), this, SLOT(new_format()));
-       connect(fileformatsModule->formatRemovePB, SIGNAL(clicked()), this, SLOT(remove_format()));
-       connect(fileformatsModule->formatModifyPB, SIGNAL(clicked()), this, SLOT(modify_format()));
-       connect(fileformatsModule->formatsLB, SIGNAL(highlighted(int)), this, SLOT(switch_format(int)));
-       connect(fileformatsModule->formatED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed()));
-       connect(fileformatsModule->guiNameED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed()));
-       connect(fileformatsModule->shortcutED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed()));
-       connect(fileformatsModule->extensionED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed()));
-       connect(fileformatsModule->viewerED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed()));
-       connect(fileformatsModule->editorED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed()));
-       connect(fileformatsModule->formatNewPB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
-       connect(fileformatsModule->formatRemovePB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
-       connect(fileformatsModule->formatModifyPB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
 
+void PrefDate::apply(LyXRC & rc) const
+{
+       rc.date_insert_format = fromqstr(DateED->text());
+}
 
 
+void PrefDate::update(LyXRC const & rc)
+{
+       DateED->setText(toqstr(rc.date_insert_format));
+}
 
-       languageModule = new UiWidget<Ui::QPrefLanguageUi>;
-       connect(languageModule->rtlCB, SIGNAL(toggled(bool)), this, SLOT(change_adaptor()));
-       connect(languageModule->markForeignCB, SIGNAL(toggled(bool)), this, SLOT(change_adaptor()));
-       connect(languageModule->autoBeginCB, SIGNAL(toggled(bool)), this, SLOT(change_adaptor()));
-       connect(languageModule->autoEndCB, SIGNAL(toggled(bool)), this, SLOT(change_adaptor()));
-       connect(languageModule->useBabelCB, SIGNAL(toggled(bool)), this, SLOT(change_adaptor()));
-       connect(languageModule->globalCB, SIGNAL(toggled(bool)), this, SLOT(change_adaptor()));
-       connect(languageModule->languagePackageED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(languageModule->startCommandED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(languageModule->endCommandED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(languageModule->defaultLanguageCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
 
-       languageModule->defaultLanguageCO->clear();
+PrefKeyboard::PrefKeyboard(QPrefs * form, QWidget * parent)
+: PrefModule(_(LookAndFeel), _("Keyboard"), form, parent)
+{
+       setupUi(this);
 
-       // store the lang identifiers for later
-       using lyx::frontend::LanguagePair;
-       std::vector<LanguagePair> const langs =
-               lyx::frontend::getLanguageData(false);
-       lang_ = getSecond(langs);
+       connect(keymapCB, SIGNAL( toggled(bool) ),
+               firstKeymapLA, SLOT( setEnabled(bool) ) );
+       connect(keymapCB, SIGNAL( toggled(bool) ),
+               secondKeymapLA, SLOT( setEnabled(bool) ) );
+       connect(keymapCB, SIGNAL( toggled(bool) ),
+               firstKeymapED, SLOT( setEnabled(bool) ) );
+       connect(keymapCB, SIGNAL( toggled(bool) ),
+               secondKeymapED, SLOT( setEnabled(bool) ) );
+       connect(keymapCB, SIGNAL( toggled(bool) ),
+               firstKeymapPB, SLOT( setEnabled(bool) ) );
+       connect(keymapCB, SIGNAL( toggled(bool) ),
+               secondKeymapPB, SLOT( setEnabled(bool) ) );
+
+       connect(keymapCB, SIGNAL(toggled(bool)),
+               this, SIGNAL(changed()));
+       connect(firstKeymapED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(secondKeymapED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+}
 
-       std::vector<LanguagePair>::const_iterator lit  = langs.begin();
-       std::vector<LanguagePair>::const_iterator lend = langs.end();
-       for (; lit != lend; ++lit) {
-               languageModule->defaultLanguageCO->insertItem(toqstr(lit->first));
-       }
 
+void PrefKeyboard::apply(LyXRC & rc) const
+{
+       // FIXME: can derive CB from the two EDs
+       rc.use_kbmap = keymapCB->isChecked();
+       rc.primary_kbmap = internal_path(firstKeymapED->text());
+       rc.secondary_kbmap = internal_path(secondKeymapED->text());
+}
 
 
+void PrefKeyboard::update(LyXRC const & rc)
+{
+       // FIXME: can derive CB from the two EDs
+       keymapCB->setChecked(rc.use_kbmap);
+       // no idea why we need these. Fscking Qt.
+       firstKeymapED->setEnabled(rc.use_kbmap);
+       firstKeymapPB->setEnabled(rc.use_kbmap);
+       firstKeymapLA->setEnabled(rc.use_kbmap);
+       secondKeymapED->setEnabled(rc.use_kbmap);
+       secondKeymapPB->setEnabled(rc.use_kbmap);
+       secondKeymapLA->setEnabled(rc.use_kbmap);
+       firstKeymapED->setText(external_path(rc.primary_kbmap));
+       secondKeymapED->setText(external_path(rc.secondary_kbmap));
+}
 
 
-       printerModule = new UiWidget<Ui::QPrefPrinterUi>;
-       connect(printerModule->printerAdaptCB, SIGNAL(toggled(bool)), this, SLOT(change_adaptor()));
-       connect(printerModule->printerCommandED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(printerModule->printerNameED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(printerModule->printerPageRangeED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(printerModule->printerCopiesED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(printerModule->printerReverseED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(printerModule->printerToPrinterED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(printerModule->printerExtensionED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(printerModule->printerSpoolCommandED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(printerModule->printerPaperTypeED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(printerModule->printerEvenED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(printerModule->printerOddED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(printerModule->printerCollatedED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(printerModule->printerLandscapeED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(printerModule->printerToFileED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(printerModule->printerExtraED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(printerModule->printerSpoolPrefixED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(printerModule->printerPaperSizeED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
+QString PrefKeyboard::testKeymap(QString keymap)
+{
+       return toqstr(form_->controller().browsekbmap(fromqstr(keymap)));
+}
 
 
+void PrefKeyboard::on_firstKeymapPB_clicked(bool)
+{
+       QString file = testKeymap(firstKeymapED->text());
+       if (!file.isEmpty())
+               firstKeymapED->setText(file);
+}
 
 
-       uiModule = new UiWidget<Ui::QPrefUi>;
-    connect( uiModule->autoSaveCB, SIGNAL( toggled(bool) ), uiModule->autoSaveLA, SLOT( setEnabled(bool) ) );
-    connect( uiModule->autoSaveCB, SIGNAL( toggled(bool) ), uiModule->autoSaveSB, SLOT( setEnabled(bool) ) );
-    connect( uiModule->autoSaveCB, SIGNAL( toggled(bool) ), uiModule->TextLabel1, SLOT( setEnabled(bool) ) );
-       connect(uiModule->uiFilePB, SIGNAL(clicked()), this, SLOT(select_ui()));
-       connect(uiModule->bindFilePB, SIGNAL(clicked()), this, SLOT(select_bind()));
-       connect(uiModule->uiFileED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(uiModule->bindFileED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(uiModule->cursorFollowsCB, SIGNAL(toggled(bool)), this, SLOT(change_adaptor()));
-       connect(uiModule->autoSaveSB, SIGNAL(valueChanged(int)), this, SLOT(change_adaptor()));
-       connect(uiModule->autoSaveCB, SIGNAL(toggled(bool)), this, SLOT(change_adaptor()));
-       connect(uiModule->lastfilesSB, SIGNAL(valueChanged(int)), this, SLOT(change_adaptor()));
-       uiModule->lastfilesSB->setMaxValue(maxlastfiles);
+void PrefKeyboard::on_secondKeymapPB_clicked(bool)
+{
+       QString file = testKeymap(secondKeymapED->text());
+       if (!file.isEmpty())
+               secondKeymapED->setText(file);
+}
 
 
+PrefLatex::PrefLatex(QPrefs * form, QWidget * parent)
+: PrefModule(_(Outputs), _("LaTeX"), form, parent)
+{
+       setupUi(this);
+       connect(latexEncodingED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(latexChecktexED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(latexBibtexED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(latexIndexED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(latexAutoresetCB, SIGNAL(toggled(bool)),
+               this, SIGNAL(changed()));
+       connect(latexDviPaperED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(latexPaperSizeCO, SIGNAL(activated(int)),
+               this, SIGNAL(changed()));
+}
 
 
-       identityModule = new UiWidget<Ui::QPrefIdentityUi>;
-       connect(identityModule->nameED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
-       connect(identityModule->emailED, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
+void PrefLatex::apply(LyXRC & rc) const
+{
+       rc.fontenc = fromqstr(latexEncodingED->text());
+       rc.chktex_command = fromqstr(latexChecktexED->text());
+       rc.bibtex_command = fromqstr(latexBibtexED->text());
+       rc.index_command = fromqstr(latexIndexED->text());
+       rc.auto_reset_options = latexAutoresetCB->isChecked();
+       rc.view_dvi_paper_option = fromqstr(latexDviPaperED->text());
+       rc.default_papersize =
+               form_->controller().toPaperSize(latexPaperSizeCO->currentItem());
+}
 
 
+void PrefLatex::update(LyXRC const & rc)
+{
+       latexEncodingED->setText(toqstr(rc.fontenc));
+       latexChecktexED->setText(toqstr(rc.chktex_command));
+       latexBibtexED->setText(toqstr(rc.bibtex_command));
+       latexIndexED->setText(toqstr(rc.index_command));
+       latexAutoresetCB->setChecked(rc.auto_reset_options);
+       latexDviPaperED->setText(toqstr(rc.view_dvi_paper_option));
+       latexPaperSizeCO->setCurrentIndex(
+               form_->controller().fromPaperSize(rc.default_papersize));
+}
 
 
-       string const laf = _("Look and feel");
-       prefsPS->addCategory(laf);
-       prefsPS->addPanel(uiModule, _("User interface"), laf);
-       prefsPS->addPanel(screenfontsModule, _("Screen fonts"), laf);
-       prefsPS->addPanel(colorsModule, _("Colors"), laf);
-       prefsPS->addPanel(displayModule, _("Graphics"), laf);
-       prefsPS->addPanel(keyboardModule, _("Keyboard"), laf);
+PrefScreenFonts::PrefScreenFonts(QPrefs * form, QWidget * parent)
+: PrefModule(_(LookAndFeel), _("Screen fonts"), form, parent)
+{
+       setupUi(this);
 
-       string const ls = _("Language settings");
-       prefsPS->addCategory(ls);
-       prefsPS->addPanel(languageModule, _("Language"), ls);
-       prefsPS->addPanel(spellcheckerModule, _("Spellchecker"), ls);
+       connect(screenRomanCO, SIGNAL(activated(const QString&)),
+               this, SLOT(select_roman(const QString&)));
+       connect(screenSansCO, SIGNAL(activated(const QString&)),
+               this, SLOT(select_sans(const QString&)));
+       connect(screenTypewriterCO, SIGNAL(activated(const QString&)),
+               this, SLOT(select_typewriter(const QString&)));
 
-       string const op = _("Outputs");
-       prefsPS->addCategory(op);
-       prefsPS->addPanel(asciiModule, _("Plain text"), op);
-       prefsPS->addPanel(dateModule, _("Date format"), op);
-       prefsPS->addPanel(latexModule, _("LaTeX"), op);
-#if defined(__CYGWIN__) || defined(__CYGWIN32__)
-       prefsPS->addPanel(cygwinpathModule, _("Paths"), op);
-#endif
-       prefsPS->addPanel(printerModule, _("Printer"), op);
+       QFontDatabase fontdb;
+       QStringList families(fontdb.families());
+       for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
+               screenRomanCO->insertItem(*it);
+               screenSansCO->insertItem(*it);
+               screenTypewriterCO->insertItem(*it);
+       }
+       connect(screenRomanCO, SIGNAL(activated(const QString&)),
+               this, SIGNAL(changed()));
+       connect(screenSansCO, SIGNAL(activated(const QString&)),
+               this, SIGNAL(changed()));
+       connect(screenTypewriterCO, SIGNAL(activated(const QString&)),
+               this, SIGNAL(changed()));
+       connect(screenZoomSB, SIGNAL(valueChanged(int)),
+               this, SIGNAL(changed()));
+       connect(screenDpiSB, SIGNAL(valueChanged(int)),
+               this, SIGNAL(changed()));
+       connect(screenTinyED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(screenSmallestED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(screenSmallerED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(screenSmallED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(screenNormalED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(screenLargeED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(screenLargerED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(screenLargestED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(screenHugeED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(screenHugerED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+
+       screenTinyED->setValidator(new QDoubleValidator(
+               screenTinyED));
+       screenSmallestED->setValidator(new QDoubleValidator(
+               screenSmallestED));
+       screenSmallerED->setValidator(new QDoubleValidator(
+               screenSmallerED));
+       screenSmallED->setValidator(new QDoubleValidator(
+               screenSmallED));
+       screenNormalED->setValidator(new QDoubleValidator(
+               screenNormalED));
+       screenLargeED->setValidator(new QDoubleValidator(
+               screenLargeED));
+       screenLargerED->setValidator(new QDoubleValidator(
+               screenLargerED));
+       screenLargestED->setValidator(new QDoubleValidator(
+               screenLargestED));
+       screenHugeED->setValidator(new QDoubleValidator(
+               screenHugeED));
+       screenHugerED->setValidator(new QDoubleValidator(
+               screenHugerED));
+}
 
-       prefsPS->addPanel(identityModule, _("Identity"));
-       prefsPS->addPanel(pathsModule, _("Paths"));
-       prefsPS->addPanel(fileformatsModule, _("File formats"));
-       prefsPS->addPanel(convertersModule, _("Converters"));
-       prefsPS->addPanel(copiersModule, _("Copiers"));
 
-       prefsPS->setCurrentPanel(_("User interface"));
+void PrefScreenFonts::apply(LyXRC & rc) const
+{
+       LyXRC const oldrc(rc);
 
+       boost::tie(rc.roman_font_name, rc.roman_font_foundry)
+               = parseFontName(fromqstr(screenRomanCO->currentText()));
+       boost::tie(rc.sans_font_name, rc.sans_font_foundry) =
+               parseFontName(fromqstr(screenSansCO->currentText()));
+       boost::tie(rc.typewriter_font_name, rc.typewriter_font_foundry) =
+               parseFontName(fromqstr(screenTypewriterCO->currentText()));
+
+       rc.zoom = screenZoomSB->value();
+       rc.dpi = screenDpiSB->value();
+       rc.font_sizes[LyXFont::SIZE_TINY] = fromqstr(screenTinyED->text());
+       rc.font_sizes[LyXFont::SIZE_SCRIPT] = fromqstr(screenSmallestED->text());
+       rc.font_sizes[LyXFont::SIZE_FOOTNOTE] = fromqstr(screenSmallerED->text());
+       rc.font_sizes[LyXFont::SIZE_SMALL] = fromqstr(screenSmallED->text());
+       rc.font_sizes[LyXFont::SIZE_NORMAL] = fromqstr(screenNormalED->text());
+       rc.font_sizes[LyXFont::SIZE_LARGE] = fromqstr(screenLargeED->text());
+       rc.font_sizes[LyXFont::SIZE_LARGER] = fromqstr(screenLargerED->text());
+       rc.font_sizes[LyXFont::SIZE_LARGEST] = fromqstr(screenLargestED->text());
+       rc.font_sizes[LyXFont::SIZE_HUGE] = fromqstr(screenHugeED->text());
+       rc.font_sizes[LyXFont::SIZE_HUGER] = fromqstr(screenHugerED->text());
 
-       form_->bcview().setOK(savePB);
-       form_->bcview().setApply(applyPB);
-       form_->bcview().setCancel(closePB);
-       form_->bcview().setRestore(restorePB);
+       if (rc.font_sizes != oldrc.font_sizes
+               || rc.roman_font_name != oldrc.roman_font_name
+               || rc.sans_font_name != oldrc.sans_font_name
+               || rc.typewriter_font_name != oldrc.typewriter_font_name
+               || rc.zoom != oldrc.zoom || rc.dpi != oldrc.dpi) {
+               form_->controller().updateScreenFonts();
+       }
 }
 
 
+void PrefScreenFonts::update(LyXRC const & rc)
+{
+       setComboxFont(screenRomanCO, rc.roman_font_name,
+                       rc.roman_font_foundry);
+       setComboxFont(screenSansCO, rc.sans_font_name,
+                       rc.sans_font_foundry);
+       setComboxFont(screenTypewriterCO, rc.typewriter_font_name,
+                       rc.typewriter_font_foundry);
 
+       select_roman(screenRomanCO->currentText());
+       select_sans(screenSansCO->currentText());
+       select_typewriter(screenTypewriterCO->currentText());
+
+       screenZoomSB->setValue(rc.zoom);
+       screenDpiSB->setValue(rc.dpi);
+       screenTinyED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_TINY]));
+       screenSmallestED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_SCRIPT]));
+       screenSmallerED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_FOOTNOTE]));
+       screenSmallED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_SMALL]));
+       screenNormalED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_NORMAL]));
+       screenLargeED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_LARGE]));
+       screenLargerED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_LARGER]));
+       screenLargestED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_LARGEST]));
+       screenHugeED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_HUGE]));
+       screenHugerED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_HUGER]));
+}
 
-QPrefsDialog::~QPrefsDialog()
+void PrefScreenFonts::select_roman(const QString& name)
 {
+       screenRomanFE->set(QFont(name), name);
 }
 
 
-void QPrefsDialog::closeEvent(QCloseEvent * e)
+void PrefScreenFonts::select_sans(const QString& name)
 {
-       form_->slotWMHide();
-       e->accept();
+       screenSansFE->set(QFont(name), name);
 }
 
 
-void QPrefsDialog::change_adaptor()
+void PrefScreenFonts::select_typewriter(const QString& name)
 {
-       form_->changed();
+       screenTypewriterFE->set(QFont(name), name);
 }
 
 
-void QPrefsDialog::updateConverters()
+PrefColors::PrefColors(QPrefs * form, QWidget * parent)
+: PrefModule(_(LookAndFeel), _("Colors"), form, parent)
 {
-       Ui::QPrefConvertersUi* convertmod(convertersModule);
-
-       // save current selection
-       QString current = convertmod->converterFromCO->currentText()
-               + " -> " + convertmod->converterToCO->currentText();
+       setupUi(this);
 
-       convertmod->converterFromCO->clear();
-       convertmod->converterToCO->clear();
+       // FIXME: put in controller
+       for (int i = 0; i < LColor::ignore; ++i) {
+               LColor::color lc = static_cast<LColor::color>(i);
+               if (lc == LColor::none
+                       || lc == LColor::black
+                       || lc == LColor::white
+                       || lc == LColor::red
+                       || lc == LColor::green
+                       || lc == LColor::blue
+                       || lc == LColor::cyan
+                       || lc == LColor::magenta
+                       || lc == LColor::yellow
+                       || lc == LColor::inherit
+                       || lc == LColor::ignore) continue;
 
-       Formats::const_iterator cit = form_->formats().begin();
-       Formats::const_iterator end = form_->formats().end();
-       for (; cit != end; ++cit) {
-               convertmod->converterFromCO->insertItem(toqstr(cit->prettyname()));
-               convertmod->converterToCO->insertItem(toqstr(cit->prettyname()));
+               lcolors_.push_back(lc);
+               QColor color = QColor(lcolorcache.get(lc));
+               prefcolors_.push_back(color.name());
+               QPixmap coloritem(32, 32);
+               coloritem.fill(color);
+               // This is not a memory leak:
+               /*QListWidgetItem * newItem =*/ new QListWidgetItem(QIcon(coloritem),
+                       toqstr(lcolor.getGUIName(lc)), lyxObjectsLW);
        }
+       newcolors_ = prefcolors_;
 
-       convertmod->convertersLB->clear();
+       connect(colorChangePB, SIGNAL(clicked()),
+               this, SLOT(change_color()));
+       connect(lyxObjectsLW, SIGNAL(itemActivated(QListWidgetItem*)),
+               this, SLOT(change_color()));
+}
 
-       Converters::const_iterator ccit = form_->converters().begin();
-       Converters::const_iterator cend = form_->converters().end();
-       for (; ccit != cend; ++ccit) {
-               std::string const name = ccit->From->prettyname() + " -> "
-                       + ccit->To->prettyname();
-               convertmod->convertersLB->insertItem(toqstr(name));
-       }
 
-       // restore selection
-       if (!current.isEmpty()) {
-               Q3ListBoxItem * item = convertmod->convertersLB->findItem(current);
-               convertmod->convertersLB->setCurrentItem(item);
+void PrefColors::apply(LyXRC & /*rc*/) const
+{
+       for (unsigned int i = 0; i < lcolors_.size(); ++i) {
+               if (prefcolors_[i]!=newcolors_[i])
+                       form_->controller().setColor(lcolors_[i], fromqstr(newcolors_[i]));
        }
-       // select first element if restoring failed
-       if (convertmod->convertersLB->currentItem() == -1)
-               convertmod->convertersLB->setCurrentItem(0);
-
-       updateConverterButtons();
 }
 
 
-void QPrefsDialog::switch_converter(int nr)
+void PrefColors::update(LyXRC const & /*rc*/)
 {
-       Converter const & c(form_->converters().get(nr));
-       convertersModule->converterFromCO->setCurrentItem(form_->formats().getNumber(c.from));
-       convertersModule->converterToCO->setCurrentItem(form_->formats().getNumber(c.to));
-       convertersModule->converterED->setText(toqstr(c.command));
-       convertersModule->converterFlagED->setText(toqstr(c.flags));
+}
 
-       updateConverterButtons();
+void PrefColors::change_color()
+{
+       int const row = lyxObjectsLW->currentRow();
+       QString color = newcolors_[row];
+       QColor c(QColorDialog::getColor(QColor(color),
+               qApp->focusWidget() ? qApp->focusWidget() : qApp->mainWidget()));
+
+       if (c.name()!=color) {
+               newcolors_[row] = c.name();
+               QPixmap coloritem(32, 32);
+               coloritem.fill(c);
+               lyxObjectsLW->currentItem()->setIcon(QIcon(coloritem));
+               // emit signal
+               changed();
+       }
 }
 
 
-void QPrefsDialog::converter_changed()
+PrefCygwinPath::PrefCygwinPath(QWidget * parent)
+: PrefModule(_(Outputs), _("Paths"), 0, parent)
 {
-       updateConverterButtons();
+       setupUi(this);
+       connect(pathCB, SIGNAL(toggled(bool)),
+               this, SIGNAL(changed()));
 }
 
 
-void QPrefsDialog::updateConverterButtons()
+void PrefCygwinPath::apply(LyXRC & rc) const
 {
-       Format const & from(form_->formats().get(
-               convertersModule->converterFromCO->currentItem()));
-       Format const & to(form_->formats().get(
-               convertersModule->converterToCO->currentItem()));
-       int const sel = form_->converters().getNumber(from.name(), to.name());
+       rc.windows_style_tex_paths = pathCB->isChecked();
+}
+
+
+void PrefCygwinPath::update(LyXRC const & rc)
+{
+       pathCB->setChecked(rc.windows_style_tex_paths);
+}
+
+
+PrefDisplay::PrefDisplay(QWidget * parent)
+: PrefModule(_(LookAndFeel), _("Graphics"), 0, parent)
+{
+       setupUi(this);
+       connect(instantPreviewCO, SIGNAL(activated(int)),
+               this, SIGNAL(changed()));
+       connect(displayGraphicsCO, SIGNAL(activated(int)),
+               this, SIGNAL(changed()));
+}
+
+
+void PrefDisplay::apply(LyXRC & rc) const
+{
+       switch (instantPreviewCO->currentItem()) {
+       case 0: rc.preview = LyXRC::PREVIEW_OFF; break;
+       case 1: rc.preview = LyXRC::PREVIEW_NO_MATH; break;
+       case 2: rc.preview = LyXRC::PREVIEW_ON; break;
+       }
+
+       lyx::graphics::DisplayType dtype;
+       switch (displayGraphicsCO->currentItem()) {
+       case 3: dtype = lyx::graphics::NoDisplay; break;
+       case 2: dtype = lyx::graphics::ColorDisplay; break;
+       case 1: dtype = lyx::graphics::GrayscaleDisplay;        break;
+       case 0: dtype = lyx::graphics::MonochromeDisplay; break;
+       default: dtype = lyx::graphics::GrayscaleDisplay;
+       }
+       rc.display_graphics = dtype;
+
+#ifdef WITH_WARNINGS
+#warning FIXME!! The graphics cache no longer has a changeDisplay method.
+#endif
+#if 0
+       if (old_value != rc.display_graphics) {
+               lyx::graphics::GCache & gc = lyx::graphics::GCache::get();
+               gc.changeDisplay();
+       }
+#endif
+}
+
+
+void PrefDisplay::update(LyXRC const & rc)
+{
+       switch (rc.preview) {
+       case LyXRC::PREVIEW_OFF:
+               instantPreviewCO->setCurrentIndex(0);
+               break;
+       case LyXRC::PREVIEW_NO_MATH :
+               instantPreviewCO->setCurrentIndex(1);
+               break;
+       case LyXRC::PREVIEW_ON :
+               instantPreviewCO->setCurrentIndex(2);
+               break;
+       }
+
+       int item = 2;
+       switch (rc.display_graphics) {
+               case lyx::graphics::NoDisplay:          item = 3; break;
+               case lyx::graphics::ColorDisplay:       item = 2; break;
+               case lyx::graphics::GrayscaleDisplay:   item = 1; break;
+               case lyx::graphics::MonochromeDisplay:  item = 0; break;
+               default: break;
+       }
+       displayGraphicsCO->setCurrentIndex(item);
+}
+
+
+PrefPaths::PrefPaths(QPrefs * form, QWidget * parent)
+: PrefModule(string(), _("Paths"), form, parent)
+{
+       setupUi(this);
+       connect(templateDirPB, SIGNAL(clicked()), this, SLOT(select_templatedir()));
+       connect(tempDirPB, SIGNAL(clicked()), this, SLOT(select_tempdir()));
+       connect(backupDirPB, SIGNAL(clicked()), this, SLOT(select_backupdir()));
+       connect(workingDirPB, SIGNAL(clicked()), this, SLOT(select_workingdir()));
+       connect(lyxserverDirPB, SIGNAL(clicked()), this, SLOT(select_lyxpipe()));
+       connect(workingDirED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(templateDirED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(backupDirED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(tempDirED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(lyxserverDirED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(pathPrefixED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+}
+
+
+void PrefPaths::apply(LyXRC & rc) const
+{
+       rc.document_path = internal_path(workingDirED->text());
+       rc.template_path = internal_path(templateDirED->text());
+       rc.backupdir_path = internal_path(backupDirED->text());
+       rc.tempdir_path = internal_path(tempDirED->text());
+       rc.path_prefix = fromqstr(pathPrefixED->text());
+       // FIXME: should be a checkbox only
+       rc.lyxpipes = internal_path(lyxserverDirED->text());
+}
+
+
+void PrefPaths::update(LyXRC const & rc)
+{
+       workingDirED->setText(external_path(rc.document_path));
+       templateDirED->setText(external_path(rc.template_path));
+       backupDirED->setText(external_path(rc.backupdir_path));
+       tempDirED->setText(external_path(rc.tempdir_path));
+       pathPrefixED->setText(toqstr(rc.path_prefix));
+       // FIXME: should be a checkbox only
+       lyxserverDirED->setText(external_path(rc.lyxpipes));
+}
+
+// NB: the _() is OK here because it gets passed back and we toqstr() them
+
+void PrefPaths::select_templatedir()
+{
+       string file(form_->controller().browsedir(fromqstr(templateDirED->text()), _("Select a document templates directory")));
+       if (!file.empty())
+               templateDirED->setText(toqstr(file));
+}
+
+
+void PrefPaths::select_tempdir()
+{
+       string file(form_->controller().browsedir(fromqstr(tempDirED->text()), _("Select a temporary directory")));
+       if (!file.empty())
+               tempDirED->setText(toqstr(file));
+}
+
+
+void PrefPaths::select_backupdir()
+{
+       string file(form_->controller().browsedir(fromqstr(backupDirED->text()), _("Select a backups directory")));
+       if (!file.empty())
+               backupDirED->setText(toqstr(file));
+}
+
+
+void PrefPaths::select_workingdir()
+{
+       string file(form_->controller().browsedir(fromqstr(workingDirED->text()), _("Select a document directory")));
+       if (!file.empty())
+               workingDirED->setText(toqstr(file));
+}
+
+
+void PrefPaths::select_lyxpipe()
+{
+       string file(form_->controller().browse(fromqstr(lyxserverDirED->text()), _("Give a filename for the LyX server pipe")));
+       if (!file.empty())
+               lyxserverDirED->setText(toqstr(file));
+}
+
+
+PrefSpellchecker::PrefSpellchecker(QPrefs * form, QWidget * parent)
+: PrefModule(_(LanguageSettings), _("Spellchecker"), form, parent)
+{
+       setupUi(this);
+
+       connect(persDictionaryPB, SIGNAL(clicked()), this, SLOT(select_dict()));
+#if defined (USE_ISPELL)
+       connect(spellCommandCO, SIGNAL(activated(int)),
+               this, SIGNAL(changed()));
+#else
+       spellCommandCO->setEnabled(false);
+#endif
+       connect(altLanguageED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(escapeCharactersED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(persDictionaryED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(compoundWordCB, SIGNAL(toggled(bool)),
+               this, SIGNAL(changed()));
+       connect(inputEncodingCB, SIGNAL(toggled(bool)),
+               this, SIGNAL(changed()));
+
+       spellCommandCO->insertItem(qt_("ispell"));
+       spellCommandCO->insertItem(qt_("aspell"));
+       spellCommandCO->insertItem(qt_("hspell"));
+#ifdef USE_PSPELL
+       spellCommandCO->insertItem(qt_("pspell (library)"));
+#else
+#ifdef USE_ASPELL
+       spellCommandCO->insertItem(qt_("aspell (library)"));
+#endif
+#endif
+}
+
+
+void PrefSpellchecker::apply(LyXRC & rc) const
+{
+       switch (spellCommandCO->currentItem()) {
+               case 0:
+               case 1:
+               case 2:
+                       rc.use_spell_lib = false;
+                       rc.isp_command = fromqstr(spellCommandCO->currentText());
+                       break;
+               case 3:
+                       rc.use_spell_lib = true;
+                       break;
+       }
+
+       // FIXME: remove isp_use_alt_lang
+       rc.isp_alt_lang = fromqstr(altLanguageED->text());
+       rc.isp_use_alt_lang = !rc.isp_alt_lang.empty();
+       // FIXME: remove isp_use_esc_chars
+       rc.isp_esc_chars = fromqstr(escapeCharactersED->text());
+       rc.isp_use_esc_chars = !rc.isp_esc_chars.empty();
+       // FIXME: remove isp_use_pers_dict
+       rc.isp_pers_dict = internal_path(persDictionaryED->text());
+       rc.isp_use_pers_dict = !rc.isp_pers_dict.empty();
+       rc.isp_accept_compound = compoundWordCB->isChecked();
+       rc.isp_use_input_encoding = inputEncodingCB->isChecked();
+}
+
+
+void PrefSpellchecker::update(LyXRC const & rc)
+{
+       spellCommandCO->setCurrentIndex(0);
+
+       if (rc.isp_command == "ispell") {
+               spellCommandCO->setCurrentIndex(0);
+       } else if (rc.isp_command == "aspell") {
+               spellCommandCO->setCurrentIndex(1);
+       } else if (rc.isp_command == "hspell") {
+               spellCommandCO->setCurrentIndex(2);
+       }
+
+       if (rc.use_spell_lib) {
+#if defined(USE_ASPELL) || defined(USE_PSPELL)
+               spellCommandCO->setCurrentIndex(3);
+#endif
+       }
+
+       // FIXME: remove isp_use_alt_lang
+       altLanguageED->setText(toqstr(rc.isp_alt_lang));
+       // FIXME: remove isp_use_esc_chars
+       escapeCharactersED->setText(toqstr(rc.isp_esc_chars));
+       // FIXME: remove isp_use_pers_dict
+       persDictionaryED->setText(external_path(rc.isp_pers_dict));
+       compoundWordCB->setChecked(rc.isp_accept_compound);
+       inputEncodingCB->setChecked(rc.isp_use_input_encoding);
+}
+
+
+void PrefSpellchecker::select_dict()
+{
+       string file(form_->controller().browsedict(fromqstr(persDictionaryED->text())));
+       if (!file.empty())
+               persDictionaryED->setText(toqstr(file));
+}
+
+
+PrefConverters::PrefConverters(QPrefs * form, QWidget * parent)
+: PrefModule(string(), _("Converters"), form, parent)
+{
+       setupUi(this);
+
+       connect(converterNewPB, SIGNAL(clicked()),
+               this, SLOT(new_converter()));
+       connect(converterRemovePB, SIGNAL(clicked()),
+               this, SLOT(remove_converter()));
+       connect(converterModifyPB, SIGNAL(clicked()),
+               this, SLOT(modify_converter()));
+       connect(convertersLW, SIGNAL(currentRowChanged(int)),
+               this, SLOT(switch_converter(int)));
+       connect(converterFromCO, SIGNAL(activated(const QString&)),
+               this, SLOT(converter_changed()));
+       connect(converterToCO, SIGNAL(activated(const QString&)),
+               this, SLOT(converter_changed()));
+       connect(converterED, SIGNAL(textChanged(const QString&)),
+               this, SLOT(converter_changed()));
+       connect(converterFlagED, SIGNAL(textChanged(const QString&)),
+               this, SLOT(converter_changed()));
+       connect(converterNewPB, SIGNAL(clicked()),
+               this, SIGNAL(changed()));
+       connect(converterRemovePB, SIGNAL(clicked()),
+               this, SIGNAL(changed()));
+       connect(converterModifyPB, SIGNAL(clicked()),
+               this, SIGNAL(changed()));
+}
+
+
+void PrefConverters::apply(LyXRC & /*rc*/) const
+{
+}
+
+
+void PrefConverters::update(LyXRC const & /*rc*/)
+{
+       updateGui();
+}
+
+
+void PrefConverters::updateGui()
+{
+       // save current selection
+       QString current = converterFromCO->currentText()
+               + " -> " + converterToCO->currentText();
+
+       converterFromCO->clear();
+       converterToCO->clear();
+
+       Formats::const_iterator cit = form_->formats().begin();
+       Formats::const_iterator end = form_->formats().end();
+       for (; cit != end; ++cit) {
+               converterFromCO->insertItem(toqstr(cit->prettyname()));
+               converterToCO->insertItem(toqstr(cit->prettyname()));
+       }
+
+       convertersLW->clear();
+
+       Converters::const_iterator ccit = form_->converters().begin();
+       Converters::const_iterator cend = form_->converters().end();
+       for (; ccit != cend; ++ccit) {
+               std::string const name = ccit->From->prettyname() + " -> "
+                                                               + ccit->To->prettyname();
+               new QListWidgetItem(toqstr(name), convertersLW,
+                                                       form_->converters().getNumber(ccit->From->name(), ccit->To->name()));
+       }
+       convertersLW->sortItems(Qt::AscendingOrder);
+
+       // restore selection
+       if (!current.isEmpty()) {
+               QList<QListWidgetItem *> const item =
+                       convertersLW->findItems(current, Qt::MatchExactly);
+               if (item.size()>0)
+                       convertersLW->setCurrentItem(item.at(0));
+       }
+       // select first element if restoring failed
+       if (convertersLW->currentRow() == -1)
+               convertersLW->setCurrentRow(0);
+
+       updateButtons();
+}
+
+
+void PrefConverters::switch_converter(int nr)
+{
+       if (nr<0)
+               return;
+
+       int const cnr = convertersLW->currentItem()->type();
+       Converter const & c(form_->converters().get(cnr));
+       converterFromCO->setCurrentIndex(form_->formats().getNumber(c.from));
+       converterToCO->setCurrentIndex(form_->formats().getNumber(c.to));
+       converterED->setText(toqstr(c.command));
+       converterFlagED->setText(toqstr(c.flags));
+
+       updateButtons();
+}
+
+
+void PrefConverters::converter_changed()
+{
+       updateButtons();
+}
+
+
+void PrefConverters::updateButtons()
+{
+       Format const & from(form_->formats().get(
+               converterFromCO->currentItem()));
+       Format const & to(form_->formats().get(
+               converterToCO->currentItem()));
+       int const sel = form_->converters().getNumber(from.name(), to.name());
        bool const known = !(sel < 0);
-       bool const valid = !(convertersModule->converterED->text().isEmpty()
+       bool const valid = !(converterED->text().isEmpty()
                || from.name() == to.name());
 
-       Converter const & c(form_->converters().get(
-               convertersModule->convertersLB->currentItem()));
+       int const cnr = convertersLW->currentItem()->type();
+       Converter const & c(form_->converters().get(cnr));
        string const old_command = c.command;
        string const old_flag = c.flags;
-       string const new_command(fromqstr(convertersModule->converterED->text()));
-       string const new_flag(fromqstr(convertersModule->converterFlagED->text()));
+       string const new_command(fromqstr(converterED->text()));
+       string const new_flag(fromqstr(converterFlagED->text()));
 
        bool modified = ((old_command != new_command) || (old_flag != new_flag));
 
-       convertersModule->converterModifyPB->setEnabled(valid && known && modified);
-       convertersModule->converterNewPB->setEnabled(valid && !known);
-       convertersModule->converterRemovePB->setEnabled(known);
+       converterModifyPB->setEnabled(valid && known && modified);
+       converterNewPB->setEnabled(valid && !known);
+       converterRemovePB->setEnabled(known);
 }
 
 
 // FIXME: user must
 // specify unique from/to or it doesn't appear. This is really bad UI
-void QPrefsDialog::new_converter()
+void PrefConverters::new_converter()
 {
-       Format const & from(form_->formats().get(convertersModule->converterFromCO->currentItem()));
-       Format const & to(form_->formats().get(convertersModule->converterToCO->currentItem()));
-       string const command(fromqstr(convertersModule->converterED->text()));
-       string const flags(fromqstr(convertersModule->converterFlagED->text()));
+       Format const & from(form_->formats().get(converterFromCO->currentItem()));
+       Format const & to(form_->formats().get(converterToCO->currentItem()));
+       string const command(fromqstr(converterED->text()));
+       string const flags(fromqstr(converterFlagED->text()));
 
        Converter const * old = form_->converters().getConverter(from.name(), to.name());
        form_->converters().add(from.name(), to.name(), command, flags);
        if (!old) {
                form_->converters().updateLast(form_->formats());
        }
-       updateConverters();
-       convertersModule->convertersLB->setCurrentItem(convertersModule->convertersLB->count() - 1);
+       updateGui();
+
+       QString const name = toqstr(from.name() + " -> " + to.name());
+       QList<QListWidgetItem *> const item =
+               convertersLW->findItems(name, Qt::MatchExactly);
+       if (item.size()>0)
+               convertersLW->setCurrentItem(item.at(0));
 }
 
 
-void QPrefsDialog::modify_converter()
+void PrefConverters::modify_converter()
 {
-       int const top_item = convertersModule->convertersLB->topItem();
        QString const current_text =
-               convertersModule->convertersLB->currentText();
+               convertersLW->currentItem()->text();
 
-       Format const & from(form_->formats().get(convertersModule->converterFromCO->currentItem()));
-       Format const & to(form_->formats().get(convertersModule->converterToCO->currentItem()));
-       string flags(fromqstr(convertersModule->converterFlagED->text()));
-       string name(fromqstr(convertersModule->converterED->text()));
+       Format const & from(form_->formats().get(converterFromCO->currentItem()));
+       Format const & to(form_->formats().get(converterToCO->currentItem()));
+       string flags(fromqstr(converterFlagED->text()));
+       string name(fromqstr(converterED->text()));
 
        Converter const * old = form_->converters().getConverter(from.name(), to.name());
        form_->converters().add(from.name(), to.name(), name, flags);
        if (!old) {
                form_->converters().updateLast(form_->formats());
        }
-       updateConverters();
+       updateGui();
 
-       Q3ListBoxItem * const item =
-               convertersModule->convertersLB->findItem(current_text);
-       convertersModule->convertersLB->setCurrentItem(item);
-       convertersModule->convertersLB->setTopItem(top_item);
+       QList<QListWidgetItem *> const item =
+               convertersLW->findItems(current_text, Qt::MatchExactly);
+       if (item.size()>0)
+               convertersLW->setCurrentItem(item.at(0));
 }
 
 
-void QPrefsDialog::remove_converter()
+void PrefConverters::remove_converter()
 {
-       Format const & from(form_->formats().get(convertersModule->converterFromCO->currentItem()));
-       Format const & to(form_->formats().get(convertersModule->converterToCO->currentItem()));
+       Format const & from(form_->formats().get(converterFromCO->currentItem()));
+       Format const & to(form_->formats().get(converterToCO->currentItem()));
        form_->converters().erase(from.name(), to.name());
-       updateConverters();
+       updateGui();
+}
+
+
+PrefCopiers::PrefCopiers(QPrefs * form, QWidget * parent)
+: PrefModule(string(), _("Copiers"), form, parent)
+{
+       setupUi(this);
+
+       connect(copierNewPB, SIGNAL(clicked()), this, SLOT(new_copier()));
+       connect(copierRemovePB, SIGNAL(clicked()), this, SLOT(remove_copier()));
+       connect(copierModifyPB, SIGNAL(clicked()), this, SLOT(modify_copier()));
+       connect(AllCopiersLW, SIGNAL(currentRowChanged(int)),
+               this, SLOT(switch_copierLB(int)));
+       connect(copierFormatCO, SIGNAL(activated(int)), this, SLOT(switch_copierCO(int)));
+       connect(copierNewPB, SIGNAL(clicked()),
+               this, SIGNAL(changed()));
+       connect(copierRemovePB, SIGNAL(clicked()),
+               this, SIGNAL(changed()));
+       connect(copierModifyPB, SIGNAL(clicked()),
+               this, SIGNAL(changed()));
+       connect(copierFormatCO, SIGNAL(activated(const QString&)), this, SLOT(copiers_changed()));
+       connect(copierED, SIGNAL(textChanged(const QString&)), this, SLOT(copiers_changed()));
+}
+
+
+void PrefCopiers::apply(LyXRC & /*rc*/) const
+{
+}
+
+
+void PrefCopiers::update(LyXRC const & /*rc*/)
+{
+       update();
 }
 
 
-void QPrefsDialog::updateCopiers()
+void PrefCopiers::update()
 {
        // The choice widget
        // save current selection
-       QString current = copiersModule->copierFormatCO->currentText();
-       copiersModule->copierFormatCO->clear();
+       QString current = copierFormatCO->currentText();
+       copierFormatCO->clear();
 
        for (Formats::const_iterator it = form_->formats().begin(),
                     end = form_->formats().end();
             it != end; ++it) {
-               copiersModule->copierFormatCO->insertItem(toqstr(it->prettyname()));
+               copierFormatCO->insertItem(toqstr(it->prettyname()));
        }
 
        // The browser widget
-       copiersModule->AllCopiersLB->clear();
+       AllCopiersLW->clear();
 
        for (Movers::iterator it = form_->movers().begin(),
                     end = form_->movers().end();
@@ -629,20 +1089,21 @@ void QPrefsDialog::updateCopiers()
                std::string const & command = it->second.command();
                if (command.empty())
                        continue;
-               std::string const & fmt = it->first;
-               std::string const & pretty = form_->formats().prettyName(fmt);
-
-               copiersModule->AllCopiersLB->insertItem(toqstr(pretty));
+               QString const pretty = toqstr(form_->formats().prettyName(it->first));
+               AllCopiersLW->addItem(pretty);
        }
+       AllCopiersLW->sortItems(Qt::AscendingOrder);
 
        // restore selection
        if (!current.isEmpty()) {
-               Q3ListBoxItem * item = copiersModule->AllCopiersLB->findItem(current);
-               copiersModule->AllCopiersLB->setCurrentItem(item);
+               QList<QListWidgetItem *> item =
+                       AllCopiersLW->findItems(current, Qt::MatchExactly);
+               if (item.size()>0)
+                       AllCopiersLW->setCurrentItem(item.at(0));
        }
        // select first element if restoring failed
-       if (copiersModule->AllCopiersLB->currentItem() == -1)
-               copiersModule->AllCopiersLB->setCurrentItem(0);
+       if (AllCopiersLW->currentRow() == -1)
+               AllCopiersLW->setCurrentRow(0);
 }
 
 
@@ -672,137 +1133,137 @@ Format const * getFormat(std::string const & prettyname)
 } // namespace anon
 
 
-void QPrefsDialog::switch_copierLB(int)
+void PrefCopiers::switch_copierLB(int row)
 {
+       if (row<0)
+               return;
+
        std::string const browser_text =
-               fromqstr(copiersModule->AllCopiersLB->currentText());
+               fromqstr(AllCopiersLW->currentItem()->text());
        Format const * fmt = getFormat(browser_text);
        if (fmt == 0)
                return;
 
-       string const & fmt_name = fmt->name();
-       string const & gui_name = fmt->prettyname();
-       string const & command = form_->movers().command(fmt_name);
+       QString const gui_name = toqstr(fmt->prettyname());
+       QString const command = toqstr(form_->movers().command(fmt->name()));
 
-       copiersModule->copierED->clear();
-       int const combo_size = copiersModule->copierFormatCO->count();
+       copierED->clear();
+       int const combo_size = copierFormatCO->count();
        for (int i = 0; i < combo_size; ++i) {
-               QString const qtext = copiersModule->copierFormatCO->text(i);
-               std::string const text = fromqstr(qtext);
+               QString const text = copierFormatCO->text(i);
                if (text == gui_name) {
-                       copiersModule->copierFormatCO->setCurrentItem(i);
-                       copiersModule->copierED->setText(toqstr(command));
+                       copierFormatCO->setCurrentIndex(i);
+                       copierED->setText(command);
                        break;
                }
        }
-       updateCopierButtons();
+       updateButtons();
 }
 
 
-void QPrefsDialog::switch_copierCO(int)
+void PrefCopiers::switch_copierCO(int row)
 {
+       if (row<0)
+               return;
+
        std::string const combo_text =
-               fromqstr(copiersModule->copierFormatCO->currentText());
+               fromqstr(copierFormatCO->currentText());
        Format const * fmt = getFormat(combo_text);
        if (fmt == 0)
                return;
 
-       string const & fmt_name = fmt->name();
-       string const & gui_name = fmt->prettyname();
-       string const & command = form_->movers().command(fmt_name);
-
-       copiersModule->copierED->setText(toqstr(command));
+       QString const command = toqstr(form_->movers().command(fmt->name()));
+       copierED->setText(command);
 
-       int const index = copiersModule->AllCopiersLB->currentItem();
+       QListWidgetItem * const index = AllCopiersLW->currentItem();
        if (index >= 0)
-               copiersModule->AllCopiersLB->setSelected(index, false);
+               AllCopiersLW->setItemSelected(index, false);
 
-       int const browser_size = copiersModule->AllCopiersLB->count();
+       QString const gui_name = toqstr(fmt->prettyname());
+       int const browser_size = AllCopiersLW->count();
        for (int i = 0; i < browser_size; ++i) {
-               QString const qtext = copiersModule->AllCopiersLB->text(i);
-               std::string const text = fromqstr(qtext);
+               QString const text = AllCopiersLW->item(i)->text();
                if (text == gui_name) {
-                       copiersModule->AllCopiersLB->setSelected(i, true);
-                       int top = std::max(i - 5, 0);
-                       copiersModule->AllCopiersLB->setTopItem(top);
+                       QListWidgetItem * item = AllCopiersLW->item(i);
+                       AllCopiersLW->setItemSelected(item, true);
                        break;
                }
        }
 }
 
 
-void QPrefsDialog::copiers_changed()
+void PrefCopiers::copiers_changed()
 {
-       updateCopierButtons();
+       updateButtons();
 }
 
 
-void QPrefsDialog::updateCopierButtons()
+void PrefCopiers::updateButtons()
 {
-       QString selected = copiersModule->copierFormatCO->currentText();
+       QString selected = copierFormatCO->currentText();
 
        bool known = false;
-       for (unsigned int i = 0; i != copiersModule->AllCopiersLB->count(); i++) {
-               if (copiersModule->AllCopiersLB->text(i) == selected)
+       for (int i = 0; i < AllCopiersLW->count(); ++i) {
+               if (AllCopiersLW->item(i)->text() == selected)
                        known = true;
        }
 
-       bool const valid = !copiersModule->copierED->text().isEmpty();
+       bool const valid = !copierED->text().isEmpty();
 
        Format const * fmt = getFormat(fromqstr(selected));
        string const old_command = form_->movers().command(fmt->name());
-       string const new_command(fromqstr(copiersModule->copierED->text()));
+       string const new_command(fromqstr(copierED->text()));
 
        bool modified = (old_command != new_command);
 
-       copiersModule->copierModifyPB->setEnabled(valid && known && modified);
-       copiersModule->copierNewPB->setEnabled(valid && !known);
-       copiersModule->copierRemovePB->setEnabled(known);
+       copierModifyPB->setEnabled(valid && known && modified);
+       copierNewPB->setEnabled(valid && !known);
+       copierRemovePB->setEnabled(known);
 }
 
 
-void QPrefsDialog::new_copier()
+void PrefCopiers::new_copier()
 {
        std::string const combo_text =
-               fromqstr(copiersModule->copierFormatCO->currentText());
+               fromqstr(copierFormatCO->currentText());
        Format const * fmt = getFormat(combo_text);
        if (fmt == 0)
                return;
 
-       string const command = fromqstr(copiersModule->copierED->text());
+       string const command = fromqstr(copierED->text());
        if (command.empty())
                return;
 
        form_->movers().set(fmt->name(), command);
 
-       updateCopiers();
-       int const last = copiersModule->AllCopiersLB->count() - 1;
-       copiersModule->AllCopiersLB->setCurrentItem(last);
+       update();
+       int const last = AllCopiersLW->count() - 1;
+       AllCopiersLW->setCurrentRow(last);
 
-       updateCopierButtons();
+       updateButtons();
 }
 
 
-void QPrefsDialog::modify_copier()
+void PrefCopiers::modify_copier()
 {
        std::string const combo_text =
-               fromqstr(copiersModule->copierFormatCO->currentText());
+               fromqstr(copierFormatCO->currentText());
        Format const * fmt = getFormat(combo_text);
        if (fmt == 0)
                return;
 
-       string const command = fromqstr(copiersModule->copierED->text());
+       string const command = fromqstr(copierED->text());
        form_->movers().set(fmt->name(), command);
 
-       updateCopiers();
-       updateCopierButtons();
+       update();
+       updateButtons();
 }
 
 
-void QPrefsDialog::remove_copier()
+void PrefCopiers::remove_copier()
 {
        std::string const combo_text =
-               fromqstr(copiersModule->copierFormatCO->currentText());
+               fromqstr(copierFormatCO->currentText());
        Format const * fmt = getFormat(combo_text);
        if (fmt == 0)
                return;
@@ -810,70 +1271,116 @@ void QPrefsDialog::remove_copier()
        string const & fmt_name = fmt->name();
        form_->movers().set(fmt_name, string());
 
-       updateCopiers();
-       updateCopierButtons();
+       update();
+       updateButtons();
+}
+
+
+
+PrefFileformats::PrefFileformats(QPrefs * form, QWidget * parent)
+: PrefModule(string(), _("File formats"), form, parent)
+{
+       setupUi(this);
+
+       connect(formatNewPB, SIGNAL(clicked()), this, SLOT(new_format()));
+       connect(formatRemovePB, SIGNAL(clicked()), this, SLOT(remove_format()));
+       connect(formatModifyPB, SIGNAL(clicked()), this, SLOT(modify_format()));
+       connect(formatsLW, SIGNAL(currentRowChanged(int)),
+               this, SLOT(switch_format(int)));
+       connect(formatED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed()));
+       connect(guiNameED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed()));
+       connect(shortcutED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed()));
+       connect(extensionED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed()));
+       connect(viewerED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed()));
+       connect(editorED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed()));
+       connect(documentCB, SIGNAL(toggled(bool)), this, SLOT(fileformat_changed()));
+       connect(formatNewPB, SIGNAL(clicked()),
+               this, SIGNAL(changed()));
+       connect(formatRemovePB, SIGNAL(clicked()),
+               this, SIGNAL(changed()));
+       connect(formatModifyPB, SIGNAL(clicked()),
+               this, SIGNAL(changed()));
+}
+
+
+void PrefFileformats::apply(LyXRC & /*rc*/) const
+{
 }
 
 
-void QPrefsDialog::updateFormats()
+void PrefFileformats::update(LyXRC const & /*rc*/)
 {
-       Ui::QPrefFileformatsUi * formatmod(fileformatsModule);
+       update();
+}
 
+
+void PrefFileformats::update()
+{
        // save current selection
-       QString current = formatmod->guiNameED->text();
+       QString current = guiNameED->text();
 
-       formatmod->formatsLB->clear();
+       formatsLW->clear();
 
        Formats::const_iterator cit = form_->formats().begin();
        Formats::const_iterator end = form_->formats().end();
        for (; cit != end; ++cit) {
-               formatmod->formatsLB->insertItem(toqstr(cit->prettyname()));
+               new QListWidgetItem(toqstr(cit->prettyname()),
+                                                       formatsLW,
+                                                       form_->formats().getNumber(cit->name()) );
        }
+       formatsLW->sortItems(Qt::AscendingOrder);
 
        // restore selection
        if (!current.isEmpty()) {
-               Q3ListBoxItem * item = formatmod->formatsLB->findItem(current);
-               formatmod->formatsLB->setCurrentItem(item);
+               QList<QListWidgetItem *>  item = formatsLW->findItems(current, Qt::MatchExactly);
+               if (item.size()>0)
+                       formatsLW->setCurrentItem(item.at(0));
        }
        // select first element if restoring failed
-       if (formatmod->formatsLB->currentItem() == -1)
-               formatmod->formatsLB->setCurrentItem(0);
+       if (formatsLW->currentRow() == -1)
+               formatsLW->setCurrentRow(0);
 }
 
 
-void QPrefsDialog::switch_format(int nr)
+void PrefFileformats::switch_format(int nr)
 {
-       Format const & f(form_->formats().get(nr));
-       fileformatsModule->formatED->setText(toqstr(f.name()));
-       fileformatsModule->guiNameED->setText(toqstr(f.prettyname()));
-       fileformatsModule->extensionED->setText(toqstr(f.extension()));
-       fileformatsModule->shortcutED->setText(toqstr(f.shortcut()));
-       fileformatsModule->viewerED->setText(toqstr(f.viewer()));
-       fileformatsModule->editorED->setText(toqstr(f.editor()));
-       fileformatsModule->formatRemovePB->setEnabled(
+       if (nr<0)
+               return;
+
+       int const ftype = formatsLW->item(nr)->type();
+       Format const f(form_->formats().get(ftype));
+
+       formatED->setText(toqstr(f.name()));
+       guiNameED->setText(toqstr(f.prettyname()));
+       extensionED->setText(toqstr(f.extension()));
+       shortcutED->setText(toqstr(f.shortcut()));
+       viewerED->setText(toqstr(f.viewer()));
+       editorED->setText(toqstr(f.editor()));
+       documentCB->setChecked((f.documentFormat()));
+       formatRemovePB->setEnabled(
                !form_->converters().formatIsUsed(f.name()));
 
-       updateFormatsButtons();
+       updateButtons();
 }
 
 
-void QPrefsDialog::fileformat_changed()
+void PrefFileformats::fileformat_changed()
 {
-       updateFormatsButtons();
+       updateButtons();
 }
 
 
-void QPrefsDialog::updateFormatsButtons()
+void PrefFileformats::updateButtons()
 {
-       QString const format = fileformatsModule->formatED->text();
-       QString const gui_name = fileformatsModule->guiNameED->text();
+       QString const format = formatED->text();
+       QString const gui_name = guiNameED->text();
        int const sel = form_->formats().getNumber(fromqstr(format));
        bool gui_name_known = false;
        int where = sel;
-       for (unsigned int i = 0; i != fileformatsModule->formatsLB->count(); i++) {
-               if (fileformatsModule->formatsLB->text(i) == gui_name) {
+       for (int i = 0; i < formatsLW->count(); ++i) {
+               if (formatsLW->item(i)->text() == gui_name) {
                        gui_name_known = true;
-                       where = i;
+                       where = formatsLW->item(i)->type();
                }
        }
 
@@ -881,93 +1388,107 @@ void QPrefsDialog::updateFormatsButtons()
        bool const known_otherwise = gui_name_known && (where != sel);
 
        bool const known = !(sel < 0);
-       bool const valid = (!fileformatsModule->formatED->text().isEmpty()
-               && !fileformatsModule->guiNameED->text().isEmpty());
+       bool const valid = (!formatED->text().isEmpty()
+               && !guiNameED->text().isEmpty());
 
-       Format const & f(form_->formats().get(
-               fileformatsModule->formatsLB->currentItem()));
+       int const ftype = formatsLW->currentItem()->type();
+       Format const & f(form_->formats().get(ftype));
        string const old_pretty(f.prettyname());
        string const old_shortcut(f.shortcut());
        string const old_extension(f.extension());
        string const old_viewer(f.viewer());
        string const old_editor(f.editor());
+       bool const old_document(f.documentFormat());
 
        string const new_pretty(fromqstr(gui_name));
-       string const new_shortcut(fromqstr(fileformatsModule->shortcutED->text()));
-       string const new_extension(fromqstr(fileformatsModule->extensionED->text()));
-       string const new_viewer(fromqstr(fileformatsModule->viewerED->text()));
-       string const new_editor(fromqstr(fileformatsModule->editorED->text()));
+       string const new_shortcut(fromqstr(shortcutED->text()));
+       string const new_extension(fromqstr(extensionED->text()));
+       string const new_viewer(fromqstr(viewerED->text()));
+       string const new_editor(fromqstr(editorED->text()));
+       bool const new_document(documentCB->isChecked());
 
        bool modified = ((old_pretty != new_pretty) || (old_shortcut != new_shortcut)
                || (old_extension != new_extension) || (old_viewer != new_viewer)
-               || (old_editor != new_editor));
+               || (old_editor != new_editor) || old_document != new_document);
 
-       fileformatsModule->formatModifyPB->setEnabled(
+       formatModifyPB->setEnabled(
                valid && known && modified && !known_otherwise);
-       fileformatsModule->formatNewPB->setEnabled(valid && !known && !gui_name_known);
-       fileformatsModule->formatRemovePB->setEnabled(known);
+       formatNewPB->setEnabled(valid && !known && !gui_name_known);
+       formatRemovePB->setEnabled(known);
 }
 
-
-void QPrefsDialog::new_format()
+void PrefFileformats::setConverters(PrefConverters * converters)
 {
-       string const name = fromqstr(fileformatsModule->formatED->text());
-       string const prettyname = fromqstr(fileformatsModule->guiNameED->text());
-       string const extension = fromqstr(fileformatsModule->extensionED->text());
-       string const shortcut = fromqstr(fileformatsModule->shortcutED->text());
-       string const viewer = fromqstr(fileformatsModule->viewerED->text());
-       string const editor = fromqstr(fileformatsModule->editorED->text());
+       converters_ = converters;
+}
 
-       form_->formats().add(name, extension, prettyname, shortcut, viewer, editor);
+void PrefFileformats::new_format()
+{
+       string const name = fromqstr(formatED->text());
+       string const prettyname = fromqstr(guiNameED->text());
+       string const extension = fromqstr(extensionED->text());
+       string const shortcut = fromqstr(shortcutED->text());
+       string const viewer = fromqstr(viewerED->text());
+       string const editor = fromqstr(editorED->text());
+       bool const document = documentCB->isChecked();
+
+       form_->formats().add(name, extension, prettyname, shortcut, viewer,
+                            editor, document);
        form_->formats().sort();
-       updateFormats();
-       fileformatsModule->formatsLB->setCurrentItem(form_->formats().getNumber(name));
+       update();
+
+       QList<QListWidgetItem *>  const item =
+               formatsLW->findItems(toqstr(prettyname), Qt::MatchExactly);
+       if (item.size()>0)
+               formatsLW->setCurrentItem(item.at(0));
+
        form_->converters().update(form_->formats());
 
-       updateConverters();
-       updateFormatsButtons();
+       converters_->updateGui();
+       updateButtons();
 }
 
 
-void QPrefsDialog::modify_format()
+void PrefFileformats::modify_format()
 {
-       int const top_item = fileformatsModule->formatsLB->topItem();
-       int const current_item = fileformatsModule->formatsLB->currentItem();
+       int const current_item = formatsLW->currentItem()->type();
        QString const current_text =
-               fileformatsModule->formatsLB->currentText();
+               formatsLW->currentItem()->text();
 
        Format const & oldformat(form_->formats().get(current_item));
        string const oldpretty(oldformat.prettyname());
-       string const name(fromqstr(fileformatsModule->formatED->text()));
+       string const name(fromqstr(formatED->text()));
        form_->formats().erase(oldformat.name());
 
-       string const prettyname = fromqstr(fileformatsModule->guiNameED->text());
-       string const extension = fromqstr(fileformatsModule->extensionED->text());
-       string const shortcut = fromqstr(fileformatsModule->shortcutED->text());
-       string const viewer = fromqstr(fileformatsModule->viewerED->text());
-       string const editor = fromqstr(fileformatsModule->editorED->text());
+       string const prettyname = fromqstr(guiNameED->text());
+       string const extension = fromqstr(extensionED->text());
+       string const shortcut = fromqstr(shortcutED->text());
+       string const viewer = fromqstr(viewerED->text());
+       string const editor = fromqstr(editorED->text());
+       bool const document = documentCB->isChecked();
 
-       form_->formats().add(name, extension, prettyname, shortcut, viewer, editor);
+       form_->formats().add(name, extension, prettyname, shortcut, viewer,
+                            editor, document);
        form_->formats().sort();
 
-       fileformatsModule->formatsLB->setUpdatesEnabled(false);
-       updateFormats();
-       fileformatsModule->formatsLB->setUpdatesEnabled(true);
-       fileformatsModule->formatsLB->update();
+       formatsLW->setUpdatesEnabled(false);
+       update();
+       formatsLW->setUpdatesEnabled(true);
+       formatsLW->update();
 
-       updateConverters();
-       updateFormatsButtons();
+       converters_->updateGui();
+       updateButtons();
 
-       Q3ListBoxItem * const item =
-               fileformatsModule->formatsLB->findItem(current_text);
-       fileformatsModule->formatsLB->setCurrentItem(item);
-       fileformatsModule->formatsLB->setTopItem(top_item);
+       QList<QListWidgetItem *>  const item =
+               formatsLW->findItems(current_text, Qt::MatchExactly);
+       if (item.size()>0)
+               formatsLW->setCurrentItem(item.at(0));
 }
 
 
-void QPrefsDialog::remove_format()
+void PrefFileformats::remove_format()
 {
-       int const nr(fileformatsModule->formatsLB->currentItem());
+       int const nr = formatsLW->currentItem()->type();
        if (nr < 0)
                return;
        string const current_text = form_->formats().get(nr).name();
@@ -977,619 +1498,390 @@ void QPrefsDialog::remove_format()
                                      "Remove the converter first."));
                return;
        }
+
        form_->formats().erase(current_text);
-       updateFormats();
+       update();
        form_->converters().update(form_->formats());
 
-       updateConverters();
-       updateFormatsButtons();
+       converters_->updateGui();
+       updateButtons();
 }
 
 
-void QPrefsDialog::change_color()
+
+PrefLanguage::PrefLanguage(QWidget * parent)
+: PrefModule(string(), _("Language"), 0, parent)
 {
-       Q3ListBox * lb(colorsModule->lyxObjectsLB);
-       if (lb->currentItem() < 0)
-               return;
-       Q3ListBoxItem * ib(lb->item(lb->currentItem()));
-       QColorItem * ci(static_cast<QColorItem*>(ib));
-       QColor c(QColorDialog::getColor(ci->color(), qApp->focusWidget() ? qApp->focusWidget() : qApp->mainWidget()));
-       if (c.isValid()) {
-               ci->color(c);
-               lb->triggerUpdate(true);
-               change_adaptor();
+       setupUi(this);
+
+       connect(rtlCB, SIGNAL(toggled(bool)),
+               this, SIGNAL(changed()));
+       connect(markForeignCB, SIGNAL(toggled(bool)),
+               this, SIGNAL(changed()));
+       connect(autoBeginCB, SIGNAL(toggled(bool)),
+               this, SIGNAL(changed()));
+       connect(autoEndCB, SIGNAL(toggled(bool)),
+               this, SIGNAL(changed()));
+       connect(useBabelCB, SIGNAL(toggled(bool)),
+               this, SIGNAL(changed()));
+       connect(globalCB, SIGNAL(toggled(bool)),
+               this, SIGNAL(changed()));
+       connect(languagePackageED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(startCommandED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(endCommandED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(defaultLanguageCO, SIGNAL(activated(int)),
+               this, SIGNAL(changed()));
+
+       defaultLanguageCO->clear();
+
+       // store the lang identifiers for later
+       using lyx::frontend::LanguagePair;
+       std::vector<LanguagePair> const langs =
+               lyx::frontend::getLanguageData(false);
+       lang_ = getSecond(langs);
+
+       std::vector<LanguagePair>::const_iterator lit  = langs.begin();
+       std::vector<LanguagePair>::const_iterator lend = langs.end();
+       for (; lit != lend; ++lit) {
+               defaultLanguageCO->insertItem(toqstr(lit->first));
        }
 }
 
 
-void QPrefsDialog::select_ui()
+void PrefLanguage::apply(LyXRC & rc) const
 {
-       string file(form_->controller().browseUI(fromqstr(uiModule->uiFileED->text())));
-       if (!file.empty())
-               uiModule->uiFileED->setText(toqstr(file));
+       // FIXME: remove rtl_support bool
+       rc.rtl_support = rtlCB->isChecked();
+       rc.mark_foreign_language = markForeignCB->isChecked();
+       rc.language_auto_begin = autoBeginCB->isChecked();
+       rc.language_auto_end = autoEndCB->isChecked();
+       rc.language_use_babel = useBabelCB->isChecked();
+       rc.language_global_options = globalCB->isChecked();
+       rc.language_package = fromqstr(languagePackageED->text());
+       rc.language_command_begin = fromqstr(startCommandED->text());
+       rc.language_command_end = fromqstr(endCommandED->text());
+       rc.default_language = lang_[defaultLanguageCO->currentItem()];
 }
 
 
-void QPrefsDialog::select_bind()
+void PrefLanguage::update(LyXRC const & rc)
 {
-       string file(form_->controller().browsebind(fromqstr(uiModule->bindFileED->text())));
-       if (!file.empty())
-               uiModule->bindFileED->setText(toqstr(file));
+       // FIXME: remove rtl_support bool
+       rtlCB->setChecked(rc.rtl_support);
+       markForeignCB->setChecked(rc.mark_foreign_language);
+       autoBeginCB->setChecked(rc.language_auto_begin);
+       autoEndCB->setChecked(rc.language_auto_end);
+       useBabelCB->setChecked(rc.language_use_babel);
+       globalCB->setChecked(rc.language_global_options);
+       languagePackageED->setText(toqstr(rc.language_package));
+       startCommandED->setText(toqstr(rc.language_command_begin));
+       endCommandED->setText(toqstr(rc.language_command_end));
+
+       int const pos = int(findPos(lang_, rc.default_language));
+       defaultLanguageCO->setCurrentIndex(pos);
 }
 
 
-void QPrefsDialog::select_keymap1()
+PrefPrinter::PrefPrinter(QWidget * parent)
+: PrefModule(_(Outputs), _("Printer"), 0, parent)
 {
-       string file(form_->controller().browsekbmap(fromqstr(keyboardModule->firstKeymapED->text())));
-       if (!file.empty())
-               keyboardModule->firstKeymapED->setText(toqstr(file));
+       setupUi(this);
+
+       connect(printerAdaptCB, SIGNAL(toggled(bool)),
+               this, SIGNAL(changed()));
+       connect(printerCommandED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(printerNameED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(printerPageRangeED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(printerCopiesED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(printerReverseED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(printerToPrinterED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(printerExtensionED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(printerSpoolCommandED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(printerPaperTypeED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(printerEvenED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(printerOddED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(printerCollatedED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(printerLandscapeED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(printerToFileED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(printerExtraED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(printerSpoolPrefixED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(printerPaperSizeED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
 }
 
 
-void QPrefsDialog::select_keymap2()
+void PrefPrinter::apply(LyXRC & rc) const
 {
-       string file(form_->controller().browsekbmap(fromqstr(keyboardModule->secondKeymapED->text())));
-       if (!file.empty())
-               keyboardModule->secondKeymapED->setText(toqstr(file));
+       rc.print_adapt_output = printerAdaptCB->isChecked();
+       rc.print_command = fromqstr(printerCommandED->text());
+       rc.printer = fromqstr(printerNameED->text());
+
+       rc.print_pagerange_flag = fromqstr(printerPageRangeED->text());
+       rc.print_copies_flag = fromqstr(printerCopiesED->text());
+       rc.print_reverse_flag = fromqstr(printerReverseED->text());
+       rc.print_to_printer = fromqstr(printerToPrinterED->text());
+       rc.print_file_extension = fromqstr(printerExtensionED->text());
+       rc.print_spool_command = fromqstr(printerSpoolCommandED->text());
+       rc.print_paper_flag = fromqstr(printerPaperTypeED->text());
+       rc.print_evenpage_flag = fromqstr(printerEvenED->text());
+       rc.print_oddpage_flag = fromqstr(printerOddED->text());
+       rc.print_collcopies_flag = fromqstr(printerCollatedED->text());
+       rc.print_landscape_flag = fromqstr(printerLandscapeED->text());
+       rc.print_to_file = internal_path(printerToFileED->text());
+       rc.print_extra_options = fromqstr(printerExtraED->text());
+       rc.print_spool_printerprefix = fromqstr(printerSpoolPrefixED->text());
+       rc.print_paper_dimension_flag = fromqstr(printerPaperSizeED->text());
 }
 
 
-void QPrefsDialog::select_dict()
+void PrefPrinter::update(LyXRC const & rc)
 {
-       string file(form_->controller().browsedict(fromqstr(spellcheckerModule->persDictionaryED->text())));
-       if (!file.empty())
-               spellcheckerModule->persDictionaryED->setText(toqstr(file));
+       printerAdaptCB->setChecked(rc.print_adapt_output);
+       printerCommandED->setText(toqstr(rc.print_command));
+       printerNameED->setText(toqstr(rc.printer));
+
+       printerPageRangeED->setText(toqstr(rc.print_pagerange_flag));
+       printerCopiesED->setText(toqstr(rc.print_copies_flag));
+       printerReverseED->setText(toqstr(rc.print_reverse_flag));
+       printerToPrinterED->setText(toqstr(rc.print_to_printer));
+       printerExtensionED->setText(toqstr(rc.print_file_extension));
+       printerSpoolCommandED->setText(toqstr(rc.print_spool_command));
+       printerPaperTypeED->setText(toqstr(rc.print_paper_flag));
+       printerEvenED->setText(toqstr(rc.print_evenpage_flag));
+       printerOddED->setText(toqstr(rc.print_oddpage_flag));
+       printerCollatedED->setText(toqstr(rc.print_collcopies_flag));
+       printerLandscapeED->setText(toqstr(rc.print_landscape_flag));
+       printerToFileED->setText(external_path(rc.print_to_file));
+       printerExtraED->setText(toqstr(rc.print_extra_options));
+       printerSpoolPrefixED->setText(toqstr(rc.print_spool_printerprefix));
+       printerPaperSizeED->setText(toqstr(rc.print_paper_dimension_flag));
 }
 
 
-// NB: the _() is OK here because it gets passed back and we toqstr() them
-
-void QPrefsDialog::select_templatedir()
+PrefUserInterface::PrefUserInterface(QPrefs * form, QWidget * parent)
+: PrefModule(_(LookAndFeel), _("User interface"), form, parent)
 {
-       string file(form_->controller().browsedir(fromqstr(pathsModule->templateDirED->text()), _("Select a document templates directory")));
-       if (!file.empty())
-               pathsModule->templateDirED->setText(toqstr(file));
+       setupUi(this);
+
+       connect(autoSaveCB, SIGNAL( toggled(bool) ), autoSaveLA, SLOT( setEnabled(bool) ) );
+       connect(autoSaveCB, SIGNAL( toggled(bool) ), autoSaveSB, SLOT( setEnabled(bool) ) );
+       connect(autoSaveCB, SIGNAL( toggled(bool) ), TextLabel1, SLOT( setEnabled(bool) ) );
+       connect(uiFilePB, SIGNAL(clicked()), this, SLOT(select_ui()));
+       connect(bindFilePB, SIGNAL(clicked()), this, SLOT(select_bind()));
+       connect(uiFileED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(bindFileED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(restoreCursorCB, SIGNAL(toggled(bool)),
+               this, SIGNAL(changed()));
+       connect(loadSessionCB, SIGNAL(toggled(bool)),
+               this, SIGNAL(changed()));
+       connect(cursorFollowsCB, SIGNAL(toggled(bool)),
+               this, SIGNAL(changed()));
+       connect(autoSaveSB, SIGNAL(valueChanged(int)),
+               this, SIGNAL(changed()));
+       connect(autoSaveCB, SIGNAL(toggled(bool)),
+               this, SIGNAL(changed()));
+       connect(lastfilesSB, SIGNAL(valueChanged(int)),
+               this, SIGNAL(changed()));
+       lastfilesSB->setMaxValue(maxlastfiles);
 }
 
 
-void QPrefsDialog::select_tempdir()
+void PrefUserInterface::apply(LyXRC & rc) const
 {
-       string file(form_->controller().browsedir(fromqstr(pathsModule->tempDirED->text()), _("Select a temporary directory")));
-       if (!file.empty())
-               pathsModule->tempDirED->setText(toqstr(file));
+       rc.ui_file = internal_path(uiFileED->text());
+       rc.bind_file = internal_path(bindFileED->text());
+       rc.use_lastfilepos = restoreCursorCB->isChecked();
+       rc.load_session = loadSessionCB->isChecked();
+       rc.cursor_follows_scrollbar = cursorFollowsCB->isChecked();
+       rc.autosave = autoSaveSB->value() * 60;
+       rc.make_backup = autoSaveCB->isChecked();
+       rc.num_lastfiles = lastfilesSB->value();
 }
 
 
-void QPrefsDialog::select_backupdir()
+void PrefUserInterface::update(LyXRC const & rc)
 {
-       string file(form_->controller().browsedir(fromqstr(pathsModule->backupDirED->text()), _("Select a backups directory")));
-       if (!file.empty())
-               pathsModule->backupDirED->setText(toqstr(file));
+       uiFileED->setText(external_path(rc.ui_file));
+       bindFileED->setText(external_path(rc.bind_file));
+       restoreCursorCB->setChecked(rc.use_lastfilepos);
+       loadSessionCB->setChecked(rc.load_session);
+       cursorFollowsCB->setChecked(rc.cursor_follows_scrollbar);
+       // convert to minutes
+       int mins(rc.autosave / 60);
+       if (rc.autosave && !mins)
+               mins = 1;
+       autoSaveSB->setValue(mins);
+       autoSaveCB->setChecked(rc.make_backup);
+       lastfilesSB->setValue(rc.num_lastfiles);
 }
 
 
-void QPrefsDialog::select_workingdir()
+
+void PrefUserInterface::select_ui()
 {
-       string file(form_->controller().browsedir(fromqstr(pathsModule->workingDirED->text()), _("Select a document directory")));
+       string file(form_->controller().browseUI(fromqstr(uiFileED->text())));
        if (!file.empty())
-               pathsModule->workingDirED->setText(toqstr(file));
+               uiFileED->setText(toqstr(file));
 }
 
 
-void QPrefsDialog::select_lyxpipe()
+void PrefUserInterface::select_bind()
 {
-       string file(form_->controller().browse(fromqstr(pathsModule->lyxserverDirED->text()), _("Give a filename for the LyX server pipe")));
+       string file(form_->controller().browsebind(fromqstr(bindFileED->text())));
        if (!file.empty())
-               pathsModule->lyxserverDirED->setText(toqstr(file));
+               bindFileED->setText(toqstr(file));
 }
 
 
-void QPrefsDialog::select_roman(const QString& name)
+PrefIdentity::PrefIdentity(QWidget * parent)
+: PrefModule(string(), _("Identity"), 0, parent)
 {
-       screenfontsModule->screenRomanFE->set(QFont(name), name);
-}
-
+       setupUi(this);
 
-void QPrefsDialog::select_sans(const QString& name)
-{
-       screenfontsModule->screenSansFE->set(QFont(name), name);
+       connect(nameED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
+       connect(emailED, SIGNAL(textChanged(const QString&)),
+               this, SIGNAL(changed()));
 }
 
 
-void QPrefsDialog::select_typewriter(const QString& name)
+void PrefIdentity::apply(LyXRC & rc) const
 {
-       screenfontsModule->screenTypewriterFE->set(QFont(name), name);
+       rc.user_name = fromqstr(nameED->text());
+       rc.user_email = fromqstr(emailED->text());
 }
 
-namespace {
 
-string const internal_path(QString const & input)
+void PrefIdentity::update(LyXRC const & rc)
 {
-       return lyx::support::os::internal_path(fromqstr(input));
-}
-
+       nameED->setText(toqstr(rc.user_name));
+       emailED->setText(toqstr(rc.user_email));
 }
 
-void QPrefsDialog::apply(LyXRC & rc) const
-{
-       // FIXME: remove rtl_support bool
-       rc.rtl_support = languageModule->rtlCB->isChecked();
-       rc.mark_foreign_language = languageModule->markForeignCB->isChecked();
-       rc.language_auto_begin = languageModule->autoBeginCB->isChecked();
-       rc.language_auto_end = languageModule->autoEndCB->isChecked();
-       rc.language_use_babel = languageModule->useBabelCB->isChecked();
-       rc.language_global_options = languageModule->globalCB->isChecked();
-       rc.language_package = fromqstr(languageModule->languagePackageED->text());
-       rc.language_command_begin = fromqstr(languageModule->startCommandED->text());
-       rc.language_command_end = fromqstr(languageModule->endCommandED->text());
-       rc.default_language = lang_[languageModule->defaultLanguageCO->currentItem()];
-
-
-       rc.ui_file = internal_path(uiModule->uiFileED->text());
-       rc.bind_file = internal_path(uiModule->bindFileED->text());
-       rc.cursor_follows_scrollbar = uiModule->cursorFollowsCB->isChecked();
-       rc.autosave = uiModule->autoSaveSB->value() * 60;
-       rc.make_backup = uiModule->autoSaveCB->isChecked();
-       rc.num_lastfiles = uiModule->lastfilesSB->value();
-
-
-       // FIXME: can derive CB from the two EDs
-       rc.use_kbmap = keyboardModule->keymapCB->isChecked();
-       rc.primary_kbmap = internal_path(keyboardModule->firstKeymapED->text());
-       rc.secondary_kbmap = internal_path(keyboardModule->secondKeymapED->text());
-
-
-       rc.ascii_linelen = asciiModule->asciiLinelengthSB->value();
-       rc.ascii_roff_command = fromqstr(asciiModule->asciiRoffED->text());
-
-
-       rc.date_insert_format = fromqstr(dateModule->DateED->text());
 
 
-#if defined(__CYGWIN__) || defined(__CYGWIN32__)
-       rc.cygwin_path_fix = cygwinpathModule->pathCB->isChecked();
-#endif
-
-
-       rc.fontenc = fromqstr(latexModule->latexEncodingED->text());
-       rc.chktex_command = fromqstr(latexModule->latexChecktexED->text());
-       rc.bibtex_command = fromqstr(latexModule->latexBibtexED->text());
-       rc.index_command = fromqstr(latexModule->latexIndexED->text());
-       rc.auto_reset_options = latexModule->latexAutoresetCB->isChecked();
-       rc.view_dvi_paper_option = fromqstr(latexModule->latexDviPaperED->text());
-       rc.default_papersize =
-               form_->controller().toPaperSize(latexModule->latexPaperSizeCO->currentItem());
-
+QPrefsDialog::QPrefsDialog(QPrefs * form)
+       : form_(form)
+{
+       setupUi(this);
+       QDialog::setModal(true);
 
-       switch (displayModule->instantPreviewCO->currentItem()) {
-       case 0: rc.preview = LyXRC::PREVIEW_OFF; break;
-       case 1: rc.preview = LyXRC::PREVIEW_NO_MATH; break;
-       case 2: rc.preview = LyXRC::PREVIEW_ON; break;
-       }
+       connect(savePB, SIGNAL(clicked()),
+               form, SLOT(slotOK()));
+       connect(applyPB, SIGNAL(clicked()),
+               form, SLOT(slotApply()));
+       connect(closePB, SIGNAL(clicked()),
+               form, SLOT(slotClose()));
+       connect(restorePB, SIGNAL(clicked()),
+               form, SLOT(slotRestore()));
 
-       lyx::graphics::DisplayType dtype;
-       switch (displayModule->displayGraphicsCO->currentItem()) {
-       case 3: dtype = lyx::graphics::NoDisplay; break;
-       case 2: dtype = lyx::graphics::ColorDisplay; break;
-       case 1: dtype = lyx::graphics::GrayscaleDisplay;        break;
-       case 0: dtype = lyx::graphics::MonochromeDisplay; break;
-       default: dtype = lyx::graphics::GrayscaleDisplay;
-       }
-       rc.display_graphics = dtype;
+       add(new PrefAscii);
+       add(new PrefDate);
+       add(new PrefKeyboard(form_));
+       add(new PrefLatex(form_));
+       add(new PrefScreenFonts(form_));
+       add(new PrefColors(form_));
 
-#ifdef WITH_WARNINGS
-#warning FIXME!! The graphics cache no longer has a changeDisplay method.
-#endif
-#if 0
-       if (old_value != rc.display_graphics) {
-               lyx::graphics::GCache & gc = lyx::graphics::GCache::get();
-               gc.changeDisplay();
-       }
+#if defined(__CYGWIN__) || defined(_WIN32)
+       add(new PrefCygwinPath);
 #endif
 
+       add(new PrefDisplay);
+       add(new PrefPaths(form_));
+       add(new PrefSpellchecker(form_));
 
-       rc.document_path = internal_path(pathsModule->workingDirED->text());
-       rc.template_path = internal_path(pathsModule->templateDirED->text());
-       rc.backupdir_path = internal_path(pathsModule->backupDirED->text());
-       rc.tempdir_path = internal_path(pathsModule->tempDirED->text());
-       rc.path_prefix = fromqstr(pathsModule->pathPrefixED->text());
-       // FIXME: should be a checkbox only
-       rc.lyxpipes = internal_path(pathsModule->lyxserverDirED->text());
-
-
-       switch (spellcheckerModule->spellCommandCO->currentItem()) {
-               case 0:
-               case 1:
-               case 2:
-                       rc.use_spell_lib = false;
-                       rc.isp_command = fromqstr(spellcheckerModule->spellCommandCO->currentText());
-                       break;
-               case 3:
-                       rc.use_spell_lib = true;
-                       break;
-       }
-
-       // FIXME: remove isp_use_alt_lang
-       rc.isp_alt_lang = fromqstr(spellcheckerModule->altLanguageED->text());
-       rc.isp_use_alt_lang = !rc.isp_alt_lang.empty();
-       // FIXME: remove isp_use_esc_chars
-       rc.isp_esc_chars = fromqstr(spellcheckerModule->escapeCharactersED->text());
-       rc.isp_use_esc_chars = !rc.isp_esc_chars.empty();
-       // FIXME: remove isp_use_pers_dict
-       rc.isp_pers_dict = internal_path(spellcheckerModule->persDictionaryED->text());
-       rc.isp_use_pers_dict = !rc.isp_pers_dict.empty();
-       rc.isp_accept_compound = spellcheckerModule->compoundWordCB->isChecked();
-       rc.isp_use_input_encoding = spellcheckerModule->inputEncodingCB->isChecked();
+       PrefConverters * converters = new PrefConverters(form_);
+       PrefFileformats * formats = new PrefFileformats(form_);
+       formats->setConverters(converters);
+       add(converters);
+       add(formats);
 
+       add(new PrefCopiers(form_));
 
+       add(new PrefLanguage);
+       add(new PrefPrinter);
+       add(new PrefUserInterface(form_));
+       add(new PrefIdentity);
 
-       rc.print_adapt_output = printerModule->printerAdaptCB->isChecked();
-       rc.print_command = fromqstr(printerModule->printerCommandED->text());
-       rc.printer = fromqstr(printerModule->printerNameED->text());
-
-       rc.print_pagerange_flag = fromqstr(printerModule->printerPageRangeED->text());
-       rc.print_copies_flag = fromqstr(printerModule->printerCopiesED->text());
-       rc.print_reverse_flag = fromqstr(printerModule->printerReverseED->text());
-       rc.print_to_printer = fromqstr(printerModule->printerToPrinterED->text());
-       rc.print_file_extension = fromqstr(printerModule->printerExtensionED->text());
-       rc.print_spool_command = fromqstr(printerModule->printerSpoolCommandED->text());
-       rc.print_paper_flag = fromqstr(printerModule->printerPaperTypeED->text());
-       rc.print_evenpage_flag = fromqstr(printerModule->printerEvenED->text());
-       rc.print_oddpage_flag = fromqstr(printerModule->printerOddED->text());
-       rc.print_collcopies_flag = fromqstr(printerModule->printerCollatedED->text());
-       rc.print_landscape_flag = fromqstr(printerModule->printerLandscapeED->text());
-       rc.print_to_file = internal_path(printerModule->printerToFileED->text());
-       rc.print_extra_options = fromqstr(printerModule->printerExtraED->text());
-       rc.print_spool_printerprefix = fromqstr(printerModule->printerSpoolPrefixED->text());
-       rc.print_paper_dimension_flag = fromqstr(printerModule->printerPaperSizeED->text());
-
-
-
-       rc.user_name = fromqstr(identityModule->nameED->text());
-       rc.user_email = fromqstr(identityModule->emailED->text());
-
-
-
-       LyXRC const oldrc(rc);
-
-       boost::tie(rc.roman_font_name, rc.roman_font_foundry)
-               = parseFontName(fromqstr(screenfontsModule->screenRomanCO->currentText()));
-       boost::tie(rc.sans_font_name, rc.sans_font_foundry) =
-               parseFontName(fromqstr(screenfontsModule->screenSansCO->currentText()));
-       boost::tie(rc.typewriter_font_name, rc.typewriter_font_foundry) =
-               parseFontName(fromqstr(screenfontsModule->screenTypewriterCO->currentText()));
-
-       rc.zoom = screenfontsModule->screenZoomSB->value();
-       rc.dpi = screenfontsModule->screenDpiSB->value();
-       rc.font_sizes[LyXFont::SIZE_TINY] = fromqstr(screenfontsModule->screenTinyED->text());
-       rc.font_sizes[LyXFont::SIZE_SCRIPT] = fromqstr(screenfontsModule->screenSmallestED->text());
-       rc.font_sizes[LyXFont::SIZE_FOOTNOTE] = fromqstr(screenfontsModule->screenSmallerED->text());
-       rc.font_sizes[LyXFont::SIZE_SMALL] = fromqstr(screenfontsModule->screenSmallED->text());
-       rc.font_sizes[LyXFont::SIZE_NORMAL] = fromqstr(screenfontsModule->screenNormalED->text());
-       rc.font_sizes[LyXFont::SIZE_LARGE] = fromqstr(screenfontsModule->screenLargeED->text());
-       rc.font_sizes[LyXFont::SIZE_LARGER] = fromqstr(screenfontsModule->screenLargerED->text());
-       rc.font_sizes[LyXFont::SIZE_LARGEST] = fromqstr(screenfontsModule->screenLargestED->text());
-       rc.font_sizes[LyXFont::SIZE_HUGE] = fromqstr(screenfontsModule->screenHugeED->text());
-       rc.font_sizes[LyXFont::SIZE_HUGER] = fromqstr(screenfontsModule->screenHugerED->text());
-
-       if (rc.font_sizes != oldrc.font_sizes
-               || rc.roman_font_name != oldrc.roman_font_name
-               || rc.sans_font_name != oldrc.sans_font_name
-               || rc.typewriter_font_name != oldrc.typewriter_font_name
-               || rc.zoom != oldrc.zoom || rc.dpi != oldrc.dpi) {
-               form_->controller().updateScreenFonts();
-       }
-
-
-
-
-       unsigned int i;
-       for (i = 0; i < colorsModule->lyxObjectsLB->count(); ++i) {
-               Q3ListBoxItem * ib(colorsModule->lyxObjectsLB->item(i));
-               QColorItem * ci(static_cast<QColorItem*>(ib));
-
-               LColor::color const col(colors_[i]);
-               QColor const & qcol(lcolorcache.get(col));
-
-               // FIXME: dubious, but it's what xforms does
-               if (qcol != ci->color()) {
-                       ostringstream ostr;
-
-                       ostr << '#' << std::setbase(16) << setfill('0')
-                            << setw(2) << ci->color().red()
-                            << setw(2) << ci->color().green()
-                            << setw(2) << ci->color().blue();
+       prefsPS->setCurrentPanel(_("User interface"));
 
-                       string newhex(ostr.str());
-                       form_->controller().setColor(col, newhex);
-               }
-       }
+       form_->bcview().setOK(savePB);
+       form_->bcview().setApply(applyPB);
+       form_->bcview().setCancel(closePB);
+       form_->bcview().setRestore(restorePB);
 }
 
-// FIXME: move to helper_funcs.h
-namespace {
 
-template<class A>
-typename std::vector<A>::size_type
-findPos(std::vector<A> const & vec, A const & val)
+QPrefsDialog::~QPrefsDialog()
 {
-       typedef typename std::vector<A>::const_iterator Cit;
-
-       Cit it = std::find(vec.begin(), vec.end(), val);
-       if (it == vec.end())
-               return 0;
-       return distance(vec.begin(), it);
 }
 
-void setComboxFont(QComboBox * cb, string const & family, string const & foundry)
-{
-       string const name = makeFontName(family, foundry);
-       for (int i = 0; i < cb->count(); ++i) {
-               if (fromqstr(cb->text(i)) == name) {
-                       cb->setCurrentItem(i);
-                       return;
-               }
-       }
 
-       // Try matching without foundry name
-
-       // We count in reverse in order to prefer the Xft foundry
-       for (int i = cb->count() - 1; i >= 0; --i) {
-               pair<string, string> tmp = parseFontName(fromqstr(cb->text(i)));
-               if (compare_no_case(tmp.first, family) == 0) {
-                       cb->setCurrentItem(i);
-                       return;
-               }
-       }
-
-       // family alone can contain e.g. "Helvetica [Adobe]"
-       pair<string, string> tmpfam = parseFontName(family);
-
-       // We count in reverse in order to prefer the Xft foundry
-       for (int i = cb->count() - 1; i >= 0; --i) {
-               pair<string, string> tmp = parseFontName(fromqstr(cb->text(i)));
-               if (compare_no_case(tmp.first, tmpfam.first) == 0) {
-                       cb->setCurrentItem(i);
-                       return;
-               }
-       }
+void QPrefsDialog::add(PrefModule * module)
+{
+       BOOST_ASSERT(module);
 
-       // Bleh, default fonts, and the names couldn't be found. Hack
-       // for bug 1063. Qt makes baby Jesus cry.
+//     if (module->category().empty())
+//             prefsPS->addPanel(module, module->title());
+//     else
+               prefsPS->addPanel(module, module->title(), module->category());
 
-       QFont font;
+       connect(module, SIGNAL(changed()), this, SLOT(change_adaptor()));
 
-       if (family == lyx_gui::roman_font_name()) {
-               font.setStyleHint(QFont::Serif);
-               font.setFamily(family.c_str());
-       } else if (family == lyx_gui::sans_font_name()) {
-               font.setStyleHint(QFont::SansSerif);
-               font.setFamily(family.c_str());
-       } else if (family == lyx_gui::typewriter_font_name()) {
-               font.setStyleHint(QFont::TypeWriter);
-               font.setFamily(family.c_str());
-       } else {
-               lyxerr << "FAILED to find the default font: '"
-                      << foundry << "', '" << family << '\''<< endl;
-               return;
-       }
+       modules_.push_back(module);
+}
 
-       QFontInfo info(font);
-       pair<string, string> tmp = parseFontName(fromqstr(info.family()));
-       string const & default_font_name = tmp.first;
-       lyxerr << "Apparent font is " << default_font_name << endl;
+void QPrefsDialog::closeEvent(QCloseEvent * e)
+{
+       form_->slotWMHide();
+       e->accept();
+}
 
-       for (int i = 0; i < cb->count(); ++i) {
-               lyxerr << "Looking at " << fromqstr(cb->text(i)) << endl;
-               if (compare_no_case(fromqstr(cb->text(i)),
-                                   default_font_name) == 0) {
-                       cb->setCurrentItem(i);
-                       return;
-               }
-       }
 
-       lyxerr << "FAILED to find the font: '"
-              << foundry << "', '" << family << '\'' <<endl;
+void QPrefsDialog::change_adaptor()
+{
+       form_->changed();
 }
 
-} // end namespace anon
-
-namespace {
 
-QString const external_path(string const & input)
+void QPrefsDialog::apply(LyXRC & rc) const
 {
-       return toqstr(lyx::support::os::external_path(input));
+       size_t end = modules_.size();
+       for (size_t i = 0; i != end; ++i)
+               modules_[i]->apply(rc);
 }
 
-}
 
 void QPrefsDialog::update(LyXRC const & rc)
 {
-       // FIXME: remove rtl_support bool
-       languageModule->rtlCB->setChecked(rc.rtl_support);
-       languageModule->markForeignCB->setChecked(rc.mark_foreign_language);
-       languageModule->autoBeginCB->setChecked(rc.language_auto_begin);
-       languageModule->autoEndCB->setChecked(rc.language_auto_end);
-       languageModule->useBabelCB->setChecked(rc.language_use_babel);
-       languageModule->globalCB->setChecked(rc.language_global_options);
-       languageModule->languagePackageED->setText(toqstr(rc.language_package));
-       languageModule->startCommandED->setText(toqstr(rc.language_command_begin));
-       languageModule->endCommandED->setText(toqstr(rc.language_command_end));
-
-       int const pos = int(findPos(lang_, rc.default_language));
-       languageModule->defaultLanguageCO->setCurrentItem(pos);
-
-       uiModule->uiFileED->setText(external_path(rc.ui_file));
-       uiModule->bindFileED->setText(external_path(rc.bind_file));
-       uiModule->cursorFollowsCB->setChecked(rc.cursor_follows_scrollbar);
-       // convert to minutes
-       int mins(rc.autosave / 60);
-       if (rc.autosave && !mins)
-               mins = 1;
-       uiModule->autoSaveSB->setValue(mins);
-       uiModule->autoSaveCB->setChecked(rc.make_backup);
-       uiModule->lastfilesSB->setValue(rc.num_lastfiles);
-
-
-       identityModule->nameED->setText(toqstr(rc.user_name));
-       identityModule->emailED->setText(toqstr(rc.user_email));
-
-
-       // FIXME: can derive CB from the two EDs
-       keyboardModule->keymapCB->setChecked(rc.use_kbmap);
-       // no idea why we need these. Fscking Qt.
-       keyboardModule->firstKeymapED->setEnabled(rc.use_kbmap);
-       keyboardModule->firstKeymapPB->setEnabled(rc.use_kbmap);
-       keyboardModule->firstKeymapLA->setEnabled(rc.use_kbmap);
-       keyboardModule->secondKeymapED->setEnabled(rc.use_kbmap);
-       keyboardModule->secondKeymapPB->setEnabled(rc.use_kbmap);
-       keyboardModule->secondKeymapLA->setEnabled(rc.use_kbmap);
-       keyboardModule->firstKeymapED->setText(external_path(rc.primary_kbmap));
-       keyboardModule->secondKeymapED->setText(external_path(rc.secondary_kbmap));
-
-
-
-       asciiModule->asciiLinelengthSB->setValue(rc.ascii_linelen);
-       asciiModule->asciiRoffED->setText(toqstr(rc.ascii_roff_command));
-
-
-
-       dateModule->DateED->setText(toqstr(rc.date_insert_format));
-
-
-
-#if defined(__CYGWIN__) || defined(__CYGWIN32__)
-       cygwinpathModule->pathCB->setChecked(rc.cygwin_path_fix);
-#endif
-
-
-
-       latexModule->latexEncodingED->setText(toqstr(rc.fontenc));
-       latexModule->latexChecktexED->setText(toqstr(rc.chktex_command));
-       latexModule->latexBibtexED->setText(toqstr(rc.bibtex_command));
-       latexModule->latexIndexED->setText(toqstr(rc.index_command));
-       latexModule->latexAutoresetCB->setChecked(rc.auto_reset_options);
-       latexModule->latexDviPaperED->setText(toqstr(rc.view_dvi_paper_option));
-       latexModule->latexPaperSizeCO->setCurrentItem(
-               form_->controller().fromPaperSize(rc.default_papersize));
-
-
-
-       switch (rc.preview) {
-       case LyXRC::PREVIEW_OFF:
-               displayModule->instantPreviewCO->setCurrentItem(0);
-               break;
-       case LyXRC::PREVIEW_NO_MATH :
-               displayModule->instantPreviewCO->setCurrentItem(1);
-               break;
-       case LyXRC::PREVIEW_ON :
-               displayModule->instantPreviewCO->setCurrentItem(2);
-               break;
-       }
-
-       int item = 2;
-       switch (rc.display_graphics) {
-               case lyx::graphics::NoDisplay:          item = 3; break;
-               case lyx::graphics::ColorDisplay:       item = 2; break;
-               case lyx::graphics::GrayscaleDisplay:   item = 1; break;
-               case lyx::graphics::MonochromeDisplay:  item = 0; break;
-               default: break;
-       }
-       displayModule->displayGraphicsCO->setCurrentItem(item);
-
-
-
-       pathsModule->workingDirED->setText(external_path(rc.document_path));
-       pathsModule->templateDirED->setText(external_path(rc.template_path));
-       pathsModule->backupDirED->setText(external_path(rc.backupdir_path));
-       pathsModule->tempDirED->setText(external_path(rc.tempdir_path));
-       pathsModule->pathPrefixED->setText(toqstr(rc.path_prefix));
-       // FIXME: should be a checkbox only
-       pathsModule->lyxserverDirED->setText(external_path(rc.lyxpipes));
-
-
-
-       spellcheckerModule->spellCommandCO->setCurrentItem(0);
-
-       if (rc.isp_command == "ispell") {
-               spellcheckerModule->spellCommandCO->setCurrentItem(0);
-       } else if (rc.isp_command == "aspell") {
-               spellcheckerModule->spellCommandCO->setCurrentItem(1);
-       } else if (rc.isp_command == "hspell") {
-               spellcheckerModule->spellCommandCO->setCurrentItem(2);
-       }
-
-       if (rc.use_spell_lib) {
-#if defined(USE_ASPELL) || defined(USE_PSPELL)
-               spellcheckerModule->spellCommandCO->setCurrentItem(3);
-#endif
-       }
-
-       // FIXME: remove isp_use_alt_lang
-       spellcheckerModule->altLanguageED->setText(toqstr(rc.isp_alt_lang));
-       // FIXME: remove isp_use_esc_chars
-       spellcheckerModule->escapeCharactersED->setText(toqstr(rc.isp_esc_chars));
-       // FIXME: remove isp_use_pers_dict
-       spellcheckerModule->persDictionaryED->setText(external_path(rc.isp_pers_dict));
-       spellcheckerModule->compoundWordCB->setChecked(rc.isp_accept_compound);
-       spellcheckerModule->inputEncodingCB->setChecked(rc.isp_use_input_encoding);
-
-
-
-
-       printerModule->printerAdaptCB->setChecked(rc.print_adapt_output);
-       printerModule->printerCommandED->setText(toqstr(rc.print_command));
-       printerModule->printerNameED->setText(toqstr(rc.printer));
-
-       printerModule->printerPageRangeED->setText(toqstr(rc.print_pagerange_flag));
-       printerModule->printerCopiesED->setText(toqstr(rc.print_copies_flag));
-       printerModule->printerReverseED->setText(toqstr(rc.print_reverse_flag));
-       printerModule->printerToPrinterED->setText(toqstr(rc.print_to_printer));
-       printerModule->printerExtensionED->setText(toqstr(rc.print_file_extension));
-       printerModule->printerSpoolCommandED->setText(toqstr(rc.print_spool_command));
-       printerModule->printerPaperTypeED->setText(toqstr(rc.print_paper_flag));
-       printerModule->printerEvenED->setText(toqstr(rc.print_evenpage_flag));
-       printerModule->printerOddED->setText(toqstr(rc.print_oddpage_flag));
-       printerModule->printerCollatedED->setText(toqstr(rc.print_collcopies_flag));
-       printerModule->printerLandscapeED->setText(toqstr(rc.print_landscape_flag));
-       printerModule->printerToFileED->setText(external_path(rc.print_to_file));
-       printerModule->printerExtraED->setText(toqstr(rc.print_extra_options));
-       printerModule->printerSpoolPrefixED->setText(toqstr(rc.print_spool_printerprefix));
-       printerModule->printerPaperSizeED->setText(toqstr(rc.print_paper_dimension_flag));
-
-
-
-
-       setComboxFont(screenfontsModule->screenRomanCO, rc.roman_font_name,
-                       rc.roman_font_foundry);
-       setComboxFont(screenfontsModule->screenSansCO, rc.sans_font_name,
-                       rc.sans_font_foundry);
-       setComboxFont(screenfontsModule->screenTypewriterCO, rc.typewriter_font_name,
-                       rc.typewriter_font_foundry);
-
-       select_roman(screenfontsModule->screenRomanCO->currentText());
-       select_sans(screenfontsModule->screenSansCO->currentText());
-       select_typewriter(screenfontsModule->screenTypewriterCO->currentText());
-
-       screenfontsModule->screenZoomSB->setValue(rc.zoom);
-       screenfontsModule->screenDpiSB->setValue(rc.dpi);
-       screenfontsModule->screenTinyED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_TINY]));
-       screenfontsModule->screenSmallestED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_SCRIPT]));
-       screenfontsModule->screenSmallerED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_FOOTNOTE]));
-       screenfontsModule->screenSmallED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_SMALL]));
-       screenfontsModule->screenNormalED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_NORMAL]));
-       screenfontsModule->screenLargeED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_LARGE]));
-       screenfontsModule->screenLargerED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_LARGER]));
-       screenfontsModule->screenLargestED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_LARGEST]));
-       screenfontsModule->screenHugeED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_HUGE]));
-       screenfontsModule->screenHugerED->setText(toqstr(rc.font_sizes[LyXFont::SIZE_HUGER]));
-
-       updateFormats();
-       updateConverters();
-       updateCopiers();
-
+       size_t end = modules_.size();
+       for (size_t i = 0; i != end; ++i)
+               modules_[i]->update(rc);
 }
 
 
 } // namespace frontend
 } // namespace lyx
+
+#include "QPrefsDialog_moc.cpp"