]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/GuiDocument.cpp
On Linux show in crash message box the backtrace
[lyx.git] / src / frontends / qt4 / GuiDocument.cpp
index 16242c09745e3a9cff3d42a7235277a3afa07809..732c8430c85e2732b7d980f6de8343830e6219f1 100644 (file)
@@ -50,6 +50,7 @@
 #include "qt_helpers.h"
 #include "Spacing.h"
 #include "TextClass.h"
+#include "Undo.h"
 
 #include "insets/InsetListingsParams.h"
 
@@ -130,48 +131,6 @@ char const * backref_opts_gui[] =
 };
 
 
-char const * packages_gui[][4] =
-{
-       {"amsmath",
-        N_("&Use amsmath package automatically"),
-        N_("Use ams&math package"),
-        N_("The LaTeX package amsmath is only used if AMS formula types or symbols from the AMS math toolbars are inserted into formulas")},
-       {"amssymb",
-        N_("&Use amssymb package automatically"),
-        N_("Use amssymb package"),
-        N_("The LaTeX package amssymb is only used if symbols from the AMS math toolbars are inserted into formulas")},
-       {"esint",
-        N_("Use esint package &automatically"),
-        N_("Use &esint package"),
-        N_("The LaTeX package esint is only used if special integral symbols are inserted into formulas")},
-       {"mathdots",
-        N_("Use math&dots package automatically"),
-        N_("Use mathdo&ts package"),
-        N_("The LaTeX package mathdots is only used if the command \\iddots is inserted into formulas")},
-       {"mathtools",
-        N_("Use mathtools package automatically"),
-        N_("Use mathtools package"),
-        N_("The LaTeX package mathtools is only used if some mathematical relations are inserted into formulas")},
-       {"mhchem",
-        N_("Use mhchem &package automatically"),
-        N_("Use mh&chem package"),
-        N_("The LaTeX package mhchem is only used if either the command \\ce or \\cf is inserted into formulas")},
-       {"stackrel",
-        N_("Use stackrel package automatically"),
-        N_("Use stackrel package"),
-        N_("The LaTeX package stackrel is only used if the command \\stackrel with subscript is inserted into formulas")},
-       {"stmaryrd",
-        N_("Use stmaryrd package automatically"),
-        N_("Use stmaryrd package"),
-        N_("The LaTeX package stmaryrd is only used if symbols from the St Mary's Road symbol font for theoretical computer science are inserted into formulas")},
-       {"undertilde",
-        N_("Use u&ndertilde package automatically"),
-        N_("Use undertilde pac&kage"),
-        N_("The LaTeX package undertilde is only used if you use the math frame decoration 'utilde'")},
-       {"", "", "", ""}
-};
-
-
 vector<string> engine_types_;
 vector<pair<string, QString> > pagestyles;
 
@@ -191,6 +150,7 @@ RGBColor set_fontcolor;
 bool is_fontcolor;
 RGBColor set_notefontcolor;
 RGBColor set_boxbgcolor;
