]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/GuiPrefs.cpp
Use <cstdint> instead of <boost/cstdint.hpp>
[lyx.git] / src / frontends / qt4 / GuiPrefs.cpp
index d56d3b068104371d5f95c21578f10f3ee3fbf795..82073bcbe7cbb07e6d9786e6b31184e6ecec89a6 100644 (file)
@@ -19,6 +19,8 @@
 #include "GuiFontExample.h"
 #include "GuiFontLoader.h"
 #include "GuiKeySymbol.h"
+#include "GuiLyXFiles.h"
+#include "GuiView.h"
 #include "qt_helpers.h"
 #include "Validator.h"
 
 #include "LyXAction.h"
 #include "LyX.h"
 #include "PanelStack.h"
-#include "paper.h"
 #include "Session.h"
 #include "SpellChecker.h"
 
 #include "support/debug.h"
 #include "support/FileName.h"
 #include "support/filetools.h"
-#include "support/foreach.h"
 #include "support/gettext.h"
 #include "support/lassert.h"
 #include "support/lstrings.h"
+#include "support/Messages.h"
 #include "support/os.h"
 #include "support/Package.h"
 
@@ -62,7 +63,6 @@
 #include <QHeaderView>
 #include <QLineEdit>
 #include <QMessageBox>
-#include <QPixmapCache>
 #include <QPushButton>
 #include <QSpinBox>
 #include <QString>
@@ -73,6 +73,7 @@
 #include <iomanip>
 #include <sstream>
 #include <algorithm>
+#include <math.h>
 
 using namespace Ui;
 
@@ -111,8 +112,8 @@ QString browseFile(QString const & filename,
        else if(!fallback_dir.isEmpty())
                lastPath = fallback_dir;
 
-       FileDialog dlg(title, LFUN_SELECT_FILE_SYNC);
-       dlg.setButton2(label1, dir1);
+       FileDialog dlg(title);
+       dlg.setButton1(label1, dir1);
        dlg.setButton2(label2, dir2);
 
        FileDialog::Result result;
@@ -126,46 +127,6 @@ QString browseFile(QString const & filename,
 }
 
 
-/** Wrapper around browseFile which tries to provide a filename
-*  relative to the user or system directory. The dir, name and ext
-*  parameters have the same meaning as in the
-*  support::LibFileSearch function.
-*/
-QString browseLibFile(QString const & dir,
-       QString const & name,
-       QString const & ext,
-       QString const & title,
-       QStringList const & filters)
-{
-       // FIXME UNICODE
-       QString const label1 = qt_("System files|#S#s");
-       QString const dir1 =
-               toqstr(addName(package().system_support().absFileName(), fromqstr(dir)));
-
-       QString const label2 = qt_("User files|#U#u");
-       QString const dir2 =
-               toqstr(addName(package().user_support().absFileName(), fromqstr(dir)));
-
-       QString const result = browseFile(toqstr(
-               libFileSearch(dir, name, ext).absFileName()),
-               title, filters, false, dir1, dir2, QString(), QString(), dir1);
-
-       // remove the extension if it is the default one
-       QString noextresult;
-       if (getExtension(result) == ext)
-               noextresult = removeExtension(result);
-       else
-               noextresult = result;
-
-       // remove the directory, if it is the default one
-       QString const file = onlyFileName(noextresult);
-       if (toqstr(libFileSearch(dir, file, ext).absFileName()) == result)
-               return file;
-       else
-               return noextresult;
-}
-
-
 /** Launch a file dialog and return the chosen directory.
        pathname: a suggested pathname.
        title: the title of the dialog.
@@ -182,7 +143,7 @@ QString browseDir(QString const & pathname,
        if (!pathname.isEmpty())
                lastPath = onlyPath(pathname);
 
-       FileDialog dlg(title, LFUN_SELECT_FILE_SYNC);
+       FileDialog dlg(title);
        dlg.setButton1(label1, dir1);
        dlg.setButton2(label2, dir2);
 
@@ -231,7 +192,7 @@ QString browseRelToSub(QString const & filename, QString const & relpath,
 
        QString testname = reloutname;
        testname.remove(QRegExp("^(\\.\\./)+"));
-       
+
        if (testname.contains("/"))
                return outname;
        else
@@ -248,11 +209,11 @@ QString browseRelToSub(QString const & filename, QString const & relpath,
 
 namespace frontend {
 
-string const catLookAndFeel = N_("Look & Feel");
-string const catEditing = N_("Editing");
-string const catLanguage = N_("Language Settings");
-string const catOutput = N_("Output");
-string const catFiles = N_("File Handling");
+QString const catLookAndFeel = N_("Look & Feel");
+QString const catEditing = N_("Editing");
+QString const catLanguage = N_("Language Settings");
+QString const catOutput = N_("Output");
+QString const catFiles = N_("File Handling");
 
 static void parseFontName(QString const & mangled0,
        string & name, string & foundry)
@@ -287,8 +248,8 @@ static void setComboxFont(QComboBox * cb, string const & family,
 
        // We count in reverse in order to prefer the Xft foundry
        for (int i = cb->count(); --i >= 0;) {
-               string name, foundry;
-               parseFontName(cb->itemText(i), name, foundry);
+               string name, fnt_foundry;
+               parseFontName(cb->itemText(i), name, fnt_foundry);
                if (compare_ascii_no_case(name, family) == 0) {
                        cb->setCurrentIndex(i);
                        return;
@@ -301,9 +262,9 @@ static void setComboxFont(QComboBox * cb, string const & family,
 
        // We count in reverse in order to prefer the Xft foundry
        for (int i = cb->count(); --i >= 0; ) {
-               string name, foundry;
-               parseFontName(cb->itemText(i), name, foundry);
-               if (compare_ascii_no_case(name, foundry) == 0) {
+               string name, fnt_foundry;
+               parseFontName(cb->itemText(i), name, fnt_foundry);
+               if (compare_ascii_no_case(name, fnt_foundry) == 0) {
                        cb->setCurrentIndex(i);
                        return;
                }
@@ -313,7 +274,6 @@ static void setComboxFont(QComboBox * cb, string const & family,
        // for bug 1063.
 
        QFont font;
-       font.setKerning(false);
 
        QString const font_family = toqstr(family);
        if (font_family == guiApp->romanFontName()) {
@@ -350,35 +310,6 @@ static void setComboxFont(QComboBox * cb, string const & family,
 }
 
 
-/////////////////////////////////////////////////////////////////////
-//
-// StrftimeValidator
-//
-/////////////////////////////////////////////////////////////////////
-
-class StrftimeValidator : public QValidator
-{
-public:
-       StrftimeValidator(QWidget *);
-       QValidator::State validate(QString & input, int & pos) const;
-};
-
-
-StrftimeValidator::StrftimeValidator(QWidget * parent)
-       : QValidator(parent)
-{
-}
-
-
-QValidator::State StrftimeValidator::validate(QString & input, int & /*pos*/) const
-{
-       if (is_valid_strftime(fromqstr(input)))
-               return QValidator::Acceptable;
-       else
-               return QValidator::Intermediate;
-}
-
-
 /////////////////////////////////////////////////////////////////////
 //
 // PrefOutput
@@ -386,16 +317,13 @@ QValidator::State StrftimeValidator::validate(QString & input, int & /*pos*/) co
 /////////////////////////////////////////////////////////////////////
 
 PrefOutput::PrefOutput(GuiPreferences * form)
-       : PrefModule(qt_(catOutput), qt_("General"), form)
+       : PrefModule(catOutput, N_("General"), form)
 {
        setupUi(this);
 
-       DateED->setValidator(new StrftimeValidator(DateED));
        dviCB->setValidator(new NoNewLineValidator(dviCB));
        pdfCB->setValidator(new NoNewLineValidator(pdfCB));
 
-       connect(DateED, SIGNAL(textChanged(QString)),
-               this, SIGNAL(changed()));
        connect(plaintextLinelengthSB, SIGNAL(valueChanged(int)),
                this, SIGNAL(changed()));
        connect(overwriteCO, SIGNAL(activated(int)),
@@ -404,33 +332,35 @@ PrefOutput::PrefOutput(GuiPreferences * form)
                this, SIGNAL(changed()));
        connect(pdfCB, SIGNAL(editTextChanged(QString)),
                this, SIGNAL(changed()));
+       connect(printerPaperTypeED, SIGNAL(textChanged(QString)),
+               this, SIGNAL(changed()));
+       connect(printerLandscapeED, SIGNAL(textChanged(QString)),
+               this, SIGNAL(changed()));
+       connect(printerPaperSizeED, SIGNAL(textChanged(QString)),
+               this, SIGNAL(changed()));
+
+       printerPaperTypeED->setValidator(new NoNewLineValidator(printerPaperTypeED));
+       printerLandscapeED->setValidator(new NoNewLineValidator(printerLandscapeED));
+       printerPaperSizeED->setValidator(new NoNewLineValidator(printerPaperSizeED));
+
        dviCB->addItem("");
        dviCB->addItem("xdvi -sourceposition '$$n:\\ $$t' $$o");
        dviCB->addItem("yap -1 -s \"$$n $$t\" $$o");
-       dviCB->addItem("okular --unique \"file:$$o#src:$$n $$t\"");
+       dviCB->addItem("okular --unique \"$$o#src:$$n $$f\"");
        dviCB->addItem("synctex view -i $$n:0:$$t -o $$o -x \"evince -i %{page+1} $$o\"");
        pdfCB->addItem("");
        pdfCB->addItem("CMCDDE SUMATRA control [ForwardSearch(\\\"$$o\\\",\\\"$$t\\\",$$n,0,0,1)]");
+       pdfCB->addItem("SumatraPDF -reuse-instance \"$$o\" -forward-search \"$$t\" $$n");
        pdfCB->addItem("synctex view -i $$n:0:$$t -o $$o -x \"xpdf -raise -remote $$t.tmp $$o %{page+1}\"");
-       pdfCB->addItem("okular --unique \"file:$$o#src:$$n $$t\"");
+       pdfCB->addItem("okular --unique \"$$o#src:$$n $$f\"");
+       pdfCB->addItem("qpdfview --unique \"$$o#src:$$f:$$n:0\"");
        pdfCB->addItem("synctex view -i $$n:0:$$t -o $$o -x \"evince -i %{page+1} $$o\"");
        pdfCB->addItem("/Applications/Skim.app/Contents/SharedSupport/displayline $$n $$o $$t");
 }
 
 
-void PrefOutput::on_DateED_textChanged(const QString &)
-{
-       QString t = DateED->text();
-       int p = 0;
-       bool valid = DateED->validator()->validate(t, p)
-                    == QValidator::Acceptable;
-       setValid(DateLA, valid);
-}
-
-
-void PrefOutput::apply(LyXRC & rc) const
+void PrefOutput::applyRC(LyXRC & rc) const
 {
-       rc.date_insert_format = fromqstr(DateED->text());
        rc.plaintext_linelen = plaintextLinelengthSB->value();
        rc.forward_search_dvi = fromqstr(dviCB->currentText());
        rc.forward_search_pdf = fromqstr(pdfCB->currentText());
@@ -446,12 +376,15 @@ void PrefOutput::apply(LyXRC & rc) const
                rc.export_overwrite = ALL_FILES;
                break;
        }
+
+       rc.print_paper_flag = fromqstr(printerPaperTypeED->text());
+       rc.print_landscape_flag = fromqstr(printerLandscapeED->text());
+       rc.print_paper_dimension_flag = fromqstr(printerPaperSizeED->text());
 }
 
 
-void PrefOutput::update(LyXRC const & rc)
+void PrefOutput::updateRC(LyXRC const & rc)
 {
-       DateED->setText(toqstr(rc.date_insert_format));
        plaintextLinelengthSB->setValue(rc.plaintext_linelen);
        dviCB->setEditText(toqstr(rc.forward_search_dvi));
        pdfCB->setEditText(toqstr(rc.forward_search_pdf));
@@ -467,6 +400,10 @@ void PrefOutput::update(LyXRC const & rc)
                overwriteCO->setCurrentIndex(2);
                break;
        }
+
+       printerPaperTypeED->setText(toqstr(rc.print_paper_flag));
+       printerLandscapeED->setText(toqstr(rc.print_landscape_flag));
+       printerPaperSizeED->setText(toqstr(rc.print_paper_dimension_flag));
 }
 
 
@@ -477,7 +414,7 @@ void PrefOutput::update(LyXRC const & rc)
 /////////////////////////////////////////////////////////////////////
 
 PrefInput::PrefInput(GuiPreferences * form)
-       : PrefModule(qt_(catEditing), qt_("Keyboard/Mouse"), form)
+       : PrefModule(catEditing, N_("Keyboard/Mouse"), form)
 {
        setupUi(this);
 
@@ -495,10 +432,12 @@ PrefInput::PrefInput(GuiPreferences * form)
                this, SIGNAL(changed()));
        connect(dontswapCB, SIGNAL(toggled(bool)),
                this, SIGNAL(changed()));
+       connect(mmPasteCB, SIGNAL(toggled(bool)),
+               this, SIGNAL(changed()));
 
        // reveal checkbox for switching Ctrl and Meta on Mac:
        bool swapcb = false;
-#ifdef Q_WS_MACX
+#ifdef Q_OS_MAC
 #if QT_VERSION > 0x040600
        swapcb = true;
 #endif
@@ -507,7 +446,7 @@ PrefInput::PrefInput(GuiPreferences * form)
 }
 
 
-void PrefInput::apply(LyXRC & rc) const
+void PrefInput::applyRC(LyXRC & rc) const
 {
        // FIXME: can derive CB from the two EDs
        rc.use_kbmap = keymapCB->isChecked();
@@ -530,10 +469,11 @@ void PrefInput::apply(LyXRC & rc) const
                rc.scroll_wheel_zoom = LyXRC::SCROLL_WHEEL_ZOOM_OFF;
        }
        rc.mac_dontswap_ctrl_meta  = dontswapCB->isChecked();
+       rc.mouse_middlebutton_paste = mmPasteCB->isChecked();
 }
 
 
-void PrefInput::update(LyXRC const & rc)
+void PrefInput::updateRC(LyXRC const & rc)
 {
        // FIXME: can derive CB from the two EDs
        keymapCB->setChecked(rc.use_kbmap);
@@ -558,6 +498,7 @@ void PrefInput::update(LyXRC const & rc)
                break;
        }
        dontswapCB->setChecked(rc.mac_dontswap_ctrl_meta);
+       mmPasteCB->setChecked(rc.mouse_middlebutton_paste);
 }
 
 
@@ -598,8 +539,8 @@ void PrefInput::on_scrollzoomEnableCB_toggled(bool enabled)
 {
        scrollzoomValueCO->setEnabled(enabled);
 }
-       
-       
+
+
 /////////////////////////////////////////////////////////////////////
 //
 // PrefCompletion
@@ -607,7 +548,7 @@ void PrefInput::on_scrollzoomEnableCB_toggled(bool enabled)
 /////////////////////////////////////////////////////////////////////
 
 PrefCompletion::PrefCompletion(GuiPreferences * form)
-       : PrefModule(qt_(catEditing), qt_("Input Completion"), form)
+       : PrefModule(catEditing, N_("Input Completion"), form)
 {
        setupUi(this);
 
@@ -631,6 +572,8 @@ PrefCompletion::PrefCompletion(GuiPreferences * form)
                this, SIGNAL(changed()));
        connect(cursorTextCB, SIGNAL(clicked()),
                this, SIGNAL(changed()));
+       connect(minlengthSB, SIGNAL(valueChanged(int)),
+                       this, SIGNAL(changed()));
 }
 
 
@@ -653,7 +596,7 @@ void PrefCompletion::enableCB()
 }
 
 
-void PrefCompletion::apply(LyXRC & rc) const
+void PrefCompletion::applyRC(LyXRC & rc) const
 {
        rc.completion_inline_delay = inlineDelaySB->value();
        rc.completion_inline_math = inlineMathCB->isChecked();
@@ -666,10 +609,11 @@ void PrefCompletion::apply(LyXRC & rc) const
        rc.completion_cursor_text = cursorTextCB->isChecked();
        rc.completion_popup_after_complete =
                popupAfterCompleteCB->isChecked();
+       rc.completion_minlength = minlengthSB->value();
 }
 
 
-void PrefCompletion::update(LyXRC const & rc)
+void PrefCompletion::updateRC(LyXRC const & rc)
 {
        inlineDelaySB->setValue(rc.completion_inline_delay);
        inlineMathCB->setChecked(rc.completion_inline_math);
@@ -681,7 +625,8 @@ void PrefCompletion::update(LyXRC const & rc)
        popupTextCB->setChecked(rc.completion_popup_text);
        cursorTextCB->setChecked(rc.completion_cursor_text);
        popupAfterCompleteCB->setChecked(rc.completion_popup_after_complete);
-        enableCB();
+       enableCB();
+       minlengthSB->setValue(rc.completion_minlength);
 }
 
 
@@ -693,11 +638,10 @@ void PrefCompletion::update(LyXRC const & rc)
 /////////////////////////////////////////////////////////////////////
 
 PrefLatex::PrefLatex(GuiPreferences * form)
-       : PrefModule(qt_(catOutput), qt_("LaTeX"), form)
+       : PrefModule(catOutput, N_("LaTeX"), form)
 {
        setupUi(this);
 
-       latexEncodingED->setValidator(new NoNewLineValidator(latexEncodingED));
        latexDviPaperED->setValidator(new NoNewLineValidator(latexDviPaperED));
        latexBibtexED->setValidator(new NoNewLineValidator(latexBibtexED));
        latexJBibtexED->setValidator(new NoNewLineValidator(latexJBibtexED));
@@ -706,16 +650,14 @@ PrefLatex::PrefLatex(GuiPreferences * form)
        latexNomenclED->setValidator(new NoNewLineValidator(latexNomenclED));
        latexChecktexED->setValidator(new NoNewLineValidator(latexChecktexED));
 
-       connect(latexEncodingCB, SIGNAL(clicked()),
-               this, SIGNAL(changed()));
-       connect(latexEncodingED, SIGNAL(textChanged(QString)),
-               this, SIGNAL(changed()));
        connect(latexChecktexED, SIGNAL(textChanged(QString)),
                this, SIGNAL(changed()));
        connect(latexBibtexCO, SIGNAL(activated(int)),
                this, SIGNAL(changed()));
        connect(latexBibtexED, SIGNAL(textChanged(QString)),
                this, SIGNAL(changed()));
+       connect(latexJBibtexCO, SIGNAL(activated(int)),
+               this, SIGNAL(changed()));
        connect(latexJBibtexED, SIGNAL(textChanged(QString)),
                this, SIGNAL(changed()));
        connect(latexIndexCO, SIGNAL(activated(int)),
@@ -728,8 +670,6 @@ PrefLatex::PrefLatex(GuiPreferences * form)
                this, SIGNAL(changed()));
        connect(latexDviPaperED, SIGNAL(textChanged(QString)),
                this, SIGNAL(changed()));
-       connect(latexPaperSizeCO, SIGNAL(activated(int)),
-               this, SIGNAL(changed()));
        connect(latexNomenclED, SIGNAL(textChanged(QString)),
                this, SIGNAL(changed()));
 
@@ -743,18 +683,12 @@ PrefLatex::PrefLatex(GuiPreferences * form)
 }
 
 
-void PrefLatex::on_latexEncodingCB_stateChanged(int state)
-{
-       latexEncodingED->setEnabled(state == Qt::Checked);
-}
-
-
 void PrefLatex::on_latexBibtexCO_activated(int n)
 {
        QString const bibtex = latexBibtexCO->itemData(n).toString();
        if (bibtex.isEmpty()) {
                latexBibtexED->clear();
-               latexBibtexOptionsLA->setText(qt_("Co&mmand:"));
+               latexBibtexOptionsLA->setText(qt_("C&ommand:"));
                return;
        }
        for (LyXRC::CommandSet::const_iterator it = bibtex_alternatives.begin();
@@ -774,6 +708,31 @@ void PrefLatex::on_latexBibtexCO_activated(int n)
 }
 
 
+void PrefLatex::on_latexJBibtexCO_activated(int n)
+{
+       QString const jbibtex = latexJBibtexCO->itemData(n).toString();
+       if (jbibtex.isEmpty()) {
+               latexJBibtexED->clear();
+               latexJBibtexOptionsLA->setText(qt_("Co&mmand:"));
+               return;
+       }
+       for (LyXRC::CommandSet::const_iterator it = jbibtex_alternatives.begin();
+            it != jbibtex_alternatives.end(); ++it) {
+               QString const bib = toqstr(*it);
+               int ind = bib.indexOf(" ");
+               QString sel_command = bib.left(ind);
+               QString sel_options = ind < 0 ? QString() : bib.mid(ind + 1);
+               if (jbibtex == sel_command) {
+                       if (ind < 0)
+                               latexJBibtexED->clear();
+                       else
+                               latexJBibtexED->setText(sel_options.trimmed());
+               }
+       }
+       latexJBibtexOptionsLA->setText(qt_("Opt&ions:"));
+}
+
+
 void PrefLatex::on_latexIndexCO_activated(int n)
 {
        QString const index = latexIndexCO->itemData(n).toString();
@@ -799,7 +758,7 @@ void PrefLatex::on_latexIndexCO_activated(int n)
 }
 
 
-void PrefLatex::apply(LyXRC & rc) const
+void PrefLatex::applyRC(LyXRC & rc) const
 {
        // If bibtex is not empty, bibopt contains the options, otherwise
        // it is a customized bibtex command with options.
@@ -813,6 +772,18 @@ void PrefLatex::apply(LyXRC & rc) const
        else
                rc.bibtex_command = fromqstr(bibtex) + " " + fromqstr(bibopt);
 
+       // If jbibtex is not empty, jbibopt contains the options, otherwise
+       // it is a customized bibtex command with options.
+       QString const jbibtex = latexJBibtexCO->itemData(
+               latexJBibtexCO->currentIndex()).toString();
+       QString const jbibopt = latexJBibtexED->text();
+       if (jbibtex.isEmpty())
+               rc.jbibtex_command = fromqstr(jbibopt);
+       else if (jbibopt.isEmpty())
+               rc.jbibtex_command = fromqstr(jbibtex);
+       else
+               rc.jbibtex_command = fromqstr(jbibtex) + " " + fromqstr(jbibopt);
+
        // If index is not empty, idxopt contains the options, otherwise
        // it is a customized index command with options.
        QString const index = latexIndexCO->itemData(
@@ -825,28 +796,22 @@ void PrefLatex::apply(LyXRC & rc) const
        else
                rc.index_command = fromqstr(index) + " " + fromqstr(idxopt);
 
-       if (latexEncodingCB->isChecked())
-               rc.fontenc = fromqstr(latexEncodingED->text());
-       else
-               rc.fontenc = "default";
        rc.chktex_command = fromqstr(latexChecktexED->text());
-       rc.jbibtex_command = fromqstr(latexJBibtexED->text());
        rc.jindex_command = fromqstr(latexJIndexED->text());
        rc.nomencl_command = fromqstr(latexNomenclED->text());
        rc.auto_reset_options = latexAutoresetCB->isChecked();
        rc.view_dvi_paper_option = fromqstr(latexDviPaperED->text());
-       rc.default_papersize =
-               form_->toPaperSize(latexPaperSizeCO->currentIndex());
 #if defined(__CYGWIN__) || defined(_WIN32)
        rc.windows_style_tex_paths = pathCB->isChecked();
 #endif
 }
 
 
-void PrefLatex::update(LyXRC const & rc)
+void PrefLatex::updateRC(LyXRC const & rc)
 {
        latexBibtexCO->clear();
 
+       latexBibtexCO->addItem(qt_("Automatic"), "automatic");
        latexBibtexCO->addItem(qt_("Custom"), QString());
        for (LyXRC::CommandSet::const_iterator it = rc.bibtex_alternatives.begin();
                             it != rc.bibtex_alternatives.end(); ++it) {
@@ -869,7 +834,35 @@ void PrefLatex::update(LyXRC const & rc)
        } else {
                latexBibtexED->setText(toqstr(rc.bibtex_command));
                latexBibtexCO->setCurrentIndex(0);
-               latexBibtexOptionsLA->setText(qt_("Co&mmand:"));
+               latexBibtexOptionsLA->setText(qt_("C&ommand:"));
+       }
+
+       latexJBibtexCO->clear();
+
+       latexJBibtexCO->addItem(qt_("Automatic"), "automatic");
+       latexJBibtexCO->addItem(qt_("Custom"), QString());
+       for (LyXRC::CommandSet::const_iterator it = rc.jbibtex_alternatives.begin();
+                            it != rc.jbibtex_alternatives.end(); ++it) {
+               QString const command = toqstr(*it).left(toqstr(*it).indexOf(" "));
+               latexJBibtexCO->addItem(command, command);
+       }
+
+       jbibtex_alternatives = rc.jbibtex_alternatives;
+
+       QString const jbib = toqstr(rc.jbibtex_command);
+       ind = jbib.indexOf(" ");
+       sel_command = jbib.left(ind);
+       sel_options = ind < 0 ? QString() : jbib.mid(ind + 1);
+
+       pos = latexJBibtexCO->findData(sel_command);
+       if (pos != -1) {
+               latexJBibtexCO->setCurrentIndex(pos);
+               latexJBibtexED->setText(sel_options.trimmed());
+               latexJBibtexOptionsLA->setText(qt_("Opt&ions:"));
+       } else {
+               latexJBibtexED->setText(toqstr(rc.bibtex_command));
+               latexJBibtexCO->setCurrentIndex(0);
+               latexJBibtexOptionsLA->setText(qt_("Co&mmand:"));
        }
 
        latexIndexCO->clear();
@@ -899,22 +892,11 @@ void PrefLatex::update(LyXRC const & rc)
                latexIndexOptionsLA->setText(qt_("Co&mmand:"));
        }
 
-       if (rc.fontenc == "default") {
-               latexEncodingCB->setChecked(false);
-               latexEncodingED->setEnabled(false);
-       } else {
-               latexEncodingCB->setChecked(true);
-               latexEncodingED->setEnabled(true);
-               latexEncodingED->setText(toqstr(rc.fontenc));
-       }
        latexChecktexED->setText(toqstr(rc.chktex_command));
-       latexJBibtexED->setText(toqstr(rc.jbibtex_command));
        latexJIndexED->setText(toqstr(rc.jindex_command));
        latexNomenclED->setText(toqstr(rc.nomencl_command));
        latexAutoresetCB->setChecked(rc.auto_reset_options);
        latexDviPaperED->setText(toqstr(rc.view_dvi_paper_option));
-       latexPaperSizeCO->setCurrentIndex(
-               form_->fromPaperSize(rc.default_papersize));
 #if defined(__CYGWIN__) || defined(_WIN32)
        pathCB->setChecked(rc.windows_style_tex_paths);
 #endif
@@ -928,7 +910,7 @@ void PrefLatex::update(LyXRC const & rc)
 /////////////////////////////////////////////////////////////////////
 
 PrefScreenFonts::PrefScreenFonts(GuiPreferences * form)
-       : PrefModule(qt_(catLookAndFeel), qt_("Screen Fonts"), form)
+       : PrefModule(catLookAndFeel, N_("Screen Fonts"), form)
 {
        setupUi(this);
 
@@ -974,8 +956,6 @@ PrefScreenFonts::PrefScreenFonts(GuiPreferences * form)
                this, SIGNAL(changed()));
        connect(screenHugerED, SIGNAL(textChanged(QString)),
                this, SIGNAL(changed()));
-       connect(pixmapCacheCB, SIGNAL(toggled(bool)),
-               this, SIGNAL(changed()));
 
        screenTinyED->setValidator(new QDoubleValidator(screenTinyED));
        screenSmallestED->setValidator(new QDoubleValidator(screenSmallestED));
@@ -990,7 +970,7 @@ PrefScreenFonts::PrefScreenFonts(GuiPreferences * form)
 }
 
 
-void PrefScreenFonts::apply(LyXRC & rc) const
+void PrefScreenFonts::applyRC(LyXRC & rc) const
 {
        LyXRC const oldrc = rc;
 
@@ -1001,35 +981,21 @@ void PrefScreenFonts::apply(LyXRC & rc) const
        parseFontName(screenTypewriterCO->currentText(),
                rc.typewriter_font_name, rc.typewriter_font_foundry);
 
-       rc.zoom = screenZoomSB->value();
-       rc.font_sizes[FONT_SIZE_TINY] = widgetToDoubleStr(screenTinyED);
-       rc.font_sizes[FONT_SIZE_SCRIPT] = widgetToDoubleStr(screenSmallestED);
-       rc.font_sizes[FONT_SIZE_FOOTNOTE] = widgetToDoubleStr(screenSmallerED);
-       rc.font_sizes[FONT_SIZE_SMALL] = widgetToDoubleStr(screenSmallED);
-       rc.font_sizes[FONT_SIZE_NORMAL] = widgetToDoubleStr(screenNormalED);
-       rc.font_sizes[FONT_SIZE_LARGE] = widgetToDoubleStr(screenLargeED);
-       rc.font_sizes[FONT_SIZE_LARGER] = widgetToDoubleStr(screenLargerED);
-       rc.font_sizes[FONT_SIZE_LARGEST] = widgetToDoubleStr(screenLargestED);
-       rc.font_sizes[FONT_SIZE_HUGE] = widgetToDoubleStr(screenHugeED);
-       rc.font_sizes[FONT_SIZE_HUGER] = widgetToDoubleStr(screenHugerED);
-       rc.use_pixmap_cache = pixmapCacheCB->isChecked();
-
-       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) {
-               // The global QPixmapCache is used in GuiPainter to cache text
-               // painting so we must reset it in case any of the above
-               // parameter is changed.
-               QPixmapCache::clear();
-               guiApp->fontLoader().update();
-               form_->updateScreenFonts();
-       }
+       rc.defaultZoom = screenZoomSB->value();
+       rc.font_sizes[TINY_SIZE] = widgetToDoubleStr(screenTinyED);
+       rc.font_sizes[SCRIPT_SIZE] = widgetToDoubleStr(screenSmallestED);
+       rc.font_sizes[FOOTNOTE_SIZE] = widgetToDoubleStr(screenSmallerED);
+       rc.font_sizes[SMALL_SIZE] = widgetToDoubleStr(screenSmallED);
+       rc.font_sizes[NORMAL_SIZE] = widgetToDoubleStr(screenNormalED);
+       rc.font_sizes[LARGE_SIZE] = widgetToDoubleStr(screenLargeED);
+       rc.font_sizes[LARGER_SIZE] = widgetToDoubleStr(screenLargerED);
+       rc.font_sizes[LARGEST_SIZE] = widgetToDoubleStr(screenLargestED);
+       rc.font_sizes[HUGE_SIZE] = widgetToDoubleStr(screenHugeED);
+       rc.font_sizes[HUGER_SIZE] = widgetToDoubleStr(screenHugerED);
 }
 
 
-void PrefScreenFonts::update(LyXRC const & rc)
+void PrefScreenFonts::updateRC(LyXRC const & rc)
 {
        setComboxFont(screenRomanCO, rc.roman_font_name,
                        rc.roman_font_foundry);
@@ -1042,29 +1008,23 @@ void PrefScreenFonts::update(LyXRC const & rc)
        selectSans(screenSansCO->currentText());
        selectTypewriter(screenTypewriterCO->currentText());
 
-       screenZoomSB->setValue(rc.zoom);
+       screenZoomSB->setValue(rc.defaultZoom);
        updateScreenFontSizes(rc);
-
-       pixmapCacheCB->setChecked(rc.use_pixmap_cache);
-#if defined(Q_WS_X11)
-       pixmapCacheCB->setEnabled(false);
-#endif
-
 }
 
 
 void PrefScreenFonts::updateScreenFontSizes(LyXRC const & rc)
 {
-       doubleToWidget(screenTinyED, rc.font_sizes[FONT_SIZE_TINY]);
-       doubleToWidget(screenSmallestED, rc.font_sizes[FONT_SIZE_SCRIPT]);
-       doubleToWidget(screenSmallerED, rc.font_sizes[FONT_SIZE_FOOTNOTE]);
-       doubleToWidget(screenSmallED, rc.font_sizes[FONT_SIZE_SMALL]);
-       doubleToWidget(screenNormalED, rc.font_sizes[FONT_SIZE_NORMAL]);
-       doubleToWidget(screenLargeED, rc.font_sizes[FONT_SIZE_LARGE]);
-       doubleToWidget(screenLargerED, rc.font_sizes[FONT_SIZE_LARGER]);
-       doubleToWidget(screenLargestED, rc.font_sizes[FONT_SIZE_LARGEST]);
-       doubleToWidget(screenHugeED, rc.font_sizes[FONT_SIZE_HUGE]);
-       doubleToWidget(screenHugerED, rc.font_sizes[FONT_SIZE_HUGER]);
+       doubleToWidget(screenTinyED, rc.font_sizes[TINY_SIZE]);
+       doubleToWidget(screenSmallestED, rc.font_sizes[SCRIPT_SIZE]);
+       doubleToWidget(screenSmallerED, rc.font_sizes[FOOTNOTE_SIZE]);
+       doubleToWidget(screenSmallED, rc.font_sizes[SMALL_SIZE]);
+       doubleToWidget(screenNormalED, rc.font_sizes[NORMAL_SIZE]);
+       doubleToWidget(screenLargeED, rc.font_sizes[LARGE_SIZE]);
+       doubleToWidget(screenLargerED, rc.font_sizes[LARGER_SIZE]);
+       doubleToWidget(screenLargestED, rc.font_sizes[LARGEST_SIZE]);
+       doubleToWidget(screenHugeED, rc.font_sizes[HUGE_SIZE]);
+       doubleToWidget(screenHugerED, rc.font_sizes[HUGER_SIZE]);
 }
 
 
@@ -1092,20 +1052,9 @@ void PrefScreenFonts::selectTypewriter(const QString & name)
 //
 /////////////////////////////////////////////////////////////////////
 
-namespace {
-
-struct ColorSorter
-{
-       bool operator()(ColorCode lhs, ColorCode rhs) const {
-               return 
-                       compare_no_case(lcolor.getGUIName(lhs), lcolor.getGUIName(rhs)) < 0;
-       }
-};
-
-} // namespace anon
 
 PrefColors::PrefColors(GuiPreferences * form)
-       : PrefModule(qt_(catLookAndFeel), qt_("Colors"), form)
+       : PrefModule(catLookAndFeel, N_("Colors"), form)
 {
        setupUi(this);
 
@@ -1118,18 +1067,29 @@ PrefColors::PrefColors(GuiPreferences * form)
                if (lc == Color_none
                    || lc == Color_black
                    || lc == Color_white
-                   || lc == Color_red
-                   || lc == Color_green
                    || lc == Color_blue
+                   || lc == Color_brown
                    || lc == Color_cyan
+                   || lc == Color_darkgray
+                   || lc == Color_gray
+                   || lc == Color_green
+                   || lc == Color_lightgray
+                   || lc == Color_lime
                    || lc == Color_magenta
+                   || lc == Color_olive
+                   || lc == Color_orange
+                   || lc == Color_pink
+                   || lc == Color_purple
+                   || lc == Color_red
+                   || lc == Color_teal
+                   || lc == Color_violet
                    || lc == Color_yellow
                    || lc == Color_inherit
                    || lc == Color_ignore)
                        continue;
                lcolors_.push_back(lc);
        }
-       sort(lcolors_.begin(), lcolors_.end(), ColorSorter());
+       qSort(lcolors_.begin(), lcolors_.end(), ColorSorter);
        vector<ColorCode>::const_iterator cit = lcolors_.begin();
        vector<ColorCode>::const_iterator const end = lcolors_.end();
        for (; cit != end; ++cit) {
@@ -1142,6 +1102,10 @@ PrefColors::PrefColors(GuiPreferences * form)
 
        connect(colorChangePB, SIGNAL(clicked()),
                this, SLOT(changeColor()));
+       connect(colorResetPB, SIGNAL(clicked()),
+               this, SLOT(resetColor()));
+       connect(colorResetAllPB, SIGNAL(clicked()),
+               this, SLOT(resetAllColor()));
        connect(lyxObjectsLW, SIGNAL(itemSelectionChanged()),
                this, SLOT(changeLyxObjectsSelection()));
        connect(lyxObjectsLW, SIGNAL(itemActivated(QListWidgetItem*)),
@@ -1153,7 +1117,7 @@ PrefColors::PrefColors(GuiPreferences * form)
 }
 
 
-void PrefColors::apply(LyXRC & rc) const
+void PrefColors::applyRC(LyXRC & rc) const
 {
        LyXRC oldrc = rc;
 
@@ -1167,17 +1131,19 @@ void PrefColors::apply(LyXRC & rc) const
 }
 
 
-void PrefColors::update(LyXRC const & rc)
+void PrefColors::updateRC(LyXRC const & rc)
 {
-       for (unsigned int i = 0; i < lcolors_.size(); ++i) {
+       for (size_type i = 0; i < lcolors_.size(); ++i) {
                QColor color = QColor(guiApp->colorCache().get(lcolors_[i], false));
                QPixmap coloritem(32, 32);
                coloritem.fill(color);
-               lyxObjectsLW->item(i)->setIcon(QIcon(coloritem));
+               lyxObjectsLW->item(int(i))->setIcon(QIcon(coloritem));
                newcolors_[i] = curcolors_[i] = color.name();
        }
        syscolorsCB->setChecked(rc.use_system_colors);
        changeLyxObjectsSelection();
+
+       setDisabledResets();
 }
 
 
@@ -1189,34 +1155,137 @@ void PrefColors::changeColor()
        if (row < 0)
                return;
 
-       QString const color = newcolors_[row];
-       QColor c = QColorDialog::getColor(QColor(color), qApp->focusWidget());
+       QString const color = newcolors_[size_t(row)];
+       QColor const c = QColorDialog::getColor(QColor(color), qApp->focusWidget());
 
-       if (c.isValid() && c.name() != color) {
-               newcolors_[row] = c.name();
-               QPixmap coloritem(32, 32);
-               coloritem.fill(c);
-               lyxObjectsLW->currentItem()->setIcon(QIcon(coloritem));
+       if (setColor(row, c, color)) {
+               setDisabledResets();
+               // emit signal
+               changed();
+       }
+}
+
+
+void PrefColors::resetColor()
+{
+       int const row = lyxObjectsLW->currentRow();
+
+       // just to be sure
+       if (row < 0)
+               return;
+
+       QString const color = newcolors_[size_t(row)];
+       QColor const c = getDefaultColorByRow(row);
+
+       if (setColor(row, c, color)) {
+               setDisabledResets();
                // emit signal
                changed();
        }
 }
 
+
+void PrefColors::resetAllColor()
+{
+       bool isChanged = false;
+
+       colorResetAllPB->setDisabled(true);
+
+       for (int irow = 0, count = lyxObjectsLW->count(); irow < count; ++irow) {
+               QString const color = newcolors_[size_t(irow)];
+               QColor const c = getDefaultColorByRow(irow);
+
+               if (setColor(irow, c, color))
+                       isChanged = true;
+       }
+
+       if (isChanged) {
+               setDisabledResets();
+               // emit signal
+               changed();
+       }
+}
+
+
+bool PrefColors::setColor(int const row, QColor const new_color,
+                         QString const old_color)
+{
+       if (new_color.isValid() && new_color.name() != old_color) {
+               newcolors_[size_t(row)] = new_color.name();
+               QPixmap coloritem(32, 32);
+               coloritem.fill(new_color);
+               lyxObjectsLW->item(row)->setIcon(QIcon(coloritem));
+               return true;
+       }
+       return false;
+}
+
+
+void PrefColors::setDisabledResets()
+{
+       int const row = lyxObjectsLW->currentRow();
+       // set disable reset buttons ...
+       if (row >= 0)
+               colorResetPB->setDisabled(isDefaultColor(row, newcolors_[size_t(row)]));
+
+       colorResetAllPB->setDisabled(true);
+
+       // ... in between process qt events to give quicker visual feedback to the user ...
+       guiApp->processEvents();
+
+       // ... set disable Reset All button
+       for (int irow = 0, count = lyxObjectsLW->count(); irow < count; ++irow) {
+               if (!isDefaultColor(irow, newcolors_[size_t(irow)])) {
+                       colorResetAllPB->setDisabled(false);
+                       // the break condition might hide performance issues
+                       // if a non-default color is at the top of the list
+                       break;
+               }
+       }
+}
+
+
+bool PrefColors::isDefaultColor(int const row, QString const color)
+{
+       return color == getDefaultColorByRow(row).name();
+}
+
+
+QColor PrefColors::getDefaultColorByRow(int const row)
+{
+       ColorSet const defaultcolor;
+       return defaultcolor.getX11Name(lcolors_[size_t(row)]).c_str();
+}
+
+
 void PrefColors::changeSysColor()
 {
        for (int row = 0 ; row < lyxObjectsLW->count() ; ++row) {
                // skip colors that are taken from system palette
-               bool const hide = syscolorsCB->isChecked()
-                       && guiApp->colorCache().isSystem(lcolors_[row]);
+               bool const disable = syscolorsCB->isChecked()
+                       && guiApp->colorCache().isSystem(lcolors_[size_t(row)]);
 
-               lyxObjectsLW->item(row)->setHidden(hide);
-       }
+               QListWidgetItem * const item = lyxObjectsLW->item(row);
+               Qt::ItemFlags const flags = item->flags();
 
+               if (disable)
+                       item->setFlags(flags & ~Qt::ItemIsEnabled);
+               else
+                       item->setFlags(flags | Qt::ItemIsEnabled);
+       }
 }
 
+
 void PrefColors::changeLyxObjectsSelection()
 {
-       colorChangePB->setDisabled(lyxObjectsLW->currentRow() < 0);
+       int currentRow = lyxObjectsLW->currentRow();
+       colorChangePB->setDisabled(currentRow < 0);
+
+       if (currentRow < 0)
+               colorResetPB->setDisabled(true);
+       else
+               colorResetPB->setDisabled(
+                       isDefaultColor(currentRow, newcolors_[size_t(currentRow)]));
 }
 
 
@@ -1227,7 +1296,7 @@ void PrefColors::changeLyxObjectsSelection()
 /////////////////////////////////////////////////////////////////////
 
 PrefDisplay::PrefDisplay(GuiPreferences * form)
-       : PrefModule(qt_(catLookAndFeel), qt_("Display"), form)
+       : PrefModule(catLookAndFeel, N_("Display"), form)
 {
        setupUi(this);
        connect(displayGraphicsCB, SIGNAL(toggled(bool)), this, SIGNAL(changed()));
@@ -1243,14 +1312,7 @@ void PrefDisplay::on_instantPreviewCO_currentIndexChanged(int index)
 }
 
 
-void PrefDisplay::on_displayGraphicsCB_toggled(bool on)
-{
-       instantPreviewCO->setEnabled(on);
-       previewSizeSB->setEnabled(on && instantPreviewCO->currentIndex() > 0);
-}
-
-
-void PrefDisplay::apply(LyXRC & rc) const
+void PrefDisplay::applyRC(LyXRC & rc) const
 {
        switch (instantPreviewCO->currentIndex()) {
                case 0:
@@ -1278,7 +1340,7 @@ void PrefDisplay::apply(LyXRC & rc) const
 }
 
 
-void PrefDisplay::update(LyXRC const & rc)
+void PrefDisplay::updateRC(LyXRC const & rc)
 {
        switch (rc.preview) {
        case LyXRC::PREVIEW_OFF:
@@ -1293,7 +1355,6 @@ void PrefDisplay::update(LyXRC const & rc)
        }
 
        displayGraphicsCB->setChecked(rc.display_graphics);
-       instantPreviewCO->setEnabled(rc.display_graphics);
        previewSizeSB->setValue(rc.preview_scale_factor);
        paragraphMarkerCB->setChecked(rc.paragraph_markers);
        previewSizeSB->setEnabled(
@@ -1309,7 +1370,7 @@ void PrefDisplay::update(LyXRC const & rc)
 /////////////////////////////////////////////////////////////////////
 
 PrefPaths::PrefPaths(GuiPreferences * form)
-       : PrefModule(QString(), qt_("Paths"), form)
+       : PrefModule(QString(), N_("Paths"), form)
 {
        setupUi(this);
 
@@ -1361,7 +1422,7 @@ PrefPaths::PrefPaths(GuiPreferences * form)
 }
 
 
-void PrefPaths::apply(LyXRC & rc) const
+void PrefPaths::applyRC(LyXRC & rc) const
 {
        rc.document_path = internal_path(fromqstr(workingDirED->text()));
        rc.example_path = internal_path(fromqstr(exampleDirED->text()));
@@ -1377,7 +1438,7 @@ void PrefPaths::apply(LyXRC & rc) const
 }
 
 
-void PrefPaths::update(LyXRC const & rc)
+void PrefPaths::updateRC(LyXRC const & rc)
 {
        workingDirED->setText(toqstr(external_path(rc.document_path)));
        exampleDirED->setText(toqstr(external_path(rc.example_path)));
@@ -1472,7 +1533,7 @@ void PrefPaths::selectLyxPipe()
 /////////////////////////////////////////////////////////////////////
 
 PrefSpellchecker::PrefSpellchecker(GuiPreferences * form)
-       : PrefModule(qt_(catLanguage), qt_("Spellchecker"), form)
+       : PrefModule(catLanguage, N_("Spellchecker"), form)
 {
        setupUi(this);
 
@@ -1520,7 +1581,7 @@ PrefSpellchecker::PrefSpellchecker(GuiPreferences * form)
 }
 
 
-void PrefSpellchecker::apply(LyXRC & rc) const
+void PrefSpellchecker::applyRC(LyXRC & rc) const
 {
        string const speller = fromqstr(spellcheckerCB->
                itemData(spellcheckerCB->currentIndex()).toString());
@@ -1534,7 +1595,7 @@ void PrefSpellchecker::apply(LyXRC & rc) const
 }
 
 
-void PrefSpellchecker::update(LyXRC const & rc)
+void PrefSpellchecker::updateRC(LyXRC const & rc)
 {
        spellcheckerCB->setCurrentIndex(
                spellcheckerCB->findData(toqstr(rc.spellchecker)));
@@ -1549,12 +1610,12 @@ void PrefSpellchecker::update(LyXRC const & rc)
 void PrefSpellchecker::on_spellcheckerCB_currentIndexChanged(int index)
 {
        QString spellchecker = spellcheckerCB->itemData(index).toString();
-       
+
        compoundWordCB->setEnabled(spellchecker == QString("aspell"));
 }
-       
-       
-       
+
+
+
 /////////////////////////////////////////////////////////////////////
 //
 // PrefConverters
@@ -1563,7 +1624,7 @@ void PrefSpellchecker::on_spellcheckerCB_currentIndexChanged(int index)
 
 
 PrefConverters::PrefConverters(GuiPreferences * form)
-       : PrefModule(qt_(catFiles), qt_("Converters"), form)
+       : PrefModule(catFiles, N_("Converters"), form)
 {
        setupUi(this);
 
@@ -1591,24 +1652,37 @@ PrefConverters::PrefConverters(GuiPreferences * form)
                this, SIGNAL(changed()));
        connect(maxAgeLE, SIGNAL(textEdited(QString)),
                this, SIGNAL(changed()));
+       connect(needauthForbiddenCB, SIGNAL(toggled(bool)),
+               this, SIGNAL(changed()));
 
        converterED->setValidator(new NoNewLineValidator(converterED));
        converterFlagED->setValidator(new NoNewLineValidator(converterFlagED));
-       maxAgeLE->setValidator(new QDoubleValidator(maxAgeLE));
+       maxAgeLE->setValidator(new QDoubleValidator(0, HUGE_VAL, 6, maxAgeLE));
        //converterDefGB->setFocusProxy(convertersLW);
 }
 
 
-void PrefConverters::apply(LyXRC & rc) const
+void PrefConverters::applyRC(LyXRC & rc) const
 {
        rc.use_converter_cache = cacheCB->isChecked();
+       rc.use_converter_needauth_forbidden = needauthForbiddenCB->isChecked();
+       rc.use_converter_needauth = needauthCB->isChecked();
        rc.converter_cache_maxage = int(widgetToDouble(maxAgeLE) * 86400.0);
 }
 
 
-void PrefConverters::update(LyXRC const & rc)
+static void setCheckboxBlockSignals(QCheckBox *cb, bool checked) {
+       cb->blockSignals(true);
+       cb->setChecked(checked);
+       cb->blockSignals(false);
+}
+
+
+void PrefConverters::updateRC(LyXRC const & rc)
 {
        cacheCB->setChecked(rc.use_converter_cache);
+       needauthForbiddenCB->setChecked(rc.use_converter_needauth_forbidden);
+       setCheckboxBlockSignals(needauthCB, rc.use_converter_needauth);
        QString max_age;
        doubleToWidget(maxAgeLE, (double(rc.converter_cache_maxage) / 86400.0), 'g', 6);
        updateGui();
@@ -1617,20 +1691,22 @@ void PrefConverters::update(LyXRC const & rc)
 
 void PrefConverters::updateGui()
 {
+       QString const pattern("%1 -> %2");
        form_->formats().sort();
        form_->converters().update(form_->formats());
        // save current selection
-       QString current = converterFromCO->currentText()
-               + " -> " + converterToCO->currentText();
+       QString current =
+               pattern
+               .arg(converterFromCO->currentText())
+               .arg(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->addItem(qt_(cit->prettyname()));
-               converterToCO->addItem(qt_(cit->prettyname()));
+       for (Format const & f : form_->formats()) {
+               QString const name = toqstr(translateIfPossible(f.prettyname()));
+               converterFromCO->addItem(name);
+               converterToCO->addItem(name);
        }
 
        // currentRowChanged(int) is also triggered when updating the listwidget
@@ -1638,19 +1714,20 @@ void PrefConverters::updateGui()
        convertersLW->blockSignals(true);
        convertersLW->clear();
 
-       Converters::const_iterator ccit = form_->converters().begin();
-       Converters::const_iterator cend = form_->converters().end();
-       for (; ccit != cend; ++ccit) {
+       for (Converter const & c : form_->converters()) {
                QString const name =
-                       qt_(ccit->From->prettyname()) + " -> " + qt_(ccit->To->prettyname());
-               int type = form_->converters().getNumber(ccit->From->name(), ccit->To->name());
+                       pattern
+                       .arg(toqstr(translateIfPossible(c.From()->prettyname())))
+                       .arg(toqstr(translateIfPossible(c.To()->prettyname())));
+               int type = form_->converters().getNumber(c.From()->name(),
+                                                        c.To()->name());
                new QListWidgetItem(name, convertersLW, type);
        }
        convertersLW->sortItems(Qt::AscendingOrder);
        convertersLW->blockSignals(false);
 
        // restore selection
-       if (!current.isEmpty()) {
+       if (current != pattern.arg(QString()).arg(QString())) {
                QList<QListWidgetItem *> const item =
                        convertersLW->findItems(current, Qt::MatchExactly);
                if (!item.isEmpty())
@@ -1669,10 +1746,10 @@ void PrefConverters::switchConverter()
 {
        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));
+       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();
 }
@@ -1686,7 +1763,7 @@ void PrefConverters::changeConverter()
 
 void PrefConverters::updateButtons()
 {
-       if (form_->formats().size() == 0)
+       if (form_->formats().empty())
                return;
        Format const & from = form_->formats().get(converterFromCO->currentIndex());
        Format const & to = form_->formats().get(converterToCO->currentIndex());
@@ -1695,10 +1772,16 @@ void PrefConverters::updateButtons()
        bool const valid = !(converterED->text().isEmpty()
                || from.name() == to.name());
 
-       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 old_command;
+       string old_flag;
+
+       if (convertersLW->count() > 0) {
+               int const cnr = convertersLW->currentItem()->type();
+               Converter const & c = form_->converters().get(cnr);
+               old_command = c.command();
+               old_flag = c.flags();
+       }
+
        string const new_command = fromqstr(converterED->text());
        string const new_flag = fromqstr(converterFlagED->text());
 
@@ -1760,6 +1843,29 @@ void PrefConverters::on_cacheCB_stateChanged(int state)
 }
 
 
+void PrefConverters::on_needauthForbiddenCB_toggled(bool checked)
+{
+       needauthCB->setEnabled(!checked);
+}
+
+
+void PrefConverters::on_needauthCB_toggled(bool checked)
+{
+       if (checked) {
+               changed();
+               return;
+       }
+
+       int ret = frontend::Alert::prompt(
+               _("SECURITY WARNING!"), _("Unchecking this option has the effect that potentially harmful converters would be run without asking your permission first. This is UNSAFE and NOT recommended, unless you know what you are doing. Are you sure you would like to proceed ? The recommended and safe answer is NO!"),
+               0, 0, _("&No"), _("&Yes"));
+       if (ret == 1)
+               changed();
+       else
+               setCheckboxBlockSignals(needauthCB, true);
+}
+
+
 /////////////////////////////////////////////////////////////////////
 //
 // FormatValidator
@@ -1859,7 +1965,7 @@ public:
 private:
        QString toString(Format const & format) const
        {
-               return qt_(format.prettyname());
+               return toqstr(translateIfPossible(format.prettyname()));
        }
 };
 
@@ -1871,7 +1977,7 @@ private:
 /////////////////////////////////////////////////////////////////////
 
 PrefFileformats::PrefFileformats(GuiPreferences * form)
-       : PrefModule(qt_(catFiles), qt_("File Formats"), form)
+       : PrefModule(catFiles, N_("File Formats"), form)
 {
        setupUi(this);
 
@@ -1895,6 +2001,10 @@ PrefFileformats::PrefFileformats(GuiPreferences * form)
                this, SIGNAL(changed()));
        connect(defaultFormatCB, SIGNAL(activated(QString)),
                this, SIGNAL(changed()));
+       connect(defaultOTFFormatCB, SIGNAL(activated(QString)),
+               this, SIGNAL(changed()));
+       connect(defaultPlatexFormatCB, SIGNAL(activated(QString)),
+               this, SIGNAL(changed()));
        connect(viewerCO, SIGNAL(activated(int)),
                this, SIGNAL(changed()));
        connect(editorCO, SIGNAL(activated(int)),
@@ -1904,37 +2014,49 @@ PrefFileformats::PrefFileformats(GuiPreferences * form)
 
 namespace {
 
-string const l10n_shortcut(string const prettyname, string const shortcut)
+string const l10n_shortcut(docstring const & prettyname, string const & shortcut)
 {
        if (shortcut.empty())
                return string();
 
        string l10n_format =
-               to_utf8(_(prettyname + '|' + shortcut));
+               to_utf8(_(to_utf8(prettyname) + '|' + shortcut));
        return split(l10n_format, '|');
 }
 
-} // namespace anon
+} // namespace
 
 
-void PrefFileformats::apply(LyXRC & rc) const
+void PrefFileformats::applyRC(LyXRC & rc) const
 {
        QString const default_format = defaultFormatCB->itemData(
                defaultFormatCB->currentIndex()).toString();
        rc.default_view_format = fromqstr(default_format);
+       QString const default_otf_format = defaultOTFFormatCB->itemData(
+               defaultOTFFormatCB->currentIndex()).toString();
+       rc.default_otf_view_format = fromqstr(default_otf_format);
+       QString const default_platex_format = defaultPlatexFormatCB->itemData(
+               defaultPlatexFormatCB->currentIndex()).toString();
+       rc.default_platex_view_format = fromqstr(default_platex_format);
 }
 
 
-void PrefFileformats::update(LyXRC const & rc)
+void PrefFileformats::updateRC(LyXRC const & rc)
 {
        viewer_alternatives = rc.viewer_alternatives;
        editor_alternatives = rc.editor_alternatives;
        bool const init = defaultFormatCB->currentText().isEmpty();
        updateView();
        if (init) {
-               int const pos =
+               int pos =
                        defaultFormatCB->findData(toqstr(rc.default_view_format));
                defaultFormatCB->setCurrentIndex(pos);
+               pos = defaultOTFFormatCB->findData(toqstr(rc.default_otf_view_format));
+                               defaultOTFFormatCB->setCurrentIndex(pos);
+               defaultOTFFormatCB->setCurrentIndex(pos);
+               pos = defaultPlatexFormatCB->findData(toqstr(rc.default_platex_view_format));
+                               defaultPlatexFormatCB->setCurrentIndex(pos);
+               defaultPlatexFormatCB->setCurrentIndex(pos);
        }
 }
 
@@ -1943,41 +2065,64 @@ void PrefFileformats::updateView()
 {
        QString const current = formatsCB->currentText();
        QString const current_def = defaultFormatCB->currentText();
+       QString const current_def_otf = defaultOTFFormatCB->currentText();
+       QString const current_def_platex = defaultPlatexFormatCB->currentText();
 
        // update comboboxes with formats
        formatsCB->blockSignals(true);
        defaultFormatCB->blockSignals(true);
+       defaultOTFFormatCB->blockSignals(true);
+       defaultPlatexFormatCB->blockSignals(true);
        formatsCB->clear();
        defaultFormatCB->clear();
+       defaultOTFFormatCB->clear();
+       defaultPlatexFormatCB->clear();
        form_->formats().sort();
-       Formats::const_iterator cit = form_->formats().begin();
-       Formats::const_iterator end = form_->formats().end();
-       for (; cit != end; ++cit) {
-               formatsCB->addItem(qt_(cit->prettyname()),
-                               QVariant(form_->formats().getNumber(cit->name())));
-               if (form_->converters().isReachable("latex", cit->name())
-                   || form_->converters().isReachable("dviluatex", cit->name())
-                   || form_->converters().isReachable("pdflatex", cit->name())
-                   || form_->converters().isReachable("luatex", cit->name())
-                   || form_->converters().isReachable("xetex", cit->name()))
-                       defaultFormatCB->addItem(qt_(cit->prettyname()),
-                                       QVariant(toqstr(cit->name())));
+       for (Format const & f : form_->formats()) {
+               QString const prettyname = toqstr(translateIfPossible(f.prettyname()));
+               formatsCB->addItem(prettyname,
+                                  QVariant(form_->formats().getNumber(f.name())));
+               if (f.viewer().empty())
+                       continue;
+               if (form_->converters().isReachable("xhtml", f.name())
+                   || form_->converters().isReachable("dviluatex", f.name())
+                   || form_->converters().isReachable("luatex", f.name())
+                   || form_->converters().isReachable("xetex", f.name())) {
+                       defaultFormatCB->addItem(prettyname,
+                                       QVariant(toqstr(f.name())));
+                       defaultOTFFormatCB->addItem(prettyname,
+                                       QVariant(toqstr(f.name())));
+               } else {
+                       if (form_->converters().isReachable("latex", f.name())
+                           || form_->converters().isReachable("pdflatex", f.name()))
+                               defaultFormatCB->addItem(prettyname,
+                                       QVariant(toqstr(f.name())));
+                       if (form_->converters().isReachable("platex", f.name()))
+                                       defaultPlatexFormatCB->addItem(prettyname,
+                                               QVariant(toqstr(f.name())));
+               }
        }
 
-       // restore selection
+       // restore selections
        int item = formatsCB->findText(current, Qt::MatchExactly);
        formatsCB->setCurrentIndex(item < 0 ? 0 : item);
        on_formatsCB_currentIndexChanged(item < 0 ? 0 : item);
        item = defaultFormatCB->findText(current_def, Qt::MatchExactly);
        defaultFormatCB->setCurrentIndex(item < 0 ? 0 : item);
+       item = defaultOTFFormatCB->findText(current_def_otf, Qt::MatchExactly);
+       defaultOTFFormatCB->setCurrentIndex(item < 0 ? 0 : item);
+       item = defaultPlatexFormatCB->findText(current_def_platex, Qt::MatchExactly);
+       defaultPlatexFormatCB->setCurrentIndex(item < 0 ? 0 : item);
        formatsCB->blockSignals(false);
        defaultFormatCB->blockSignals(false);
+       defaultOTFFormatCB->blockSignals(false);
+       defaultPlatexFormatCB->blockSignals(false);
 }
 
 
 void PrefFileformats::on_formatsCB_currentIndexChanged(int i)
 {
-       if (form_->formats().size() == 0)
+       if (form_->formats().empty())
                return;
        int const nr = formatsCB->itemData(i).toInt();
        Format const f = form_->formats().get(nr);
@@ -1985,6 +2130,7 @@ void PrefFileformats::on_formatsCB_currentIndexChanged(int i)
        formatED->setText(toqstr(f.name()));
        copierED->setText(toqstr(form_->movers().command(f.name())));
        extensionsED->setText(toqstr(f.extensions()));
+       mimeED->setText(toqstr(f.mime()));
        shortcutED->setText(
                toqstr(l10n_shortcut(f.prettyname(), f.shortcut())));
        documentCB->setChecked((f.documentFormat()));
@@ -2040,6 +2186,13 @@ void PrefFileformats::on_editorED_textEdited(const QString & s)
 }
 
 
+void PrefFileformats::on_mimeED_textEdited(const QString & s)
+{
+       currentFormat().setMime(fromqstr(s));
+       changed();
+}
+
+
 void PrefFileformats::on_shortcutED_textEdited(const QString & s)
 {
        string const new_shortcut = fromqstr(s);
@@ -2092,10 +2245,10 @@ void PrefFileformats::on_formatsCB_editTextChanged(const QString &)
 void PrefFileformats::updatePrettyname()
 {
        QString const newname = formatsCB->currentText();
-       if (newname == qt_(currentFormat().prettyname()))
+       if (newname == toqstr(translateIfPossible(currentFormat().prettyname())))
                return;
 
-       currentFormat().setPrettyname(fromqstr(newname));
+       currentFormat().setPrettyname(qstring_to_ucs4(newname));
        formatsChanged();
        updateView();
        changed();
@@ -2106,13 +2259,13 @@ namespace {
        void updateComboBox(LyXRC::Alternatives const & alts,
                            string const & fmt, QComboBox * combo)
        {
-               LyXRC::Alternatives::const_iterator it = 
+               LyXRC::Alternatives::const_iterator it =
                                alts.find(fmt);
                if (it != alts.end()) {
                        LyXRC::CommandSet const & cmds = it->second;
-                       LyXRC::CommandSet::const_iterator sit = 
+                       LyXRC::CommandSet::const_iterator sit =
                                        cmds.begin();
-                       LyXRC::CommandSet::const_iterator const sen = 
+                       LyXRC::CommandSet::const_iterator const sen =
                                        cmds.end();
                        for (; sit != sen; ++sit) {
                                QString const qcmd = toqstr(*sit);
@@ -2120,7 +2273,7 @@ namespace {
                        }
                }
        }
-}
+} // namespace
 
 
 void PrefFileformats::updateViewers()
@@ -2197,7 +2350,7 @@ Format & PrefFileformats::currentFormat()
 
 void PrefFileformats::on_formatNewPB_clicked()
 {
-       form_->formats().add("", "", "", "", "", "", Format::none);
+       form_->formats().add("", "", docstring(), "", "", "", "", Format::none);
        updateView();
        formatsCB->setCurrentIndex(0);
        formatsCB->setFocus(Qt::OtherFocusReason);
@@ -2231,12 +2384,10 @@ void PrefFileformats::on_formatRemovePB_clicked()
 /////////////////////////////////////////////////////////////////////
 
 PrefLanguage::PrefLanguage(GuiPreferences * form)
-       : PrefModule(qt_(catLanguage), qt_("Language"), form)
+       : PrefModule(catLanguage, N_("Language"), form)
 {
        setupUi(this);
 
-       connect(rtlGB, SIGNAL(clicked()),
-               this, SIGNAL(changed()));
        connect(visualCursorRB, SIGNAL(clicked()),
                this, SIGNAL(changed()));
        connect(logicalCursorRB, SIGNAL(clicked()),
@@ -2261,21 +2412,23 @@ PrefLanguage::PrefLanguage(GuiPreferences * form)
                this, SIGNAL(changed()));
        connect(defaultDecimalPointLE, SIGNAL(textChanged(QString)),
                this, SIGNAL(changed()));
+       connect(defaultLengthUnitCO, SIGNAL(activated(int)),
+               this, SIGNAL(changed()));
 
        languagePackageED->setValidator(new NoNewLineValidator(languagePackageED));
        startCommandED->setValidator(new NoNewLineValidator(startCommandED));
        endCommandED->setValidator(new NoNewLineValidator(endCommandED));
 
-       uiLanguageCO->clear();
-
-       QAbstractItemModel * language_model = guiApp->languageModel();
-       // FIXME: it would be nice if sorting was enabled/disabled via a checkbox.
-       language_model->sort(0);
        defaultDecimalPointLE->setInputMask("X; ");
        defaultDecimalPointLE->setMaxLength(1);
 
-       set<string> added;
+       defaultLengthUnitCO->addItem(lyx::qt_(unit_name_gui[Length::CM]), Length::CM);
+       defaultLengthUnitCO->addItem(lyx::qt_(unit_name_gui[Length::IN]), Length::IN);
+
+       QAbstractItemModel * language_model = guiApp->languageModel();
+       language_model->sort(0);
        uiLanguageCO->blockSignals(true);
+       uiLanguageCO->clear();
        uiLanguageCO->addItem(qt_("Default"), toqstr("auto"));
        for (int i = 0; i != language_model->rowCount(); ++i) {
                QModelIndex index = language_model->index(i, 0);
@@ -2283,13 +2436,16 @@ PrefLanguage::PrefLanguage(GuiPreferences * form)
                // each language code only once
                string const name = fromqstr(index.data(Qt::UserRole).toString());
                Language const * lang = languages.getLanguage(name);
+               if (!lang)
+                       continue;
                // never remove the currently selected language
-               if (lang && name != form->rc().gui_language && name != lyxrc.gui_language)
-                       if (!lang->translated() || added.find(lang->code()) != added.end())
-                               continue;
-               added.insert(lang->code());
+               if (name != form->rc().gui_language
+                   && name != lyxrc.gui_language
+                   && (!Messages::available(lang->code())
+                       || !lang->hasGuiSupport()))
+                       continue;
                uiLanguageCO->addItem(index.data(Qt::DisplayRole).toString(),
-                       index.data(Qt::UserRole).toString());
+                                     index.data(Qt::UserRole).toString());
        }
        uiLanguageCO->blockSignals(false);
 }
@@ -2309,11 +2465,9 @@ void PrefLanguage::on_languagePackageCO_currentIndexChanged(int i)
 }
 
 
-void PrefLanguage::apply(LyXRC & rc) const
+void PrefLanguage::applyRC(LyXRC & rc) const
 {
-       // FIXME: remove rtl_support bool
-       rc.rtl_support = rtlGB->isChecked();
-       rc.visual_cursor = rtlGB->isChecked() && visualCursorRB->isChecked();
+       rc.visual_cursor = visualCursorRB->isChecked();
        rc.mark_foreign_language = markForeignCB->isChecked();
        rc.language_auto_begin = autoBeginCB->isChecked();
        rc.language_auto_end = autoEndCB->isChecked();
@@ -2333,13 +2487,12 @@ void PrefLanguage::apply(LyXRC & rc) const
        rc.gui_language = fromqstr(
                uiLanguageCO->itemData(uiLanguageCO->currentIndex()).toString());
        rc.default_decimal_point = fromqstr(defaultDecimalPointLE->text());
+       rc.default_length_unit = (Length::UNIT) defaultLengthUnitCO->itemData(defaultLengthUnitCO->currentIndex()).toInt();
 }
 
 
-void PrefLanguage::update(LyXRC const & rc)
+void PrefLanguage::updateRC(LyXRC const & rc)
 {
-       // FIXME: remove rtl_support bool
-       rtlGB->setChecked(rc.rtl_support);
        if (rc.visual_cursor)
                visualCursorRB->setChecked(true);
        else
@@ -2354,8 +2507,10 @@ void PrefLanguage::update(LyXRC const & rc)
        startCommandED->setText(toqstr(rc.language_command_begin));
        endCommandED->setText(toqstr(rc.language_command_end));
        defaultDecimalPointLE->setText(toqstr(rc.default_decimal_point));
+       int pos = defaultLengthUnitCO->findData(int(rc.default_length_unit));
+       defaultLengthUnitCO->setCurrentIndex(pos);
 
-       int pos = uiLanguageCO->findData(toqstr(rc.gui_language));
+       pos = uiLanguageCO->findData(toqstr(rc.gui_language));
        uiLanguageCO->blockSignals(true);
        uiLanguageCO->setCurrentIndex(pos);
        uiLanguageCO->blockSignals(false);
@@ -2364,128 +2519,80 @@ void PrefLanguage::update(LyXRC const & rc)
 
 /////////////////////////////////////////////////////////////////////
 //
-// PrefPrinter
+// PrefUserInterface
 //
 /////////////////////////////////////////////////////////////////////
 
-PrefPrinter::PrefPrinter(GuiPreferences * form)
-       : PrefModule(qt_(catOutput), qt_("Printer"), form)
+PrefUserInterface::PrefUserInterface(GuiPreferences * form)
+       : PrefModule(catLookAndFeel, N_("User Interface"), form)
 {
        setupUi(this);
 
-       connect(printerAdaptCB, SIGNAL(clicked()),
-               this, SIGNAL(changed()));
-       connect(printerCommandED, SIGNAL(textChanged(QString)),
-               this, SIGNAL(changed()));
-       connect(printerNameED, SIGNAL(textChanged(QString)),
-               this, SIGNAL(changed()));
-       connect(printerPageRangeED, SIGNAL(textChanged(QString)),
-               this, SIGNAL(changed()));
-       connect(printerCopiesED, SIGNAL(textChanged(QString)),
-               this, SIGNAL(changed()));
-       connect(printerReverseED, SIGNAL(textChanged(QString)),
-               this, SIGNAL(changed()));
-       connect(printerToPrinterED, SIGNAL(textChanged(QString)),
-               this, SIGNAL(changed()));
-       connect(printerExtensionED, SIGNAL(textChanged(QString)),
-               this, SIGNAL(changed()));
-       connect(printerSpoolCommandED, SIGNAL(textChanged(QString)),
-               this, SIGNAL(changed()));
-       connect(printerPaperTypeED, SIGNAL(textChanged(QString)),
-               this, SIGNAL(changed()));
-       connect(printerEvenED, SIGNAL(textChanged(QString)),
-               this, SIGNAL(changed()));
-       connect(printerOddED, SIGNAL(textChanged(QString)),
-               this, SIGNAL(changed()));
-       connect(printerCollatedED, SIGNAL(textChanged(QString)),
-               this, SIGNAL(changed()));
-       connect(printerLandscapeED, SIGNAL(textChanged(QString)),
+       connect(uiFilePB, SIGNAL(clicked()),
+               this, SLOT(selectUi()));
+       connect(uiFileED, SIGNAL(textChanged(QString)),
                this, SIGNAL(changed()));
-       connect(printerToFileED, SIGNAL(textChanged(QString)),
+       connect(iconSetCO, SIGNAL(activated(int)),
                this, SIGNAL(changed()));
-       connect(printerExtraED, SIGNAL(textChanged(QString)),
+       connect(useSystemThemeIconsCB, SIGNAL(clicked()),
                this, SIGNAL(changed()));
-       connect(printerSpoolPrefixED, SIGNAL(textChanged(QString)),
+       connect(lastfilesSB, SIGNAL(valueChanged(int)),
                this, SIGNAL(changed()));
-       connect(printerPaperSizeED, SIGNAL(textChanged(QString)),
+       connect(tooltipCB, SIGNAL(toggled(bool)),
                this, SIGNAL(changed()));
+       lastfilesSB->setMaximum(maxlastfiles);
 
-       printerNameED->setValidator(new NoNewLineValidator(printerNameED));
-       printerCommandED->setValidator(new NoNewLineValidator(printerCommandED));
-       printerEvenED->setValidator(new NoNewLineValidator(printerEvenED));
-       printerPageRangeED->setValidator(new NoNewLineValidator(printerPageRangeED));
-       printerCopiesED->setValidator(new NoNewLineValidator(printerCopiesED));
-       printerReverseED->setValidator(new NoNewLineValidator(printerReverseED));
-       printerToFileED->setValidator(new NoNewLineValidator(printerToFileED));
-       printerPaperTypeED->setValidator(new NoNewLineValidator(printerPaperTypeED));
-       printerExtraED->setValidator(new NoNewLineValidator(printerExtraED));
-       printerOddED->setValidator(new NoNewLineValidator(printerOddED));
-       printerCollatedED->setValidator(new NoNewLineValidator(printerCollatedED));
-       printerLandscapeED->setValidator(new NoNewLineValidator(printerLandscapeED));
-       printerToPrinterED->setValidator(new NoNewLineValidator(printerToPrinterED));
-       printerExtensionED->setValidator(new NoNewLineValidator(printerExtensionED));
-       printerPaperSizeED->setValidator(new NoNewLineValidator(printerPaperSizeED));
-       printerSpoolCommandED->setValidator(new NoNewLineValidator(printerSpoolCommandED));
-       printerSpoolPrefixED->setValidator(new NoNewLineValidator(printerSpoolPrefixED));
+       iconSetCO->addItem(qt_("Default"), QString());
+       iconSetCO->addItem(qt_("Classic"), "classic");
+       iconSetCO->addItem(qt_("Oxygen"), "oxygen");
+
+#if (!(defined Q_WS_X11 || defined(QPA_XCB)) || QT_VERSION < 0x040600)
+       useSystemThemeIconsCB->hide();
+#endif
 }
 
 
-void PrefPrinter::apply(LyXRC & rc) const
+void PrefUserInterface::applyRC(LyXRC & rc) const
 {
-       rc.print_adapt_output = printerAdaptCB->isChecked();
-       rc.print_command = fromqstr(printerCommandED->text());
-       rc.printer = fromqstr(printerNameED->text());
+       rc.icon_set = fromqstr(iconSetCO->itemData(
+               iconSetCO->currentIndex()).toString());
 
-       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(fromqstr(printerToFileED->text()));
-       rc.print_extra_options = fromqstr(printerExtraED->text());
-       rc.print_spool_printerprefix = fromqstr(printerSpoolPrefixED->text());
-       rc.print_paper_dimension_flag = fromqstr(printerPaperSizeED->text());
+       rc.ui_file = internal_path(fromqstr(uiFileED->text()));
+       rc.use_system_theme_icons = useSystemThemeIconsCB->isChecked();
+       rc.num_lastfiles = lastfilesSB->value();
+       rc.use_tooltip = tooltipCB->isChecked();
 }
 
 
-void PrefPrinter::update(LyXRC const & rc)
+void PrefUserInterface::updateRC(LyXRC const & rc)
 {
-       printerAdaptCB->setChecked(rc.print_adapt_output);
-       printerCommandED->setText(toqstr(rc.print_command));
-       printerNameED->setText(toqstr(rc.printer));
+       int iconset = iconSetCO->findData(toqstr(rc.icon_set));
+       if (iconset < 0)
+               iconset = 0;
+       iconSetCO->setCurrentIndex(iconset);
+       useSystemThemeIconsCB->setChecked(rc.use_system_theme_icons);
+       uiFileED->setText(toqstr(external_path(rc.ui_file)));
+       lastfilesSB->setValue(rc.num_lastfiles);
+       tooltipCB->setChecked(rc.use_tooltip);
+}
 
-       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(toqstr(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));
+
+void PrefUserInterface::selectUi()
+{
+       QString file = form_->browseUI(internalPath(uiFileED->text()));
+       if (!file.isEmpty())
+               uiFileED->setText(file);
 }
 
 
 /////////////////////////////////////////////////////////////////////
 //
-// PrefUserInterface
+// PrefDocumentHandling
 //
 /////////////////////////////////////////////////////////////////////
 
-PrefUserInterface::PrefUserInterface(GuiPreferences * form)
-       : PrefModule(qt_(catLookAndFeel), qt_("User Interface"), form)
+PrefDocHandling::PrefDocHandling(GuiPreferences * form)
+       : PrefModule(catLookAndFeel, N_("Document Handling"), form)
 {
        setupUi(this);
 
@@ -2497,16 +2604,9 @@ PrefUserInterface::PrefUserInterface(GuiPreferences * form)
                this, SIGNAL(changed()));
        connect(singleInstanceCB, SIGNAL(clicked()),
                this, SIGNAL(changed()));
-#if QT_VERSION < 0x040500
-       singleCloseTabButtonCB->setEnabled(false);
-#endif
        connect(singleCloseTabButtonCB, SIGNAL(clicked()),
                this, SIGNAL(changed()));
-       connect(uiFilePB, SIGNAL(clicked()),
-               this, SLOT(selectUi()));
-       connect(uiFileED, SIGNAL(textChanged(QString)),
-               this, SIGNAL(changed()));
-       connect(iconSetCO, SIGNAL(activated(int)),
+       connect(closeLastViewCO, SIGNAL(activated(int)),
                this, SIGNAL(changed()));
        connect(restoreCursorCB, SIGNAL(clicked()),
                this, SIGNAL(changed()));
@@ -2522,48 +2622,42 @@ PrefUserInterface::PrefUserInterface(GuiPreferences * form)
                this, SIGNAL(changed()));
        connect(saveCompressedCB, SIGNAL(clicked()),
                this, SIGNAL(changed()));
-       connect(lastfilesSB, SIGNAL(valueChanged(int)),
-               this, SIGNAL(changed()));
-       connect(tooltipCB, SIGNAL(toggled(bool)),
+       connect(saveOriginCB, SIGNAL(clicked()),
                this, SIGNAL(changed()));
-       lastfilesSB->setMaximum(maxlastfiles);
-
-       iconSetCO->addItem(qt_("Default"), QString());
-       iconSetCO->addItem(qt_("Classic"), "classic");
-       iconSetCO->addItem(qt_("Oxygen"), "oxygen");
 }
 
 
-void PrefUserInterface::apply(LyXRC & rc) const
+void PrefDocHandling::applyRC(LyXRC & rc) const
 {
-       rc.icon_set = fromqstr(iconSetCO->itemData(
-               iconSetCO->currentIndex()).toString());
-
-       rc.ui_file = internal_path(fromqstr(uiFileED->text()));
        rc.use_lastfilepos = restoreCursorCB->isChecked();
        rc.load_session = loadSessionCB->isChecked();
        rc.allow_geometry_session = allowGeometrySessionCB->isChecked();
        rc.autosave = autoSaveCB->isChecked() ?  autoSaveSB->value() * 60 : 0;
        rc.make_backup = backupCB->isChecked();
        rc.save_compressed = saveCompressedCB->isChecked();
-       rc.num_lastfiles = lastfilesSB->value();
-       rc.use_tooltip = tooltipCB->isChecked();
+       rc.save_origin = saveOriginCB->isChecked();
        rc.open_buffers_in_tabs = openDocumentsInTabsCB->isChecked();
        rc.single_instance = singleInstanceCB->isChecked();
        rc.single_close_tab_button = singleCloseTabButtonCB->isChecked();
-#if QT_VERSION < 0x040500
-       rc.single_close_tab_button = true;
-#endif
+
+       switch (closeLastViewCO->currentIndex()) {
+       case 0:
+               rc.close_buffer_with_last_view = "yes";
+               break;
+       case 1:
+               rc.close_buffer_with_last_view = "no";
+               break;
+       case 2:
+               rc.close_buffer_with_last_view = "ask";
+               break;
+       default:
+               ;
+       }
 }
 
 
-void PrefUserInterface::update(LyXRC const & rc)
+void PrefDocHandling::updateRC(LyXRC const & rc)
 {
-       int iconset = iconSetCO->findData(toqstr(rc.icon_set));
-       if (iconset < 0)
-               iconset = 0;
-       iconSetCO->setCurrentIndex(iconset);
-       uiFileED->setText(toqstr(external_path(rc.ui_file)));
        restoreCursorCB->setChecked(rc.use_lastfilepos);
        loadSessionCB->setChecked(rc.load_session);
        allowGeometrySessionCB->setChecked(rc.allow_geometry_session);
@@ -2577,24 +2671,21 @@ void PrefUserInterface::update(LyXRC const & rc)
        autoSaveSB->setEnabled(autosave);
        backupCB->setChecked(rc.make_backup);
        saveCompressedCB->setChecked(rc.save_compressed);
-       lastfilesSB->setValue(rc.num_lastfiles);
-       tooltipCB->setChecked(rc.use_tooltip);
+       saveOriginCB->setChecked(rc.save_origin);
        openDocumentsInTabsCB->setChecked(rc.open_buffers_in_tabs);
        singleInstanceCB->setChecked(rc.single_instance && !rc.lyxpipes.empty());
        singleInstanceCB->setEnabled(!rc.lyxpipes.empty());
        singleCloseTabButtonCB->setChecked(rc.single_close_tab_button);
+       if (rc.close_buffer_with_last_view == "yes")
+               closeLastViewCO->setCurrentIndex(0);
+       else if (rc.close_buffer_with_last_view == "no")
+               closeLastViewCO->setCurrentIndex(1);
+       else if (rc.close_buffer_with_last_view == "ask")
+               closeLastViewCO->setCurrentIndex(2);
 }
 
 
-void PrefUserInterface::selectUi()
-{
-       QString file = form_->browseUI(internalPath(uiFileED->text()));
-       if (!file.isEmpty())
-               uiFileED->setText(file);
-}
-
-
-void PrefUserInterface::on_clearSessionPB_clicked()
+void PrefDocHandling::on_clearSessionPB_clicked()
 {
        guiApp->clearSession();
 }
@@ -2608,7 +2699,7 @@ void PrefUserInterface::on_clearSessionPB_clicked()
 /////////////////////////////////////////////////////////////////////
 
 PrefEdit::PrefEdit(GuiPreferences * form)
-       : PrefModule(qt_(catEditing), qt_("Control"), form)
+       : PrefModule(catEditing, N_("Control"), form)
 {
        setupUi(this);
 
@@ -2616,7 +2707,7 @@ PrefEdit::PrefEdit(GuiPreferences * form)
                this, SIGNAL(changed()));
        connect(scrollBelowCB, SIGNAL(clicked()),
                this, SIGNAL(changed()));
-       connect(macLikeWordMovementCB, SIGNAL(clicked()),
+       connect(macLikeCursorMovementCB, SIGNAL(clicked()),
                this, SIGNAL(changed()));
        connect(sortEnvironmentsCB, SIGNAL(clicked()),
                this, SIGNAL(changed()));
@@ -2636,16 +2727,18 @@ PrefEdit::PrefEdit(GuiPreferences * form)
                this, SIGNAL(changed()));
        connect(toggleScrollbarCB, SIGNAL(toggled(bool)),
                this, SIGNAL(changed()));
+       connect(toggleStatusbarCB, SIGNAL(toggled(bool)),
+               this, SIGNAL(changed()));
        connect(toggleToolbarsCB, SIGNAL(toggled(bool)),
                this, SIGNAL(changed()));
 }
 
 
-void PrefEdit::apply(LyXRC & rc) const
+void PrefEdit::applyRC(LyXRC & rc) const
 {
        rc.cursor_follows_scrollbar = cursorFollowsCB->isChecked();
        rc.scroll_below_document = scrollBelowCB->isChecked();
-       rc.mac_like_word_movement = macLikeWordMovementCB->isChecked();
+       rc.mac_like_cursor_movement = macLikeCursorMovementCB->isChecked();
        rc.sort_layouts = sortEnvironmentsCB->isChecked();
        rc.group_layouts = groupEnvironmentsCB->isChecked();
        switch (macroEditStyleCO->currentIndex()) {
@@ -2656,6 +2749,7 @@ void PrefEdit::apply(LyXRC & rc) const
        rc.cursor_width = cursorWidthSB->value();
        rc.full_screen_toolbars = toggleToolbarsCB->isChecked();
        rc.full_screen_scrollbar = toggleScrollbarCB->isChecked();
+       rc.full_screen_statusbar = toggleStatusbarCB->isChecked();
        rc.full_screen_tabbar = toggleTabbarCB->isChecked();
        rc.full_screen_menubar = toggleMenubarCB->isChecked();
        rc.full_screen_width = fullscreenWidthSB->value();
@@ -2663,16 +2757,17 @@ void PrefEdit::apply(LyXRC & rc) const
 }
 
 
-void PrefEdit::update(LyXRC const & rc)
+void PrefEdit::updateRC(LyXRC const & rc)
 {
        cursorFollowsCB->setChecked(rc.cursor_follows_scrollbar);
        scrollBelowCB->setChecked(rc.scroll_below_document);
-       macLikeWordMovementCB->setChecked(rc.mac_like_word_movement);
+       macLikeCursorMovementCB->setChecked(rc.mac_like_cursor_movement);
        sortEnvironmentsCB->setChecked(rc.sort_layouts);
        groupEnvironmentsCB->setChecked(rc.group_layouts);
        macroEditStyleCO->setCurrentIndex(rc.macro_edit_style);
        cursorWidthSB->setValue(rc.cursor_width);
        toggleScrollbarCB->setChecked(rc.full_screen_scrollbar);
+       toggleStatusbarCB->setChecked(rc.full_screen_statusbar);
        toggleToolbarsCB->setChecked(rc.full_screen_toolbars);
        toggleTabbarCB->setChecked(rc.full_screen_tabbar);
        toggleMenubarCB->setChecked(rc.full_screen_menubar);
@@ -2696,7 +2791,9 @@ GuiShortcutDialog::GuiShortcutDialog(QWidget * parent) : QDialog(parent)
 
 
 PrefShortcuts::PrefShortcuts(GuiPreferences * form)
-       : PrefModule(qt_(catEditing), qt_("Shortcuts"), form)
+       : PrefModule(catEditing, N_("Shortcuts"), form),
+         editItem_(0), mathItem_(0), bufferItem_(0), layoutItem_(0),
+         systemItem_(0)
 {
        setupUi(this);
 
@@ -2714,27 +2811,25 @@ PrefShortcuts::PrefShortcuts(GuiPreferences * form)
 
        shortcut_ = new GuiShortcutDialog(this);
        shortcut_bc_.setPolicy(ButtonPolicy::OkCancelPolicy);
-       shortcut_bc_.setOK(shortcut_->okPB);
-       shortcut_bc_.setCancel(shortcut_->cancelPB);
+       shortcut_bc_.setOK(shortcut_->buttonBox->button(QDialogButtonBox::Ok));
+       shortcut_bc_.setCancel(shortcut_->buttonBox->button(QDialogButtonBox::Cancel));
 
-       connect(shortcut_->okPB, SIGNAL(clicked()),
-               shortcut_, SLOT(accept()));
-       connect(shortcut_->okPB, SIGNAL(clicked()),
+       connect(shortcut_->buttonBox, SIGNAL(accepted()),
                this, SIGNAL(changed()));
-       connect(shortcut_->cancelPB, SIGNAL(clicked()),
+       connect(shortcut_->buttonBox, SIGNAL(rejected()),
                shortcut_, SLOT(reject()));
        connect(shortcut_->clearPB, SIGNAL(clicked()),
                this, SLOT(shortcutClearPressed()));
        connect(shortcut_->removePB, SIGNAL(clicked()),
                this, SLOT(shortcutRemovePressed()));
-       connect(shortcut_->okPB, SIGNAL(clicked()),
+       connect(shortcut_->buttonBox, SIGNAL(accepted()),
                this, SLOT(shortcutOkPressed()));
-       connect(shortcut_->cancelPB, SIGNAL(clicked()),
+       connect(shortcut_->buttonBox, SIGNAL(rejected()),
                this, SLOT(shortcutCancelPressed()));
 }
 
 
-void PrefShortcuts::apply(LyXRC & rc) const
+void PrefShortcuts::applyRC(LyXRC & rc) const
 {
        rc.bind_file = internal_path(fromqstr(bindFileED->text()));
        // write user_bind and user_unbind to .lyx/bind/user.bind
@@ -2761,7 +2856,7 @@ void PrefShortcuts::apply(LyXRC & rc) const
 }
 
 
-void PrefShortcuts::update(LyXRC const & rc)
+void PrefShortcuts::updateRC(LyXRC const & rc)
 {
        bindFileED->setText(toqstr(external_path(rc.bind_file)));
        //
@@ -2816,17 +2911,30 @@ void PrefShortcuts::updateShortcutsTW()
        KeyMap::BindingList::const_iterator it = bindinglist.begin();
        KeyMap::BindingList::const_iterator it_end = bindinglist.end();
        for (; it != it_end; ++it)
-               insertShortcutItem(it->request, it->sequence, KeyMap::ItemType(it->tag));
+               insertShortcutItem(it->request, it->sequence, it->tag);
 
        shortcutsTW->sortItems(0, Qt::AscendingOrder);
-       QList<QTreeWidgetItem*> items = shortcutsTW->selectedItems();
-       removePB->setEnabled(!items.isEmpty() && !items[0]->text(1).isEmpty());
-       modifyPB->setEnabled(!items.isEmpty());
-
+       on_shortcutsTW_itemSelectionChanged();
+       on_searchLE_textEdited();
        shortcutsTW->resizeColumnToContents(0);
 }
 
 
+//static
+KeyMap::ItemType PrefShortcuts::itemType(QTreeWidgetItem & item)
+{
+       return static_cast<KeyMap::ItemType>(item.data(0, Qt::UserRole).toInt());
+}
+
+
+//static
+bool PrefShortcuts::isAlwaysHidden(QTreeWidgetItem & item)
+{
+       // Hide rebound system settings that are empty
+       return itemType(item) == KeyMap::UserUnbind && item.text(1).isEmpty();
+}
+
+
 void PrefShortcuts::setItemType(QTreeWidgetItem * item, KeyMap::ItemType tag)
 {
        item->setData(0, Qt::UserRole, QVariant(tag));
@@ -2846,7 +2954,7 @@ void PrefShortcuts::setItemType(QTreeWidgetItem * item, KeyMap::ItemType tag)
                font.setStrikeOut(true);
                break;
        }
-
+       item->setHidden(isAlwaysHidden(*item));
        item->setFont(1, font);
 }
 
@@ -2859,7 +2967,6 @@ QTreeWidgetItem * PrefShortcuts::insertShortcutItem(FuncRequest const & lfun,
        QString const lfun_name = toqstr(from_utf8(action_name)
                        + ' ' + lfun.argument());
        QString const shortcut = toqstr(seq.print(KeySequence::ForGui));
-       KeyMap::ItemType item_tag = tag;
 
        QTreeWidgetItem * newItem = 0;
        // for unbind items, try to find an existing item in the system bind list
@@ -2867,15 +2974,15 @@ QTreeWidgetItem * PrefShortcuts::insertShortcutItem(FuncRequest const & lfun,
                QList<QTreeWidgetItem*> const items = shortcutsTW->findItems(lfun_name,
                        Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 0);
                for (int i = 0; i < items.size(); ++i) {
-                       if (items[i]->text(1) == shortcut)
+                       if (items[i]->text(1) == shortcut) {
                                newItem = items[i];
                                break;
                        }
+               }
                // if not found, this unbind item is KeyMap::UserExtraUnbind
                // Such an item is not displayed to avoid confusion (what is
                // unmatched removed?).
                if (!newItem) {
-                       item_tag = KeyMap::UserExtraUnbind;
                        return 0;
                }
        }
@@ -2908,7 +3015,7 @@ QTreeWidgetItem * PrefShortcuts::insertShortcutItem(FuncRequest const & lfun,
        newItem->setText(1, shortcut);
        // record BindFile representation to recover KeySequence when needed.
        newItem->setData(1, Qt::UserRole, toqstr(seq.print(KeySequence::BindFile)));
-       setItemType(newItem, item_tag);
+       setItemType(newItem, tag);
        return newItem;
 }
 
@@ -2921,9 +3028,7 @@ void PrefShortcuts::on_shortcutsTW_itemSelectionChanged()
        if (items.isEmpty())
                return;
 
-       KeyMap::ItemType tag = 
-               static_cast<KeyMap::ItemType>(items[0]->data(0, Qt::UserRole).toInt());
-       if (tag == KeyMap::UserUnbind)
+       if (itemType(*items[0]) == KeyMap::UserUnbind)
                removePB->setText(qt_("Res&tore"));
        else
                removePB->setText(qt_("Remo&ve"));
@@ -2952,6 +3057,23 @@ void PrefShortcuts::modifyShortcut()
 }
 
 
+void PrefShortcuts::unhideEmpty(QString const & lfun, bool select)
+{
+       // list of items that match lfun
+       QList<QTreeWidgetItem*> items = shortcutsTW->findItems(lfun,
+            Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 0);
+       for (int i = 0; i < items.size(); ++i) {
+               QTreeWidgetItem * item = items[i];
+               if (isAlwaysHidden(*item)) {
+                       setItemType(item, KeyMap::System);
+                       if (select)
+                               shortcutsTW->setCurrentItem(item);
+                       return;
+               }
+       }
+}
+
+
 void PrefShortcuts::removeShortcut()
 {
        // it seems that only one item can be selected, but I am
@@ -2961,10 +3083,8 @@ void PrefShortcuts::removeShortcut()
                string shortcut = fromqstr(items[i]->data(1, Qt::UserRole).toString());
                string lfun = fromqstr(items[i]->text(0));
                FuncRequest func = lyxaction.lookupFunc(lfun);
-               KeyMap::ItemType tag = 
-                       static_cast<KeyMap::ItemType>(items[i]->data(0, Qt::UserRole).toInt());
 
-               switch (tag) {
+               switch (itemType(*items[i])) {
                case KeyMap::System: {
                        // for system bind, we do not touch the item
                        // but add an user unbind item
@@ -2983,11 +3103,19 @@ void PrefShortcuts::removeShortcut()
                        else
                                shortcutsTW->scrollToItem(parent);
                        user_bind_.unbind(shortcut, func);
+                       // If this user binding hid an empty system binding, unhide the
+                       // latter and select it.
+                       unhideEmpty(items[i]->text(0), true);
                        break;
                }
                case KeyMap::UserUnbind: {
                        // for user_unbind, we remove the unbind, and the item
                        // become KeyMap::System again.
+                       KeySequence seq;
+                       seq.parse(shortcut);
+                       // Ask the user to replace current binding
+                       if (!validateNewShortcut(func, seq, QString()))
+                               break;
                        user_unbind_.unbind(shortcut, func);
                        setItemType(items[i], KeyMap::System);
                        removePB->setText(qt_("Remo&ve"));
@@ -3005,6 +3133,37 @@ void PrefShortcuts::removeShortcut()
 }
 
 
+void PrefShortcuts::deactivateShortcuts(QList<QTreeWidgetItem*> const & items)
+{
+       for (int i = 0; i < items.size(); ++i) {
+               string shortcut = fromqstr(items[i]->data(1, Qt::UserRole).toString());
+               string lfun = fromqstr(items[i]->text(0));
+               FuncRequest func = lyxaction.lookupFunc(lfun);
+
+               switch (itemType(*items[i])) {
+               case KeyMap::System:
+                       // for system bind, we do not touch the item
+                       // but add an user unbind item
+                       user_unbind_.bind(shortcut, func);
+                       setItemType(items[i], KeyMap::UserUnbind);
+                       break;
+
+               case KeyMap::UserBind: {
+                       // for user_bind, we remove this bind
+                       QTreeWidgetItem * parent = items[i]->parent();
+                       int itemIdx = parent->indexOfChild(items[i]);
+                       parent->takeChild(itemIdx);
+                       user_bind_.unbind(shortcut, func);
+                       unhideEmpty(items[i]->text(0), false);
+                       break;
+               }
+               default:
+                       break;
+               }
+       }
+}
+
+
 void PrefShortcuts::selectBind()
 {
        QString file = form_->browsebind(internalPath(bindFileED->text()));
@@ -3044,8 +3203,11 @@ void PrefShortcuts::on_searchLE_textEdited()
        if (searchLE->text().isEmpty()) {
                // show all hidden items
                QTreeWidgetItemIterator it(shortcutsTW, QTreeWidgetItemIterator::Hidden);
-               while (*it)
-                       shortcutsTW->setItemHidden(*it++, false);
+               for (; *it; ++it)
+                       shortcutsTW->setItemHidden(*it, isAlwaysHidden(**it));
+               // close all categories
+               for (int i = 0; i < shortcutsTW->topLevelItemCount(); ++i)
+                       shortcutsTW->collapseItem(shortcutsTW->topLevelItem(i));
                return;
        }
        // search both columns
@@ -3059,10 +3221,11 @@ void PrefShortcuts::on_searchLE_textEdited()
        while (*it)
                shortcutsTW->setItemHidden(*it++, true);
        // show matched items
-       for (int i = 0; i < matched.size(); ++i) {
-               shortcutsTW->setItemHidden(matched[i], false);
-        shortcutsTW->setItemExpanded(matched[i]->parent(), true);
-       }
+       for (int i = 0; i < matched.size(); ++i)
+               if (!isAlwaysHidden(*matched[i])) {
+                       shortcutsTW->setItemHidden(matched[i], false);
+                       shortcutsTW->setItemExpanded(matched[i]->parent(), true);
+               }
 }
 
 
@@ -3075,56 +3238,101 @@ docstring makeCmdString(FuncRequest const & f)
 }
 
 
-void PrefShortcuts::shortcutOkPressed()
+FuncRequest PrefShortcuts::currentBinding(KeySequence const & k)
 {
-       QString const new_lfun = shortcut_->lfunLE->text();
-       FuncRequest func = lyxaction.lookupFunc(fromqstr(new_lfun));
+       FuncRequest res = user_bind_.getBinding(k);
+       if (res.action() != LFUN_UNKNOWN_ACTION)
+               return res;
+       res = system_bind_.getBinding(k);
+       // Check if it is unbound. Note: user_unbind_ can only unbind one
+       // FuncRequest per key sequence.
+       if (user_unbind_.getBinding(k) == res)
+               return FuncRequest::unknown;
+       return res;
+}
+
 
+bool PrefShortcuts::validateNewShortcut(FuncRequest const & func,
+                                        KeySequence const & k,
+                                        QString const & lfun_to_modify)
+{
        if (func.action() == LFUN_UNKNOWN_ACTION) {
                Alert::error(_("Failed to create shortcut"),
                        _("Unknown or invalid LyX function"));
-               return;
+               return false;
+       }
+
+       // It is not currently possible to bind Hidden lfuns such as self-insert. In
+       // the future, to remove this limitation, see GuiPrefs::insertShortcutItem
+       // and how it is used in GuiPrefs::shortcutOkPressed.
+       if (lyxaction.getActionType(func.action()) == LyXAction::Hidden) {
+               Alert::error(_("Failed to create shortcut"),
+                       _("This LyX function is hidden and cannot be bound."));
+               return false;
        }
 
-       KeySequence k = shortcut_->shortcutWG->getKeySequence();
        if (k.length() == 0) {
                Alert::error(_("Failed to create shortcut"),
                        _("Invalid or empty key sequence"));
-               return;
+               return false;
        }
 
-       // check to see if there's been any change
-       FuncRequest oldBinding = system_bind_.getBinding(k);
-       if (oldBinding.action() == LFUN_UNKNOWN_ACTION)
-               oldBinding = user_bind_.getBinding(k);
+       FuncRequest oldBinding = currentBinding(k);
        if (oldBinding == func)
-               // nothing has changed
-               return;
-       
-       // make sure this key isn't already bound---and, if so, not unbound
-       FuncCode const unbind = user_unbind_.getBinding(k).action();
+               // nothing to change
+               return false;
+
+       // make sure this key isn't already bound---and, if so, prompt user
+       // (exclude the lfun the user already wants to modify)
        docstring const action_string = makeCmdString(oldBinding);
-       if (oldBinding.action() > LFUN_NOACTION && unbind == LFUN_UNKNOWN_ACTION
-                 && save_lfun_ != toqstr(action_string)) {
-               // FIXME Perhaps we should offer to over-write the old shortcut?
-               // If so, we'll need to remove it from our list, etc.
-               Alert::error(_("Failed to create shortcut"),
-                       bformat(_("Shortcut `%1$s' is already bound to:\n%2$s\n"
-                         "You need to remove that binding before creating a new one."), 
-                       k.print(KeySequence::ForGui), action_string));
-               return;
+       if (oldBinding.action() != LFUN_UNKNOWN_ACTION
+           && lfun_to_modify != toqstr(action_string)) {
+               docstring const new_action_string = makeCmdString(func);
+               docstring const text = bformat(_("Shortcut `%1$s' is already bound to "
+                                                "%2$s.\n"
+                                                "Are you sure you want to unbind the "
+                                                "current shortcut and bind it to %3$s?"),
+                                              k.print(KeySequence::ForGui), action_string,
+                                              new_action_string);
+               int ret = Alert::prompt(_("Redefine shortcut?"),
+                                       text, 0, 1, _("&Redefine"), _("&Cancel"));
+               if (ret != 0)
+                       return false;
+               QString const sequence_text = toqstr(k.print(KeySequence::ForGui));
+               QList<QTreeWidgetItem*> items = shortcutsTW->findItems(sequence_text,
+                       Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 1);
+               deactivateShortcuts(items);
        }
+       return true;
+}
 
-       if (!save_lfun_.isEmpty())
+
+void PrefShortcuts::shortcutOkPressed()
+{
+       QString const new_lfun = shortcut_->lfunLE->text();
+       FuncRequest func = lyxaction.lookupFunc(fromqstr(new_lfun));
+       KeySequence k = shortcut_->shortcutWG->getKeySequence();
+
+       // save_lfun_ contains the text of the lfun to modify, if the user clicked
+       // "modify", or is empty if they clicked "new" (which I do not really like)
+       if (!validateNewShortcut(func, k, save_lfun_))
+               return;
+
+       if (!save_lfun_.isEmpty()) {
                // real modification of the lfun's shortcut,
                // so remove the previous one
-               removeShortcut();
+               QList<QTreeWidgetItem*> to_modify = shortcutsTW->selectedItems();
+               deactivateShortcuts(to_modify);
+       }
+
+       shortcut_->accept();
 
        QTreeWidgetItem * item = insertShortcutItem(func, k, KeyMap::UserBind);
        if (item) {
                user_bind_.bind(&k, func);
                shortcutsTW->sortItems(0, Qt::AscendingOrder);
                shortcutsTW->setItemExpanded(item->parent(), true);
+               shortcutsTW->setCurrentItem(item);
                shortcutsTW->scrollToItem(item);
        } else {
                Alert::error(_("Failed to create shortcut"),
@@ -3159,7 +3367,7 @@ void PrefShortcuts::shortcutRemovePressed()
 /////////////////////////////////////////////////////////////////////
 
 PrefIdentity::PrefIdentity(GuiPreferences * form)
-       : PrefModule(QString(), qt_("Identity"), form)
+       : PrefModule(QString(), N_("Identity"), form)
 {
        setupUi(this);
 
@@ -3173,14 +3381,14 @@ PrefIdentity::PrefIdentity(GuiPreferences * form)
 }
 
 
-void PrefIdentity::apply(LyXRC & rc) const
+void PrefIdentity::applyRC(LyXRC & rc) const
 {
        rc.user_name = fromqstr(nameED->text());
        rc.user_email = fromqstr(emailED->text());
 }
 
 
-void PrefIdentity::update(LyXRC const & rc)
+void PrefIdentity::updateRC(LyXRC const & rc)
 {
        nameED->setText(toqstr(rc.user_name));
        emailED->setText(toqstr(rc.user_email));
@@ -3195,18 +3403,17 @@ void PrefIdentity::update(LyXRC const & rc)
 /////////////////////////////////////////////////////////////////////
 
 GuiPreferences::GuiPreferences(GuiView & lv)
-       : GuiDialog(lv, "prefs", qt_("Preferences")), update_screen_font_(false)
+       : GuiDialog(lv, "prefs", qt_("Preferences"))
 {
        setupUi(this);
 
        QDialog::setModal(false);
 
-       connect(savePB, SIGNAL(clicked()), this, SLOT(slotOK()));
-       connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
-       connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
-       connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore()));
+       connect(buttonBox, SIGNAL(clicked(QAbstractButton *)),
+               this, SLOT(slotButtonBox(QAbstractButton *)));
 
        addModule(new PrefUserInterface(this));
+       addModule(new PrefDocHandling(this));
        addModule(new PrefEdit(this));
        addModule(new PrefShortcuts(this));
        PrefScreenFonts * screenfonts = new PrefScreenFonts(this);
@@ -3225,10 +3432,8 @@ GuiPreferences::GuiPreferences(GuiView & lv)
        addModule(new PrefLanguage(this));
        addModule(new PrefSpellchecker(this));
 
-       //for strftime validator
-       PrefOutput * output = new PrefOutput(this); 
+       PrefOutput * output = new PrefOutput(this);
        addModule(output);
-       addModule(new PrefPrinter(this));
        addModule(new PrefLatex(this));
 
        PrefConverters * converters = new PrefConverters(this);
@@ -3238,7 +3443,7 @@ GuiPreferences::GuiPreferences(GuiView & lv)
        addModule(converters);
        addModule(formats);
 
-       prefsPS->setCurrentPanel(qt_("User Interface"));
+       prefsPS->setCurrentPanel("User Interface");
 // FIXME: hack to work around resizing bug in Qt >= 4.2
 // bug verified with Qt 4.2.{0-3} (JSpitzm)
 #if QT_VERSION >= 0x040200
@@ -3246,13 +3451,14 @@ GuiPreferences::GuiPreferences(GuiView & lv)
 #endif
 
        bc().setPolicy(ButtonPolicy::PreferencesPolicy);
-       bc().setOK(savePB);
-       bc().setApply(applyPB);
-       bc().setCancel(closePB);
-       bc().setRestore(restorePB);
+       bc().setOK(buttonBox->button(QDialogButtonBox::Ok));
+       bc().setApply(buttonBox->button(QDialogButtonBox::Apply));
+       bc().setCancel(buttonBox->button(QDialogButtonBox::Cancel));
+       bc().setRestore(buttonBox->button(QDialogButtonBox::Reset));
 
-       // initialize the strftime validator
-       bc().addCheckedLineEdit(output->DateED);
+       guilyxfiles_ = new GuiLyXFiles(lv);
+       connect(guilyxfiles_, SIGNAL(fileSelected(QString)),
+                       this, SLOT(slotFileSelected(QString)));
 }
 
 
@@ -3274,42 +3480,41 @@ void GuiPreferences::change_adaptor()
 }
 
 
-void GuiPreferences::apply(LyXRC & rc) const
+void GuiPreferences::applyRC(LyXRC & rc) const
 {
        size_t end = modules_.size();
        for (size_t i = 0; i != end; ++i)
-               modules_[i]->apply(rc);
+               modules_[i]->applyRC(rc);
 }
 
 
-void GuiPreferences::updateRc(LyXRC const & rc)
+void GuiPreferences::updateRC(LyXRC const & rc)
 {
        size_t const end = modules_.size();
        for (size_t i = 0; i != end; ++i)
-               modules_[i]->update(rc);
+               modules_[i]->updateRC(rc);
 }
 
 
 void GuiPreferences::applyView()
 {
-       apply(rc());
+       applyRC(rc());
 }
 
 
 bool GuiPreferences::initialiseParams(string const &)
 {
        rc_ = lyxrc;
-       formats_ = lyx::formats;
+       formats_ = theFormats();
        converters_ = theConverters();
        converters_.update(formats_);
        movers_ = theMovers();
        colors_.clear();
-       update_screen_font_ = false;
-       
-       updateRc(rc_);
-       // Make sure that the bc is in the INITIAL state  
-       if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))  
-               bc().restore();  
+
+       updateRC(rc_);
+       // Make sure that the bc is in the INITIAL state
+       if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
+               bc().restore();
 
        return true;
 }
@@ -3325,31 +3530,25 @@ void GuiPreferences::dispatchParams()
        prefsApplied(rc_);
        // FIXME: these need lfuns
        // FIXME UNICODE
-       Author const & author = 
+       Author const & author =
                Author(from_utf8(rc_.user_name), from_utf8(rc_.user_email));
        theBufferList().recordCurrentAuthor(author);
 
-       lyx::formats = formats_;
+       theFormats() = formats_;
 
        theConverters() = converters_;
-       theConverters().update(lyx::formats);
+       theConverters().update(formats_);
        theConverters().buildGraph();
+       theBufferList().invalidateConverterCache();
 
        theMovers() = movers_;
 
-       vector<string>::const_iterator it = colors_.begin();
-       vector<string>::const_iterator const end = colors_.end();
-       for (; it != end; ++it)
-               dispatch(FuncRequest(LFUN_SET_COLOR, *it));
+       for (string const & color : colors_)
+               dispatch(FuncRequest(LFUN_SET_COLOR, color));
        colors_.clear();
 
-       if (update_screen_font_) {
-               dispatch(FuncRequest(LFUN_SCREEN_FONT_UPDATE));
-               update_screen_font_ = false;
-       }
-
-       // The Save button has been pressed
-       if (isClosing())
+       // Save permanently
+       if (!tempSaveCB->isChecked())
                dispatch(FuncRequest(LFUN_PREFERENCES_SAVE));
 }
 
@@ -3360,91 +3559,61 @@ void GuiPreferences::setColor(ColorCode col, QString const & hex)
 }
 
 
-void GuiPreferences::updateScreenFonts()
+void GuiPreferences::slotFileSelected(QString const file)
 {
-       update_screen_font_ = true;
+       uifile_ = file;
 }
 
 
-QString GuiPreferences::browsebind(QString const & file) const
+QString GuiPreferences::browseLibFile(QString const & dir,
+       QString const & name, QString const & ext)
 {
-       return browseLibFile("bind", file, "bind", qt_("Choose bind file"),
-                            QStringList(qt_("LyX bind files (*.bind)")));
+       uifile_.clear();
+
+       guilyxfiles_->passParams(fromqstr(dir));
+       guilyxfiles_->selectItem(name);
+       guilyxfiles_->exec();
+
+       QString const result = uifile_;
+
+       // remove the extension if it is the default one
+       QString noextresult;
+       if (getExtension(result) == ext)
+               noextresult = removeExtension(result);
+       else
+               noextresult = result;
+
+       // remove the directory, if it is the default one
+       QString const file = onlyFileName(noextresult);
+       if (toqstr(libFileSearch(dir, file, ext).absFileName()) == result)
+               return file;
+       else
+               return noextresult;
 }
 
 
-QString GuiPreferences::browseUI(QString const & file) const
+QString GuiPreferences::browsebind(QString const & file)
 {
-       return browseLibFile("ui", file, "ui", qt_("Choose UI file"),
-                            QStringList(qt_("LyX UI files (*.ui)")));
+       return browseLibFile("bind", file, "bind");
 }
 
 
-QString GuiPreferences::browsekbmap(QString const & file) const
+QString GuiPreferences::browseUI(QString const & file)
 {
-       return browseLibFile("kbd", file, "kmap", qt_("Choose keyboard map"),
-                            QStringList(qt_("LyX keyboard maps (*.kmap)")));
+       return browseLibFile("ui", file, "ui");
 }
 
 
-QString GuiPreferences::browse(QString const & file,
-       QString const & title) const
+QString GuiPreferences::browsekbmap(QString const & file)
 {
-       return browseFile(file, title, QStringList(), true);
+       return browseLibFile("kbd", file, "kmap");
 }
 
 
-// We support less paper sizes than the document dialog
-// Therefore this adjustment is needed.
-PAPER_SIZE GuiPreferences::toPaperSize(int i) const
+QString GuiPreferences::browse(QString const & file,
+       QString const & title) const
 {
-       switch (i) {
-       case 0:
-               return PAPER_DEFAULT;
-       case 1:
-               return PAPER_USLETTER;
-       case 2:
-               return PAPER_USLEGAL;
-       case 3:
-               return PAPER_USEXECUTIVE;
-       case 4:
-               return PAPER_A3;
-       case 5:
-               return PAPER_A4;
-       case 6:
-               return PAPER_A5;
-       case 7:
-               return PAPER_B5;
-       default:
-               // should not happen
-               return PAPER_DEFAULT;
-       }
-}
-
-
-int GuiPreferences::fromPaperSize(PAPER_SIZE papersize) const
-{
-       switch (papersize) {
-       case PAPER_DEFAULT:
-               return 0;
-       case PAPER_USLETTER:
-               return 1;
-       case PAPER_USLEGAL:
-               return 2;
-       case PAPER_USEXECUTIVE:
-               return 3;
-       case PAPER_A3:
-               return 4;
-       case PAPER_A4:
-               return 5;
-       case PAPER_A5:
-               return 6;
-       case PAPER_B5:
-               return 7;
-       default:
-               // should not happen
-               return 0;
-       }
+       return browseFile(file, title, QStringList(), true);
 }