+bool forced_fontspec_activation;
 
 namespace {
 // used when sorting the textclass list.
@@ -559,7 +519,7 @@ LocalLayout::LocalLayout() : current_id_(0), validated_(false)
 
 void LocalLayout::update(BufferParams const & params, BufferId id)
 {
-       QString layout = toqstr(params.local_layout);
+       QString layout = toqstr(params.getLocalLayout(false));
        // Nothing to do if the params and preamble are unchanged.
        if (id == current_id_
                && layout == locallayoutTE->document()->toPlainText())
@@ -575,7 +535,7 @@ void LocalLayout::update(BufferParams const & params, BufferId id)
 void LocalLayout::apply(BufferParams & params)
 {
        string const layout = fromqstr(locallayoutTE->document()->toPlainText());
-       params.local_layout = layout;
+       params.setLocalLayout(layout, false);
 }
 
 
@@ -850,8 +810,12 @@ GuiDocument::GuiDocument(GuiView & lv)
                this, SLOT(change_adaptor()));
        connect(fontModule->fontScCB, SIGNAL(clicked()),
                this, SLOT(change_adaptor()));
+       connect(fontModule->fontScCB, SIGNAL(toggled(bool)),
+               this, SLOT(fontScToggled(bool)));
        connect(fontModule->fontOsfCB, SIGNAL(clicked()),
                this, SLOT(change_adaptor()));
+       connect(fontModule->fontOsfCB, SIGNAL(toggled(bool)),
+               this, SLOT(fontOsfToggled(bool)));
 
        fontModule->fontencLE->setValidator(new NoNewLineValidator(
                fontModule->fontencLE));
@@ -1187,49 +1151,71 @@ GuiDocument::GuiDocument(GuiView & lv)
 
 
        // maths
-       // FIXME This UI has problems:
-       //       1) It is not generic, packages_gui needs to be changed for each new package
-       //       2) Two checkboxes have 4 states, but one is invalid (both pressed)
-       //       3) The auto cb is not disabled if the use cb is checked
        mathsModule = new UiWidget<Ui::MathsUi>;
-       vector<string> const & packages = BufferParams::auto_packages();
-        for (size_t i = 0; i < packages.size(); ++i) {
-               // Use the order of BufferParams::auto_packages() for easier
-               // access in applyView() and paramsToDialog()
-               int n = 0;
-               for (n = 0; packages_gui[n][0][0]; n++)
-                       if (packages_gui[n][0] == packages[i])
-                               break;
-               // If this fires somebody changed
-               // BufferParams::auto_packages() without adjusting packages_gui
-               LASSERT(packages_gui[n][0][0], /**/);
-               QString autoText = qt_(packages_gui[n][1]);
-               QString alwaysText = qt_(packages_gui[n][2]);
-               QString autoTooltip = qt_(packages_gui[n][3]);
+       QStringList headers;
+       headers << qt_("Package") << qt_("Load automatically")
+               << qt_("Load always") << qt_("Do not load");
+       mathsModule->packagesTW->setHorizontalHeaderLabels(headers);
+       setSectionResizeMode(mathsModule->packagesTW->horizontalHeader(), QHeaderView::Stretch);        
+       map<string, string> const & packages = BufferParams::auto_packages();
+       mathsModule->packagesTW->setRowCount(packages.size());
+       int i = 0;
+       for (map<string, string>::const_iterator it = packages.begin();
+            it != packages.end(); ++it) {
+               docstring const package = from_ascii(it->first);
+               QString autoTooltip = qt_(it->second);
                QString alwaysTooltip;
-               if (packages[i] == "amsmath")
+               if (package == "amsmath")
                        alwaysTooltip =
                                qt_("The AMS LaTeX packages are always used");
                else
                        alwaysTooltip = toqstr(bformat(
                                _("The LaTeX package %1$s is always used"),
-                               from_ascii(packages[i])));
-               QCheckBox * autoCB = new QCheckBox(autoText, mathsModule);
-               QCheckBox * alwaysCB = new QCheckBox(alwaysText, mathsModule);
-               mathsModule->gridLayout->addWidget(autoCB, 2 * i, 0);
-               mathsModule->gridLayout->addWidget(alwaysCB, 2 * i + 1, 0);
-               autoCB->setToolTip(autoTooltip);
-               alwaysCB->setToolTip(alwaysTooltip);
-               connect(autoCB, SIGNAL(toggled(bool)),
-                       alwaysCB, SLOT(setDisabled(bool)));
-               connect(autoCB, SIGNAL(clicked()),
+                               package));
+               QString neverTooltip;
+               if (package == "amsmath")
+                       neverTooltip =
+                               qt_("The AMS LaTeX packages are never used");
+               else
+                       neverTooltip = toqstr(bformat(
+                               _("The LaTeX package %1$s is never used"),
+                               package));
+               QRadioButton * autoRB = new QRadioButton(mathsModule);
+               QRadioButton * alwaysRB = new QRadioButton(mathsModule);
+               QRadioButton * neverRB = new QRadioButton(mathsModule);
+               QButtonGroup * packageGroup = new QButtonGroup(mathsModule);
+               packageGroup->addButton(autoRB);
+               packageGroup->addButton(alwaysRB);
+               packageGroup->addButton(neverRB);
+               autoRB->setToolTip(autoTooltip);
+               alwaysRB->setToolTip(alwaysTooltip);
+               neverRB->setToolTip(neverTooltip);
+               QTableWidgetItem * pack = new QTableWidgetItem(toqstr(package));
+               mathsModule->packagesTW->setItem(i, 0, pack);
+               mathsModule->packagesTW->setCellWidget(i, 1, autoRB);
+               mathsModule->packagesTW->setCellWidget(i, 2, alwaysRB);
+               mathsModule->packagesTW->setCellWidget(i, 3, neverRB);
+
+               connect(autoRB, SIGNAL(clicked()),
                        this, SLOT(change_adaptor()));
-               connect(alwaysCB, SIGNAL(clicked()),
+               connect(alwaysRB, SIGNAL(clicked()),
                        this, SLOT(change_adaptor()));
+               connect(neverRB, SIGNAL(clicked()),
+                       this, SLOT(change_adaptor()));
+               ++i;
        }
-       QSpacerItem * spacer = new QSpacerItem(20, 20, QSizePolicy::Minimum,
-                                              QSizePolicy::Expanding);
-       mathsModule->gridLayout->addItem(spacer, 2 * packages.size(), 0);
+       connect(mathsModule->allPackagesAutoPB, SIGNAL(clicked()),
+               this, SLOT(allPackagesAuto()));
+       connect(mathsModule->allPackagesAlwaysPB, SIGNAL(clicked()),
+               this, SLOT(allPackagesAlways()));
+       connect(mathsModule->allPackagesNotPB, SIGNAL(clicked()),
+               this, SLOT(allPackagesNot()));
+       connect(mathsModule->allPackagesAutoPB, SIGNAL(clicked()),
+               this, SLOT(change_adaptor()));
+       connect(mathsModule->allPackagesAlwaysPB, SIGNAL(clicked()),
+               this, SLOT(change_adaptor()));
+       connect(mathsModule->allPackagesNotPB, SIGNAL(clicked()),
+               this, SLOT(change_adaptor()));
 
 
        // latex class
@@ -1413,28 +1399,28 @@ GuiDocument::GuiDocument(GuiView & lv)
 
 
        // add the panels
-       docPS->addPanel(latexModule, qt_("Document Class"));
-       docPS->addPanel(masterChildModule, qt_("Child Documents"));
-       docPS->addPanel(modulesModule, qt_("Modules"));
-       docPS->addPanel(localLayout, qt_("Local Layout"));
-       docPS->addPanel(fontModule, qt_("Fonts"));
-       docPS->addPanel(textLayoutModule, qt_("Text Layout"));
-       docPS->addPanel(pageLayoutModule, qt_("Page Layout"));
-       docPS->addPanel(marginsModule, qt_("Page Margins"));
-       docPS->addPanel(langModule, qt_("Language"));
-       docPS->addPanel(colorModule, qt_("Colors"));
-       docPS->addPanel(numberingModule, qt_("Numbering & TOC"));
-       docPS->addPanel(biblioModule, qt_("Bibliography"));
-       docPS->addPanel(indicesModule, qt_("Indexes"));
-       docPS->addPanel(pdfSupportModule, qt_("PDF Properties"));
-       docPS->addPanel(mathsModule, qt_("Math Options"));
-       docPS->addPanel(floatModule, qt_("Float Placement"));
-       docPS->addPanel(listingsModule, qt_("Listings[[inset]]"));
-       docPS->addPanel(bulletsModule, qt_("Bullets"));
-       docPS->addPanel(branchesModule, qt_("Branches"));
-       docPS->addPanel(outputModule, qt_("Output"));
-       docPS->addPanel(preambleModule, qt_("LaTeX Preamble"));
-       docPS->setCurrentPanel(qt_("Document Class"));
+       docPS->addPanel(latexModule, N_("Document Class"));
+       docPS->addPanel(masterChildModule, N_("Child Documents"));
+       docPS->addPanel(modulesModule, N_("Modules"));
+       docPS->addPanel(localLayout, N_("Local Layout"));
+       docPS->addPanel(fontModule, N_("Fonts"));
+       docPS->addPanel(textLayoutModule, N_("Text Layout"));
+       docPS->addPanel(pageLayoutModule, N_("Page Layout"));
+       docPS->addPanel(marginsModule, N_("Page Margins"));
+       docPS->addPanel(langModule, N_("Language"));
+       docPS->addPanel(colorModule, N_("Colors"));
+       docPS->addPanel(numberingModule, N_("Numbering & TOC"));
+       docPS->addPanel(biblioModule, N_("Bibliography"));
+       docPS->addPanel(indicesModule, N_("Indexes"));
+       docPS->addPanel(pdfSupportModule, N_("PDF Properties"));
+       docPS->addPanel(mathsModule, N_("Math Options"));
+       docPS->addPanel(floatModule, N_("Float Placement"));
+       docPS->addPanel(listingsModule, N_("Listings[[inset]]"));
+       docPS->addPanel(bulletsModule, N_("Bullets"));
+       docPS->addPanel(branchesModule, N_("Branches"));
+       docPS->addPanel(outputModule, N_("Output"));
+       docPS->addPanel(preambleModule, N_("LaTeX Preamble"));
+       docPS->setCurrentPanel("Document Class");
 // FIXME: hack to work around resizing bug in Qt >= 4.2
 // bug verified with Qt 4.2.{0-3} (JSpitzm)
 #if QT_VERSION >= 0x040200
@@ -1485,6 +1471,7 @@ QString GuiDocument::validateListingsParameters()
 {
        // use a cache here to avoid repeated validation
        // of the same parameters
+       // FIXME THREAD
        static string param_cache;
        static QString msg_cache;
 
@@ -1502,6 +1489,7 @@ QString GuiDocument::validateListingsParameters()
 
 void GuiDocument::setListingsMessage()
 {
+       // FIXME THREAD
        static bool isOK = true;
        QString msg = validateListingsParameters();
        if (msg.isEmpty()) {
@@ -1757,11 +1745,22 @@ void GuiDocument::languageChanged(int i)
        Language const * lang = lyx::languages.getLanguage(
                fromqstr(langModule->languageCO->itemData(i).toString()));
        if (lang->babel().empty() && !lang->polyglossia().empty()) {
+                       // If we force to switch fontspec on, store
+                       // current state (#8717)
+                       if (fontModule->osFontsCB->isEnabled())
+                               forced_fontspec_activation =
+                                       !fontModule->osFontsCB->isChecked();
                        fontModule->osFontsCB->setChecked(true);
                        fontModule->osFontsCB->setEnabled(false);
        }
-       else
+       else {
                fontModule->osFontsCB->setEnabled(true);
+               // If we have forced to switch fontspec on,
+               // restore previous state (#8717)
+               if (forced_fontspec_activation)
+                       fontModule->osFontsCB->setChecked(false);
+               forced_fontspec_activation = false;
+       }
 
        // set appropriate quotation mark style
        if (!lang->quoteStyle().empty()) {
@@ -1812,6 +1811,28 @@ void GuiDocument::mathFontChanged(int)
 }
 
 
+void GuiDocument::fontOsfToggled(bool state)
+{
+       if (fontModule->osFontsCB->isChecked())
+               return;
+       QString font = fontModule->fontsRomanCO->itemData(
+                       fontModule->fontsRomanCO->currentIndex()).toString();
+       if (hasMonolithicExpertSet(font))
+               fontModule->fontScCB->setChecked(state);
+}
+
+
+void GuiDocument::fontScToggled(bool state)
+{
+       if (fontModule->osFontsCB->isChecked())
+               return;
+       QString font = fontModule->fontsRomanCO->itemData(
+                       fontModule->fontsRomanCO->currentIndex()).toString();
+       if (hasMonolithicExpertSet(font))
+               fontModule->fontOsfCB->setChecked(state);
+}
+
+
 void GuiDocument::updateFontOptions()
 {
        bool const tex_fonts = !fontModule->osFontsCB->isChecked();
@@ -1916,7 +1937,7 @@ void GuiDocument::updateFontlist()
        fontModule->fontsTypewriterCO->clear();
        fontModule->fontsMathCO->clear();
 
-       // With XeTeX, we have access to all system fonts, but not the LaTeX fonts
+       // With fontspec (XeTeX, LuaTeX), we have access to all system fonts, but not the LaTeX fonts
        if (fontModule->osFontsCB->isChecked()) {
                fontModule->fontsRomanCO->addItem(qt_("Default"), QString("default"));
                fontModule->fontsSansCO->addItem(qt_("Default"), QString("default"));
@@ -2251,6 +2272,7 @@ void GuiDocument::updateEngineType(string const & items, CiteEngineType const &
                        biblioModule->citeStyleCO->setCurrentIndex(0);
                        break;
                case ENGINE_TYPE_NUMERICAL:
+               case ENGINE_TYPE_DEFAULT:
                        biblioModule->citeStyleCO->setCurrentIndex(1);
                        break;
        }
@@ -2448,7 +2470,7 @@ void GuiDocument::updateNumbering()
        DocumentClass::const_iterator len = tclass.end();
        for (; lit != len; ++lit) {
                int const toclevel = lit->toclevel;
-               if (toclevel != Layout::NOT_IN_TOC && lit->labeltype == LABEL_COUNTER) {
+               if (toclevel != Layout::NOT_IN_TOC && !lit->counter.empty()) {
                        item = new QTreeWidgetItem(numberingModule->tocTW);
                        item->setText(0, toqstr(translateIfPossible(lit->name())));
                        item->setText(1, (toclevel <= depth) ? yes : no);
@@ -2472,7 +2494,7 @@ void GuiDocument::updateDefaultFormat()
        if (idx >= 0) {
                string const classname = fromqstr(latexModule->classCO->getData(idx));
                param_copy.setBaseClass(classname);
-               param_copy.makeDocumentClass();
+               param_copy.makeDocumentClass(true);
        }
        outputModule->defaultFormatCO->blockSignals(true);
        outputModule->defaultFormatCO->clear();
@@ -2480,6 +2502,7 @@ void GuiDocument::updateDefaultFormat()
                                QVariant(QString("default")));
        typedef vector<Format const *> Formats;
        Formats formats = param_copy.exportableFormats(true);
+       sort(formats.begin(), formats.end(), Format::formatSorter);
        Formats::const_iterator cit = formats.begin();
        Formats::const_iterator end = formats.end();
        for (; cit != end; ++cit)
@@ -2513,9 +2536,11 @@ void GuiDocument::applyView()
                bp_.setCiteEngine("natbib");
        else if (biblioModule->citeJurabibRB->isChecked())
                bp_.setCiteEngine("jurabib");
-       else
+       if (biblioModule->citeDefaultRB->isChecked()) {
                bp_.setCiteEngine("basic");
-
+               bp_.setCiteEngineType(ENGINE_TYPE_DEFAULT);
+       }
+       else
        if (biblioModule->citeStyleCO->currentIndex())
                bp_.setCiteEngineType(ENGINE_TYPE_NUMERICAL);
        else
@@ -2560,7 +2585,7 @@ void GuiDocument::applyView()
                        for (; it != end; ++it) {
                                if (qt_(it->guiName()) == enc_gui &&
                                    !it->unsafe()) {
-                                       bp_.inputenc = it->latexName();
+                                       bp_.inputenc = it->name();
                                        found = true;
                                        break;
                                }
@@ -2623,20 +2648,26 @@ void GuiDocument::applyView()
        modulesToParams(bp_);
 
        // Math
-       vector<string> const & packages = BufferParams::auto_packages();
-        for (size_t n = 0; n < packages.size(); ++n) {
-               QCheckBox * autoCB = static_cast<QCheckBox *>(
-                       mathsModule->gridLayout->itemAtPosition(2 * n, 0)->widget());
-               if (autoCB->isChecked())
-                       bp_.use_package(packages[n], BufferParams::package_auto);
-               else {
-                       QCheckBox * alwaysCB = static_cast<QCheckBox *>(
-                               mathsModule->gridLayout->itemAtPosition(2 * n + 1, 0)->widget());
-                       if (alwaysCB->isChecked())
-                               bp_.use_package(packages[n], BufferParams::package_on);
-                       else
-                               bp_.use_package(packages[n], BufferParams::package_off);
+       map<string, string> const & packages = BufferParams::auto_packages();
+       for (map<string, string>::const_iterator it = packages.begin();
+            it != packages.end(); ++it) {
+               QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
+               if (!item)
+                       continue;
+               int row = mathsModule->packagesTW->row(item);
+               QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1);
+               if (rb->isChecked()) {
+                       bp_.use_package(it->first, BufferParams::package_auto);
+                       continue;
+               }
+               rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2);
+               if (rb->isChecked()) {
+                       bp_.use_package(it->first, BufferParams::package_on);
+                       continue;
                }
+               rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3);
+               if (rb->isChecked())
+                       bp_.use_package(it->first, BufferParams::package_off);
        }
 
        // Page Layout
@@ -2916,7 +2947,7 @@ void GuiDocument::paramsToDialog()
                cite_engine == "natbib");
 
        biblioModule->citeStyleCO->setCurrentIndex(
-               bp_.citeEngineType() == ENGINE_TYPE_NUMERICAL);
+               bp_.citeEngineType() & ENGINE_TYPE_NUMERICAL);
 
        updateEngineType(documentClass().opt_enginetype(),
                bp_.citeEngineType());
@@ -2967,7 +2998,7 @@ void GuiDocument::paramsToDialog()
                        Encodings::const_iterator it = encodings.begin();
                        Encodings::const_iterator const end = encodings.end();
                        for (; it != end; ++it) {
-                               if (it->latexName() == bp_.inputenc &&
+                               if (it->name() == bp_.inputenc &&
                                    !it->unsafe()) {
                                        enc_gui = it->guiName();
                                        break;
@@ -3048,14 +3079,30 @@ void GuiDocument::paramsToDialog()
                latexModule->psdriverCO->setCurrentIndex(nitem);
        updateModuleInfo();
 
-       vector<string> const & packages = BufferParams::auto_packages();
-        for (size_t n = 0; n < packages.size(); ++n) {
-               QCheckBox * alwaysCB = static_cast<QCheckBox *>(
-                       mathsModule->gridLayout->itemAtPosition(2 * n + 1, 0)->widget());
-               alwaysCB->setChecked(bp_.use_package(packages[n]) == BufferParams::package_on);
-               QCheckBox * autoCB = static_cast<QCheckBox *>(
-                       mathsModule->gridLayout->itemAtPosition(2 * n, 0)->widget());
-               autoCB->setChecked(bp_.use_package(packages[n]) == BufferParams::package_auto);
+       map<string, string> const & packages = BufferParams::auto_packages();
+       for (map<string, string>::const_iterator it = packages.begin();
+            it != packages.end(); ++it) {
+               QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
+               if (!item)
+                       continue;
+               int row = mathsModule->packagesTW->row(item);
+               switch (bp_.use_package(it->first)) {
+                       case BufferParams::package_off: {
+                               QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3);
+                               rb->setChecked(true);
+                               break;
+                       }
+                       case BufferParams::package_on: {
+                               QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2);
+                               rb->setChecked(true);
+                               break;
+                       }
+                       case BufferParams::package_auto: {
+                               QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1);
+                               rb->setChecked(true);
+                               break;
+                       }
+               }
        }
 
        switch (bp_.spacing().getSpace()) {
@@ -3169,11 +3216,11 @@ void GuiDocument::paramsToDialog()
        if (!bufferview() || !buffer().hasChildren()) {
                masterChildModule->childrenTW->clear();
                includeonlys_.clear();
-               docPS->showPanel(qt_("Child Documents"), false);
-               if (docPS->isCurrentPanel(qt_("Child Documents")))
-                       docPS->setCurrentPanel(qt_("Document Class"));
+               docPS->showPanel("Child Documents", false);
+               if (docPS->isCurrentPanel("Child Documents"))
+                       docPS->setCurrentPanel("Document Class");
        } else {
-               docPS->showPanel(qt_("Child Documents"), true);
+               docPS->showPanel("Child Documents", true);
                masterChildModule->setEnabled(true);
                includeonlys_ = bp_.getIncludedChildren();
                updateIncludeonlys();
@@ -3191,12 +3238,18 @@ void GuiDocument::paramsToDialog()
        listingsModule->listingsED->setPlainText(toqstr(lstparams));
 
        // Fonts
+       // some languages only work with polyglossia/XeTeX
+       Language const * lang = lyx::languages.getLanguage(
+               fromqstr(langModule->languageCO->itemData(
+                       langModule->languageCO->currentIndex()).toString()));
+       bool const need_fontspec =
+               lang->babel().empty() && !lang->polyglossia().empty();
        bool const os_fonts_available =
                bp_.baseClass()->outputType() == lyx::LATEX
                && LaTeXFeatures::isAvailable("fontspec");
-       fontModule->osFontsCB->setEnabled(os_fonts_available);
+       fontModule->osFontsCB->setEnabled(os_fonts_available && !need_fontspec);
        fontModule->osFontsCB->setChecked(
-               os_fonts_available && bp_.useNonTeXFonts);
+               (os_fonts_available && bp_.useNonTeXFonts) || need_fontspec);
        updateFontsize(documentClass().opt_fontsize(),
                        bp_.fontsize);
 
@@ -3629,6 +3682,11 @@ static void dispatch_bufferparams(Dialog const & dialog,
 
 void GuiDocument::dispatchParams()
 {
+       // We need a non-const buffer object.
+       Buffer & buf = const_cast<BufferView *>(bufferview())->buffer();
+       // There may be several undo records; group them (bug #8998)
+       buf.undo().beginUndoGroup();
+
        // This must come first so that a language change is correctly noticed
        setLanguage();
 
@@ -3698,6 +3756,10 @@ void GuiDocument::dispatchParams()
        // If we used an LFUN, we would not need these two lines:
        BufferView * bv = const_cast<BufferView *>(bufferview());
        bv->processUpdateFlags(Update::Force | Update::FitCursor);
+
+       // Don't forget to close the group. Note that it is important
+       // to check that there is no early return in the method.
+       buf.undo().endUndoGroup();
 }
 
 
@@ -3763,6 +3825,17 @@ bool GuiDocument::providesNoMath(QString const & font) const
 }
 
 
+bool GuiDocument::hasMonolithicExpertSet(QString const & font) const
+{
+       if (fontModule->osFontsCB->isChecked())
+               return false;
+       return theLaTeXFonts().getLaTeXFont(
+                               qstring_to_ucs4(font)).hasMonolithicExpertSet(ot1(),
+                                                                             completeFontset(),
+                                                                             noMathFont());
+}
+
+
 void GuiDocument::loadModuleInfo()
 {
        moduleNames_.clear();
@@ -3828,6 +3901,33 @@ void GuiDocument::executeBranchRenaming() const
 }
 
 
+void GuiDocument::allPackagesAuto()
+{
+       allPackages(1);
+}
+
+
+void GuiDocument::allPackagesAlways()
+{
+       allPackages(2);
+}
+
+
+void GuiDocument::allPackagesNot()
+{
+       allPackages(3);
+}
+
+
+void GuiDocument::allPackages(int col)
+{
+       for (int row = 0; row < mathsModule->packagesTW->rowCount(); ++row) {
+               QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, col);
+               rb->setChecked(true);
+       }
+}
+
+
 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }