]> git.lyx.org Git - lyx.git/blob - src/frontends/qt/GuiDocument.cpp
DocBook: add the MathML-namespace prefix in the GUI.
[lyx.git] / src / frontends / qt / GuiDocument.cpp
1 /**
2  * \file GuiDocument.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Edwin Leuven
7  * \author Richard Kimberly Heck (modules)
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "GuiDocument.h"
15
16 #include "BulletsModule.h"
17 #include "CategorizedCombo.h"
18 #include "FancyLineEdit.h"
19 #include "GuiApplication.h"
20 #include "GuiBranches.h"
21 #include "GuiIndices.h"
22 #include "GuiSelectionManager.h"
23 #include "LaTeXHighlighter.h"
24 #include "Validator.h"
25
26 #include "LayoutFile.h"
27 #include "BranchList.h"
28 #include "buffer_funcs.h"
29 #include "Buffer.h"
30 #include "BufferView.h"
31 #include "CiteEnginesList.h"
32 #include "Color.h"
33 #include "ColorCache.h"
34 #include "Converter.h"
35 #include "Cursor.h"
36 #include "Encoding.h"
37 #include "FloatPlacement.h"
38 #include "Format.h"
39 #include "FuncRequest.h"
40 #include "IndicesList.h"
41 #include "Language.h"
42 #include "LaTeXFeatures.h"
43 #include "LaTeXFonts.h"
44 #include "Layout.h"
45 #include "LayoutEnums.h"
46 #include "LayoutModuleList.h"
47 #include "LyXRC.h"
48 #include "ModuleList.h"
49 #include "PDFOptions.h"
50 #include "qt_helpers.h"
51 #include "Session.h"
52 #include "Spacing.h"
53 #include "TextClass.h"
54 #include "Undo.h"
55 #include "VSpace.h"
56
57 #include "insets/InsetListingsParams.h"
58 #include "insets/InsetQuotes.h"
59
60 #include "support/debug.h"
61 #include "support/docstream.h"
62 #include "support/FileName.h"
63 #include "support/filetools.h"
64 #include "support/gettext.h"
65 #include "support/lassert.h"
66 #include "support/lstrings.h"
67 #include "support/Package.h"
68 #include "support/TempFile.h"
69
70 #include "frontends/alert.h"
71
72 #include <QAbstractItemModel>
73 #include <QButtonGroup>
74 #include <QColor>
75 #include <QColorDialog>
76 #include <QCloseEvent>
77 #include <QDirIterator>
78 #include <QFontDatabase>
79 #include <QHeaderView>
80 #include <QPixmap>
81 #include <QScrollBar>
82 #include <QTextBoundaryFinder>
83 #include <QTextCursor>
84
85 #include <sstream>
86 #include <vector>
87
88
89 // a style sheet for buttons
90 // this is for example used for the background color setting button
91 static inline QString colorButtonStyleSheet(QColor const & bgColor)
92 {
93         if (bgColor.isValid()) {
94                 QString rc = QLatin1String("background-color:");
95                 rc += bgColor.name();
96                 return rc;
97         }
98         return QString();
99 }
100
101
102 using namespace std;
103 using namespace lyx::support;
104
105
106 namespace {
107
108 char const * const tex_graphics[] =
109 {
110         "default", "dvialw", "dvilaser", "dvipdf", "dvipdfm", "dvipdfmx",
111         "dvips", "dvipsone", "dvitops", "dviwin", "dviwindo", "dvi2ps", "emtex",
112         "ln", "oztex", "pctexhp", "pctexps", "pctexwin", "pctex32", "pdftex",
113         "psprint", "pubps", "tcidvi", "textures", "truetex", "vtex", "xdvi",
114         "xetex", "none", ""
115 };
116
117
118 char const * const tex_graphics_gui[] =
119 {
120         N_("Default"), "dvialw", "DviLaser", "dvipdf", "DVIPDFM", "DVIPDFMx",
121         "Dvips", "DVIPSONE", "DVItoPS", "DVIWIN", "DVIWindo", "dvi2ps", "EmTeX",
122         "LN", "OzTeX", "pctexhp", "pctexps", "pctexwin", "PCTeX32", "pdfTeX",
123         "psprint", "pubps", "tcidvi", "Textures", "TrueTeX", "VTeX", "xdvi",
124         "XeTeX", N_("None"), ""
125 };
126
127
128 char const * backref_opts[] =
129 {
130         "false", "section", "slide", "page", ""
131 };
132
133
134 char const * backref_opts_gui[] =
135 {
136         N_("Off"), N_("Section"), N_("Slide"), N_("Page"), ""
137 };
138
139
140 char const * lst_packages[] =
141 {
142         "Listings", "Minted", ""
143 };
144
145
146 vector<string> engine_types_;
147 vector<pair<string, QString> > pagestyles;
148
149 QMap<QString, QString> rmfonts_;
150 QMap<QString, QString> sffonts_;
151 QMap<QString, QString> ttfonts_;
152 QMap<QString, QString> mathfonts_;
153
154 enum EncodingSets {
155         unicode = 0,
156         legacy = 1,
157         custom = 2
158 };
159
160 lyx::RGBColor set_backgroundcolor;
161 bool is_backgroundcolor;
162 lyx::RGBColor set_fontcolor;
163 bool is_fontcolor;
164 lyx::RGBColor set_notefontcolor;
165 bool is_notefontcolor;
166 lyx::RGBColor set_boxbgcolor;
167 bool is_boxbgcolor;
168 bool forced_fontspec_activation;
169
170 } // anonymous namespace
171
172 namespace lyx {
173
174 namespace {
175 // used when sorting the textclass list.
176 class less_textclass_avail_desc
177 {
178 public:
179         bool operator()(string const & lhs, string const & rhs) const
180         {
181                 // Ordering criteria:
182                 //   1. Availability of text class
183                 //   2. Description (lexicographic)
184                 LayoutFile const & tc1 = LayoutFileList::get()[lhs];
185                 LayoutFile const & tc2 = LayoutFileList::get()[rhs];
186                 int const order = compare_no_case(
187                         translateIfPossible(from_utf8(tc1.description())),
188                         translateIfPossible(from_utf8(tc2.description())));
189                 return (tc1.isTeXClassAvailable() && !tc2.isTeXClassAvailable()) ||
190                         (tc1.isTeXClassAvailable() == tc2.isTeXClassAvailable() && order < 0);
191         }
192 };
193
194 } // namespace
195
196 namespace frontend {
197 namespace {
198
199 vector<string> getRequiredList(string const & modName)
200 {
201         LyXModule const * const mod = theModuleList[modName];
202         if (!mod)
203                 return vector<string>(); //empty such thing
204         return mod->getRequiredModules();
205 }
206
207
208 vector<string> getExcludedList(string const & modName)
209 {
210         LyXModule const * const mod = theModuleList[modName];
211         if (!mod)
212                 return vector<string>(); //empty such thing
213         return mod->getExcludedModules();
214 }
215
216
217 docstring getModuleCategory(string const & modName)
218 {
219         LyXModule const * const mod = theModuleList[modName];
220         if (!mod)
221                 return docstring();
222         return from_utf8(mod->category());
223 }
224
225
226 docstring getModuleDescription(string const & modName)
227 {
228         LyXModule const * const mod = theModuleList[modName];
229         if (!mod)
230                 return _("Module not found!");
231         // FIXME Unicode
232         return translateIfPossible(from_utf8(mod->getDescription()));
233 }
234
235
236 vector<string> getPackageList(string const & modName)
237 {
238         LyXModule const * const mod = theModuleList[modName];
239         if (!mod)
240                 return vector<string>(); //empty such thing
241         return mod->getPackageList();
242 }
243
244
245 bool isModuleAvailable(string const & modName)
246 {
247         LyXModule const * const mod = theModuleList[modName];
248         if (!mod)
249                 return false;
250         return mod->isAvailable();
251 }
252
253 } // anonymous namespace
254
255
256 /////////////////////////////////////////////////////////////////////
257 //
258 // ModuleSelectionManager
259 //
260 /////////////////////////////////////////////////////////////////////
261
262 /// SelectionManager for use with modules
263 class ModuleSelectionManager : public GuiSelectionManager
264 {
265 public:
266         ///
267         ModuleSelectionManager(QObject * parent,
268                                                    QTreeView * availableLVarg,
269                                                    QTreeView * selectedLVarg,
270                                                    QPushButton * addPBarg,
271                                                    QPushButton * delPBarg,
272                                                    QPushButton * upPBarg,
273                                                    QPushButton * downPBarg,
274                                                    QStandardItemModel * availableModelarg,
275                                                    GuiIdListModel * selectedModelarg,
276                                GuiDocument const * container)
277                 : GuiSelectionManager(parent, availableLVarg, selectedLVarg, addPBarg, delPBarg,
278                                                           upPBarg, downPBarg, availableModelarg, selectedModelarg),
279                   container_(container)
280                 {}
281         ///
282         void updateProvidedModules(LayoutModuleList const & pm)
283                         { provided_modules_ = pm.list(); }
284         ///
285         void updateExcludedModules(LayoutModuleList const & em)
286                         { excluded_modules_ = em.list(); }
287 private:
288         ///
289         void updateAddPB() override;
290         ///
291         void updateUpPB() override;
292         ///
293         void updateDownPB() override;
294         ///
295         void updateDelPB() override;
296         /// returns availableModel as a GuiIdListModel
297         QStandardItemModel * getAvailableModel()
298         {
299                 return dynamic_cast<QStandardItemModel *>(availableModel);
300         }
301         /// returns selectedModel as a GuiIdListModel
302         GuiIdListModel * getSelectedModel()
303         {
304                 return dynamic_cast<GuiIdListModel *>(selectedModel);
305         }
306         /// keeps a list of the modules the text class provides
307         list<string> provided_modules_;
308         /// similarly...
309         list<string> excluded_modules_;
310         ///
311         GuiDocument const * container_;
312 };
313
314 void ModuleSelectionManager::updateAddPB()
315 {
316         int const arows = availableModel->rowCount();
317         QModelIndexList const avail_sels =
318                         availableLV->selectionModel()->selectedRows(0);
319
320         // disable if there aren't any modules (?), if none of them is chosen
321         // in the dialog, or if the chosen one is already selected for use.
322         if (arows == 0 || avail_sels.isEmpty() || isSelected(avail_sels.first())) {
323                 addPB->setEnabled(false);
324                 return;
325         }
326
327         QModelIndex const & idx = availableLV->selectionModel()->currentIndex();
328
329         if (getAvailableModel()->itemFromIndex(idx)->hasChildren()) {
330                 // This is a category header
331                 addPB->setEnabled(false);
332                 return;
333         }
334
335         string const modname = fromqstr(getAvailableModel()->data(idx, Qt::UserRole).toString());
336
337         bool const enable =
338                 container_->params().layoutModuleCanBeAdded(modname);
339         addPB->setEnabled(enable);
340 }
341
342
343 void ModuleSelectionManager::updateDownPB()
344 {
345         int const srows = selectedModel->rowCount();
346         if (srows == 0) {
347                 downPB->setEnabled(false);
348                 return;
349         }
350         QModelIndex const & curidx = selectedLV->selectionModel()->currentIndex();
351         int const curRow = curidx.row();
352         if (curRow < 0 || curRow >= srows - 1) { // invalid or last item
353                 downPB->setEnabled(false);
354                 return;
355         }
356
357         // determine whether immediately succeeding element requires this one
358         string const curmodname = getSelectedModel()->getIDString(curRow);
359         string const nextmodname = getSelectedModel()->getIDString(curRow + 1);
360
361         vector<string> reqs = getRequiredList(nextmodname);
362
363         // if it doesn't require anything....
364         if (reqs.empty()) {
365                 downPB->setEnabled(true);
366                 return;
367         }
368
369         // Enable it if this module isn't required.
370         // FIXME This should perhaps be more flexible and check whether, even
371         // if the next one is required, there is also an earlier one that will do.
372         downPB->setEnabled(
373                         find(reqs.begin(), reqs.end(), curmodname) == reqs.end());
374 }
375
376 void ModuleSelectionManager::updateUpPB()
377 {
378         int const srows = selectedModel->rowCount();
379         if (srows == 0) {
380                 upPB->setEnabled(false);
381                 return;
382         }
383
384         QModelIndex const & curIdx = selectedLV->selectionModel()->currentIndex();
385         int curRow = curIdx.row();
386         if (curRow <= 0 || curRow > srows - 1) { // first item or invalid
387                 upPB->setEnabled(false);
388                 return;
389         }
390         string const curmodname = getSelectedModel()->getIDString(curRow);
391
392         // determine whether immediately preceding element is required by this one
393         vector<string> reqs = getRequiredList(curmodname);
394
395         // if this one doesn't require anything....
396         if (reqs.empty()) {
397                 upPB->setEnabled(true);
398                 return;
399         }
400
401
402         // Enable it if the preceding module isn't required.
403         // NOTE This is less flexible than it might be. We could check whether, even
404         // if the previous one is required, there is an earlier one that would do.
405         string const premod = getSelectedModel()->getIDString(curRow - 1);
406         upPB->setEnabled(find(reqs.begin(), reqs.end(), premod) == reqs.end());
407 }
408
409 void ModuleSelectionManager::updateDelPB()
410 {
411         int const srows = selectedModel->rowCount();
412         if (srows == 0) {
413                 deletePB->setEnabled(false);
414                 return;
415         }
416
417         QModelIndex const & curidx =
418                 selectedLV->selectionModel()->currentIndex();
419         int const curRow = curidx.row();
420         if (curRow < 0 || curRow >= srows) { // invalid index?
421                 deletePB->setEnabled(false);
422                 return;
423         }
424
425         string const curmodname = getSelectedModel()->getIDString(curRow);
426
427         // We're looking here for a reason NOT to enable the button. If we
428         // find one, we disable it and return. If we don't, we'll end up at
429         // the end of the function, and then we enable it.
430         for (int i = curRow + 1; i < srows; ++i) {
431                 string const thisMod = getSelectedModel()->getIDString(i);
432                 vector<string> reqs = getRequiredList(thisMod);
433                 //does this one require us?
434                 if (find(reqs.begin(), reqs.end(), curmodname) == reqs.end())
435                         //no...
436                         continue;
437
438                 // OK, so this module requires us
439                 // is there an EARLIER module that also satisfies the require?
440                 // NOTE We demand that it be earlier to keep the list of modules
441                 // consistent with the rule that a module must be proceeded by a
442                 // required module. There would be more flexible ways to proceed,
443                 // but that would be a lot more complicated, and the logic here is
444                 // already complicated. (That's why I've left the debugging code.)
445                 // lyxerr << "Testing " << thisMod << endl;
446                 bool foundone = false;
447                 for (int j = 0; j < curRow; ++j) {
448                         string const mod = getSelectedModel()->getIDString(j);
449                         // lyxerr << "In loop: Testing " << mod << endl;
450                         // do we satisfy the require?
451                         if (find(reqs.begin(), reqs.end(), mod) != reqs.end()) {
452                                 // lyxerr << mod << " does the trick." << endl;
453                                 foundone = true;
454                                 break;
455                         }
456                 }
457                 // did we find a module to satisfy the require?
458                 if (!foundone) {
459                         // lyxerr << "No matching module found." << endl;
460                         deletePB->setEnabled(false);
461                         return;
462                 }
463         }
464         // lyxerr << "All's well that ends well." << endl;
465         deletePB->setEnabled(true);
466 }
467
468
469 /////////////////////////////////////////////////////////////////////
470 //
471 // PreambleModule
472 //
473 /////////////////////////////////////////////////////////////////////
474
475 PreambleModule::PreambleModule(QWidget * parent)
476         : UiWidget<Ui::PreambleUi>(parent), current_id_(nullptr)
477 {
478         // This is not a memory leak. The object will be destroyed
479         // with this.
480         // @ is letter in the LyX user preamble
481         (void) new LaTeXHighlighter(preambleTE->document(), true);
482         preambleTE->setFont(guiApp->typewriterSystemFont());
483         preambleTE->setWordWrapMode(QTextOption::NoWrap);
484         setFocusProxy(preambleTE);
485         connect(preambleTE, SIGNAL(textChanged()), this, SIGNAL(changed()));
486         connect(findLE, SIGNAL(textEdited(const QString &)), this, SLOT(checkFindButton()));
487         connect(findButtonPB, SIGNAL(clicked()), this, SLOT(findText()));
488         connect(editPB, SIGNAL(clicked()), this, SLOT(editExternal()));
489         connect(findLE, SIGNAL(returnPressed()), this, SLOT(findText()));
490         checkFindButton();
491         // https://stackoverflow.com/questions/13027091/how-to-override-tab-width-in-qt
492         const int tabStop = 4;
493         QFontMetrics metrics(preambleTE->currentFont());
494 #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
495         // horizontalAdvance() is available starting in 5.11.0
496         // setTabStopDistance() is available starting in 5.10.0
497         preambleTE->setTabStopDistance(tabStop * metrics.horizontalAdvance(' '));
498 #else
499         preambleTE->setTabStopWidth(tabStop * metrics.width(' '));
500 #endif
501 }
502
503
504 void PreambleModule::checkFindButton()
505 {
506         findButtonPB->setEnabled(!findLE->text().isEmpty());
507 }
508
509
510 void PreambleModule::findText()
511 {
512         bool const found = preambleTE->find(findLE->text());
513         if (!found) {
514                 // wrap
515                 QTextCursor qtcur = preambleTE->textCursor();
516                 qtcur.movePosition(QTextCursor::Start);
517                 preambleTE->setTextCursor(qtcur);
518                 preambleTE->find(findLE->text());
519         }
520 }
521
522
523 void PreambleModule::update(BufferParams const & params, BufferId id)
524 {
525         QString preamble = toqstr(params.preamble);
526         // Nothing to do if the params and preamble are unchanged.
527         if (id == current_id_
528                 && preamble == preambleTE->document()->toPlainText())
529                 return;
530
531         QTextCursor cur = preambleTE->textCursor();
532         // Save the coords before switching to the new one.
533         preamble_coords_[current_id_] =
534                 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
535
536         // Save the params address for further use.
537         current_id_ = id;
538         preambleTE->document()->setPlainText(preamble);
539         Coords::const_iterator it = preamble_coords_.find(current_id_);
540         if (it == preamble_coords_.end())
541                 // First time we open this one.
542                 preamble_coords_[current_id_] = make_pair(0, 0);
543         else {
544                 // Restore saved coords.
545                 cur = preambleTE->textCursor();
546                 cur.setPosition(it->second.first);
547                 preambleTE->setTextCursor(cur);
548                 preambleTE->verticalScrollBar()->setValue(it->second.second);
549         }
550 }
551
552
553 void PreambleModule::apply(BufferParams & params)
554 {
555         params.preamble = qstring_to_ucs4(preambleTE->document()->toPlainText());
556 }
557
558
559 void PreambleModule::closeEvent(QCloseEvent * e)
560 {
561         // Save the coords before closing.
562         QTextCursor cur = preambleTE->textCursor();
563         preamble_coords_[current_id_] =
564                 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
565         e->accept();
566 }
567
568
569 void PreambleModule::editExternal() {
570         if (!current_id_)
571                 return;
572
573         if (tempfile_) {
574                 preambleTE->setReadOnly(false);
575                 FileName const tempfilename = tempfile_->name();
576                 docstring const s = tempfilename.fileContents("UTF-8");
577                 preambleTE->document()->setPlainText(toqstr(s));
578                 tempfile_.reset();
579                 editPB->setText(qt_("&Edit"));
580                 changed();
581                 return;
582         }
583
584         string const format =
585                 current_id_->params().documentClass().outputFormat();
586         string const ext = theFormats().extension(format);
587         tempfile_.reset(new TempFile("preamble_editXXXXXX." + ext));
588         FileName const tempfilename = tempfile_->name();
589         string const name = tempfilename.toFilesystemEncoding();
590         ofdocstream os(name.c_str());
591         os << qstring_to_ucs4(preambleTE->document()->toPlainText());
592         os.close();
593         preambleTE->setReadOnly(true);
594         theFormats().edit(*current_id_, tempfilename, format);
595         editPB->setText(qt_("&End Edit"));
596         changed();
597 }
598
599 /////////////////////////////////////////////////////////////////////
600 //
601 // LocalLayout
602 //
603 /////////////////////////////////////////////////////////////////////
604
605
606 LocalLayout::LocalLayout(QWidget * parent)
607         : UiWidget<Ui::LocalLayoutUi>(parent), current_id_(nullptr), validated_(false)
608 {
609         locallayoutTE->setFont(guiApp->typewriterSystemFont());
610         locallayoutTE->setWordWrapMode(QTextOption::NoWrap);
611         connect(locallayoutTE, SIGNAL(textChanged()), this, SLOT(textChanged()));
612         connect(validatePB, SIGNAL(clicked()), this, SLOT(validatePressed()));
613         connect(convertPB, SIGNAL(clicked()), this, SLOT(convertPressed()));
614         connect(editPB, SIGNAL(clicked()), this, SLOT(editExternal()));
615 }
616
617
618 void LocalLayout::update(BufferParams const & params, BufferId id)
619 {
620         QString layout = toqstr(params.getLocalLayout(false));
621         // Nothing to do if the params and preamble are unchanged.
622         if (id == current_id_
623                 && layout == locallayoutTE->document()->toPlainText())
624                 return;
625
626         // Save the params address for further use.
627         current_id_ = id;
628         locallayoutTE->document()->setPlainText(layout);
629         validate();
630 }
631
632
633 void LocalLayout::apply(BufferParams & params)
634 {
635         docstring const layout =
636                 qstring_to_ucs4(locallayoutTE->document()->toPlainText());
637         params.setLocalLayout(layout, false);
638 }
639
640
641 void LocalLayout::hideConvert()
642 {
643         convertPB->setEnabled(false);
644         convertLB->setText("");
645         convertPB->hide();
646         convertLB->hide();
647 }
648
649
650 void LocalLayout::textChanged()
651 {
652         // Flashy red bold text
653         static const QString ivpar("<p style=\"color: #c00000; font-weight: bold; text-align:left\">"
654                                    "%1</p>");
655         static const QString message = ivpar.arg(qt_("Validation required!"));
656         string const layout =
657                 fromqstr(locallayoutTE->document()->toPlainText().trimmed());
658
659         if (layout.empty()) {
660                 validated_ = true;
661                 validatePB->setEnabled(false);
662                 validLB->setText("");
663                 hideConvert();
664                 changed();
665         } else if (!validatePB->isEnabled()) {
666                 // if that's already enabled, we shouldn't need to do anything.
667                 validated_ = false;
668                 validLB->setText(message);
669                 validatePB->setEnabled(true);
670                 hideConvert();
671                 changed();
672         }
673 }
674
675
676 void LocalLayout::convert() {
677         string const layout =
678                 fromqstr(locallayoutTE->document()->toPlainText().trimmed());
679         string const newlayout = TextClass::convert(layout);
680         if (!newlayout.empty())
681                 locallayoutTE->setPlainText(toqstr(newlayout));
682         validate();
683 }
684
685
686 void LocalLayout::convertPressed() {
687         convert();
688         hideConvert();
689         changed();
690 }
691
692
693 void LocalLayout::validate() {
694         // Bold text
695         static const QString vpar("<p style=\"font-weight: bold; text-align:left\">%1</p>");
696         // Flashy red bold text
697         static const QString ivpar("<p style=\"color: #c00000; font-weight: bold; text-align:left\">"
698                                    "%1</p>");
699         string const layout =
700                 fromqstr(locallayoutTE->document()->toPlainText().trimmed());
701         if (!layout.empty()) {
702                 TextClass::ReturnValues const ret = TextClass::validate(layout);
703                 validated_ = (ret == TextClass::OK) || (ret == TextClass::OK_OLDFORMAT);
704                 validatePB->setEnabled(false);
705                 validLB->setText(validated_ ? vpar.arg(qt_("Layout is valid!"))
706                                             : ivpar.arg(qt_("Layout is invalid!")));
707                 if (ret == TextClass::OK_OLDFORMAT) {
708                         convertPB->show();
709                         // Testing conversion to LYXFILE_LAYOUT_FORMAT at this point
710                         // already.
711                         if (TextClass::convert(layout).empty()) {
712                                 // Conversion failed. If LAYOUT_FORMAT > LYXFILE_LAYOUT_FORMAT,
713                                 // then maybe the layout is still valid, but its format is more
714                                 // recent than LYXFILE_LAYOUT_FORMAT. However, if LAYOUT_FORMAT
715                                 // == LYXFILE_LAYOUT_FORMAT then something is definitely wrong.
716                                 convertPB->setEnabled(false);
717                                 const QString text = (LAYOUT_FORMAT == LYXFILE_LAYOUT_FORMAT)
718                                         ? ivpar.arg(qt_("Conversion to current format impossible!"))
719                                         : vpar.arg(qt_("Conversion to current stable format "
720                                                        "impossible."));
721                                 convertLB->setText(text);
722                         } else {
723                                 convertPB->setEnabled(true);
724                                 convertLB->setText(qt_("Convert to current format"));
725                         }
726                         convertLB->show();
727                 } else {
728                         convertPB->hide();
729                         convertLB->hide();
730                 }
731         }
732 }
733
734
735 void LocalLayout::validatePressed() {
736         validate();
737         changed();
738 }
739
740
741 void LocalLayout::editExternal() {
742         if (!current_id_)
743                 return;
744
745         if (tempfile_) {
746                 locallayoutTE->setReadOnly(false);
747                 FileName const tempfilename = tempfile_->name();
748                 docstring const s = tempfilename.fileContents("UTF-8");
749                 locallayoutTE->document()->setPlainText(toqstr(s));
750                 tempfile_.reset();
751                 editPB->setText(qt_("&Edit"));
752                 changed();
753                 return;
754         }
755
756         string const format =
757                 current_id_->params().documentClass().outputFormat();
758         string const ext = theFormats().extension(format);
759         tempfile_.reset(new TempFile("preamble_editXXXXXX." + ext));
760         FileName const tempfilename = tempfile_->name();
761         string const name = tempfilename.toFilesystemEncoding();
762         ofdocstream os(name.c_str());
763         os << qstring_to_ucs4(locallayoutTE->document()->toPlainText());
764         os.close();
765         locallayoutTE->setReadOnly(true);
766         theFormats().edit(*current_id_, tempfilename, format);
767         editPB->setText(qt_("&End Edit"));
768         validatePB->setEnabled(false);
769         hideConvert();
770         changed();
771 }
772
773 /////////////////////////////////////////////////////////////////////
774 //
775 // DocumentDialog
776 //
777 /////////////////////////////////////////////////////////////////////
778
779
780 GuiDocument::GuiDocument(GuiView & lv)
781         : GuiDialog(lv, "document", qt_("Document Settings")),
782           biblioChanged_(false), nonModuleChanged_(false),
783           modulesChanged_(false), shellescapeChanged_(false)
784 {
785         setupUi(this);
786
787         connect(buttonBox, SIGNAL(clicked(QAbstractButton *)),
788                 this, SLOT(slotButtonBox(QAbstractButton *)));
789
790         connect(savePB, SIGNAL(clicked()), this, SLOT(saveDefaultClicked()));
791         connect(defaultPB, SIGNAL(clicked()), this, SLOT(useDefaultsClicked()));
792
793         // Manage the restore, ok, apply, restore and cancel/close buttons
794         bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
795         bc().setOK(buttonBox->button(QDialogButtonBox::Ok));
796         bc().setApply(buttonBox->button(QDialogButtonBox::Apply));
797         bc().setCancel(buttonBox->button(QDialogButtonBox::Cancel));
798         bc().setRestore(buttonBox->button(QDialogButtonBox::Reset));
799
800
801         // text layout
802         textLayoutModule = new UiWidget<Ui::TextLayoutUi>(this);
803         connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
804                 this, SLOT(change_adaptor()));
805         connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
806                 this, SLOT(setLSpacing(int)));
807         connect(textLayoutModule->lspacingLE, SIGNAL(textChanged(const QString &)),
808                 this, SLOT(change_adaptor()));
809
810         connect(textLayoutModule->indentRB, SIGNAL(clicked()),
811                 this, SLOT(change_adaptor()));
812         connect(textLayoutModule->indentRB, SIGNAL(toggled(bool)),
813                 textLayoutModule->indentCO, SLOT(setEnabled(bool)));
814         connect(textLayoutModule->indentCO, SIGNAL(activated(int)),
815                 this, SLOT(change_adaptor()));
816         connect(textLayoutModule->indentCO, SIGNAL(activated(int)),
817                 this, SLOT(setIndent(int)));
818         connect(textLayoutModule->indentLE, SIGNAL(textChanged(const QString &)),
819                 this, SLOT(change_adaptor()));
820         connect(textLayoutModule->indentLengthCO, SIGNAL(activated(int)),
821                 this, SLOT(change_adaptor()));
822
823         connect(textLayoutModule->skipRB, SIGNAL(clicked()),
824                 this, SLOT(change_adaptor()));
825         connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
826                 textLayoutModule->skipCO, SLOT(setEnabled(bool)));
827         connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
828                 this, SLOT(change_adaptor()));
829         connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
830                 this, SLOT(setSkip(int)));
831         connect(textLayoutModule->skipLE, SIGNAL(textChanged(const QString &)),
832                 this, SLOT(change_adaptor()));
833         connect(textLayoutModule->skipLengthCO, SIGNAL(activated(int)),
834                 this, SLOT(change_adaptor()));
835
836         connect(textLayoutModule->indentRB, SIGNAL(toggled(bool)),
837                 this, SLOT(enableIndent(bool)));
838         connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
839                 this, SLOT(enableSkip(bool)));
840
841         connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
842                 this, SLOT(change_adaptor()));
843         connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
844                 this, SLOT(setColSep()));
845         connect(textLayoutModule->justCB, SIGNAL(clicked()),
846                 this, SLOT(change_adaptor()));
847
848         connect(textLayoutModule->tableStyleCO, SIGNAL(activated(int)),
849                 this, SLOT(change_adaptor()));
850
851         textLayoutModule->lspacingLE->setValidator(new QDoubleValidator(
852                 textLayoutModule->lspacingLE));
853         textLayoutModule->indentLE->setValidator(new LengthValidator(
854                 textLayoutModule->indentLE));
855         textLayoutModule->skipLE->setValidator(new LengthValidator(
856                 textLayoutModule->skipLE));
857
858         textLayoutModule->indentCO->addItem(qt_("Default"));
859         textLayoutModule->indentCO->addItem(qt_("Custom"));
860         textLayoutModule->skipCO->addItem(qt_("Half line height"), VSpace::HALFLINE);
861         textLayoutModule->skipCO->addItem(qt_("Line height"), VSpace::FULLLINE);
862         textLayoutModule->skipCO->addItem(qt_("SmallSkip"), VSpace::SMALLSKIP);
863         textLayoutModule->skipCO->addItem(qt_("MedSkip"), VSpace::MEDSKIP);
864         textLayoutModule->skipCO->addItem(qt_("BigSkip"), VSpace::BIGSKIP);
865         textLayoutModule->skipCO->addItem(qt_("Custom"), VSpace::LENGTH);
866         textLayoutModule->lspacingCO->insertItem(
867                 Spacing::Single, qt_("Single"));
868         textLayoutModule->lspacingCO->insertItem(
869                 Spacing::Onehalf, qt_("OneHalf"));
870         textLayoutModule->lspacingCO->insertItem(
871                 Spacing::Double, qt_("Double"));
872         textLayoutModule->lspacingCO->insertItem(
873                 Spacing::Other, qt_("Custom"));
874         // initialize the length validator
875         bc().addCheckedLineEdit(textLayoutModule->indentLE);
876         bc().addCheckedLineEdit(textLayoutModule->skipLE);
877
878         textLayoutModule->tableStyleCO->addItem(qt_("Default"), toqstr("default"));
879         getTableStyles();
880
881
882         // master/child handling
883         masterChildModule = new UiWidget<Ui::MasterChildUi>(this);
884
885         connect(masterChildModule->childrenTW, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),
886                 this, SLOT(includeonlyClicked(QTreeWidgetItem *, int)));
887         connect(masterChildModule->includeonlyRB, SIGNAL(toggled(bool)),
888                 masterChildModule->childrenTW, SLOT(setEnabled(bool)));
889         connect(masterChildModule->includeonlyRB, SIGNAL(toggled(bool)),
890                 masterChildModule->maintainGB, SLOT(setEnabled(bool)));
891         connect(masterChildModule->includeallRB, SIGNAL(clicked()),
892                 this, SLOT(change_adaptor()));
893         connect(masterChildModule->includeonlyRB, SIGNAL(clicked()),
894                 this, SLOT(change_adaptor()));
895         connect(masterChildModule->maintainCRNoneRB, SIGNAL(clicked()),
896                 this, SLOT(change_adaptor()));
897         connect(masterChildModule->maintainCRMostlyRB, SIGNAL(clicked()),
898                 this, SLOT(change_adaptor()));
899         connect(masterChildModule->maintainCRStrictRB, SIGNAL(clicked()),
900                 this, SLOT(change_adaptor()));
901         masterChildModule->childrenTW->setColumnCount(2);
902         masterChildModule->childrenTW->headerItem()->setText(0, qt_("Child Document"));
903         masterChildModule->childrenTW->headerItem()->setText(1, qt_("Include to Output"));
904 #if (QT_VERSION > 0x050000)
905         masterChildModule->childrenTW->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
906         masterChildModule->childrenTW->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
907 #else
908         masterChildModule->childrenTW->header()->setResizeMode(0, QHeaderView::ResizeToContents);
909         masterChildModule->childrenTW->header()->setResizeMode(1, QHeaderView::ResizeToContents);
910 #endif
911
912         // Formats
913         outputModule = new UiWidget<Ui::OutputUi>(this);
914
915         connect(outputModule->defaultFormatCO, SIGNAL(activated(int)),
916                 this, SLOT(change_adaptor()));
917         connect(outputModule->mathimgSB, SIGNAL(valueChanged(double)),
918                 this, SLOT(change_adaptor()));
919         connect(outputModule->strictCB, SIGNAL(stateChanged(int)),
920                 this, SLOT(change_adaptor()));
921         connect(outputModule->cssCB, SIGNAL(stateChanged(int)),
922                 this, SLOT(change_adaptor()));
923         connect(outputModule->mathoutCB, SIGNAL(currentIndexChanged(int)),
924                 this, SLOT(change_adaptor()));
925         connect(outputModule->tableoutCB, SIGNAL(currentIndexChanged(int)),
926                 this, SLOT(change_adaptor()));
927
928         connect(outputModule->shellescapeCB, SIGNAL(stateChanged(int)),
929                 this, SLOT(shellescapeChanged()));
930         connect(outputModule->outputsyncCB, SIGNAL(toggled(bool)),
931                 this, SLOT(setOutputSync(bool)));
932         connect(outputModule->synccustomCB, SIGNAL(editTextChanged(QString)),
933                 this, SLOT(change_adaptor()));
934         outputModule->synccustomCB->addItem("");
935         outputModule->synccustomCB->addItem("\\synctex=1");
936         outputModule->synccustomCB->addItem("\\synctex=-1");
937         outputModule->synccustomCB->addItem("\\usepackage[active]{srcltx}");
938
939         outputModule->synccustomCB->setValidator(new NoNewLineValidator(
940                 outputModule->synccustomCB));
941
942         connect(outputModule->saveTransientPropertiesCB, SIGNAL(clicked()),
943                 this, SLOT(change_adaptor()));
944         connect(outputModule->postponeFragileCB, SIGNAL(clicked()),
945                 this, SLOT(change_adaptor()));
946
947
948         // language & quote
949         // this must precede font, since fonts depend on this
950         langModule = new UiWidget<Ui::LanguageUi>(this);
951         connect(langModule->languageCO, SIGNAL(activated(int)),
952                 this, SLOT(change_adaptor()));
953         connect(langModule->languageCO, SIGNAL(activated(int)),
954                 this, SLOT(languageChanged(int)));
955         connect(langModule->encodingCO, SIGNAL(activated(int)),
956                 this, SLOT(change_adaptor()));
957         connect(langModule->encodingCO, SIGNAL(activated(int)),
958                 this, SLOT(encodingSwitched(int)));
959         connect(langModule->unicodeEncodingCO, SIGNAL(activated(int)),
960                 this, SLOT(change_adaptor()));
961         connect(langModule->autoEncodingCO, SIGNAL(activated(int)),
962                 this, SLOT(change_adaptor()));
963         connect(langModule->customEncodingCO, SIGNAL(activated(int)),
964                 this, SLOT(change_adaptor()));
965         connect(langModule->quoteStyleCO, SIGNAL(activated(int)),
966                 this, SLOT(change_adaptor()));
967         connect(langModule->languagePackageCO, SIGNAL(activated(int)),
968                 this, SLOT(change_adaptor()));
969         connect(langModule->languagePackageLE, SIGNAL(textChanged(QString)),
970                 this, SLOT(change_adaptor()));
971         connect(langModule->languagePackageCO, SIGNAL(currentIndexChanged(int)),
972                 this, SLOT(languagePackageChanged(int)));
973         connect(langModule->dynamicQuotesCB, SIGNAL(clicked()),
974                 this, SLOT(change_adaptor()));
975
976         langModule->languagePackageLE->setValidator(new NoNewLineValidator(
977                 langModule->languagePackageLE));
978
979         QAbstractItemModel * language_model = guiApp->languageModel();
980         // FIXME: it would be nice if sorting was enabled/disabled via a checkbox.
981         language_model->sort(0);
982         langModule->languageCO->setModel(language_model);
983         langModule->languageCO->setModelColumn(0);
984
985         langModule->encodingCO->addItem(qt_("Unicode (utf8)"));
986         langModule->encodingCO->addItem(qt_("Traditional (auto-selected)"));
987         langModule->encodingCO->addItem(qt_("Custom"));
988         langModule->encodingCO->setItemData(EncodingSets::unicode,
989                 qt_("Select Unicode (utf8) encoding."), Qt::ToolTipRole);
990         langModule->encodingCO->setItemData(EncodingSets::legacy,
991                 qt_("Use language-dependent traditional encodings."), Qt::ToolTipRole);
992         langModule->encodingCO->setItemData(EncodingSets::custom,
993                 qt_("Select a custom, document-wide encoding."), Qt::ToolTipRole);
994
995         // basic Unicode encodings: keep order
996         const QStringList utf8_base_encodings = {"utf8", "utf8-plain", "utf8x"};
997         for (auto const & i : utf8_base_encodings) {
998                 langModule->unicodeEncodingCO->addItem(
999                                         qt_(encodings.fromLyXName(fromqstr(i))->guiName()), i);
1000         }
1001         langModule->unicodeEncodingCO->setItemData(0,
1002                 qt_("Standard Unicode support by the ``inputenc'' package."),
1003                 Qt::ToolTipRole);
1004         langModule->unicodeEncodingCO->setItemData(1,
1005                 qt_("Use UTF-8 'as-is': do not load any supporting packages, "
1006                         "do not convert any characters to LaTeX macros. "
1007                         "For use with non-TeX fonts (XeTeX/LuaTeX) or custom preamble code."),
1008                 Qt::ToolTipRole);
1009         langModule->unicodeEncodingCO->setItemData(2,
1010                 qt_("Load ``inputenc'' with option 'utf8x' "
1011                         "for extended Unicode support by the ``ucs'' package."),
1012                 Qt::ToolTipRole);
1013         langModule->autoEncodingCO->addItem(qt_("Language Default"), toqstr("auto-legacy"));
1014         langModule->autoEncodingCO->addItem(qt_("Language Default (no inputenc)"), toqstr("auto-legacy-plain"));
1015         langModule->autoEncodingCO->setItemData(0,
1016                 qt_("Use the traditional default encoding of the text language. Switch encoding "
1017                         "if a text part is set to a language with different default."),
1018                 Qt::ToolTipRole);
1019         langModule->autoEncodingCO->setItemData(1,
1020                 qt_("Do not load the 'inputenc' package. Switch encoding if required "
1021                         "but do not write input encoding switch commands to the source."),
1022                 Qt::ToolTipRole);
1023         // sort encodings
1024         QMap<QString,QString> encodingmap;
1025         QMap<QString,QString> encodingmap_utf8;
1026         for (auto const & encvar : encodings) {
1027                 if (encvar.unsafe() ||encvar.guiName().empty()
1028                     || utf8_base_encodings.contains(toqstr(encvar.name())))
1029                         continue;
1030                 if (std::string(encvar.name()).find("utf8") == 0)
1031                         encodingmap_utf8.insert(qt_(encvar.guiName()), toqstr(encvar.name()));
1032                 else
1033                         encodingmap.insert(qt_(encvar.guiName()), toqstr(encvar.name()));
1034         }
1035         for (auto const & i : encodingmap_utf8.keys()) {
1036                 langModule->unicodeEncodingCO->addItem(i, encodingmap_utf8.value(i));
1037         }
1038         for (auto const & i : encodingmap.keys()) {
1039                 langModule->customEncodingCO->addItem(i, encodingmap.value(i));
1040         }
1041         // equalise the width of encoding selectors
1042         langModule->autoEncodingCO->setMinimumSize(
1043                 langModule->unicodeEncodingCO->minimumSizeHint());
1044         langModule->customEncodingCO->setMinimumSize(
1045                 langModule->unicodeEncodingCO->minimumSizeHint());
1046
1047         langModule->languagePackageCO->addItem(
1048                 qt_("Default"), toqstr("default"));
1049         langModule->languagePackageCO->addItem(
1050                 qt_("Automatic"), toqstr("auto"));
1051         langModule->languagePackageCO->addItem(
1052                 qt_("Always Babel"), toqstr("babel"));
1053         langModule->languagePackageCO->addItem(
1054                 qt_("Custom"), toqstr("custom"));
1055         langModule->languagePackageCO->addItem(
1056                 qt_("None[[language package]]"), toqstr("none"));
1057
1058
1059         // fonts
1060         fontModule = new FontModule(this);
1061         connect(fontModule->osFontsCB, SIGNAL(clicked()),
1062                 this, SLOT(change_adaptor()));
1063         connect(fontModule->osFontsCB, SIGNAL(toggled(bool)),
1064                 this, SLOT(osFontsChanged(bool)));
1065         connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
1066                 this, SLOT(change_adaptor()));
1067         connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
1068                 this, SLOT(romanChanged(int)));
1069         connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
1070                 this, SLOT(change_adaptor()));
1071         connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
1072                 this, SLOT(sansChanged(int)));
1073         connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
1074                 this, SLOT(change_adaptor()));
1075         connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
1076                 this, SLOT(ttChanged(int)));
1077         connect(fontModule->fontsMathCO, SIGNAL(activated(int)),
1078                 this, SLOT(change_adaptor()));
1079         connect(fontModule->fontsMathCO, SIGNAL(activated(int)),
1080                 this, SLOT(mathFontChanged(int)));
1081         connect(fontModule->fontsDefaultCO, SIGNAL(activated(int)),
1082                 this, SLOT(change_adaptor()));
1083         connect(fontModule->fontencCO, SIGNAL(activated(int)),
1084                 this, SLOT(change_adaptor()));
1085         connect(fontModule->fontencCO, SIGNAL(activated(int)),
1086                 this, SLOT(fontencChanged(int)));
1087         connect(fontModule->fontencLE, SIGNAL(textChanged(const QString &)),
1088                 this, SLOT(change_adaptor()));
1089         connect(fontModule->fontsizeCO, SIGNAL(activated(int)),
1090                 this, SLOT(change_adaptor()));
1091         connect(fontModule->cjkFontLE, SIGNAL(textChanged(const QString &)),
1092                 this, SLOT(change_adaptor()));
1093         connect(fontModule->microtypeCB, SIGNAL(clicked()),
1094                 this, SLOT(change_adaptor()));
1095         connect(fontModule->dashesCB, SIGNAL(clicked()),
1096                 this, SLOT(change_adaptor()));
1097         connect(fontModule->scaleSansSB, SIGNAL(valueChanged(int)),
1098                 this, SLOT(change_adaptor()));
1099         connect(fontModule->scaleTypewriterSB, SIGNAL(valueChanged(int)),
1100                 this, SLOT(change_adaptor()));
1101         connect(fontModule->fontScCB, SIGNAL(clicked()),
1102                 this, SLOT(change_adaptor()));
1103         connect(fontModule->fontScCB, SIGNAL(toggled(bool)),
1104                 this, SLOT(fontScToggled(bool)));
1105         connect(fontModule->fontOsfCB, SIGNAL(clicked()),
1106                 this, SLOT(change_adaptor()));
1107         connect(fontModule->fontOsfCB, SIGNAL(toggled(bool)),
1108                 this, SLOT(fontOsfToggled(bool)));
1109         connect(fontModule->fontSansOsfCB, SIGNAL(clicked()),
1110                 this, SLOT(change_adaptor()));
1111         connect(fontModule->fontTypewriterOsfCB, SIGNAL(clicked()),
1112                 this, SLOT(change_adaptor()));
1113         connect(fontModule->fontspecRomanLE, SIGNAL(textChanged(const QString &)),
1114                 this, SLOT(change_adaptor()));
1115         connect(fontModule->fontspecSansLE, SIGNAL(textChanged(const QString &)),
1116                 this, SLOT(change_adaptor()));
1117         connect(fontModule->fontspecTypewriterLE, SIGNAL(textChanged(const QString &)),
1118                 this, SLOT(change_adaptor()));
1119
1120         fontModule->fontencLE->setValidator(new NoNewLineValidator(
1121                 fontModule->fontencLE));
1122         fontModule->cjkFontLE->setValidator(new NoNewLineValidator(
1123                 fontModule->cjkFontLE));
1124         fontModule->fontspecRomanLE->setValidator(new NoNewLineValidator(
1125                 fontModule->fontspecRomanLE));
1126         fontModule->fontspecSansLE->setValidator(new NoNewLineValidator(
1127                 fontModule->fontspecSansLE));
1128         fontModule->fontspecTypewriterLE->setValidator(new NoNewLineValidator(
1129                 fontModule->fontspecTypewriterLE));
1130
1131         updateFontlist();
1132
1133         fontModule->fontsizeCO->addItem(qt_("Default"));
1134         fontModule->fontsizeCO->addItem(qt_("10"));
1135         fontModule->fontsizeCO->addItem(qt_("11"));
1136         fontModule->fontsizeCO->addItem(qt_("12"));
1137
1138         fontModule->fontencCO->addItem(qt_("Automatic[[encoding]]"), QString("auto"));
1139         fontModule->fontencCO->addItem(qt_("Class Default"), QString("default"));
1140         fontModule->fontencCO->addItem(qt_("Custom"), QString("custom"));
1141
1142         for (int n = 0; GuiDocument::fontfamilies_gui[n][0]; ++n)
1143                 fontModule->fontsDefaultCO->addItem(
1144                         qt_(GuiDocument::fontfamilies_gui[n]));
1145
1146         if (!LaTeXFeatures::isAvailable("fontspec"))
1147                 fontModule->osFontsCB->setToolTip(
1148                         qt_("Use OpenType and TrueType fonts directly (requires XeTeX or LuaTeX)\n"
1149                             "You need to install the package \"fontspec\" to use this feature"));
1150
1151
1152         // page layout
1153         pageLayoutModule = new UiWidget<Ui::PageLayoutUi>(this);
1154         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
1155                 this, SLOT(papersizeChanged(int)));
1156         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
1157                 this, SLOT(papersizeChanged(int)));
1158         connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
1159                 this, SLOT(change_adaptor()));
1160         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
1161                 this, SLOT(change_adaptor()));
1162         connect(pageLayoutModule->paperheightLE, SIGNAL(textChanged(const QString &)),
1163                 this, SLOT(change_adaptor()));
1164         connect(pageLayoutModule->paperwidthLE, SIGNAL(textChanged(const QString &)),
1165                 this, SLOT(change_adaptor()));
1166         connect(pageLayoutModule->paperwidthUnitCO, SIGNAL(activated(int)),
1167                 this, SLOT(change_adaptor()));
1168         connect(pageLayoutModule->paperheightUnitCO, SIGNAL(activated(int)),
1169                 this, SLOT(change_adaptor()));
1170         connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
1171                 this, SLOT(change_adaptor()));
1172         connect(pageLayoutModule->landscapeRB, SIGNAL(clicked()),
1173                 this, SLOT(change_adaptor()));
1174         connect(pageLayoutModule->facingPagesCB, SIGNAL(clicked()),
1175                 this, SLOT(change_adaptor()));
1176         connect(pageLayoutModule->pagestyleCO, SIGNAL(activated(int)),
1177                 this, SLOT(change_adaptor()));
1178
1179         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1180         pageLayoutModule->pagestyleCO->addItem(qt_("empty"));
1181         pageLayoutModule->pagestyleCO->addItem(qt_("plain"));
1182         pageLayoutModule->pagestyleCO->addItem(qt_("headings"));
1183         pageLayoutModule->pagestyleCO->addItem(qt_("fancy"));
1184         bc().addCheckedLineEdit(pageLayoutModule->paperheightLE,
1185                 pageLayoutModule->paperheightL);
1186         bc().addCheckedLineEdit(pageLayoutModule->paperwidthLE,
1187                 pageLayoutModule->paperwidthL);
1188
1189         QComboBox * cb = pageLayoutModule->papersizeCO;
1190         cb->addItem(qt_("Default"));
1191         cb->addItem(qt_("Custom"));
1192         cb->addItem(qt_("US letter"));
1193         cb->addItem(qt_("US legal"));
1194         cb->addItem(qt_("US executive"));
1195         cb->addItem(qt_("A0"));
1196         cb->addItem(qt_("A1"));
1197         cb->addItem(qt_("A2"));
1198         cb->addItem(qt_("A3"));
1199         cb->addItem(qt_("A4"));
1200         cb->addItem(qt_("A5"));
1201         cb->addItem(qt_("A6"));
1202         cb->addItem(qt_("B0"));
1203         cb->addItem(qt_("B1"));
1204         cb->addItem(qt_("B2"));
1205         cb->addItem(qt_("B3"));
1206         cb->addItem(qt_("B4"));
1207         cb->addItem(qt_("B5"));
1208         cb->addItem(qt_("B6"));
1209         cb->addItem(qt_("C0"));
1210         cb->addItem(qt_("C1"));
1211         cb->addItem(qt_("C2"));
1212         cb->addItem(qt_("C3"));
1213         cb->addItem(qt_("C4"));
1214         cb->addItem(qt_("C5"));
1215         cb->addItem(qt_("C6"));
1216         cb->addItem(qt_("JIS B0"));
1217         cb->addItem(qt_("JIS B1"));
1218         cb->addItem(qt_("JIS B2"));
1219         cb->addItem(qt_("JIS B3"));
1220         cb->addItem(qt_("JIS B4"));
1221         cb->addItem(qt_("JIS B5"));
1222         cb->addItem(qt_("JIS B6"));
1223         // remove the %-items from the unit choice
1224         pageLayoutModule->paperwidthUnitCO->noPercents();
1225         pageLayoutModule->paperheightUnitCO->noPercents();
1226         pageLayoutModule->paperheightLE->setValidator(unsignedLengthValidator(
1227                 pageLayoutModule->paperheightLE));
1228         pageLayoutModule->paperwidthLE->setValidator(unsignedLengthValidator(
1229                 pageLayoutModule->paperwidthLE));
1230
1231
1232         // margins
1233         marginsModule = new UiWidget<Ui::MarginsUi>(this);
1234         connect(marginsModule->marginCB, SIGNAL(toggled(bool)),
1235                 this, SLOT(setCustomMargins(bool)));
1236         connect(marginsModule->marginCB, SIGNAL(clicked()),
1237                 this, SLOT(change_adaptor()));
1238         connect(marginsModule->topLE, SIGNAL(textChanged(QString)),
1239                 this, SLOT(change_adaptor()));
1240         connect(marginsModule->topUnit, SIGNAL(activated(int)),
1241                 this, SLOT(change_adaptor()));
1242         connect(marginsModule->bottomLE, SIGNAL(textChanged(QString)),
1243                 this, SLOT(change_adaptor()));
1244         connect(marginsModule->bottomUnit, SIGNAL(activated(int)),
1245                 this, SLOT(change_adaptor()));
1246         connect(marginsModule->innerLE, SIGNAL(textChanged(QString)),
1247                 this, SLOT(change_adaptor()));
1248         connect(marginsModule->innerUnit, SIGNAL(activated(int)),
1249                 this, SLOT(change_adaptor()));
1250         connect(marginsModule->outerLE, SIGNAL(textChanged(QString)),
1251                 this, SLOT(change_adaptor()));
1252         connect(marginsModule->outerUnit, SIGNAL(activated(int)),
1253                 this, SLOT(change_adaptor()));
1254         connect(marginsModule->headheightLE, SIGNAL(textChanged(QString)),
1255                 this, SLOT(change_adaptor()));
1256         connect(marginsModule->headheightUnit, SIGNAL(activated(int)),
1257                 this, SLOT(change_adaptor()));
1258         connect(marginsModule->headsepLE, SIGNAL(textChanged(QString)),
1259                 this, SLOT(change_adaptor()));
1260         connect(marginsModule->headsepUnit, SIGNAL(activated(int)),
1261                 this, SLOT(change_adaptor()));
1262         connect(marginsModule->footskipLE, SIGNAL(textChanged(QString)),
1263                 this, SLOT(change_adaptor()));
1264         connect(marginsModule->footskipUnit, SIGNAL(activated(int)),
1265                 this, SLOT(change_adaptor()));
1266         connect(marginsModule->columnsepLE, SIGNAL(textChanged(QString)),
1267                 this, SLOT(change_adaptor()));
1268         connect(marginsModule->columnsepUnit, SIGNAL(activated(int)),
1269                 this, SLOT(change_adaptor()));
1270         marginsModule->topLE->setValidator(new LengthValidator(
1271                 marginsModule->topLE));
1272         marginsModule->bottomLE->setValidator(new LengthValidator(
1273                 marginsModule->bottomLE));
1274         marginsModule->innerLE->setValidator(new LengthValidator(
1275                 marginsModule->innerLE));
1276         marginsModule->outerLE->setValidator(new LengthValidator(
1277                 marginsModule->outerLE));
1278         marginsModule->headsepLE->setValidator(new LengthValidator(
1279                 marginsModule->headsepLE));
1280         marginsModule->headheightLE->setValidator(new LengthValidator(
1281                 marginsModule->headheightLE));
1282         marginsModule->footskipLE->setValidator(new LengthValidator(
1283                 marginsModule->footskipLE));
1284         marginsModule->columnsepLE->setValidator(new LengthValidator(
1285                 marginsModule->columnsepLE));
1286
1287         bc().addCheckedLineEdit(marginsModule->topLE,
1288                 marginsModule->topL);
1289         bc().addCheckedLineEdit(marginsModule->bottomLE,
1290                 marginsModule->bottomL);
1291         bc().addCheckedLineEdit(marginsModule->innerLE,
1292                 marginsModule->innerL);
1293         bc().addCheckedLineEdit(marginsModule->outerLE,
1294                 marginsModule->outerL);
1295         bc().addCheckedLineEdit(marginsModule->headsepLE,
1296                 marginsModule->headsepL);
1297         bc().addCheckedLineEdit(marginsModule->headheightLE,
1298                 marginsModule->headheightL);
1299         bc().addCheckedLineEdit(marginsModule->footskipLE,
1300                 marginsModule->footskipL);
1301         bc().addCheckedLineEdit(marginsModule->columnsepLE,
1302                 marginsModule->columnsepL);
1303
1304
1305         // color
1306         colorModule = new UiWidget<Ui::ColorUi>(this);
1307         connect(colorModule->fontColorPB, SIGNAL(clicked()),
1308                 this, SLOT(changeFontColor()));
1309         connect(colorModule->delFontColorTB, SIGNAL(clicked()),
1310                 this, SLOT(deleteFontColor()));
1311         connect(colorModule->noteFontColorPB, SIGNAL(clicked()),
1312                 this, SLOT(changeNoteFontColor()));
1313         connect(colorModule->delNoteFontColorTB, SIGNAL(clicked()),
1314                 this, SLOT(deleteNoteFontColor()));
1315         connect(colorModule->backgroundPB, SIGNAL(clicked()),
1316                 this, SLOT(changeBackgroundColor()));
1317         connect(colorModule->delBackgroundTB, SIGNAL(clicked()),
1318                 this, SLOT(deleteBackgroundColor()));
1319         connect(colorModule->boxBackgroundPB, SIGNAL(clicked()),
1320                 this, SLOT(changeBoxBackgroundColor()));
1321         connect(colorModule->delBoxBackgroundTB, SIGNAL(clicked()),
1322                 this, SLOT(deleteBoxBackgroundColor()));
1323
1324         // change tracking
1325         changesModule = new UiWidget<Ui::ChangeTrackingUi>(this);
1326         connect(changesModule->trackChangesCB, SIGNAL(clicked()),
1327                 this, SLOT(change_adaptor()));
1328         connect(changesModule->outputChangesCB, SIGNAL(toggled(bool)),
1329                 this, SLOT(outputChangesToggled(bool)));
1330         connect(changesModule->changeBarsCB, SIGNAL(clicked()),
1331                 this, SLOT(change_adaptor()));
1332
1333         // numbering
1334         numberingModule = new UiWidget<Ui::NumberingUi>(this);
1335         connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
1336                 this, SLOT(change_adaptor()));
1337         connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
1338                 this, SLOT(change_adaptor()));
1339         connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
1340                 this, SLOT(updateNumbering()));
1341         connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
1342                 this, SLOT(updateNumbering()));
1343         numberingModule->tocTW->setColumnCount(3);
1344         numberingModule->tocTW->headerItem()->setText(0, qt_("Example"));
1345         numberingModule->tocTW->headerItem()->setText(1, qt_("Numbered"));
1346         numberingModule->tocTW->headerItem()->setText(2, qt_("Appears in TOC"));
1347         setSectionResizeMode(numberingModule->tocTW->header(), QHeaderView::ResizeToContents);
1348         connect(numberingModule->linenoCB, SIGNAL(toggled(bool)),
1349                 this, SLOT(linenoToggled(bool)));
1350         connect(numberingModule->linenoCB, SIGNAL(clicked()),
1351                 this, SLOT(change_adaptor()));
1352         connect(numberingModule->linenoLE, SIGNAL(textChanged(QString)),
1353                 this, SLOT(change_adaptor()));
1354
1355
1356         // biblio
1357         biblioModule = new UiWidget<Ui::BiblioUi>(this);
1358         connect(biblioModule->citeEngineCO, SIGNAL(activated(int)),
1359                 this, SLOT(citeEngineChanged(int)));
1360         connect(biblioModule->citeStyleCO, SIGNAL(activated(int)),
1361                 this, SLOT(citeStyleChanged()));
1362         connect(biblioModule->bibtopicCB, SIGNAL(clicked()),
1363                 this, SLOT(biblioChanged()));
1364         connect(biblioModule->bibunitsCO, SIGNAL(activated(int)),
1365                 this, SLOT(biblioChanged()));
1366         connect(biblioModule->bibtexCO, SIGNAL(activated(int)),
1367                 this, SLOT(bibtexChanged(int)));
1368         connect(biblioModule->bibtexOptionsLE, SIGNAL(textChanged(QString)),
1369                 this, SLOT(biblioChanged()));
1370         connect(biblioModule->citePackageOptionsLE, SIGNAL(textChanged(QString)),
1371                 this, SLOT(biblioChanged()));
1372         connect(biblioModule->defaultBiblioCO, SIGNAL(activated(int)),
1373                 this, SLOT(biblioChanged()));
1374         connect(biblioModule->defaultBiblioCO, SIGNAL(editTextChanged(QString)),
1375                 this, SLOT(biblioChanged()));
1376         connect(biblioModule->defaultBiblioCO, SIGNAL(editTextChanged(QString)),
1377                 this, SLOT(updateResetDefaultBiblio()));
1378         connect(biblioModule->biblatexBbxCO, SIGNAL(activated(int)),
1379                 this, SLOT(biblioChanged()));
1380         connect(biblioModule->biblatexBbxCO, SIGNAL(editTextChanged(QString)),
1381                 this, SLOT(biblioChanged()));
1382         connect(biblioModule->biblatexBbxCO, SIGNAL(editTextChanged(QString)),
1383                 this, SLOT(updateResetDefaultBiblio()));
1384         connect(biblioModule->biblatexCbxCO, SIGNAL(activated(int)),
1385                 this, SLOT(biblioChanged()));
1386         connect(biblioModule->biblatexCbxCO, SIGNAL(editTextChanged(QString)),
1387                 this, SLOT(biblioChanged()));
1388         connect(biblioModule->biblatexCbxCO, SIGNAL(editTextChanged(QString)),
1389                 this, SLOT(updateResetDefaultBiblio()));
1390         connect(biblioModule->rescanBibliosPB, SIGNAL(clicked()),
1391                 this, SLOT(rescanBibFiles()));
1392         connect(biblioModule->resetDefaultBiblioPB, SIGNAL(clicked()),
1393                 this, SLOT(resetDefaultBibfile()));
1394         connect(biblioModule->resetCbxPB, SIGNAL(clicked()),
1395                 this, SLOT(resetDefaultCbxBibfile()));
1396         connect(biblioModule->resetBbxPB, SIGNAL(clicked()),
1397                 this, SLOT(resetDefaultBbxBibfile()));
1398         connect(biblioModule->matchBbxPB, SIGNAL(clicked()),
1399                 this, SLOT(matchBiblatexStyles()));
1400
1401         biblioModule->citeEngineCO->clear();
1402         for (LyXCiteEngine const & cet : theCiteEnginesList) {
1403                 biblioModule->citeEngineCO->addItem(qt_(cet.getName()), toqstr(cet.getID()));
1404                 int const i = biblioModule->citeEngineCO->findData(toqstr(cet.getID()));
1405                 biblioModule->citeEngineCO->setItemData(i, qt_(cet.getDescription()),
1406                                                         Qt::ToolTipRole);
1407         }
1408
1409         biblioModule->bibtexOptionsLE->setValidator(new NoNewLineValidator(
1410                 biblioModule->bibtexOptionsLE));
1411         biblioModule->defaultBiblioCO->lineEdit()->setValidator(new NoNewLineValidator(
1412                 biblioModule->defaultBiblioCO->lineEdit()));
1413         biblioModule->citePackageOptionsLE->setValidator(new NoNewLineValidator(
1414                 biblioModule->citePackageOptionsLE));
1415
1416         // NOTE: we do not provide "custom" here for security reasons!
1417         biblioModule->bibtexCO->clear();
1418         biblioModule->bibtexCO->addItem(qt_("Default"), QString("default"));
1419         for (auto const & alts : lyxrc.bibtex_alternatives) {
1420                 QString const command = toqstr(alts).left(toqstr(alts).indexOf(" "));
1421                 biblioModule->bibtexCO->addItem(command, command);
1422         }
1423
1424
1425         // indices
1426         indicesModule = new GuiIndices;
1427         connect(indicesModule, SIGNAL(changed()),
1428                 this, SLOT(change_adaptor()));
1429
1430
1431         // maths
1432         mathsModule = new UiWidget<Ui::MathsUi>(this);
1433         QStringList headers;
1434         headers << qt_("Package") << qt_("Load automatically")
1435                 << qt_("Load always") << qt_("Do not load");
1436         mathsModule->packagesTW->setHorizontalHeaderLabels(headers);
1437         setSectionResizeMode(mathsModule->packagesTW->horizontalHeader(), QHeaderView::Stretch);
1438         map<string, string> const & packages = BufferParams::auto_packages();
1439         mathsModule->packagesTW->setRowCount(packages.size());
1440         int packnum = 0;
1441         for (auto const & pkgvar : packages) {
1442                 docstring const package = from_ascii(pkgvar.first);
1443                 QString autoTooltip = qt_(pkgvar.second);
1444                 QString alwaysTooltip;
1445                 if (package == "amsmath")
1446                         alwaysTooltip =
1447                                 qt_("The AMS LaTeX packages are always used");
1448                 else
1449                         alwaysTooltip = toqstr(bformat(
1450                                 _("The LaTeX package %1$s is always used"),
1451                                 package));
1452                 QString neverTooltip;
1453                 if (package == "amsmath")
1454                         neverTooltip =
1455                                 qt_("The AMS LaTeX packages are never used");
1456                 else
1457                         neverTooltip = toqstr(bformat(
1458                                 _("The LaTeX package %1$s is never used"),
1459                                 package));
1460                 QRadioButton * autoRB = new QRadioButton(mathsModule);
1461                 QRadioButton * alwaysRB = new QRadioButton(mathsModule);
1462                 QRadioButton * neverRB = new QRadioButton(mathsModule);
1463                 QButtonGroup * packageGroup = new QButtonGroup(mathsModule);
1464                 packageGroup->addButton(autoRB);
1465                 packageGroup->addButton(alwaysRB);
1466                 packageGroup->addButton(neverRB);
1467                 autoRB->setToolTip(autoTooltip);
1468                 alwaysRB->setToolTip(alwaysTooltip);
1469                 neverRB->setToolTip(neverTooltip);
1470
1471                 // Pack the buttons in a layout in order to get proper alignment
1472                 QWidget * autoRBWidget = new QWidget();
1473                 QHBoxLayout * autoRBLayout = new QHBoxLayout(autoRBWidget);
1474                 autoRBLayout->addWidget(autoRB);
1475                 autoRBLayout->setAlignment(Qt::AlignCenter);
1476                 autoRBLayout->setContentsMargins(0, 0, 0, 0);
1477                 autoRBWidget->setLayout(autoRBLayout);
1478
1479                 QWidget * alwaysRBWidget = new QWidget();
1480                 QHBoxLayout * alwaysRBLayout = new QHBoxLayout(alwaysRBWidget);
1481                 alwaysRBLayout->addWidget(alwaysRB);
1482                 alwaysRBLayout->setAlignment(Qt::AlignCenter);
1483                 alwaysRBLayout->setContentsMargins(0, 0, 0, 0);
1484                 alwaysRBWidget->setLayout(alwaysRBLayout);
1485
1486                 QWidget * neverRBWidget = new QWidget();
1487                 QHBoxLayout * neverRBLayout = new QHBoxLayout(neverRBWidget);
1488                 neverRBLayout->addWidget(neverRB);
1489                 neverRBLayout->setAlignment(Qt::AlignCenter);
1490                 neverRBLayout->setContentsMargins(0, 0, 0, 0);
1491                 neverRBWidget->setLayout(neverRBLayout);
1492
1493                 QTableWidgetItem * pack = new QTableWidgetItem(toqstr(package));
1494                 mathsModule->packagesTW->setItem(packnum, 0, pack);
1495                 mathsModule->packagesTW->setCellWidget(packnum, 1, autoRBWidget);
1496                 mathsModule->packagesTW->setCellWidget(packnum, 2, alwaysRBWidget);
1497                 mathsModule->packagesTW->setCellWidget(packnum, 3, neverRBWidget);
1498
1499                 connect(autoRB, SIGNAL(clicked()),
1500                         this, SLOT(change_adaptor()));
1501                 connect(alwaysRB, SIGNAL(clicked()),
1502                         this, SLOT(change_adaptor()));
1503                 connect(neverRB, SIGNAL(clicked()),
1504                         this, SLOT(change_adaptor()));
1505                 ++packnum;
1506         }
1507         connect(mathsModule->allPackagesAutoPB, SIGNAL(clicked()),
1508                 this, SLOT(allPackagesAuto()));
1509         connect(mathsModule->allPackagesAlwaysPB, SIGNAL(clicked()),
1510                 this, SLOT(allPackagesAlways()));
1511         connect(mathsModule->allPackagesNotPB, SIGNAL(clicked()),
1512                 this, SLOT(allPackagesNot()));
1513         connect(mathsModule->allPackagesAutoPB, SIGNAL(clicked()),
1514                 this, SLOT(change_adaptor()));
1515         connect(mathsModule->allPackagesAlwaysPB, SIGNAL(clicked()),
1516                 this, SLOT(change_adaptor()));
1517         connect(mathsModule->allPackagesNotPB, SIGNAL(clicked()),
1518                 this, SLOT(change_adaptor()));
1519         connect(mathsModule->MathNumberingPosCO, SIGNAL(activated(int)),
1520                 this, SLOT(change_adaptor()));
1521
1522         connect(mathsModule->MathIndentCB, SIGNAL(toggled(bool)),
1523                 this, SLOT(change_adaptor()));
1524         connect(mathsModule->MathIndentCB, SIGNAL(toggled(bool)),
1525                 this, SLOT(allowMathIndent()));
1526         connect(mathsModule->MathIndentCO, SIGNAL(activated(int)),
1527                 this, SLOT(change_adaptor()));
1528         connect(mathsModule->MathIndentCO, SIGNAL(activated(int)),
1529                 this, SLOT(enableMathIndent(int)));
1530         connect(mathsModule->MathIndentLE, SIGNAL(textChanged(const QString &)),
1531                 this, SLOT(change_adaptor()));
1532         connect(mathsModule->MathIndentLengthCO, SIGNAL(activated(int)),
1533                 this, SLOT(change_adaptor()));
1534
1535
1536         mathsModule->MathIndentCO->addItem(qt_("Default"));
1537         mathsModule->MathIndentCO->addItem(qt_("Custom"));
1538         mathsModule->MathIndentLE->setValidator(new LengthValidator(
1539                 mathsModule->MathIndentLE));
1540         // initialize the length validator
1541         bc().addCheckedLineEdit(mathsModule->MathIndentLE);
1542         mathsModule->MathNumberingPosCO->addItem(qt_("Left"));
1543         mathsModule->MathNumberingPosCO->addItem(qt_("Default"));
1544         mathsModule->MathNumberingPosCO->addItem(qt_("Right"));
1545         mathsModule->MathNumberingPosCO->setCurrentIndex(1);
1546
1547
1548         // latex class
1549         latexModule = new UiWidget<Ui::LaTeXUi>(this);
1550         connect(latexModule->optionsLE, SIGNAL(textChanged(QString)),
1551                 this, SLOT(change_adaptor()));
1552         connect(latexModule->defaultOptionsCB, SIGNAL(clicked()),
1553                 this, SLOT(change_adaptor()));
1554         connect(latexModule->psdriverCO, SIGNAL(activated(int)),
1555                 this, SLOT(change_adaptor()));
1556         connect(latexModule->classCO, SIGNAL(activated(int)),
1557                 this, SLOT(classChanged_adaptor()));
1558         connect(latexModule->classCO, SIGNAL(activated(int)),
1559                 this, SLOT(change_adaptor()));
1560         connect(latexModule->layoutPB, SIGNAL(clicked()),
1561                 this, SLOT(browseLayout()));
1562         connect(latexModule->layoutPB, SIGNAL(clicked()),
1563                 this, SLOT(change_adaptor()));
1564         connect(latexModule->childDocGB, SIGNAL(clicked()),
1565                 this, SLOT(change_adaptor()));
1566         connect(latexModule->childDocLE, SIGNAL(textChanged(QString)),
1567                 this, SLOT(change_adaptor()));
1568         connect(latexModule->childDocPB, SIGNAL(clicked()),
1569                 this, SLOT(browseMaster()));
1570         connect(latexModule->suppressDateCB, SIGNAL(clicked()),
1571                 this, SLOT(change_adaptor()));
1572         connect(latexModule->refstyleCB, SIGNAL(clicked()),
1573                 this, SLOT(change_adaptor()));
1574
1575         latexModule->optionsLE->setValidator(new NoNewLineValidator(
1576                 latexModule->optionsLE));
1577         latexModule->childDocLE->setValidator(new NoNewLineValidator(
1578                 latexModule->childDocLE));
1579
1580         // postscript drivers
1581         for (int n = 0; tex_graphics[n][0]; ++n) {
1582                 QString enc = qt_(tex_graphics_gui[n]);
1583                 latexModule->psdriverCO->addItem(enc);
1584         }
1585         // latex classes
1586         LayoutFileList const & bcl = LayoutFileList::get();
1587         vector<LayoutFileIndex> classList = bcl.classList();
1588         sort(classList.begin(), classList.end(), less_textclass_avail_desc());
1589
1590         for (auto const & cvar : classList) {
1591                 LayoutFile const & tc = bcl[cvar];
1592                 bool const available = tc.isTeXClassAvailable();
1593                 docstring const guiname = translateIfPossible(from_utf8(tc.description()));
1594                 // tooltip sensu "KOMA-Script Article [Class 'scrartcl']"
1595                 QString tooltip = toqstr(bformat(_("%1$s [Class '%2$s']"), guiname, from_utf8(tc.latexname())));
1596                 if (!available) {
1597                         docstring const output_type = _("LaTeX");
1598                         tooltip += '\n' + toqstr(bformat(_("Class not found by LyX. "
1599                                                            "Please check if you have the matching %1$s class "
1600                                                            "and all required packages (%2$s) installed."),
1601                                                          output_type, from_utf8(tc.prerequisites(", "))));
1602                 }
1603                 latexModule->classCO->addItemSort(toqstr(tc.name()),
1604                                                   toqstr(guiname),
1605                                                   toqstr(translateIfPossible(from_utf8(tc.category()))),
1606                                                   tooltip,
1607                                                   true, true, true, available);
1608         }
1609
1610
1611         // branches
1612         branchesModule = new GuiBranches(this);
1613         connect(branchesModule, SIGNAL(changed()),
1614                 this, SLOT(change_adaptor()));
1615         connect(branchesModule, SIGNAL(renameBranches(docstring const &, docstring const &)),
1616                 this, SLOT(branchesRename(docstring const &, docstring const &)));
1617         connect(branchesModule, SIGNAL(okPressed()), this, SLOT(slotOK()));
1618         updateUnknownBranches();
1619
1620
1621         // preamble
1622         preambleModule = new PreambleModule(this);
1623         connect(preambleModule, SIGNAL(changed()),
1624                 this, SLOT(change_adaptor()));
1625
1626         localLayout = new LocalLayout(this);
1627         connect(localLayout, SIGNAL(changed()),
1628                 this, SLOT(change_adaptor()));
1629
1630
1631         // bullets
1632         bulletsModule = new BulletsModule(this);
1633         connect(bulletsModule, SIGNAL(changed()),
1634                 this, SLOT(change_adaptor()));
1635
1636
1637         // Modules
1638         modulesModule = new UiWidget<Ui::ModulesUi>(this);
1639         modulesModule->availableLV->header()->setVisible(false);
1640         setSectionResizeMode(modulesModule->availableLV->header(), QHeaderView::ResizeToContents);
1641         modulesModule->availableLV->header()->setStretchLastSection(false);
1642         modulesModule->selectedLV->header()->setVisible(false);
1643         setSectionResizeMode(modulesModule->selectedLV->header(), QHeaderView::ResizeToContents);
1644         modulesModule->selectedLV->header()->setStretchLastSection(false);
1645         selectionManager =
1646                 new ModuleSelectionManager(this, modulesModule->availableLV,
1647                                            modulesModule->selectedLV,
1648                                            modulesModule->addPB,
1649                                            modulesModule->deletePB,
1650                                            modulesModule->upPB,
1651                                            modulesModule->downPB,
1652                                            availableModel(), selectedModel(), this);
1653         connect(selectionManager, SIGNAL(updateHook()),
1654                 this, SLOT(updateModuleInfo()));
1655         connect(selectionManager, SIGNAL(selectionChanged()),
1656                 this, SLOT(modulesChanged()));
1657         // The filter bar
1658         filter_ = new FancyLineEdit(this);
1659         filter_->setClearButton(true);
1660         filter_->setPlaceholderText(qt_("All avail. modules"));
1661         modulesModule->moduleFilterBarL->addWidget(filter_, 0);
1662         modulesModule->findModulesLA->setBuddy(filter_);
1663
1664         connect(filter_, SIGNAL(rightButtonClicked()),
1665                 this, SLOT(resetModuleFilter()));
1666         connect(filter_, SIGNAL(textEdited(QString)),
1667                 this, SLOT(moduleFilterChanged(QString)));
1668         connect(filter_, SIGNAL(returnPressed()),
1669                 this, SLOT(moduleFilterPressed()));
1670 #if (QT_VERSION < 0x050000)
1671         connect(filter_, SIGNAL(downPressed()),
1672                 modulesModule->availableLV, SLOT(setFocus()));
1673 #else
1674         connect(filter_, &FancyLineEdit::downPressed,
1675                 modulesModule->availableLV, [this](){ focusAndHighlight(modulesModule->availableLV); });
1676 #endif
1677
1678
1679         // PDF support
1680         pdfSupportModule = new UiWidget<Ui::PDFSupportUi>(this);
1681         connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
1682                 this, SLOT(change_adaptor()));
1683         connect(pdfSupportModule->titleLE, SIGNAL(textChanged(QString)),
1684                 this, SLOT(change_adaptor()));
1685         connect(pdfSupportModule->authorLE, SIGNAL(textChanged(QString)),
1686                 this, SLOT(change_adaptor()));
1687         connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(QString)),
1688                 this, SLOT(change_adaptor()));
1689         connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(QString)),
1690                 this, SLOT(change_adaptor()));
1691         connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
1692                 this, SLOT(change_adaptor()));
1693         connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
1694                 this, SLOT(change_adaptor()));
1695         connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
1696                 this, SLOT(change_adaptor()));
1697         connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
1698                 this, SLOT(bookmarksopenChanged(bool)));
1699         connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
1700                 this, SLOT(change_adaptor()));
1701         connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
1702                 this, SLOT(change_adaptor()));
1703         connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
1704                 this, SLOT(change_adaptor()));
1705         connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
1706                 this, SLOT(change_adaptor()));
1707         connect(pdfSupportModule->backrefCO, SIGNAL(activated(int)),
1708                 this, SLOT(change_adaptor()));
1709         connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
1710                 this, SLOT(change_adaptor()));
1711         connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
1712                 this, SLOT(change_adaptor()));
1713         connect(pdfSupportModule->optionsLE, SIGNAL(textChanged(QString)),
1714                 this, SLOT(change_adaptor()));
1715
1716         pdfSupportModule->titleLE->setValidator(new NoNewLineValidator(
1717                 pdfSupportModule->titleLE));
1718         pdfSupportModule->authorLE->setValidator(new NoNewLineValidator(
1719                 pdfSupportModule->authorLE));
1720         pdfSupportModule->subjectLE->setValidator(new NoNewLineValidator(
1721                 pdfSupportModule->subjectLE));
1722         pdfSupportModule->keywordsLE->setValidator(new NoNewLineValidator(
1723                 pdfSupportModule->keywordsLE));
1724         pdfSupportModule->optionsLE->setValidator(new NoNewLineValidator(
1725                 pdfSupportModule->optionsLE));
1726
1727         for (int i = 0; backref_opts[i][0]; ++i)
1728                 pdfSupportModule->backrefCO->addItem(qt_(backref_opts_gui[i]));
1729
1730
1731         // float
1732         floatModule = new FloatPlacement;
1733         connect(floatModule, SIGNAL(changed()),
1734                 this, SLOT(change_adaptor()));
1735
1736
1737         // listings
1738         listingsModule = new UiWidget<Ui::ListingsSettingsUi>(this);
1739         connect(listingsModule->listingsED, SIGNAL(textChanged()),
1740                 this, SLOT(change_adaptor()));
1741         connect(listingsModule->bypassCB, SIGNAL(clicked()),
1742                 this, SLOT(change_adaptor()));
1743         connect(listingsModule->bypassCB, SIGNAL(clicked()),
1744                 this, SLOT(setListingsMessage()));
1745         connect(listingsModule->packageCO, SIGNAL(activated(int)),
1746                 this, SLOT(change_adaptor()));
1747         connect(listingsModule->packageCO, SIGNAL(activated(int)),
1748                 this, SLOT(listingsPackageChanged(int)));
1749         connect(listingsModule->listingsED, SIGNAL(textChanged()),
1750                 this, SLOT(setListingsMessage()));
1751         listingsModule->listingsTB->setPlainText(
1752                 qt_("Input listings parameters below. Enter ? for a list of parameters."));
1753
1754         for (int i = 0; lst_packages[i][0]; ++i)
1755             listingsModule->packageCO->addItem(lst_packages[i]);
1756
1757
1758         // add the panels
1759         docPS->addPanel(latexModule, N_("Document Class"));
1760         docPS->addPanel(masterChildModule, N_("Child Documents"));
1761         docPS->addPanel(modulesModule, N_("Modules"));
1762         docPS->addPanel(localLayout, N_("Local Layout"));
1763         docPS->addPanel(fontModule, N_("Fonts"));
1764         docPS->addPanel(textLayoutModule, N_("Text Layout"));
1765         docPS->addPanel(pageLayoutModule, N_("Page Layout"));
1766         docPS->addPanel(marginsModule, N_("Page Margins"));
1767         docPS->addPanel(langModule, N_("Language"));
1768         docPS->addPanel(colorModule, N_("Colors"));
1769         docPS->addPanel(changesModule, N_("Change Tracking"));
1770         docPS->addPanel(numberingModule, N_("Numbering & TOC"));
1771         docPS->addPanel(biblioModule, N_("Bibliography"));
1772         docPS->addPanel(indicesModule, N_("Indexes"));
1773         docPS->addPanel(pdfSupportModule, N_("PDF Properties"));
1774         docPS->addPanel(mathsModule, N_("Math Options"));
1775         docPS->addPanel(floatModule, N_("Float Settings"));
1776         docPS->addPanel(listingsModule, N_("Listings[[inset]]"));
1777         docPS->addPanel(bulletsModule, N_("Bullets"));
1778         docPS->addPanel(branchesModule, N_("Branches"));
1779         docPS->addPanel(outputModule, N_("Formats[[output]]"));
1780         docPS->addPanel(preambleModule, N_("LaTeX Preamble"));
1781         docPS->setCurrentPanel("Document Class");
1782 // FIXME: hack to work around resizing bug in Qt >= 4.2
1783 // bug verified with Qt 4.2.{0-3} (JSpitzm)
1784 #if QT_VERSION >= 0x040200
1785         docPS->updateGeometry();
1786 #endif
1787 }
1788
1789
1790 void GuiDocument::onBufferViewChanged()
1791 {
1792         if (isVisibleView())
1793                 initialiseParams("");
1794 }
1795
1796
1797 void GuiDocument::saveDefaultClicked()
1798 {
1799         saveDocDefault();
1800 }
1801
1802
1803 void GuiDocument::useDefaultsClicked()
1804 {
1805         useClassDefaults();
1806 }
1807
1808
1809 void GuiDocument::change_adaptor()
1810 {
1811         nonModuleChanged_ = true;
1812         changed();
1813 }
1814
1815
1816 void GuiDocument::shellescapeChanged()
1817 {
1818         shellescapeChanged_ = true;
1819         changed();
1820 }
1821
1822 void GuiDocument::bookmarksopenChanged(bool state)
1823 {
1824         pdfSupportModule->bookmarksopenlevelSB->setEnabled(state);
1825         pdfSupportModule->bookmarksopenlevelLA->setEnabled(state);
1826 }
1827
1828
1829 void GuiDocument::slotApply()
1830 {
1831         bool only_shellescape_changed = !nonModuleChanged_ && !modulesChanged_;
1832         bool wasclean = buffer().isClean();
1833         GuiDialog::slotApply();
1834         if (wasclean && only_shellescape_changed)
1835                 buffer().markClean();
1836         modulesChanged_ = false;
1837 }
1838
1839
1840 void GuiDocument::slotOK()
1841 {
1842         bool only_shellescape_changed = !nonModuleChanged_ && !modulesChanged_;
1843         bool wasclean = buffer().isClean();
1844         GuiDialog::slotOK();
1845         if (wasclean && only_shellescape_changed)
1846                 buffer().markClean();
1847         modulesChanged_ = false;
1848 }
1849
1850
1851 void GuiDocument::slotButtonBox(QAbstractButton * button)
1852 {
1853         switch (buttonBox->standardButton(button)) {
1854         case QDialogButtonBox::Ok:
1855                 slotOK();
1856                 break;
1857         case QDialogButtonBox::Apply:
1858                 slotApply();
1859                 break;
1860         case QDialogButtonBox::Cancel:
1861                 slotClose();
1862                 break;
1863         case QDialogButtonBox::Reset:
1864         case QDialogButtonBox::RestoreDefaults:
1865                 slotRestore();
1866                 break;
1867         default:
1868                 break;
1869         }
1870 }
1871
1872
1873 void GuiDocument::filterModules(QString const & str)
1874 {
1875         updateAvailableModules();
1876         if (str.isEmpty())
1877                 return;
1878
1879         modules_av_model_.clear();
1880         list<modInfoStruct> modInfoList = getModuleInfo();
1881         // Sort names according to the locale
1882         modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
1883                         return 0 < b.name.localeAwareCompare(a.name);
1884                 });
1885
1886         QIcon user_icon(getPixmap("images/", "lyxfiles-user", "svgz,png"));
1887         QIcon system_icon(getPixmap("images/", "lyxfiles-system", "svgz,png"));
1888
1889         int i = 0;
1890         for (modInfoStruct const & m : modInfoList) {
1891                 if (m.name.contains(str, Qt::CaseInsensitive) || contains(m.id, fromqstr(str))) {
1892                         QStandardItem * item = new QStandardItem();
1893                         item->setData(m.name, Qt::DisplayRole);
1894                         item->setData(toqstr(m.id), Qt::UserRole);
1895                         item->setData(m.description, Qt::ToolTipRole);
1896                         item->setEditable(false);
1897                         if (m.local)
1898                                 item->setIcon(user_icon);
1899                         else
1900                                 item->setIcon(system_icon);
1901                         modules_av_model_.insertRow(i, item);
1902                         ++i;
1903                 }
1904         }
1905 }
1906
1907
1908 void GuiDocument::moduleFilterChanged(const QString & text)
1909 {
1910         if (!text.isEmpty()) {
1911                 filterModules(filter_->text());
1912                 return;
1913         }
1914         filterModules(filter_->text());
1915         filter_->setFocus();
1916 }
1917
1918
1919 void GuiDocument::moduleFilterPressed()
1920 {
1921         filterModules(filter_->text());
1922 }
1923
1924
1925 void GuiDocument::resetModuleFilter()
1926 {
1927         filter_->setText(QString());
1928         filterModules(filter_->text());
1929 }
1930
1931
1932 void GuiDocument::includeonlyClicked(QTreeWidgetItem * item, int)
1933 {
1934         if (item == nullptr)
1935                 return;
1936
1937         string child = fromqstr(item->text(0));
1938         if (child.empty())
1939                 return;
1940
1941         if (std::find(includeonlys_.begin(),
1942                       includeonlys_.end(), child) != includeonlys_.end())
1943                 includeonlys_.remove(child);
1944         else
1945                 includeonlys_.push_back(child);
1946
1947         updateIncludeonlys();
1948         change_adaptor();
1949 }
1950
1951
1952 QString GuiDocument::validateListingsParameters()
1953 {
1954         if (listingsModule->bypassCB->isChecked())
1955                 return QString();
1956         string const package =
1957             lst_packages[listingsModule->packageCO->currentIndex()];
1958         string params = fromqstr(listingsModule->listingsED->toPlainText());
1959         InsetListingsParams lstparams(params);
1960         lstparams.setMinted(package == "Minted");
1961         return toqstr(lstparams.validate());
1962 }
1963
1964
1965 void GuiDocument::setListingsMessage()
1966 {
1967         // FIXME THREAD
1968         static bool isOK = true;
1969         QString msg = validateListingsParameters();
1970         if (msg.isEmpty()) {
1971                 if (isOK)
1972                         return;
1973                 isOK = true;
1974                 // listingsModule->listingsTB->setTextColor("black");
1975                 listingsModule->listingsTB->setPlainText(
1976                         qt_("Input listings parameters below. "
1977                             "Enter ? for a list of parameters."));
1978         } else {
1979                 isOK = false;
1980                 // listingsModule->listingsTB->setTextColor("red");
1981                 listingsModule->listingsTB->setPlainText(msg);
1982         }
1983 }
1984
1985
1986 void GuiDocument::listingsPackageChanged(int index)
1987 {
1988         string const package = lst_packages[index];
1989         if (package == "Minted" && lyxrc.pygmentize_command.empty()) {
1990                 Alert::warning(_("Pygments driver command not found!"),
1991                     _("The driver command necessary to use the minted package\n"
1992                       "(pygmentize) has not been found. Make sure you have\n"
1993                       "the python-pygments module installed or, if the driver\n"
1994                       "is named differently, to add the following line to the\n"
1995                       "document preamble:\n\n"
1996                       "\\AtBeginDocument{\\renewcommand{\\MintedPygmentize}{driver}}\n\n"
1997                       "where 'driver' is name of the driver command."));
1998         }
1999 }
2000
2001
2002 void GuiDocument::setLSpacing(int item)
2003 {
2004         textLayoutModule->lspacingLE->setEnabled(item == 3);
2005 }
2006
2007
2008 void GuiDocument::setIndent(int item)
2009 {
2010         bool const enable = (item == 1);
2011         textLayoutModule->indentLE->setEnabled(enable);
2012         textLayoutModule->indentLengthCO->setEnabled(enable);
2013         textLayoutModule->skipLE->setEnabled(false);
2014         textLayoutModule->skipLengthCO->setEnabled(false);
2015         isValid();
2016 }
2017
2018
2019 void GuiDocument::enableIndent(bool indent)
2020 {
2021         textLayoutModule->skipLE->setEnabled(!indent);
2022         textLayoutModule->skipLengthCO->setEnabled(!indent);
2023         if (indent)
2024                 setIndent(textLayoutModule->indentCO->currentIndex());
2025 }
2026
2027
2028 void GuiDocument::setSkip(int item)
2029 {
2030         VSpace::VSpaceKind kind =
2031                 VSpace::VSpaceKind(textLayoutModule->skipCO->itemData(item).toInt());
2032         bool const enable = (kind == VSpace::LENGTH);
2033         textLayoutModule->skipLE->setEnabled(enable);
2034         textLayoutModule->skipLengthCO->setEnabled(enable);
2035         isValid();
2036 }
2037
2038
2039 void GuiDocument::enableSkip(bool skip)
2040 {
2041         textLayoutModule->indentLE->setEnabled(!skip);
2042         textLayoutModule->indentLengthCO->setEnabled(!skip);
2043         if (skip)
2044                 setSkip(textLayoutModule->skipCO->currentIndex());
2045 }
2046
2047 void GuiDocument::allowMathIndent() {
2048         // only disable when not checked, checked does not always allow enabling
2049         if (!mathsModule->MathIndentCB->isChecked()) {
2050                 mathsModule->MathIndentLE->setEnabled(false);
2051                 mathsModule->MathIndentLengthCO->setEnabled(false);
2052         }
2053         if (mathsModule->MathIndentCB->isChecked()
2054             && mathsModule->MathIndentCO->currentIndex() == 1) {
2055                         mathsModule->MathIndentLE->setEnabled(true);
2056                         mathsModule->MathIndentLengthCO->setEnabled(true);
2057         }
2058         isValid();
2059 }
2060
2061 void GuiDocument::enableMathIndent(int item)
2062 {
2063         bool const enable = (item == 1);
2064         mathsModule->MathIndentLE->setEnabled(enable);
2065         mathsModule->MathIndentLengthCO->setEnabled(enable);
2066         isValid();
2067 }
2068
2069
2070 void GuiDocument::setMargins()
2071 {
2072         bool const extern_geometry =
2073                 documentClass().provides("geometry");
2074         marginsModule->marginCB->setEnabled(!extern_geometry);
2075         if (extern_geometry) {
2076                 marginsModule->marginCB->setChecked(false);
2077                 setCustomMargins(true);
2078         } else {
2079                 marginsModule->marginCB->setChecked(!bp_.use_geometry);
2080                 setCustomMargins(!bp_.use_geometry);
2081         }
2082
2083         // set some placeholder text that hint on defaults
2084         QString const placeholder = marginsModule->marginCB->isChecked() ?
2085                 qt_("Class defaults") : qt_("Package defaults");
2086         // set tooltip depending on gemoetry state
2087         QString const tooltip = marginsModule->marginCB->isChecked() ?
2088                 qt_("If no value is given, the defaults as set by the class are used.")
2089                 : qt_("If no value is given, the defaults as set by the geometry package or a package/class overriding geometry's defaults are used.");
2090         marginsModule->topLE->setPlaceholderText(placeholder);
2091         marginsModule->bottomLE->setPlaceholderText(placeholder);
2092         marginsModule->innerLE->setPlaceholderText(placeholder);
2093         marginsModule->outerLE->setPlaceholderText(placeholder);
2094         marginsModule->headheightLE->setPlaceholderText(placeholder);
2095         marginsModule->headsepLE->setPlaceholderText(placeholder);
2096         marginsModule->footskipLE->setPlaceholderText(placeholder);
2097         marginsModule->columnsepLE->setPlaceholderText(placeholder);
2098         marginsModule->topLE->setToolTip(tooltip);
2099         marginsModule->bottomLE->setToolTip(tooltip);
2100         marginsModule->innerLE->setToolTip(tooltip);
2101         marginsModule->outerLE->setToolTip(tooltip);
2102         marginsModule->headheightLE->setToolTip(tooltip);
2103         marginsModule->headsepLE->setToolTip(tooltip);
2104         marginsModule->footskipLE->setToolTip(tooltip);
2105         marginsModule->columnsepLE->setToolTip(tooltip);
2106 }
2107
2108
2109 void GuiDocument::papersizeChanged(int paper_size)
2110 {
2111         setCustomPapersize(paper_size == 1);
2112 }
2113
2114
2115 void GuiDocument::setCustomPapersize(bool custom)
2116 {
2117         pageLayoutModule->paperwidthL->setEnabled(custom);
2118         pageLayoutModule->paperwidthLE->setEnabled(custom);
2119         pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
2120         pageLayoutModule->paperheightL->setEnabled(custom);
2121         pageLayoutModule->paperheightLE->setEnabled(custom);
2122         pageLayoutModule->paperheightLE->setFocus();
2123         pageLayoutModule->paperheightUnitCO->setEnabled(custom);
2124 }
2125
2126
2127 void GuiDocument::setColSep()
2128 {
2129         setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
2130 }
2131
2132
2133 void GuiDocument::setCustomMargins(bool custom)
2134 {
2135         marginsModule->topL->setEnabled(!custom);
2136         marginsModule->topLE->setEnabled(!custom);
2137         marginsModule->topUnit->setEnabled(!custom);
2138
2139         marginsModule->bottomL->setEnabled(!custom);
2140         marginsModule->bottomLE->setEnabled(!custom);
2141         marginsModule->bottomUnit->setEnabled(!custom);
2142
2143         marginsModule->innerL->setEnabled(!custom);
2144         marginsModule->innerLE->setEnabled(!custom);
2145         marginsModule->innerUnit->setEnabled(!custom);
2146
2147         marginsModule->outerL->setEnabled(!custom);
2148         marginsModule->outerLE->setEnabled(!custom);
2149         marginsModule->outerUnit->setEnabled(!custom);
2150
2151         marginsModule->headheightL->setEnabled(!custom);
2152         marginsModule->headheightLE->setEnabled(!custom);
2153         marginsModule->headheightUnit->setEnabled(!custom);
2154
2155         marginsModule->headsepL->setEnabled(!custom);
2156         marginsModule->headsepLE->setEnabled(!custom);
2157         marginsModule->headsepUnit->setEnabled(!custom);
2158
2159         marginsModule->footskipL->setEnabled(!custom);
2160         marginsModule->footskipLE->setEnabled(!custom);
2161         marginsModule->footskipUnit->setEnabled(!custom);
2162
2163         bool const enableColSep = !custom &&
2164                         textLayoutModule->twoColumnCB->checkState() == Qt::Checked;
2165         marginsModule->columnsepL->setEnabled(enableColSep);
2166         marginsModule->columnsepLE->setEnabled(enableColSep);
2167         marginsModule->columnsepUnit->setEnabled(enableColSep);
2168
2169         // set some placeholder text that hint on defaults
2170         QString const placeholder = marginsModule->marginCB->isChecked() ?
2171                 qt_("Class defaults") : qt_("Package defaults");
2172         // set tooltip depending on gemoetry state
2173         QString const tooltip = marginsModule->marginCB->isChecked() ?
2174                 qt_("If no value is given, the defaults as set by the class are used.")
2175                 : qt_("If no value is given, the defaults as set by the geometry package or a package/class overriding geometry's defaults are used.");
2176         marginsModule->topLE->setPlaceholderText(placeholder);
2177         marginsModule->bottomLE->setPlaceholderText(placeholder);
2178         marginsModule->innerLE->setPlaceholderText(placeholder);
2179         marginsModule->outerLE->setPlaceholderText(placeholder);
2180         marginsModule->headheightLE->setPlaceholderText(placeholder);
2181         marginsModule->headsepLE->setPlaceholderText(placeholder);
2182         marginsModule->footskipLE->setPlaceholderText(placeholder);
2183         marginsModule->columnsepLE->setPlaceholderText(placeholder);
2184         marginsModule->topLE->setToolTip(tooltip);
2185         marginsModule->bottomLE->setToolTip(tooltip);
2186         marginsModule->innerLE->setToolTip(tooltip);
2187         marginsModule->outerLE->setToolTip(tooltip);
2188         marginsModule->headheightLE->setToolTip(tooltip);
2189         marginsModule->headsepLE->setToolTip(tooltip);
2190         marginsModule->footskipLE->setToolTip(tooltip);
2191         marginsModule->columnsepLE->setToolTip(tooltip);
2192
2193 }
2194
2195
2196 void GuiDocument::changeBackgroundColor()
2197 {
2198         QColor const & newColor = QColorDialog::getColor(
2199                 rgb2qcolor(set_backgroundcolor), asQWidget());
2200         if (!newColor.isValid())
2201                 return;
2202         // set the button color and text
2203         colorModule->backgroundPB->setStyleSheet(
2204                 colorButtonStyleSheet(newColor));
2205         colorModule->backgroundPB->setText(qt_("&Change..."));
2206         // save color
2207         set_backgroundcolor = rgbFromHexName(fromqstr(newColor.name()));
2208         is_backgroundcolor = true;
2209         change_adaptor();
2210 }
2211
2212
2213 void GuiDocument::deleteBackgroundColor()
2214 {
2215         // set the button color back to default by setting an empty StyleSheet
2216         colorModule->backgroundPB->setStyleSheet(QLatin1String(""));
2217         // change button text
2218         colorModule->backgroundPB->setText(qt_("&Default..."));
2219         // save default color (white)
2220         set_backgroundcolor = rgbFromHexName("#ffffff");
2221         is_backgroundcolor = false;
2222         change_adaptor();
2223 }
2224
2225
2226 void GuiDocument::changeFontColor()
2227 {
2228         QColor const & newColor = QColorDialog::getColor(
2229                 rgb2qcolor(set_fontcolor), asQWidget());
2230         if (!newColor.isValid())
2231                 return;
2232         // set the button color and text
2233         colorModule->fontColorPB->setStyleSheet(
2234                 colorButtonStyleSheet(newColor));
2235         colorModule->fontColorPB->setText(qt_("&Change..."));
2236         // save color
2237         set_fontcolor = rgbFromHexName(fromqstr(newColor.name()));
2238         is_fontcolor = true;
2239         change_adaptor();
2240 }
2241
2242
2243 void GuiDocument::deleteFontColor()
2244 {
2245         // set the button color back to default by setting an empty StyleSheet
2246         colorModule->fontColorPB->setStyleSheet(QLatin1String(""));
2247         // change button text
2248         colorModule->fontColorPB->setText(qt_("&Default..."));
2249         // save default color (black)
2250         set_fontcolor = rgbFromHexName("#000000");
2251         is_fontcolor = false;
2252         change_adaptor();
2253 }
2254
2255
2256 void GuiDocument::changeNoteFontColor()
2257 {
2258         QColor const & newColor = QColorDialog::getColor(
2259                 rgb2qcolor(set_notefontcolor), asQWidget());
2260         if (!newColor.isValid())
2261                 return;
2262         // set the button color
2263         colorModule->noteFontColorPB->setStyleSheet(
2264                 colorButtonStyleSheet(newColor));
2265         // save color
2266         set_notefontcolor = rgbFromHexName(fromqstr(newColor.name()));
2267         is_notefontcolor = true;
2268         change_adaptor();
2269 }
2270
2271
2272 void GuiDocument::deleteNoteFontColor()
2273 {
2274         // set the button color back to pref
2275         theApp()->getRgbColor(Color_greyedouttext, set_notefontcolor);
2276         colorModule->noteFontColorPB->setStyleSheet(
2277                 colorButtonStyleSheet(rgb2qcolor(set_notefontcolor)));
2278         is_notefontcolor = false;
2279         change_adaptor();
2280 }
2281
2282
2283 void GuiDocument::changeBoxBackgroundColor()
2284 {
2285         QColor const & newColor = QColorDialog::getColor(
2286                 rgb2qcolor(set_boxbgcolor), asQWidget());
2287         if (!newColor.isValid())
2288                 return;
2289         // set the button color
2290         colorModule->boxBackgroundPB->setStyleSheet(
2291                 colorButtonStyleSheet(newColor));
2292         // save color
2293         set_boxbgcolor = rgbFromHexName(fromqstr(newColor.name()));
2294         is_boxbgcolor = true;
2295         change_adaptor();
2296 }
2297
2298
2299 void GuiDocument::deleteBoxBackgroundColor()
2300 {
2301         // set the button color back to pref
2302         theApp()->getRgbColor(Color_shadedbg, set_boxbgcolor);
2303         colorModule->boxBackgroundPB->setStyleSheet(
2304                 colorButtonStyleSheet(rgb2qcolor(set_boxbgcolor)));
2305         is_boxbgcolor = false;
2306         change_adaptor();
2307 }
2308
2309
2310 void GuiDocument::updateQuoteStyles(bool const set)
2311 {
2312         Language const * lang = lyx::languages.getLanguage(
2313                 fromqstr(langModule->languageCO->itemData(
2314                         langModule->languageCO->currentIndex()).toString()));
2315
2316         QuoteStyle def = bp_.getQuoteStyle(lang->quoteStyle());
2317
2318         langModule->quoteStyleCO->clear();
2319
2320         bool has_default = false;
2321         for (int i = 0; i < quoteparams.stylescount(); ++i) {
2322                 QuoteStyle qs = QuoteStyle(i);
2323                 if (qs == QuoteStyle::Dynamic)
2324                         continue;
2325                 bool const langdef = (qs == def);
2326                 if (langdef) {
2327                         // add the default style on top
2328                         langModule->quoteStyleCO->insertItem(0,
2329                                 toqstr(quoteparams.getGuiLabel(qs, langdef)), static_cast<int>(qs));
2330                         has_default = true;
2331                 }
2332                 else
2333                         langModule->quoteStyleCO->addItem(
2334                                 toqstr(quoteparams.getGuiLabel(qs, langdef)), static_cast<int>(qs));
2335         }
2336         if (set && has_default)
2337                 // (re)set to the default style
2338                 langModule->quoteStyleCO->setCurrentIndex(0);
2339 }
2340
2341
2342 void GuiDocument::languageChanged(int i)
2343 {
2344         // some languages only work with Polyglossia
2345         Language const * lang = lyx::languages.getLanguage(
2346                 fromqstr(langModule->languageCO->itemData(i).toString()));
2347         if (lang->babel().empty() && !lang->polyglossia().empty()
2348                 && lang->required() != "CJK" && lang->required() != "japanese") {
2349                         // If we force to switch fontspec on, store
2350                         // current state (#8717)
2351                         if (fontModule->osFontsCB->isEnabled())
2352                                 forced_fontspec_activation =
2353                                         !fontModule->osFontsCB->isChecked();
2354                         fontModule->osFontsCB->setChecked(true);
2355                         fontModule->osFontsCB->setEnabled(false);
2356         }
2357         else {
2358                 fontModule->osFontsCB->setEnabled(true);
2359                 // If we have forced to switch fontspec on,
2360                 // restore previous state (#8717)
2361                 if (forced_fontspec_activation)
2362                         fontModule->osFontsCB->setChecked(false);
2363                 forced_fontspec_activation = false;
2364         }
2365
2366         // set appropriate quotation mark style
2367         updateQuoteStyles(true);
2368 }
2369
2370
2371 void GuiDocument::osFontsChanged(bool nontexfonts)
2372 {
2373         bool const tex_fonts = !nontexfonts;
2374         // store current fonts
2375         QString const font_roman = fontModule->fontsRomanCO->itemData(
2376                         fontModule->fontsRomanCO->currentIndex()).toString();
2377         QString const font_sans = fontModule->fontsSansCO->itemData(
2378                         fontModule->fontsSansCO->currentIndex()).toString();
2379         QString const font_typewriter = fontModule->fontsTypewriterCO->itemData(
2380                         fontModule->fontsTypewriterCO->currentIndex()).toString();
2381         QString const font_math = fontModule->fontsMathCO->itemData(
2382                         fontModule->fontsMathCO->currentIndex()).toString();
2383         int const font_sf_scale = fontModule->scaleSansSB->value();
2384         int const font_tt_scale = fontModule->scaleTypewriterSB->value();
2385
2386         updateFontlist();
2387         // store default format
2388         QString const dformat = outputModule->defaultFormatCO->itemData(
2389                 outputModule->defaultFormatCO->currentIndex()).toString();
2390         updateDefaultFormat();
2391         // try to restore default format
2392         int index = outputModule->defaultFormatCO->findData(dformat);
2393         // set to default if format is not found
2394         if (index == -1)
2395                 index = 0;
2396         outputModule->defaultFormatCO->setCurrentIndex(index);
2397
2398         // try to restore fonts which were selected two toggles ago
2399         index = fontModule->fontsRomanCO->findData(fontModule->font_roman);
2400         if (index != -1)
2401                 fontModule->fontsRomanCO->setCurrentIndex(index);
2402         index = fontModule->fontsSansCO->findData(fontModule->font_sans);
2403         if (index != -1)
2404                 fontModule->fontsSansCO->setCurrentIndex(index);
2405         index = fontModule->fontsTypewriterCO->findData(fontModule->font_typewriter);
2406         if (index != -1)
2407                 fontModule->fontsTypewriterCO->setCurrentIndex(index);
2408         index = fontModule->fontsMathCO->findData(fontModule->font_math);
2409         if (index != -1)
2410                 fontModule->fontsMathCO->setCurrentIndex(index);
2411         // save fonts for next next toggle
2412         fontModule->font_roman = font_roman;
2413         fontModule->font_sans = font_sans;
2414         fontModule->font_typewriter = font_typewriter;
2415         fontModule->font_math = font_math;
2416         fontModule->font_sf_scale = font_sf_scale;
2417         fontModule->font_tt_scale = font_tt_scale;
2418
2419         // non-tex fonts override the "\inputencoding" option with "utf8-plain"
2420         langModule->encodingCO->setEnabled(tex_fonts);
2421         inputencodingToDialog();
2422
2423         fontModule->fontsDefaultCO->setEnabled(tex_fonts);
2424         fontModule->fontsDefaultLA->setEnabled(tex_fonts);
2425         fontModule->cjkFontLE->setEnabled(tex_fonts);
2426         fontModule->cjkFontLA->setEnabled(tex_fonts);
2427
2428         updateFontOptions();
2429
2430         fontModule->fontencLA->setEnabled(tex_fonts);
2431         fontModule->fontencCO->setEnabled(tex_fonts);
2432         if (!tex_fonts)
2433                 fontModule->fontencLE->setEnabled(false);
2434         else
2435                 fontencChanged(fontModule->fontencCO->currentIndex());
2436 }
2437
2438
2439 void GuiDocument::encodingSwitched(int i)
2440 {
2441         bool const tex_fonts = !fontModule->osFontsCB->isChecked();
2442         langModule->unicodeEncodingCO->setEnabled(tex_fonts);
2443         langModule->customEncodingCO->setEnabled(tex_fonts);
2444         langModule->autoEncodingCO->setEnabled(tex_fonts);
2445         langModule->unicodeEncodingCO->setVisible(i == EncodingSets::unicode);
2446         langModule->autoEncodingCO->setVisible(i == EncodingSets::legacy);
2447         langModule->customEncodingCO->setVisible(i == EncodingSets::custom);
2448         if (tex_fonts)
2449                 langModule->unicodeEncodingCO->setItemText(1, qt_("Direct (No inputenc)"));
2450         else
2451                 langModule->unicodeEncodingCO->setItemText(1, qt_("Direct (XeTeX/LuaTeX)"));
2452 }
2453
2454 void GuiDocument::inputencodingToDialog()
2455 {
2456         QString inputenc = toqstr(bp_.inputenc);
2457         int p;
2458         if (fontModule->osFontsCB->isChecked()) { // non-tex fonts require utf8-plain
2459                 langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
2460                 langModule->unicodeEncodingCO->setCurrentIndex(
2461                         langModule->unicodeEncodingCO->findData("utf8-plain"));
2462         } else if (inputenc.startsWith("utf8")) {
2463                 langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
2464                 p = langModule->unicodeEncodingCO->findData(inputenc);
2465                 if (p == -1)
2466                         p = 0;
2467                 langModule->unicodeEncodingCO->setCurrentIndex(p);
2468                 langModule->autoEncodingCO->setCurrentIndex(0);
2469                 langModule->customEncodingCO->setCurrentIndex(0);
2470         } else if (inputenc.startsWith("auto")) {
2471                 langModule->encodingCO->setCurrentIndex(EncodingSets::legacy);
2472                 p = langModule->autoEncodingCO->findData(inputenc);
2473                 if (p == -1)
2474                         p = 0;
2475                 langModule->unicodeEncodingCO->setCurrentIndex(0);
2476                 langModule->autoEncodingCO->setCurrentIndex(p);
2477                 langModule->customEncodingCO->setCurrentIndex(0);
2478         } else {
2479                 langModule->encodingCO->setCurrentIndex(EncodingSets::custom);
2480                 p = langModule->customEncodingCO->findData(inputenc);
2481                 if (p == -1) {
2482                         p = 0;
2483                         langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
2484                 }
2485                 langModule->unicodeEncodingCO->setCurrentIndex(0);
2486                 langModule->autoEncodingCO->setCurrentIndex(0);
2487                 langModule->customEncodingCO->setCurrentIndex(p);
2488         }
2489         encodingSwitched(langModule->encodingCO->currentIndex());
2490 }
2491
2492
2493 void GuiDocument::mathFontChanged(int)
2494 {
2495         updateFontOptions();
2496 }
2497
2498 void GuiDocument::fontOsfToggled(bool state)
2499 {
2500         if (fontModule->osFontsCB->isChecked())
2501                 return;
2502         QString font = fontModule->fontsRomanCO->itemData(
2503                         fontModule->fontsRomanCO->currentIndex()).toString();
2504         if (hasMonolithicExpertSet(font))
2505                 fontModule->fontScCB->setChecked(state);
2506 }
2507
2508
2509 void GuiDocument::fontScToggled(bool state)
2510 {
2511         if (fontModule->osFontsCB->isChecked())
2512                 return;
2513         QString font = fontModule->fontsRomanCO->itemData(
2514                         fontModule->fontsRomanCO->currentIndex()).toString();
2515         if (hasMonolithicExpertSet(font))
2516                 fontModule->fontOsfCB->setChecked(state);
2517 }
2518
2519
2520 void GuiDocument::updateExtraOpts()
2521 {
2522         bool const tex_fonts = !fontModule->osFontsCB->isChecked();
2523         QString font;
2524         if (tex_fonts)
2525                 font = fontModule->fontsRomanCO->itemData(
2526                                 fontModule->fontsRomanCO->currentIndex()).toString();
2527         bool const rm_opts = providesExtraOpts(font);
2528         if (tex_fonts)
2529                 font = fontModule->fontsSansCO->itemData(
2530                                 fontModule->fontsSansCO->currentIndex()).toString();
2531         bool const sf_opts = providesExtraOpts(font);
2532         if (tex_fonts)
2533                 font = fontModule->fontsTypewriterCO->itemData(
2534                                 fontModule->fontsTypewriterCO->currentIndex()).toString();
2535         bool const tt_opts = providesExtraOpts(font);
2536         fontModule->fontspecRomanLA->setEnabled(!tex_fonts || rm_opts);
2537         fontModule->fontspecRomanLE->setEnabled(!tex_fonts || rm_opts);
2538         fontModule->fontspecSansLA->setEnabled(!tex_fonts || sf_opts);
2539         fontModule->fontspecSansLE->setEnabled(!tex_fonts || sf_opts);
2540         fontModule->fontspecTypewriterLA->setEnabled(!tex_fonts || tt_opts);
2541         fontModule->fontspecTypewriterLE->setEnabled(!tex_fonts || tt_opts);
2542 }
2543
2544
2545 void GuiDocument::updateFontOptions()
2546 {
2547         bool const tex_fonts = !fontModule->osFontsCB->isChecked();
2548         QString font;
2549         if (tex_fonts)
2550                 font = fontModule->fontsSansCO->itemData(
2551                                 fontModule->fontsSansCO->currentIndex()).toString();
2552         bool scalable = providesScale(font);
2553         fontModule->scaleSansSB->setEnabled(scalable);
2554         fontModule->scaleSansLA->setEnabled(scalable);
2555         fontModule->fontSansOsfCB->setEnabled(providesOSF(font));
2556         if (tex_fonts)
2557                 font = fontModule->fontsTypewriterCO->itemData(
2558                                 fontModule->fontsTypewriterCO->currentIndex()).toString();
2559         scalable = providesScale(font);
2560         fontModule->scaleTypewriterSB->setEnabled(scalable);
2561         fontModule->scaleTypewriterLA->setEnabled(scalable);
2562         fontModule->fontTypewriterOsfCB->setEnabled(providesOSF(font));
2563         if (tex_fonts)
2564                 font = fontModule->fontsRomanCO->itemData(
2565                                 fontModule->fontsRomanCO->currentIndex()).toString();
2566         fontModule->fontScCB->setEnabled(providesSC(font));
2567         fontModule->fontOsfCB->setEnabled(providesOSF(font));
2568         updateExtraOpts();
2569         updateMathFonts(font);
2570 }
2571
2572
2573 void GuiDocument::updateFontsize(string const & items, string const & sel)
2574 {
2575         fontModule->fontsizeCO->clear();
2576         fontModule->fontsizeCO->addItem(qt_("Default"));
2577
2578         for (int n = 0; !token(items,'|',n).empty(); ++n)
2579                 fontModule->fontsizeCO->
2580                         addItem(toqstr(token(items,'|',n)));
2581
2582         for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
2583                 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
2584                         fontModule->fontsizeCO->setCurrentIndex(n);
2585                         break;
2586                 }
2587         }
2588 }
2589
2590
2591 bool GuiDocument::ot1() const
2592 {
2593         QString const fontenc =
2594                 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
2595         int const i = langModule->languageCO->currentIndex();
2596         if (i == -1)
2597                 return false;
2598         QString const langname = langModule->languageCO->itemData(i).toString();
2599         Language const * newlang = lyx::languages.getLanguage(fromqstr(langname));
2600         return (fontenc == "default"
2601                 || (fontenc == "auto" && newlang->fontenc(buffer().params()) == "OT1")
2602                 || (fontenc == "custom" && fontModule->fontencLE->text() == "OT1"));
2603 }
2604
2605
2606 bool GuiDocument::completeFontset() const
2607 {
2608         return (fontModule->fontsSansCO->itemData(
2609                         fontModule->fontsSansCO->currentIndex()).toString() == "default"
2610                 && fontModule->fontsSansCO->itemData(
2611                         fontModule->fontsTypewriterCO->currentIndex()).toString() == "default");
2612 }
2613
2614
2615 bool GuiDocument::noMathFont() const
2616 {
2617         return (fontModule->fontsMathCO->itemData(
2618                 fontModule->fontsMathCO->currentIndex()).toString() == "default");
2619 }
2620
2621
2622 void GuiDocument::updateTexFonts()
2623 {
2624         LaTeXFonts::TexFontMap texfontmap = theLaTeXFonts().getLaTeXFonts();
2625
2626         LaTeXFonts::TexFontMap::const_iterator it = texfontmap.begin();
2627         LaTeXFonts::TexFontMap::const_iterator end = texfontmap.end();
2628         for (; it != end; ++it) {
2629                 LaTeXFont lf = it->second;
2630                 if (lf.name().empty()) {
2631                         LYXERR0("Error: Unnamed font: " << it->first);
2632                         continue;
2633                 }
2634                 docstring const family = lf.family();
2635                 docstring guiname = translateIfPossible(lf.guiname());
2636                 if (!lf.available(ot1(), noMathFont()))
2637                         guiname += _(" (not installed)");
2638                 if (family == "rm")
2639                         rmfonts_.insert(toqstr(guiname), toqstr(it->first));
2640                 else if (family == "sf")
2641                         sffonts_.insert(toqstr(guiname), toqstr(it->first));
2642                 else if (family == "tt")
2643                         ttfonts_.insert(toqstr(guiname), toqstr(it->first));
2644                 else if (family == "math")
2645                         mathfonts_.insert(toqstr(guiname), toqstr(it->first));
2646         }
2647 }
2648
2649
2650 void GuiDocument::updateFontlist()
2651 {
2652         // reset the filters of the CategorizedCombos
2653         fontModule->fontsRomanCO->resetFilter();
2654         fontModule->fontsSansCO->resetFilter();
2655         fontModule->fontsTypewriterCO->resetFilter();
2656         fontModule->fontsRomanCO->clear();
2657         fontModule->fontsSansCO->clear();
2658         fontModule->fontsTypewriterCO->clear();
2659         fontModule->fontsMathCO->clear();
2660
2661         // With fontspec (XeTeX, LuaTeX), we have access to all system fonts, but not the LaTeX fonts
2662         if (fontModule->osFontsCB->isChecked()) {
2663                 fontModule->fontsRomanCO->addItem(qt_("Default"), QString("default"));
2664                 fontModule->fontsSansCO->addItem(qt_("Default"), QString("default"));
2665                 fontModule->fontsTypewriterCO->addItem(qt_("Default"), QString("default"));
2666                 QString unimath = qt_("Non-TeX Fonts Default");
2667                 if (!LaTeXFeatures::isAvailable("unicode-math"))
2668                         unimath += qt_(" (not available)");
2669                 fontModule->fontsMathCO->addItem(qt_("Class Default (TeX Fonts)"), QString("auto"));
2670                 fontModule->fontsMathCO->addItem(unimath, QString("default"));
2671
2672                 QFontDatabase fontdb;
2673                 QStringList families(fontdb.families());
2674                 for (auto const & family : families) {
2675                         fontModule->fontsRomanCO->addItem(family, family);
2676                         fontModule->fontsSansCO->addItem(family, family);
2677                         fontModule->fontsTypewriterCO->addItem(family, family);
2678                 }
2679                 return;
2680         }
2681
2682         if (rmfonts_.empty())
2683                 updateTexFonts();
2684
2685         fontModule->fontsRomanCO->addItem(qt_("Default"), QString("default"));
2686         QMap<QString, QString>::const_iterator rmi = rmfonts_.constBegin();
2687         while (rmi != rmfonts_.constEnd()) {
2688                 fontModule->fontsRomanCO->addItem(rmi.key(), rmi.value());
2689                 ++rmi;
2690         }
2691
2692         fontModule->fontsSansCO->addItem(qt_("Default"), QString("default"));
2693         QMap<QString, QString>::const_iterator sfi = sffonts_.constBegin();
2694         while (sfi != sffonts_.constEnd()) {
2695                 fontModule->fontsSansCO->addItem(sfi.key(), sfi.value());
2696                 ++sfi;
2697         }
2698
2699         fontModule->fontsTypewriterCO->addItem(qt_("Default"), QString("default"));
2700         QMap<QString, QString>::const_iterator tti = ttfonts_.constBegin();
2701         while (tti != ttfonts_.constEnd()) {
2702                 fontModule->fontsTypewriterCO->addItem(tti.key(), tti.value());
2703                 ++tti;
2704         }
2705
2706         fontModule->fontsMathCO->addItem(qt_("Automatic"), QString("auto"));
2707         fontModule->fontsMathCO->addItem(qt_("Class Default"), QString("default"));
2708         QMap<QString, QString>::const_iterator mmi = mathfonts_.constBegin();
2709         while (mmi != mathfonts_.constEnd()) {
2710                 fontModule->fontsMathCO->addItem(mmi.key(), mmi.value());
2711                 ++mmi;
2712         }
2713 }
2714
2715
2716 void GuiDocument::fontencChanged(int item)
2717 {
2718         fontModule->fontencLE->setEnabled(
2719                 fontModule->fontencCO->itemData(item).toString() == "custom");
2720         // The availability of TeX fonts depends on the font encoding
2721         updateTexFonts();
2722         updateFontOptions();
2723 }
2724
2725
2726 void GuiDocument::updateMathFonts(QString const & rm)
2727 {
2728         if (fontModule->osFontsCB->isChecked())
2729                 return;
2730         QString const math =
2731                 fontModule->fontsMathCO->itemData(fontModule->fontsMathCO->currentIndex()).toString();
2732         int const i = fontModule->fontsMathCO->findData("default");
2733         if (providesNoMath(rm) && i == -1)
2734                 fontModule->fontsMathCO->insertItem(1, qt_("Class Default"), QString("default"));
2735         else if (!providesNoMath(rm) && i != -1) {
2736                 int const c = fontModule->fontsMathCO->currentIndex();
2737                 fontModule->fontsMathCO->removeItem(i);
2738                 if (c == i)
2739                         fontModule->fontsMathCO->setCurrentIndex(0);
2740         }
2741 }
2742
2743
2744 void GuiDocument::romanChanged(int item)
2745 {
2746         if (fontModule->osFontsCB->isChecked())
2747                 return;
2748         QString const font =
2749                 fontModule->fontsRomanCO->itemData(item).toString();
2750         fontModule->fontScCB->setEnabled(providesSC(font));
2751         fontModule->fontOsfCB->setEnabled(providesOSF(font));
2752         updateExtraOpts();
2753         updateMathFonts(font);
2754 }
2755
2756
2757 void GuiDocument::sansChanged(int item)
2758 {
2759         if (fontModule->osFontsCB->isChecked())
2760                 return;
2761         QString const font =
2762                 fontModule->fontsSansCO->itemData(item).toString();
2763         bool const scalable = providesScale(font);
2764         fontModule->scaleSansSB->setEnabled(scalable);
2765         fontModule->scaleSansLA->setEnabled(scalable);
2766         fontModule->fontSansOsfCB->setEnabled(providesOSF(font));
2767         updateExtraOpts();
2768 }
2769
2770
2771 void GuiDocument::ttChanged(int item)
2772 {
2773         if (fontModule->osFontsCB->isChecked())
2774                 return;
2775         QString const font =
2776                 fontModule->fontsTypewriterCO->itemData(item).toString();
2777         bool scalable = providesScale(font);
2778         fontModule->scaleTypewriterSB->setEnabled(scalable);
2779         fontModule->scaleTypewriterLA->setEnabled(scalable);
2780         fontModule->fontTypewriterOsfCB->setEnabled(providesOSF(font));
2781         updateExtraOpts();
2782 }
2783
2784
2785 void GuiDocument::updatePagestyle(string const & items, string const & sel)
2786 {
2787         pagestyles.clear();
2788         pageLayoutModule->pagestyleCO->clear();
2789         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
2790
2791         for (int n = 0; !token(items, '|', n).empty(); ++n) {
2792                 string style = token(items, '|', n);
2793                 QString style_gui = qt_(style);
2794                 pagestyles.push_back(pair<string, QString>(style, style_gui));
2795                 pageLayoutModule->pagestyleCO->addItem(style_gui);
2796         }
2797
2798         if (sel == "default") {
2799                 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
2800                 return;
2801         }
2802
2803         int nn = 0;
2804
2805         for (auto const & pagestyle : pagestyles)
2806                 if (pagestyle.first == sel)
2807                         nn = pageLayoutModule->pagestyleCO->findText(pagestyle.second);
2808
2809         if (nn > 0)
2810                 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
2811 }
2812
2813
2814 void GuiDocument::browseLayout()
2815 {
2816         QString const label1 = qt_("Lay&outs");
2817         QString const dir1 = toqstr(lyxrc.document_path);
2818         QStringList const filter(qt_("LyX Layout (*.layout)"));
2819         QString file = browseRelToParent(QString(), bufferFilePath(),
2820                 qt_("Local layout file"), filter, false,
2821                 label1, dir1);
2822
2823         if (!file.endsWith(".layout"))
2824                 return;
2825
2826         FileName layoutFile = support::makeAbsPath(fromqstr(file),
2827                 fromqstr(bufferFilePath()));
2828
2829         int const ret = Alert::prompt(_("Local layout file"),
2830                 _("The layout file you have selected is a local layout\n"
2831                   "file, not one in the system or user directory.\n"
2832                   "Your document will not work with this layout if you\n"
2833                   "move the layout file to a different directory."),
2834                   1, 1, _("&Set Layout"), _("&Cancel"));
2835         if (ret == 1)
2836                 return;
2837
2838         // load the layout file
2839         LayoutFileList & bcl = LayoutFileList::get();
2840         string classname = layoutFile.onlyFileName();
2841         // this will update an existing layout if that layout has been loaded before.
2842         LayoutFileIndex name = support::onlyFileName(bcl.addLocalLayout(
2843                 classname.substr(0, classname.size() - 7),
2844                 layoutFile.onlyPath().absFileName()));
2845
2846         if (name.empty()) {
2847                 Alert::error(_("Error"),
2848                         _("Unable to read local layout file."));
2849                 return;
2850         }
2851
2852         const_cast<Buffer &>(buffer()).setLayoutPos(layoutFile.onlyPath().absFileName());
2853
2854         // do not trigger classChanged if there is no change.
2855         if (latexModule->classCO->currentText() == toqstr(name))
2856                 return;
2857
2858         // add to combo box
2859         bool const avail = latexModule->classCO->set(toqstr(name));
2860         if (!avail) {
2861                 LayoutFile const & tc = bcl[name];
2862                 docstring const guiname = translateIfPossible(from_utf8(tc.description()));
2863                 // tooltip sensu "KOMA-Script Article [Class 'scrartcl']"
2864                 QString tooltip = toqstr(bformat(_("%1$s [Class '%2$s']"), guiname, from_utf8(tc.latexname())));
2865                 tooltip += '\n' + qt_("This is a local layout file.");
2866                 latexModule->classCO->addItemSort(toqstr(tc.name()), toqstr(guiname),
2867                                                   toqstr(translateIfPossible(from_utf8(tc.category()))),
2868                                                   tooltip,
2869                                                   true, true, true, true);
2870                 latexModule->classCO->set(toqstr(name));
2871         }
2872
2873         classChanged();
2874 }
2875
2876
2877 void GuiDocument::browseMaster()
2878 {
2879         QString const title = qt_("Select master document");
2880         QString const dir1 = toqstr(lyxrc.document_path);
2881         QString const old = latexModule->childDocLE->text();
2882         QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
2883         QStringList const filter(qt_("LyX Files (*.lyx)"));
2884         QString file = browseRelToSub(old, docpath, title, filter, false,
2885                 qt_("D&ocuments"), toqstr(lyxrc.document_path));
2886
2887         if (!file.isEmpty())
2888                 latexModule->childDocLE->setText(file);
2889 }
2890
2891
2892 void GuiDocument::classChanged_adaptor()
2893 {
2894         const_cast<Buffer &>(buffer()).setLayoutPos(string());
2895         classChanged();
2896 }
2897
2898
2899 void GuiDocument::classChanged()
2900 {
2901         int idx = latexModule->classCO->currentIndex();
2902         if (idx < 0)
2903                 return;
2904         string const classname = fromqstr(latexModule->classCO->getData(idx));
2905
2906         if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
2907                 int const ret = Alert::prompt(_("Unapplied changes"),
2908                                 _("Some changes in the dialog were not yet applied.\n"
2909                                 "If you do not apply now, they will be lost after this action."),
2910                                 1, 1, _("&Apply"), _("&Dismiss"));
2911                 if (ret == 0)
2912                         applyView();
2913         }
2914
2915         // We load the TextClass as soon as it is selected. This is
2916         // necessary so that other options in the dialog can be updated
2917         // according to the new class. Note, however, that, if you use
2918         // the scroll wheel when sitting on the combo box, we'll load a
2919         // lot of TextClass objects very quickly....
2920         if (!bp_.setBaseClass(classname, buffer().layoutPos())) {
2921                 Alert::error(_("Error"), _("Unable to set document class."));
2922                 return;
2923         }
2924         if (lyxrc.auto_reset_options)
2925                 bp_.useClassDefaults();
2926
2927         // With the introduction of modules came a distinction between the base
2928         // class and the document class. The former corresponds to the main layout
2929         // file; the latter is that plus the modules (or the document-specific layout,
2930         // or  whatever else there could be). Our parameters come from the document
2931         // class. So when we set the base class, we also need to recreate the document
2932         // class. Otherwise, we still have the old one.
2933         bp_.makeDocumentClass();
2934         paramsToDialog();
2935 }
2936
2937
2938 void GuiDocument::languagePackageChanged(int i)
2939 {
2940          langModule->languagePackageLE->setEnabled(
2941                 langModule->languagePackageCO->itemData(i).toString() == "custom");
2942 }
2943
2944
2945 void GuiDocument::biblioChanged()
2946 {
2947         biblioChanged_ = true;
2948         change_adaptor();
2949 }
2950
2951
2952 void GuiDocument::checkPossibleCiteEngines()
2953 {
2954         // Check if the class provides a specific engine,
2955         // and if so, enforce this.
2956         string force_engine;
2957         if (documentClass().provides("natbib")
2958             || documentClass().provides("natbib-internal"))
2959                 force_engine = "natbib";
2960         else if (documentClass().provides("jurabib"))
2961                 force_engine = "jurabib";
2962         else if (documentClass().provides("biblatex"))
2963                 force_engine = "biblatex";
2964         else if (documentClass().provides("biblatex-natbib"))
2965                 force_engine = "biblatex-natbib";
2966
2967         if (!force_engine.empty())
2968                 biblioModule->citeEngineCO->setCurrentIndex(
2969                         biblioModule->citeEngineCO->findData(toqstr(force_engine)));
2970         biblioModule->citeEngineCO->setEnabled(force_engine.empty());
2971 }
2972
2973
2974 void GuiDocument::rescanBibFiles()
2975 {
2976         if (isBiblatex())
2977                 rescanTexStyles("bbx cbx");
2978         else
2979                 rescanTexStyles("bst");
2980 }
2981
2982
2983 void GuiDocument::resetDefaultBibfile(string const & which)
2984 {
2985         QString const engine =
2986                 biblioModule->citeEngineCO->itemData(
2987                                 biblioModule->citeEngineCO->currentIndex()).toString();
2988
2989         CiteEngineType const cet =
2990                 CiteEngineType(biblioModule->citeStyleCO->itemData(
2991                                                           biblioModule->citeStyleCO->currentIndex()).toInt());
2992
2993         updateDefaultBiblio(theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet), which);
2994 }
2995
2996
2997 void GuiDocument::resetDefaultBbxBibfile()
2998 {
2999         resetDefaultBibfile("bbx");
3000 }
3001
3002
3003 void GuiDocument::resetDefaultCbxBibfile()
3004 {
3005         resetDefaultBibfile("cbx");
3006 }
3007
3008
3009 void GuiDocument::citeEngineChanged(int n)
3010 {
3011         QString const engine =
3012                 biblioModule->citeEngineCO->itemData(n).toString();
3013
3014         vector<string> const engs =
3015                 theCiteEnginesList[fromqstr(engine)]->getEngineType();
3016
3017         updateCiteStyles(engs);
3018         updateEngineDependends();
3019         resetDefaultBibfile();
3020         biblioChanged();
3021 }
3022
3023
3024 void GuiDocument::updateEngineDependends()
3025 {
3026         bool const biblatex = isBiblatex();
3027
3028         // These are only useful with BibTeX
3029         biblioModule->defaultBiblioCO->setEnabled(!biblatex);
3030         biblioModule->bibtexStyleLA->setEnabled(!biblatex);
3031         biblioModule->resetDefaultBiblioPB->setEnabled(!biblatex);
3032         biblioModule->bibtopicCB->setEnabled(!biblatex);
3033
3034         // These are only useful with Biblatex
3035         biblioModule->biblatexBbxCO->setEnabled(biblatex);
3036         biblioModule->biblatexBbxLA->setEnabled(biblatex);
3037         biblioModule->biblatexCbxCO->setEnabled(biblatex);
3038         biblioModule->biblatexCbxLA->setEnabled(biblatex);
3039         biblioModule->resetBbxPB->setEnabled(biblatex);
3040         biblioModule->resetCbxPB->setEnabled(biblatex);
3041         biblioModule->matchBbxPB->setEnabled(biblatex);
3042
3043         // These are useful with biblatex, jurabib and natbib
3044         QString const engine =
3045                 biblioModule->citeEngineCO->itemData(
3046                                 biblioModule->citeEngineCO->currentIndex()).toString();
3047         LyXCiteEngine const * ce = theCiteEnginesList[fromqstr(engine)];
3048
3049         bool const citepack = ce->required("biblatex.sty") || ce->required("jurabib.sty")
3050                         || ce->required("natbib.sty");
3051         biblioModule->citePackageOptionsLE->setEnabled(citepack);
3052         biblioModule->citePackageOptionsL->setEnabled(citepack);
3053 }
3054
3055
3056 void GuiDocument::citeStyleChanged()
3057 {
3058         QString const engine =
3059                 biblioModule->citeEngineCO->itemData(
3060                                 biblioModule->citeEngineCO->currentIndex()).toString();
3061         QString const currentDef = isBiblatex() ?
3062                 biblioModule->biblatexBbxCO->currentText()
3063                 : biblioModule->defaultBiblioCO->currentText();
3064         if (theCiteEnginesList[fromqstr(engine)]->isDefaultBiblio(fromqstr(currentDef)))
3065                 resetDefaultBibfile();
3066
3067         biblioChanged();
3068 }
3069
3070
3071 void GuiDocument::bibtexChanged(int n)
3072 {
3073         biblioModule->bibtexOptionsLE->setEnabled(
3074                 biblioModule->bibtexCO->itemData(n).toString() != "default");
3075         biblioChanged();
3076 }
3077
3078
3079 void GuiDocument::updateCiteStyles(vector<string> const & engs, CiteEngineType const & sel)
3080 {
3081         biblioModule->citeStyleCO->clear();
3082
3083         vector<string>::const_iterator it  = engs.begin();
3084         vector<string>::const_iterator end = engs.end();
3085         for (; it != end; ++it) {
3086                 if (*it == "default")
3087                         biblioModule->citeStyleCO->addItem(qt_("Basic numerical"),
3088                                                            ENGINE_TYPE_DEFAULT);
3089                 else if (*it == "authoryear")
3090                         biblioModule->citeStyleCO->addItem(qt_("Author-year"),
3091                                                            ENGINE_TYPE_AUTHORYEAR);
3092                 else if (*it == "numerical")
3093                         biblioModule->citeStyleCO->addItem(qt_("Author-number"),
3094                                                            ENGINE_TYPE_NUMERICAL);
3095         }
3096         int i = biblioModule->citeStyleCO->findData(sel);
3097         if (biblioModule->citeStyleCO->findData(sel) == -1)
3098                 i = 0;
3099         biblioModule->citeStyleCO->setCurrentIndex(i);
3100
3101         biblioModule->citationStyleL->setEnabled(engs.size() > 1);
3102         biblioModule->citeStyleCO->setEnabled(engs.size() > 1);
3103 }
3104
3105
3106 void GuiDocument::updateEngineType(string const & items, CiteEngineType const & sel)
3107 {
3108         engine_types_.clear();
3109
3110         int nn = 0;
3111
3112         for (int n = 0; !token(items, '|', n).empty(); ++n) {
3113                 nn += 1;
3114                 string style = token(items, '|', n);
3115                 engine_types_.push_back(style);
3116         }
3117
3118         updateCiteStyles(engine_types_, sel);
3119 }
3120
3121
3122 namespace {
3123         // FIXME unicode
3124         // both of these should take a vector<docstring>
3125
3126         // This is an insanely complicated attempt to make this sort of thing
3127         // work with RTL languages.
3128         docstring formatStrVec(vector<string> const & v, docstring const & s)
3129         {
3130                 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
3131                 if (v.empty())
3132                         return docstring();
3133                 if (v.size() == 1)
3134                         return translateIfPossible(from_utf8(v[0]));
3135                 if (v.size() == 2) {
3136                         docstring retval = _("%1$s and %2$s");
3137                         retval = subst(retval, _("and"), s);
3138                         return bformat(retval, translateIfPossible(from_utf8(v[0])),
3139                                        translateIfPossible(from_utf8(v[1])));
3140                 }
3141                 // The idea here is to format all but the last two items...
3142                 int const vSize = v.size();
3143                 docstring t2 = _("%1$s, %2$s");
3144                 docstring retval = translateIfPossible(from_utf8(v[0]));
3145                 for (int i = 1; i < vSize - 2; ++i)
3146                         retval = bformat(t2, retval, translateIfPossible(from_utf8(v[i])));
3147                 //...and then to  plug them, and the last two, into this schema
3148                 docstring t = _("%1$s, %2$s, and %3$s");
3149                 t = subst(t, _("and"), s);
3150                 return bformat(t, retval, translateIfPossible(from_utf8(v[vSize - 2])),
3151                                translateIfPossible(from_utf8(v[vSize - 1])));
3152         }
3153
3154         vector<string> idsToNames(vector<string> const & idList)
3155         {
3156                 vector<string> retval;
3157                 vector<string>::const_iterator it  = idList.begin();
3158                 vector<string>::const_iterator end = idList.end();
3159                 for (; it != end; ++it) {
3160                         LyXModule const * const mod = theModuleList[*it];
3161                         if (!mod)
3162                                 retval.push_back(to_utf8(bformat(_("%1$s (unavailable)"),
3163                                                 translateIfPossible(from_utf8(*it)))));
3164                         else
3165                                 retval.push_back(mod->getName());
3166                 }
3167                 return retval;
3168         }
3169 } // end anonymous namespace
3170
3171
3172 void GuiDocument::modulesToParams(BufferParams & bp)
3173 {
3174         // update list of loaded modules
3175         bp.clearLayoutModules();
3176         int const srows = modules_sel_model_.rowCount();
3177         for (int i = 0; i < srows; ++i)
3178                 bp.addLayoutModule(modules_sel_model_.getIDString(i));
3179         updateSelectedModules();
3180
3181         // update the list of removed modules
3182         bp.clearRemovedModules();
3183         LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
3184         list<string>::const_iterator rit = reqmods.begin();
3185         list<string>::const_iterator ren = reqmods.end();
3186
3187         // check each of the default modules
3188         for (; rit != ren; ++rit) {
3189                 list<string>::const_iterator mit = bp.getModules().begin();
3190                 list<string>::const_iterator men = bp.getModules().end();
3191                 bool found = false;
3192                 for (; mit != men; ++mit) {
3193                         if (*rit == *mit) {
3194                                 found = true;
3195                                 break;
3196                         }
3197                 }
3198                 if (!found) {
3199                         // the module isn't present so must have been removed by the user
3200                         bp.addRemovedModule(*rit);
3201                 }
3202         }
3203 }
3204
3205 void GuiDocument::modulesChanged()
3206 {
3207         modulesToParams(bp_);
3208
3209         if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()
3210             && (nonModuleChanged_ || shellescapeChanged_)) {
3211                 int const ret = Alert::prompt(_("Unapplied changes"),
3212                                 _("Some changes in the dialog were not yet applied.\n"
3213                                 "If you do not apply now, they will be lost after this action."),
3214                                 1, 1, _("&Apply"), _("&Dismiss"));
3215                 if (ret == 0)
3216                         applyView();
3217         }
3218
3219         modulesChanged_ = true;
3220         bp_.makeDocumentClass();
3221         paramsToDialog();
3222         changed();
3223 }
3224
3225
3226 void GuiDocument::updateModuleInfo()
3227 {
3228         selectionManager->update();
3229
3230         //Module description
3231         bool const focus_on_selected = selectionManager->selectedFocused();
3232         QAbstractItemView * lv;
3233         bool category = false;
3234         if (focus_on_selected) {
3235                 lv = modulesModule->selectedLV;
3236                 category = true;
3237         } else
3238                 lv = modulesModule->availableLV;
3239         if (lv->selectionModel()->selectedIndexes().isEmpty()) {
3240                 modulesModule->infoML->document()->clear();
3241                 return;
3242         }
3243         QModelIndex const & idx = lv->selectionModel()->currentIndex();
3244
3245         if (!focus_on_selected
3246             && modules_av_model_.itemFromIndex(idx)->hasChildren()) {
3247                 // This is a category header
3248                 modulesModule->infoML->document()->clear();
3249                 return;
3250         }
3251
3252         string const modName = focus_on_selected ?
3253                                 modules_sel_model_.getIDString(idx.row())
3254                               : fromqstr(modules_av_model_.data(idx, Qt::UserRole).toString());
3255         docstring desc = getModuleDescription(modName);
3256
3257         LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
3258         if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
3259                 if (!desc.empty())
3260                         desc += "\n";
3261                 desc += _("Module provided by document class.");
3262         }
3263
3264         if (category) {
3265                 docstring cat = getModuleCategory(modName);
3266                 if (!cat.empty()) {
3267                         if (!desc.empty())
3268                                 desc += "\n";
3269                         desc += bformat(_("<p><b>Category:</b> %1$s.</p>"),
3270                                         translateIfPossible(cat));
3271                 }
3272         }
3273
3274         vector<string> pkglist = getPackageList(modName);
3275         docstring pkgdesc = formatStrVec(pkglist, _("and"));
3276         if (!pkgdesc.empty()) {
3277                 if (!desc.empty())
3278                         desc += "\n";
3279                 desc += bformat(_("<p><b>Package(s) required:</b> %1$s.</p>"), pkgdesc);
3280         }
3281
3282         pkglist = getRequiredList(modName);
3283         if (!pkglist.empty()) {
3284                 vector<string> const reqdescs = idsToNames(pkglist);
3285                 pkgdesc = formatStrVec(reqdescs, _("or"));
3286                 if (!desc.empty())
3287                         desc += "\n";
3288                 desc += bformat(_("<p><b>Modules required:</b> %1$s.</p>"), pkgdesc);
3289         }
3290
3291         pkglist = getExcludedList(modName);
3292         if (!pkglist.empty()) {
3293                 vector<string> const reqdescs = idsToNames(pkglist);
3294                 pkgdesc = formatStrVec(reqdescs, _( "and"));
3295                 if (!desc.empty())
3296                         desc += "\n";
3297                 desc += bformat(_("<p><b>Modules excluded:</b> %1$s.</p>"), pkgdesc);
3298         }
3299
3300         if (!desc.empty())
3301                 desc += "\n";
3302         desc += bformat(_("<p><b>Filename:</b> <tt>%1$s.module</tt>.</p>"), from_utf8(modName));
3303
3304         if (!isModuleAvailable(modName)) {
3305                 if (!desc.empty())
3306                         desc += "\n";
3307                 desc += _("<p><font color=red><b>WARNING: Some required packages are unavailable!</b></font></p>");
3308         }
3309
3310         modulesModule->infoML->document()->setHtml(toqstr(desc));
3311 }
3312
3313
3314 void GuiDocument::updateNumbering()
3315 {
3316         DocumentClass const & tclass = documentClass();
3317
3318         numberingModule->tocTW->setUpdatesEnabled(false);
3319         numberingModule->tocTW->clear();
3320
3321         int const depth = numberingModule->depthSL->value();
3322         int const toc = numberingModule->tocSL->value();
3323         QString const no = qt_("No");
3324         QString const yes = qt_("Yes");
3325         QTreeWidgetItem * item = nullptr;
3326
3327         DocumentClass::const_iterator lit = tclass.begin();
3328         DocumentClass::const_iterator len = tclass.end();
3329         for (; lit != len; ++lit) {
3330                 int const toclevel = lit->toclevel;
3331                 if (toclevel != Layout::NOT_IN_TOC && !lit->counter.empty()) {
3332                         item = new QTreeWidgetItem(numberingModule->tocTW);
3333                         item->setText(0, toqstr(translateIfPossible(lit->name())));
3334                         item->setText(1, (toclevel <= depth) ? yes : no);
3335                         item->setText(2, (toclevel <= toc) ? yes : no);
3336                 }
3337         }
3338
3339         numberingModule->tocTW->setUpdatesEnabled(true);
3340         numberingModule->tocTW->update();
3341 }
3342
3343
3344 void GuiDocument::getTableStyles()
3345 {
3346         // We look for lyx files in the subdirectory dir of
3347         //   1) user_lyxdir
3348         //   2) build_lyxdir (if not empty)
3349         //   3) system_lyxdir
3350         // in this order. Files with a given sub-hierarchy will
3351         // only be listed once.
3352         // We also consider i18n subdirectories and store them separately.
3353         QStringList dirs;
3354
3355         // The three locations to look at.
3356         string const user = addPath(package().user_support().absFileName(), "tabletemplates");
3357         string const build = addPath(package().build_support().absFileName(), "tabletemplates");
3358         string const system = addPath(package().system_support().absFileName(), "tabletemplates");
3359
3360         dirs << toqstr(user)
3361              << toqstr(build)
3362              << toqstr(system);
3363
3364         for (int i = 0; i < dirs.size(); ++i) {
3365                 QString const & dir = dirs.at(i);
3366                 QDirIterator it(dir, QDir::Files, QDirIterator::Subdirectories);
3367                 while (it.hasNext()) {
3368                         QString fn = QFileInfo(it.next()).fileName();
3369                         if (!fn.endsWith(".lyx") || fn.contains("_1x"))
3370                                 continue;
3371                         QString data = fn.left(fn.lastIndexOf(".lyx"));
3372                         QString guiname = data;
3373                         guiname = toqstr(translateIfPossible(qstring_to_ucs4(guiname.replace('_', ' '))));
3374                         QString relpath = toqstr(makeRelPath(qstring_to_ucs4(fn),
3375                                                              qstring_to_ucs4(dir)));
3376                         if (textLayoutModule->tableStyleCO->findData(data) == -1)
3377                                 textLayoutModule->tableStyleCO->addItem(guiname, data);
3378                 }
3379         }
3380 }
3381
3382
3383 void GuiDocument::updateDefaultFormat()
3384 {
3385         if (!bufferview())
3386                 return;
3387         // make a copy in order to consider unapplied changes
3388         BufferParams param_copy = buffer().params();
3389         param_copy.useNonTeXFonts = fontModule->osFontsCB->isChecked();
3390         int const idx = latexModule->classCO->currentIndex();
3391         if (idx >= 0) {
3392                 string const classname = fromqstr(latexModule->classCO->getData(idx));
3393                 param_copy.setBaseClass(classname, buffer().layoutPos());
3394                 param_copy.makeDocumentClass(true);
3395         }
3396         outputModule->defaultFormatCO->blockSignals(true);
3397         outputModule->defaultFormatCO->clear();
3398         outputModule->defaultFormatCO->addItem(qt_("Default"),
3399                                 QVariant(QString("default")));
3400         FormatList const & formats =
3401                                 param_copy.exportableFormats(true);
3402         for (Format const * f : formats)
3403                 outputModule->defaultFormatCO->addItem
3404                         (toqstr(translateIfPossible(f->prettyname())),
3405                          QVariant(toqstr(f->name())));
3406         outputModule->defaultFormatCO->blockSignals(false);
3407 }
3408
3409
3410 bool GuiDocument::isChildIncluded(string const & child)
3411 {
3412         if (includeonlys_.empty())
3413                 return false;
3414         return (std::find(includeonlys_.begin(),
3415                           includeonlys_.end(), child) != includeonlys_.end());
3416 }
3417
3418
3419 void GuiDocument::applyView()
3420 {
3421         // preamble
3422         preambleModule->apply(bp_);
3423         localLayout->apply(bp_);
3424
3425         // date
3426         bp_.suppress_date = latexModule->suppressDateCB->isChecked();
3427         bp_.use_refstyle  = latexModule->refstyleCB->isChecked();
3428
3429         // biblio
3430         string const engine =
3431                 fromqstr(biblioModule->citeEngineCO->itemData(
3432                                 biblioModule->citeEngineCO->currentIndex()).toString());
3433         bp_.setCiteEngine(engine);
3434
3435         CiteEngineType const style = CiteEngineType(biblioModule->citeStyleCO->itemData(
3436                 biblioModule->citeStyleCO->currentIndex()).toInt());
3437         if (theCiteEnginesList[engine]->hasEngineType(style))
3438                 bp_.setCiteEngineType(style);
3439         else
3440                 bp_.setCiteEngineType(ENGINE_TYPE_DEFAULT);
3441
3442         bp_.splitbib(biblioModule->bibtopicCB->isChecked());
3443
3444         bp_.multibib = fromqstr(biblioModule->bibunitsCO->itemData(
3445                                 biblioModule->bibunitsCO->currentIndex()).toString());
3446
3447         bp_.setDefaultBiblioStyle(fromqstr(biblioModule->defaultBiblioCO->currentText()));
3448
3449         bp_.biblatex_bibstyle = fromqstr(biblioModule->biblatexBbxCO->currentText());
3450         bp_.biblatex_citestyle = fromqstr(biblioModule->biblatexCbxCO->currentText());
3451         bp_.biblio_opts = fromqstr(biblioModule->citePackageOptionsLE->text());
3452
3453         string const bibtex_command =
3454                 fromqstr(biblioModule->bibtexCO->itemData(
3455                         biblioModule->bibtexCO->currentIndex()).toString());
3456         string const bibtex_options =
3457                 fromqstr(biblioModule->bibtexOptionsLE->text());
3458         if (bibtex_command == "default" || bibtex_options.empty())
3459                 bp_.bibtex_command = bibtex_command;
3460         else
3461                 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
3462
3463         if (biblioChanged_) {
3464                 buffer().invalidateBibinfoCache();
3465                 buffer().removeBiblioTempFiles();
3466         }
3467
3468         // Indices
3469         indicesModule->apply(bp_);
3470
3471         // language & quotes
3472         switch (langModule->encodingCO->currentIndex()) {
3473                 case EncodingSets::unicode: {
3474                         if (!fontModule->osFontsCB->isChecked())
3475                                 bp_.inputenc = fromqstr(langModule->unicodeEncodingCO->itemData(
3476                                         langModule->unicodeEncodingCO->currentIndex()).toString());
3477                         break;
3478                 }
3479                 case EncodingSets::legacy: {
3480                         bp_.inputenc = "auto-legacy";
3481                         bp_.inputenc = fromqstr(langModule->autoEncodingCO->itemData(
3482                                 langModule->autoEncodingCO->currentIndex()).toString());
3483                         break;
3484                 }
3485                 case EncodingSets::custom: {
3486                         bp_.inputenc = fromqstr(langModule->customEncodingCO->itemData(
3487                                 langModule->customEncodingCO->currentIndex()).toString());
3488                         break;
3489                 }
3490                 default:
3491                         // this should never happen
3492                         bp_.inputenc = "utf8";
3493         }
3494         bp_.quotes_style = QuoteStyle(langModule->quoteStyleCO->itemData(
3495                 langModule->quoteStyleCO->currentIndex()).toInt());
3496         bp_.dynamic_quotes = langModule->dynamicQuotesCB->isChecked();
3497
3498         QString const langname = langModule->languageCO->itemData(
3499                 langModule->languageCO->currentIndex()).toString();
3500         Language const * newlang = lyx::languages.getLanguage(fromqstr(langname));
3501         Cursor & cur = const_cast<BufferView *>(bufferview())->cursor();
3502         // If current cursor language was the document language, then update it too.
3503         if (cur.current_font.language() == bp_.language) {
3504                 cur.current_font.setLanguage(newlang);
3505                 cur.real_current_font.setLanguage(newlang);
3506         }
3507         bp_.language = newlang;
3508
3509         QString const pack = langModule->languagePackageCO->itemData(
3510                 langModule->languagePackageCO->currentIndex()).toString();
3511         if (pack == "custom")
3512                 bp_.lang_package =
3513                         fromqstr(langModule->languagePackageLE->text());
3514         else
3515                 bp_.lang_package = fromqstr(pack);
3516
3517         //color
3518         bp_.backgroundcolor = set_backgroundcolor;
3519         bp_.isbackgroundcolor = is_backgroundcolor;
3520         bp_.fontcolor = set_fontcolor;
3521         bp_.isfontcolor = is_fontcolor;
3522         bp_.notefontcolor = set_notefontcolor;
3523         bp_.isnotefontcolor = is_notefontcolor;
3524         if (is_notefontcolor) {
3525                 // Set information used in statusbar (#12130)
3526                 lcolor.setColor("notefontcolor", lyx::X11hexname(set_notefontcolor));
3527                 lcolor.setGUIName("notefontcolor", N_("greyedout inset text"));
3528         }
3529         bp_.boxbgcolor = set_boxbgcolor;
3530         bp_.isboxbgcolor = is_boxbgcolor;
3531
3532         // numbering
3533         if (bp_.documentClass().hasTocLevels()) {
3534                 bp_.tocdepth = numberingModule->tocSL->value();
3535                 bp_.secnumdepth = numberingModule->depthSL->value();
3536         }
3537         bp_.use_lineno = numberingModule->linenoCB->isChecked();
3538         bp_.lineno_opts = fromqstr(numberingModule->linenoLE->text());
3539
3540         // bullets
3541         bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
3542         bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
3543         bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
3544         bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
3545
3546         // packages
3547         bp_.graphics_driver =
3548                 tex_graphics[latexModule->psdriverCO->currentIndex()];
3549
3550         // text layout
3551         int idx = latexModule->classCO->currentIndex();
3552         if (idx >= 0) {
3553                 string const classname = fromqstr(latexModule->classCO->getData(idx));
3554                 bp_.setBaseClass(classname, buffer().layoutPos());
3555         }
3556
3557         // Modules
3558         modulesToParams(bp_);
3559
3560         // Math
3561         map<string, string> const & packages = BufferParams::auto_packages();
3562         for (map<string, string>::const_iterator it = packages.begin();
3563              it != packages.end(); ++it) {
3564                 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
3565                 if (!item)
3566                         continue;
3567                 int row = mathsModule->packagesTW->row(item);
3568
3569                 QRadioButton * rb =
3570                         (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1)->layout()->itemAt(0)->widget();
3571                 if (rb->isChecked()) {
3572                         bp_.use_package(it->first, BufferParams::package_auto);
3573                         continue;
3574                 }
3575                 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2)->layout()->itemAt(0)->widget();
3576                 if (rb->isChecked()) {
3577                         bp_.use_package(it->first, BufferParams::package_on);
3578                         continue;
3579                 }
3580                 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3)->layout()->itemAt(0)->widget();
3581                 if (rb->isChecked())
3582                         bp_.use_package(it->first, BufferParams::package_off);
3583         }
3584         // if math is indented
3585         bp_.is_math_indent = mathsModule->MathIndentCB->isChecked();
3586         if (bp_.is_math_indent) {
3587                 // if formulas are indented
3588                 switch (mathsModule->MathIndentCO->currentIndex()) {
3589                 case 0:
3590                         bp_.setMathIndent(Length());
3591                         break;
3592                 case 1: {
3593                         Length mathindent(widgetsToLength(mathsModule->MathIndentLE,
3594                                                           mathsModule->MathIndentLengthCO));
3595                         bp_.setMathIndent(mathindent);
3596                         break;
3597                 }
3598                 default:
3599                         // this should never happen
3600                         bp_.setMathIndent(Length());
3601                         break;
3602                 }
3603         }
3604         switch (mathsModule->MathNumberingPosCO->currentIndex()) {
3605                 case 0:
3606                         bp_.math_numbering_side = BufferParams::LEFT;
3607                         break;
3608                 case 1:
3609                         bp_.math_numbering_side = BufferParams::DEFAULT;
3610                         break;
3611                 case 2:
3612                         bp_.math_numbering_side = BufferParams::RIGHT;
3613                         break;
3614                 default:
3615                         // this should never happen
3616                         bp_.math_numbering_side = BufferParams::DEFAULT;
3617                         break;
3618         }
3619
3620         // Page Layout
3621         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
3622                 bp_.pagestyle = "default";
3623         else {
3624                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
3625                 for (size_t i = 0; i != pagestyles.size(); ++i)
3626                         if (pagestyles[i].second == style_gui)
3627                                 bp_.pagestyle = pagestyles[i].first;
3628         }
3629
3630         // Text Layout
3631         switch (textLayoutModule->lspacingCO->currentIndex()) {
3632         case 0:
3633                 bp_.spacing().set(Spacing::Single);
3634                 break;
3635         case 1:
3636                 bp_.spacing().set(Spacing::Onehalf);
3637                 break;
3638         case 2:
3639                 bp_.spacing().set(Spacing::Double);
3640                 break;
3641         case 3: {
3642                 string s = widgetToDoubleStr(textLayoutModule->lspacingLE);
3643                 if (s.empty())
3644                         bp_.spacing().set(Spacing::Single);
3645                 else
3646                         bp_.spacing().set(Spacing::Other, s);
3647                 break;
3648                 }
3649         }
3650
3651         if (textLayoutModule->twoColumnCB->isChecked())
3652                 bp_.columns = 2;
3653         else
3654                 bp_.columns = 1;
3655
3656         bp_.justification = textLayoutModule->justCB->isChecked();
3657
3658         if (textLayoutModule->indentRB->isChecked()) {
3659                 // if paragraphs are separated by an indentation
3660                 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
3661                 switch (textLayoutModule->indentCO->currentIndex()) {
3662                 case 0:
3663                         bp_.setParIndent(Length());
3664                         break;
3665                 case 1: {
3666                         Length parindent(widgetsToLength(textLayoutModule->indentLE,
3667                                                          textLayoutModule->indentLengthCO));
3668                         bp_.setParIndent(parindent);
3669                         break;
3670                 }
3671                 default:
3672                         // this should never happen
3673                         bp_.setParIndent(Length());
3674                         break;
3675                 }
3676         } else {
3677                 // if paragraphs are separated by a skip
3678                 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
3679                 VSpace::VSpaceKind spacekind =
3680                         VSpace::VSpaceKind(textLayoutModule->skipCO->itemData(textLayoutModule->skipCO->currentIndex()).toInt());
3681                 switch (spacekind) {
3682                 case VSpace::SMALLSKIP:
3683                 case VSpace::MEDSKIP:
3684                 case VSpace::BIGSKIP:
3685                 case VSpace::HALFLINE:
3686                 case VSpace::FULLLINE:
3687                         bp_.setDefSkip(VSpace(spacekind));
3688                         break;
3689                 case VSpace::LENGTH: {
3690                         VSpace vs = VSpace(
3691                                 widgetsToLength(textLayoutModule->skipLE,
3692                                 textLayoutModule->skipLengthCO)
3693                                 );
3694                         bp_.setDefSkip(vs);
3695                         break;
3696                 }
3697                 default:
3698                         // this should never happen
3699                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
3700                         break;
3701                 }
3702         }
3703         bp_.tablestyle = fromqstr(textLayoutModule->tableStyleCO->itemData(
3704                                       textLayoutModule->tableStyleCO->currentIndex()).toString());
3705
3706         bp_.options =
3707                 fromqstr(latexModule->optionsLE->text());
3708
3709         bp_.use_default_options =
3710                 latexModule->defaultOptionsCB->isChecked();
3711
3712         if (latexModule->childDocGB->isChecked())
3713                 bp_.master =
3714                         fromqstr(latexModule->childDocLE->text());
3715         else
3716                 bp_.master = string();
3717
3718         // Master/Child
3719         bp_.clearIncludedChildren();
3720         if (masterChildModule->includeonlyRB->isChecked()) {
3721                 list<string>::const_iterator it = includeonlys_.begin();
3722                 for (; it != includeonlys_.end() ; ++it) {
3723                         bp_.addIncludedChildren(*it);
3724                 }
3725         }
3726         if (masterChildModule->maintainCRNoneRB->isChecked())
3727                 bp_.maintain_unincluded_children =
3728                         BufferParams::CM_None;
3729         else if (masterChildModule->maintainCRMostlyRB->isChecked())
3730                 bp_.maintain_unincluded_children =
3731                         BufferParams::CM_Mostly;
3732         else
3733                 bp_.maintain_unincluded_children =
3734                         BufferParams::CM_Strict;
3735         updateIncludeonlyDisplay();
3736
3737         // Float Settings
3738         bp_.float_placement = floatModule->getPlacement();
3739         bp_.float_alignment = floatModule->getAlignment();
3740
3741         // Listings
3742         // text should have passed validation
3743         idx = listingsModule->packageCO->currentIndex();
3744         bp_.use_minted = string(lst_packages[idx]) == "Minted";
3745         bp_.listings_params =
3746                 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
3747
3748         // Formats
3749         bp_.default_output_format = fromqstr(outputModule->defaultFormatCO->itemData(
3750                 outputModule->defaultFormatCO->currentIndex()).toString());
3751
3752         bool const nontexfonts = fontModule->osFontsCB->isChecked();
3753         bp_.useNonTeXFonts = nontexfonts;
3754
3755         bp_.shell_escape = outputModule->shellescapeCB->isChecked();
3756         if (!bp_.shell_escape)
3757             theSession().shellescapeFiles().remove(buffer().absFileName());
3758         else if (!theSession().shellescapeFiles().find(buffer().absFileName()))
3759             theSession().shellescapeFiles().insert(buffer().absFileName());
3760         Buffer & buf = const_cast<Buffer &>(buffer());
3761         buf.params().shell_escape = bp_.shell_escape;
3762
3763         bp_.output_sync = outputModule->outputsyncCB->isChecked();
3764
3765         bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
3766
3767         int mathfmt = outputModule->mathoutCB->currentIndex();
3768         if (mathfmt == -1)
3769                 mathfmt = 0;
3770         BufferParams::MathOutput const mo =
3771                 static_cast<BufferParams::MathOutput>(mathfmt);
3772         bp_.html_math_output = mo;
3773         bp_.html_be_strict = outputModule->strictCB->isChecked();
3774         bp_.html_css_as_file = outputModule->cssCB->isChecked();
3775         bp_.html_math_img_scale = outputModule->mathimgSB->value();
3776         bp_.display_pixel_ratio = theGuiApp()->pixelRatio();
3777
3778         int tablefmt = outputModule->tableoutCB->currentIndex();
3779         if (tablefmt == -1)
3780                 tablefmt = 0;
3781         auto const to = static_cast<BufferParams::TableOutput>(tablefmt);
3782         bp_.docbook_table_output = to;
3783
3784         int mathmlprefix = outputModule->mathmlprefixCB->currentIndex();
3785         if (mathmlprefix == -1)
3786                 mathmlprefix = 0;
3787         auto const mp = static_cast<BufferParams::MathMLNameSpacePrefix>(mathmlprefix);
3788         bp_.docbook_mathml_prefix = mp;
3789
3790         bp_.save_transient_properties =
3791                 outputModule->saveTransientPropertiesCB->isChecked();
3792         bp_.postpone_fragile_content =
3793                 outputModule->postponeFragileCB->isChecked();
3794
3795         // fonts
3796         bp_.fonts_roman[nontexfonts] =
3797                 fromqstr(fontModule->fontsRomanCO->
3798                         itemData(fontModule->fontsRomanCO->currentIndex()).toString());
3799         bp_.fonts_roman[!nontexfonts] = fromqstr(fontModule->font_roman);
3800         bp_.font_roman_opts = fromqstr(fontModule->fontspecRomanLE->text());
3801
3802         bp_.fonts_sans[nontexfonts] =
3803                 fromqstr(fontModule->fontsSansCO->
3804                         itemData(fontModule->fontsSansCO->currentIndex()).toString());
3805         bp_.fonts_sans[!nontexfonts] = fromqstr(fontModule->font_sans);
3806         bp_.font_sans_opts = fromqstr(fontModule->fontspecSansLE->text());
3807
3808         bp_.fonts_typewriter[nontexfonts] =
3809                 fromqstr(fontModule->fontsTypewriterCO->
3810                         itemData(fontModule->fontsTypewriterCO->currentIndex()).toString());
3811         bp_.fonts_typewriter[!nontexfonts] = fromqstr(fontModule->font_typewriter);
3812         bp_.font_typewriter_opts = fromqstr(fontModule->fontspecTypewriterLE->text());
3813
3814         bp_.fonts_math[nontexfonts] =
3815                 fromqstr(fontModule->fontsMathCO->
3816                         itemData(fontModule->fontsMathCO->currentIndex()).toString());
3817         bp_.fonts_math[!nontexfonts] = fromqstr(fontModule->font_math);
3818
3819         QString const fontenc =
3820                 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
3821         if (fontenc == "custom")
3822                 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
3823         else
3824                 bp_.fontenc = fromqstr(fontenc);
3825
3826         bp_.fonts_cjk =
3827                 fromqstr(fontModule->cjkFontLE->text());
3828
3829         bp_.use_microtype = fontModule->microtypeCB->isChecked();
3830         bp_.use_dash_ligatures = !fontModule->dashesCB->isChecked();
3831
3832         bp_.fonts_sans_scale[nontexfonts] = fontModule->scaleSansSB->value();
3833         bp_.fonts_sans_scale[!nontexfonts] = fontModule->font_sf_scale;
3834
3835         bp_.fonts_typewriter_scale[nontexfonts] = fontModule->scaleTypewriterSB->value();
3836         bp_.fonts_typewriter_scale[!nontexfonts] = fontModule->font_tt_scale;
3837
3838         bp_.fonts_expert_sc = fontModule->fontScCB->isChecked();
3839
3840         bp_.fonts_roman_osf = fontModule->fontOsfCB->isChecked();
3841         bp_.fonts_sans_osf = fontModule->fontSansOsfCB->isChecked();
3842         bp_.fonts_typewriter_osf = fontModule->fontTypewriterOsfCB->isChecked();
3843
3844         if (nontexfonts)
3845                 bp_.fonts_default_family = "default";
3846         else
3847                 bp_.fonts_default_family = GuiDocument::fontfamilies[
3848                         fontModule->fontsDefaultCO->currentIndex()];
3849
3850         if (fontModule->fontsizeCO->currentIndex() == 0)
3851                 bp_.fontsize = "default";
3852         else
3853                 bp_.fontsize =
3854                         fromqstr(fontModule->fontsizeCO->currentText());
3855
3856         // paper
3857         bp_.papersize = PAPER_SIZE(
3858                 pageLayoutModule->papersizeCO->currentIndex());
3859
3860         bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
3861                 pageLayoutModule->paperwidthUnitCO);
3862
3863         bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
3864                 pageLayoutModule->paperheightUnitCO);
3865
3866         if (pageLayoutModule->facingPagesCB->isChecked())
3867                 bp_.sides = TwoSides;
3868         else
3869                 bp_.sides = OneSide;
3870
3871         if (pageLayoutModule->landscapeRB->isChecked())
3872                 bp_.orientation = ORIENTATION_LANDSCAPE;
3873         else
3874                 bp_.orientation = ORIENTATION_PORTRAIT;
3875
3876         // margins
3877         bp_.use_geometry = !marginsModule->marginCB->isChecked();
3878
3879         Ui::MarginsUi const * m = marginsModule;
3880
3881         bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
3882         bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
3883         bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
3884         bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
3885         bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
3886         bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
3887         bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
3888         bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
3889
3890         // branches
3891         branchesModule->apply(bp_);
3892
3893         // PDF support
3894         PDFOptions & pdf = bp_.pdfoptions();
3895         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
3896         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
3897         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
3898         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
3899         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
3900
3901         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
3902         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
3903         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
3904         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
3905
3906         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
3907         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
3908         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
3909         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
3910         pdf.backref =
3911                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
3912         if (pdfSupportModule->fullscreenCB->isChecked())
3913                 pdf.pagemode = pdf.pagemode_fullscreen;
3914         else
3915                 pdf.pagemode.clear();
3916         pdf.quoted_options = pdf.quoted_options_check(
3917                                 fromqstr(pdfSupportModule->optionsLE->text()));
3918
3919         // change tracking
3920         bp_.track_changes = changesModule->trackChangesCB->isChecked();
3921         bp_.output_changes = changesModule->outputChangesCB->isChecked();
3922         bool const cb_switched_off = (bp_.change_bars
3923                                       && !changesModule->changeBarsCB->isChecked());
3924         bp_.change_bars = changesModule->changeBarsCB->isChecked();
3925         if (cb_switched_off)
3926                 // if change bars have been switched off,
3927                 // we need to ditch the aux file
3928                 buffer().requireFreshStart(true);
3929
3930         // reset trackers
3931         nonModuleChanged_ = false;
3932         shellescapeChanged_ = false;
3933 }
3934
3935
3936 void GuiDocument::paramsToDialog()
3937 {
3938         // set the default unit
3939         Length::UNIT const default_unit = Length::defaultUnit();
3940
3941         // preamble
3942         preambleModule->update(bp_, id());
3943         localLayout->update(bp_, id());
3944
3945         // date
3946         latexModule->suppressDateCB->setChecked(bp_.suppress_date);
3947         latexModule->refstyleCB->setChecked(bp_.use_refstyle);
3948
3949         // biblio
3950         string const cite_engine = bp_.citeEngine();
3951
3952         biblioModule->citeEngineCO->setCurrentIndex(
3953                 biblioModule->citeEngineCO->findData(toqstr(cite_engine)));
3954
3955         updateEngineType(documentClass().opt_enginetype(),
3956                 bp_.citeEngineType());
3957
3958         checkPossibleCiteEngines();
3959
3960         biblioModule->citeStyleCO->setCurrentIndex(
3961                 biblioModule->citeStyleCO->findData(bp_.citeEngineType()));
3962
3963         biblioModule->bibtopicCB->setChecked(bp_.splitbib());
3964
3965         biblioModule->bibunitsCO->clear();
3966         biblioModule->bibunitsCO->addItem(qt_("No"), QString());
3967         if (documentClass().hasLaTeXLayout("part"))
3968                 biblioModule->bibunitsCO->addItem(qt_("per part"), toqstr("part"));
3969         if (documentClass().hasLaTeXLayout("chapter"))
3970                 biblioModule->bibunitsCO->addItem(qt_("per chapter"), toqstr("chapter"));
3971         if (documentClass().hasLaTeXLayout("section"))
3972                 biblioModule->bibunitsCO->addItem(qt_("per section"), toqstr("section"));
3973         if (documentClass().hasLaTeXLayout("subsection"))
3974                 biblioModule->bibunitsCO->addItem(qt_("per subsection"), toqstr("subsection"));
3975         biblioModule->bibunitsCO->addItem(qt_("per child document"), toqstr("child"));
3976
3977         int const mbpos = biblioModule->bibunitsCO->findData(toqstr(bp_.multibib));
3978         if (mbpos != -1)
3979                 biblioModule->bibunitsCO->setCurrentIndex(mbpos);
3980         else
3981                 biblioModule->bibunitsCO->setCurrentIndex(0);
3982
3983         updateEngineDependends();
3984
3985         if (isBiblatex()) {
3986                 updateDefaultBiblio(bp_.biblatex_bibstyle, "bbx");
3987                 updateDefaultBiblio(bp_.biblatex_citestyle, "cbx");
3988         } else
3989                 updateDefaultBiblio(bp_.defaultBiblioStyle());
3990
3991         biblioModule->citePackageOptionsLE->setText(toqstr(bp_.biblio_opts));
3992
3993         string command;
3994         string options =
3995                 split(bp_.bibtex_command, command, ' ');
3996
3997         int const bpos = biblioModule->bibtexCO->findData(toqstr(command));
3998         if (bpos != -1) {
3999                 biblioModule->bibtexCO->setCurrentIndex(bpos);
4000                 biblioModule->bibtexOptionsLE->setText(toqstr(options).trimmed());
4001         } else {
4002                 // We reset to default if we do not know the specified compiler
4003                 // This is for security reasons
4004                 biblioModule->bibtexCO->setCurrentIndex(
4005                         biblioModule->bibtexCO->findData(toqstr("default")));
4006                 biblioModule->bibtexOptionsLE->clear();
4007         }
4008         biblioModule->bibtexOptionsLE->setEnabled(
4009                 biblioModule->bibtexCO->currentIndex() != 0);
4010
4011         biblioChanged_ = false;
4012
4013         // indices
4014         // We may be called when there is no Buffer, e.g., when
4015         // the last view has just been closed.
4016         bool const isReadOnly = isBufferAvailable() ? buffer().isReadonly() : false;
4017         indicesModule->update(bp_, isReadOnly);
4018
4019         // language & quotes
4020         int const pos = langModule->languageCO->findData(toqstr(
4021                 bp_.language->lang()));
4022         langModule->languageCO->setCurrentIndex(pos);
4023
4024         updateQuoteStyles();
4025
4026         langModule->quoteStyleCO->setCurrentIndex(
4027                 langModule->quoteStyleCO->findData(static_cast<int>(bp_.quotes_style)));
4028         langModule->dynamicQuotesCB->setChecked(bp_.dynamic_quotes);
4029
4030         // LaTeX input encoding: set after the fonts (see below)
4031
4032         int p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
4033         if (p == -1) {
4034                 langModule->languagePackageCO->setCurrentIndex(
4035                           langModule->languagePackageCO->findData("custom"));
4036                 langModule->languagePackageLE->setText(toqstr(bp_.lang_package));
4037         } else {
4038                 langModule->languagePackageCO->setCurrentIndex(p);
4039                 langModule->languagePackageLE->clear();
4040         }
4041
4042         //color
4043         if (bp_.isfontcolor) {
4044                 colorModule->fontColorPB->setStyleSheet(
4045                         colorButtonStyleSheet(rgb2qcolor(bp_.fontcolor)));
4046         }
4047         set_fontcolor = bp_.fontcolor;
4048         is_fontcolor = bp_.isfontcolor;
4049
4050         colorModule->noteFontColorPB->setStyleSheet(
4051                 colorButtonStyleSheet(rgb2qcolor(bp_.notefontcolor)));
4052         set_notefontcolor = bp_.notefontcolor;
4053         is_notefontcolor = bp_.isnotefontcolor;
4054
4055         if (bp_.isbackgroundcolor) {
4056                 colorModule->backgroundPB->setStyleSheet(
4057                         colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
4058         }
4059         set_backgroundcolor = bp_.backgroundcolor;
4060         is_backgroundcolor = bp_.isbackgroundcolor;
4061
4062         colorModule->boxBackgroundPB->setStyleSheet(
4063                 colorButtonStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
4064         set_boxbgcolor = bp_.boxbgcolor;
4065         is_boxbgcolor = bp_.isboxbgcolor;
4066
4067         // numbering
4068         int const min_toclevel = documentClass().min_toclevel();
4069         int const max_toclevel = documentClass().max_toclevel();
4070         if (documentClass().hasTocLevels()) {
4071                 numberingModule->setEnabled(true);
4072                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
4073                 numberingModule->depthSL->setMaximum(max_toclevel);
4074                 numberingModule->depthSL->setValue(bp_.secnumdepth);
4075                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
4076                 numberingModule->tocSL->setMaximum(max_toclevel);
4077                 numberingModule->tocSL->setValue(bp_.tocdepth);
4078                 updateNumbering();
4079         } else {
4080                 numberingModule->setEnabled(false);
4081                 numberingModule->tocTW->clear();
4082         }
4083
4084         numberingModule->linenoCB->setChecked(bp_.use_lineno);
4085         numberingModule->linenoLE->setEnabled(bp_.use_lineno);
4086         numberingModule->linenoLA->setEnabled(bp_.use_lineno);
4087         numberingModule->linenoLE->setText(toqstr(bp_.lineno_opts));
4088
4089         // bullets
4090         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
4091         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
4092         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
4093         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
4094         bulletsModule->init();
4095
4096         // packages
4097         int nitem = findToken(tex_graphics, bp_.graphics_driver);
4098         if (nitem >= 0)
4099                 latexModule->psdriverCO->setCurrentIndex(nitem);
4100         updateModuleInfo();
4101
4102         // math
4103         mathsModule->MathIndentCB->setChecked(bp_.is_math_indent);
4104         if (bp_.is_math_indent) {
4105                 Length const mathindent = bp_.getMathIndent();
4106                 int indent = 0;
4107                 if (!mathindent.empty()) {
4108                         lengthToWidgets(mathsModule->MathIndentLE,
4109                                         mathsModule->MathIndentLengthCO,
4110                                         mathindent, default_unit);
4111                         indent = 1;
4112                 }
4113                 mathsModule->MathIndentCO->setCurrentIndex(indent);
4114                 enableMathIndent(indent);
4115         }
4116         switch(bp_.math_numbering_side) {
4117         case BufferParams::LEFT:
4118                 mathsModule->MathNumberingPosCO->setCurrentIndex(0);
4119                 break;
4120         case BufferParams::DEFAULT:
4121                 mathsModule->MathNumberingPosCO->setCurrentIndex(1);
4122                 break;
4123         case BufferParams::RIGHT:
4124                 mathsModule->MathNumberingPosCO->setCurrentIndex(2);
4125         }
4126
4127         map<string, string> const & packages = BufferParams::auto_packages();
4128         for (map<string, string>::const_iterator it = packages.begin();
4129              it != packages.end(); ++it) {
4130                 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
4131                 if (!item)
4132                         continue;
4133                 int row = mathsModule->packagesTW->row(item);
4134                 switch (bp_.use_package(it->first)) {
4135                         case BufferParams::package_off: {
4136                                 QRadioButton * rb =
4137                                         (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3)->layout()->itemAt(0)->widget();
4138                                 rb->setChecked(true);
4139                                 break;
4140                         }
4141                         case BufferParams::package_on: {
4142                                 QRadioButton * rb =
4143                                         (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2)->layout()->itemAt(0)->widget();
4144                                 rb->setChecked(true);
4145                                 break;
4146                         }
4147                         case BufferParams::package_auto: {
4148                                 QRadioButton * rb =
4149                                         (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1)->layout()->itemAt(0)->widget();
4150                                 rb->setChecked(true);
4151                                 break;
4152                         }
4153                 }
4154         }
4155
4156         switch (bp_.spacing().getSpace()) {
4157                 case Spacing::Other: nitem = 3; break;
4158                 case Spacing::Double: nitem = 2; break;
4159                 case Spacing::Onehalf: nitem = 1; break;
4160                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
4161         }
4162
4163         // text layout
4164         string const & layoutID = bp_.baseClassID();
4165         setLayoutComboByIDString(layoutID);
4166
4167         updatePagestyle(documentClass().opt_pagestyle(),
4168                                  bp_.pagestyle);
4169
4170         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
4171         if (bp_.spacing().getSpace() == Spacing::Other) {
4172                 doubleToWidget(textLayoutModule->lspacingLE,
4173                         bp_.spacing().getValueAsString());
4174         }
4175         setLSpacing(nitem);
4176         int ts = textLayoutModule->tableStyleCO->findData(toqstr(bp_.tablestyle));
4177         if (ts != -1)
4178                 textLayoutModule->tableStyleCO->setCurrentIndex(ts);
4179
4180         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
4181                 textLayoutModule->indentRB->setChecked(true);
4182                 string parindent = bp_.getParIndent().asString();
4183                 int indent = 0;
4184                 if (!parindent.empty()) {
4185                         lengthToWidgets(textLayoutModule->indentLE,
4186                                         textLayoutModule->indentLengthCO,
4187                                         parindent, default_unit);
4188                         indent = 1;
4189                 }
4190                 textLayoutModule->indentCO->setCurrentIndex(indent);
4191                 setIndent(indent);
4192         } else {
4193                 textLayoutModule->skipRB->setChecked(true);
4194                 VSpace::VSpaceKind skip = bp_.getDefSkip().kind();
4195                 textLayoutModule->skipCO->setCurrentIndex(textLayoutModule->skipCO->findData(skip));
4196                 if (skip == VSpace::LENGTH) {
4197                         string const length = bp_.getDefSkip().asLyXCommand();
4198                         lengthToWidgets(textLayoutModule->skipLE,
4199                                 textLayoutModule->skipLengthCO,
4200                                 length, default_unit);
4201                 }
4202                 setSkip(textLayoutModule->skipCO->currentIndex());
4203         }
4204
4205         textLayoutModule->twoColumnCB->setChecked(
4206                 bp_.columns == 2);
4207         textLayoutModule->justCB->setChecked(bp_.justification);
4208
4209         if (!bp_.options.empty()) {
4210                 latexModule->optionsLE->setText(
4211                         toqstr(bp_.options));
4212         } else {
4213                 latexModule->optionsLE->setText(QString());
4214         }
4215
4216         // latex
4217         latexModule->defaultOptionsCB->setChecked(
4218                         bp_.use_default_options);
4219         updateSelectedModules();
4220         selectionManager->updateProvidedModules(
4221                         bp_.baseClass()->providedModules());
4222         selectionManager->updateExcludedModules(
4223                         bp_.baseClass()->excludedModules());
4224
4225         if (!documentClass().options().empty()) {
4226                 latexModule->defaultOptionsLE->setText(
4227                         toqstr(documentClass().options()));
4228         } else {
4229                 latexModule->defaultOptionsLE->setText(
4230                         toqstr(_("[No options predefined]")));
4231         }
4232
4233         latexModule->defaultOptionsLE->setEnabled(
4234                 bp_.use_default_options
4235                 && !documentClass().options().empty());
4236
4237         latexModule->defaultOptionsCB->setEnabled(
4238                 !documentClass().options().empty());
4239
4240         if (!bp_.master.empty()) {
4241                 latexModule->childDocGB->setChecked(true);
4242                 latexModule->childDocLE->setText(
4243                         toqstr(bp_.master));
4244         } else {
4245                 latexModule->childDocLE->setText(QString());
4246                 latexModule->childDocGB->setChecked(false);
4247         }
4248
4249         // Master/Child
4250         if (!bufferview() || !buffer().hasChildren()) {
4251                 masterChildModule->childrenTW->clear();
4252                 includeonlys_.clear();
4253                 docPS->showPanel("Child Documents", false);
4254                 if (docPS->isCurrentPanel("Child Documents"))
4255                         docPS->setCurrentPanel("Document Class");
4256         } else {
4257                 docPS->showPanel("Child Documents", true);
4258                 masterChildModule->setEnabled(true);
4259                 includeonlys_ = bp_.getIncludedChildren();
4260                 updateIncludeonlys();
4261                 updateIncludeonlyDisplay();
4262         }
4263         switch (bp_.maintain_unincluded_children) {
4264         case BufferParams::CM_None:
4265                 masterChildModule->maintainCRNoneRB->setChecked(true);
4266                 break;
4267         case BufferParams::CM_Mostly:
4268                 masterChildModule->maintainCRMostlyRB->setChecked(true);
4269                 break;
4270         case BufferParams::CM_Strict:
4271         default:
4272                 masterChildModule->maintainCRStrictRB->setChecked(true);
4273                 break;
4274         }
4275
4276         // Float Settings
4277         floatModule->setPlacement(bp_.float_placement);
4278         floatModule->setAlignment(bp_.float_alignment);
4279
4280         // ListingsSettings
4281         // break listings_params to multiple lines
4282         string lstparams =
4283                 InsetListingsParams(bp_.listings_params).separatedParams();
4284         listingsModule->listingsED->setPlainText(toqstr(lstparams));
4285         int nn = findToken(lst_packages, bp_.use_minted ? "Minted" : "Listings");
4286         if (nn >= 0)
4287                 listingsModule->packageCO->setCurrentIndex(nn);
4288
4289         // Fonts
4290         // some languages only work with Polyglossia (which requires non-TeX fonts)
4291         Language const * lang = lyx::languages.getLanguage(
4292                 fromqstr(langModule->languageCO->itemData(
4293                         langModule->languageCO->currentIndex()).toString()));
4294         bool const need_fontspec =
4295                 lang->babel().empty() && !lang->polyglossia().empty()
4296                 && lang->required() != "CJK" && lang->required() != "japanese";
4297         bool const os_fonts_available =
4298                 bp_.baseClass()->outputType() == lyx::LATEX
4299                 && LaTeXFeatures::isAvailable("fontspec");
4300         fontModule->osFontsCB->setEnabled(os_fonts_available && !need_fontspec);
4301         fontModule->osFontsCB->setChecked(
4302                 (os_fonts_available && bp_.useNonTeXFonts) || need_fontspec);
4303         updateFontsize(documentClass().opt_fontsize(),
4304                         bp_.fontsize);
4305
4306         QString font = toqstr(bp_.fontsRoman());
4307         int rpos = fontModule->fontsRomanCO->findData(font);
4308         if (rpos == -1) {
4309                 rpos = fontModule->fontsRomanCO->count();
4310                 fontModule->fontsRomanCO->addItem(font + qt_(" (not installed)"), font);
4311         }
4312         fontModule->fontsRomanCO->setCurrentIndex(rpos);
4313         fontModule->font_roman = toqstr(bp_.fonts_roman[!bp_.useNonTeXFonts]);
4314
4315         font = toqstr(bp_.fontsSans());
4316         int spos = fontModule->fontsSansCO->findData(font);
4317         if (spos == -1) {
4318                 spos = fontModule->fontsSansCO->count();
4319                 fontModule->fontsSansCO->addItem(font + qt_(" (not installed)"), font);
4320         }
4321         fontModule->fontsSansCO->setCurrentIndex(spos);
4322         fontModule->font_sans = toqstr(bp_.fonts_sans[!bp_.useNonTeXFonts]);
4323
4324         font = toqstr(bp_.fontsTypewriter());
4325         int tpos = fontModule->fontsTypewriterCO->findData(font);
4326         if (tpos == -1) {
4327                 tpos = fontModule->fontsTypewriterCO->count();
4328                 fontModule->fontsTypewriterCO->addItem(font + qt_(" (not installed)"), font);
4329         }
4330         fontModule->fontsTypewriterCO->setCurrentIndex(tpos);
4331         fontModule->font_typewriter = toqstr(bp_.fonts_typewriter[!bp_.useNonTeXFonts]);
4332
4333         font = toqstr(bp_.fontsMath());
4334         int mpos = fontModule->fontsMathCO->findData(font);
4335         if (mpos == -1) {
4336                 mpos = fontModule->fontsMathCO->count();
4337                 fontModule->fontsMathCO->addItem(font + qt_(" (not installed)"), font);
4338         }
4339         fontModule->fontsMathCO->setCurrentIndex(mpos);
4340         fontModule->font_math = toqstr(bp_.fonts_math[!bp_.useNonTeXFonts]);
4341
4342         if (bp_.useNonTeXFonts && os_fonts_available) {
4343                 fontModule->fontencLA->setEnabled(false);
4344                 fontModule->fontencCO->setEnabled(false);
4345                 fontModule->fontencLE->setEnabled(false);
4346         } else {
4347                 fontModule->fontencLA->setEnabled(true);
4348                 fontModule->fontencCO->setEnabled(true);
4349                 fontModule->fontencLE->setEnabled(true);
4350                 romanChanged(rpos);
4351                 sansChanged(spos);
4352                 ttChanged(tpos);
4353         }
4354
4355         if (!bp_.fonts_cjk.empty())
4356                 fontModule->cjkFontLE->setText(
4357                         toqstr(bp_.fonts_cjk));
4358         else
4359                 fontModule->cjkFontLE->setText(QString());
4360
4361         fontModule->microtypeCB->setChecked(bp_.use_microtype);
4362         fontModule->dashesCB->setChecked(!bp_.use_dash_ligatures);
4363
4364         fontModule->fontScCB->setChecked(bp_.fonts_expert_sc);
4365         fontModule->fontOsfCB->setChecked(bp_.fonts_roman_osf);
4366         fontModule->fontSansOsfCB->setChecked(bp_.fonts_sans_osf);
4367         fontModule->fontTypewriterOsfCB->setChecked(bp_.fonts_typewriter_osf);
4368         fontModule->scaleSansSB->setValue(bp_.fontsSansScale());
4369         fontModule->font_sf_scale = bp_.fonts_sans_scale[!bp_.useNonTeXFonts];
4370         fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale());
4371         fontModule->font_tt_scale = bp_.fonts_typewriter_scale[!bp_.useNonTeXFonts];
4372         if (!bp_.font_roman_opts.empty())
4373                 fontModule->fontspecRomanLE->setText(
4374                         toqstr(bp_.font_roman_opts));
4375         else
4376                 fontModule->fontspecRomanLE->setText(QString());
4377         if (!bp_.font_sans_opts.empty())
4378                 fontModule->fontspecSansLE->setText(
4379                         toqstr(bp_.font_sans_opts));
4380         else
4381                 fontModule->fontspecSansLE->setText(QString());
4382         if (!bp_.font_typewriter_opts.empty())
4383                 fontModule->fontspecTypewriterLE->setText(
4384                         toqstr(bp_.font_typewriter_opts));
4385         else
4386                 fontModule->fontspecTypewriterLE->setText(QString());
4387
4388         nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
4389         if (nn >= 0)
4390                 fontModule->fontsDefaultCO->setCurrentIndex(nn);
4391
4392         if (bp_.fontenc == "auto" || bp_.fontenc == "default") {
4393                 fontModule->fontencCO->setCurrentIndex(
4394                         fontModule->fontencCO->findData(toqstr(bp_.fontenc)));
4395                 fontModule->fontencLE->setEnabled(false);
4396         } else {
4397                 fontModule->fontencCO->setCurrentIndex(
4398                                         fontModule->fontencCO->findData("custom"));
4399                 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
4400         }
4401
4402         // LaTeX input encoding
4403         // Set after fonts because non-tex fonts override "\inputencoding".
4404         inputencodingToDialog();
4405
4406         // Formats
4407         // This must be set _after_ fonts since updateDefaultFormat()
4408         // checks osFontsCB settings.
4409         // update combobox with formats
4410         updateDefaultFormat();
4411         int index = outputModule->defaultFormatCO->findData(toqstr(
4412                 bp_.default_output_format));
4413         // set to default if format is not found
4414         if (index == -1)
4415                 index = 0;
4416         outputModule->defaultFormatCO->setCurrentIndex(index);
4417
4418         outputModule->shellescapeCB->setChecked(bp_.shell_escape);
4419         outputModule->outputsyncCB->setChecked(bp_.output_sync);
4420         outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
4421         outputModule->synccustomCB->setEnabled(bp_.output_sync);
4422         outputModule->synccustomLA->setEnabled(bp_.output_sync);
4423
4424         outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
4425         outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
4426         outputModule->strictCB->setChecked(bp_.html_be_strict);
4427         outputModule->cssCB->setChecked(bp_.html_css_as_file);
4428
4429         outputModule->tableoutCB->setCurrentIndex(bp_.docbook_table_output);
4430         outputModule->mathmlprefixCB->setCurrentIndex(bp_.docbook_mathml_prefix);
4431
4432         outputModule->saveTransientPropertiesCB
4433                 ->setChecked(bp_.save_transient_properties);
4434         outputModule->postponeFragileCB
4435                 ->setChecked(bp_.postpone_fragile_content);
4436
4437         // paper
4438         bool const extern_geometry =
4439                 documentClass().provides("geometry");
4440         int const psize = bp_.papersize;
4441         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
4442         setCustomPapersize(!extern_geometry && psize == 1);
4443         pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
4444
4445         bool const landscape =
4446                 bp_.orientation == ORIENTATION_LANDSCAPE;
4447         pageLayoutModule->landscapeRB->setChecked(landscape);
4448         pageLayoutModule->portraitRB->setChecked(!landscape);
4449         pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
4450         pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
4451
4452         pageLayoutModule->facingPagesCB->setChecked(
4453                 bp_.sides == TwoSides);
4454
4455         lengthToWidgets(pageLayoutModule->paperwidthLE,
4456                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, default_unit);
4457         lengthToWidgets(pageLayoutModule->paperheightLE,
4458                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, default_unit);
4459
4460         // margins
4461         Ui::MarginsUi * m = marginsModule;
4462
4463         setMargins();
4464
4465         lengthToWidgets(m->topLE, m->topUnit,
4466                 bp_.topmargin, default_unit);
4467
4468         lengthToWidgets(m->bottomLE, m->bottomUnit,
4469                 bp_.bottommargin, default_unit);
4470
4471         lengthToWidgets(m->innerLE, m->innerUnit,
4472                 bp_.leftmargin, default_unit);
4473
4474         lengthToWidgets(m->outerLE, m->outerUnit,
4475                 bp_.rightmargin, default_unit);
4476
4477         lengthToWidgets(m->headheightLE, m->headheightUnit,
4478                 bp_.headheight, default_unit);
4479
4480         lengthToWidgets(m->headsepLE, m->headsepUnit,
4481                 bp_.headsep, default_unit);
4482
4483         lengthToWidgets(m->footskipLE, m->footskipUnit,
4484                 bp_.footskip, default_unit);
4485
4486         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
4487                 bp_.columnsep, default_unit);
4488
4489         // branches
4490         updateUnknownBranches();
4491         branchesModule->update(bp_);
4492
4493         // PDF support
4494         PDFOptions const & pdf = bp_.pdfoptions();
4495         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
4496         if (bp_.documentClass().provides("hyperref"))
4497                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("C&ustomize Hyperref Options"));
4498         else
4499                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("&Use Hyperref Support"));
4500         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
4501         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
4502         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
4503         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
4504
4505         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
4506         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
4507         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
4508
4509         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
4510         pdfSupportModule->bookmarksopenlevelSB->setEnabled(pdf.bookmarksopen);
4511         pdfSupportModule->bookmarksopenlevelLA->setEnabled(pdf.bookmarksopen);
4512
4513         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
4514         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
4515         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
4516         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
4517
4518         nn = findToken(backref_opts, pdf.backref);
4519         if (nn >= 0)
4520                 pdfSupportModule->backrefCO->setCurrentIndex(nn);
4521
4522         pdfSupportModule->fullscreenCB->setChecked
4523                 (pdf.pagemode == pdf.pagemode_fullscreen);
4524
4525         pdfSupportModule->optionsLE->setText(
4526                 toqstr(pdf.quoted_options));
4527
4528         // change tracking
4529         changesModule->trackChangesCB->setChecked(bp_.track_changes);
4530         changesModule->outputChangesCB->setChecked(bp_.output_changes);
4531         changesModule->changeBarsCB->setChecked(bp_.change_bars);
4532         changesModule->changeBarsCB->setEnabled(bp_.output_changes);
4533
4534         // Make sure that the bc is in the INITIAL state
4535         if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
4536                 bc().restore();
4537
4538         // clear changed branches cache
4539         changedBranches_.clear();
4540
4541         // re-initiate module filter
4542         if (!filter_->text().isEmpty())
4543                 moduleFilterPressed();
4544
4545         // reset trackers
4546         nonModuleChanged_ = false;
4547         shellescapeChanged_ = false;
4548 }
4549
4550
4551 void GuiDocument::saveDocDefault()
4552 {
4553         // we have to apply the params first
4554         applyView();
4555         saveAsDefault();
4556 }
4557
4558
4559 void GuiDocument::updateAvailableModules()
4560 {
4561         modules_av_model_.clear();
4562         list<modInfoStruct> modInfoList = getModuleInfo();
4563         // Sort names according to the locale
4564         modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
4565                         return 0 < b.name.localeAwareCompare(a.name);
4566                 });
4567         QIcon user_icon(getPixmap("images/", "lyxfiles-user", "svgz,png"));
4568         QIcon system_icon(getPixmap("images/", "lyxfiles-system", "svgz,png"));
4569         int i = 0;
4570         QFont catfont;
4571         catfont.setBold(true);
4572         QBrush unavbrush;
4573         unavbrush.setColor(Qt::gray);
4574         for (modInfoStruct const & m : modInfoList) {
4575                 QStandardItem * item = new QStandardItem();
4576                 QStandardItem * catItem;
4577                 QString const catname = m.category;
4578                 QList<QStandardItem *> fcats = modules_av_model_.findItems(catname, Qt::MatchExactly);
4579                 if (!fcats.empty())
4580                         catItem = fcats.first();
4581                 else {
4582                         catItem = new QStandardItem();
4583                         catItem->setText(catname);
4584                         catItem->setFont(catfont);
4585                         modules_av_model_.insertRow(i, catItem);
4586                         ++i;
4587                 }
4588                 item->setEditable(false);
4589                 catItem->setEditable(false);
4590                 item->setData(m.name, Qt::DisplayRole);
4591                 if (m.missingreqs)
4592                         item->setForeground(unavbrush);
4593                 item->setData(toqstr(m.id), Qt::UserRole);
4594                 item->setData(m.description, Qt::ToolTipRole);
4595                 if (m.local)
4596                         item->setIcon(user_icon);
4597                 else
4598                         item->setIcon(system_icon);
4599                 catItem->appendRow(item);
4600         }
4601         modules_av_model_.sort(0);
4602 }
4603
4604
4605 void GuiDocument::updateSelectedModules()
4606 {
4607         modules_sel_model_.clear();
4608         list<modInfoStruct> const selModList = getSelectedModules();
4609         int i = 0;
4610         for (modInfoStruct const & m : selModList) {
4611                 modules_sel_model_.insertRow(i, m.name, m.id, m.description);
4612                 ++i;
4613         }
4614 }
4615
4616
4617 void GuiDocument::updateIncludeonlyDisplay()
4618 {
4619         if (includeonlys_.empty()) {
4620                 masterChildModule->includeallRB->setChecked(true);
4621                 masterChildModule->childrenTW->setEnabled(false);
4622                 masterChildModule->maintainGB->setEnabled(false);
4623         } else {
4624                 masterChildModule->includeonlyRB->setChecked(true);
4625                 masterChildModule->childrenTW->setEnabled(true);
4626                 masterChildModule->maintainGB->setEnabled(true);
4627         }
4628 }
4629
4630
4631 void GuiDocument::updateIncludeonlys()
4632 {
4633         masterChildModule->childrenTW->clear();
4634         QString const no = qt_("No");
4635         QString const yes = qt_("Yes");
4636
4637         ListOfBuffers children = buffer().getChildren();
4638         ListOfBuffers::const_iterator it  = children.begin();
4639         ListOfBuffers::const_iterator end = children.end();
4640         bool has_unincluded = false;
4641         bool all_unincluded = true;
4642         for (; it != end; ++it) {
4643                 QTreeWidgetItem * item = new QTreeWidgetItem(masterChildModule->childrenTW);
4644                 // FIXME Unicode
4645                 string const name =
4646                         to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
4647                                                         from_utf8(buffer().filePath())));
4648                 item->setText(0, toqstr(name));
4649                 item->setText(1, isChildIncluded(name) ? yes : no);
4650                 if (!isChildIncluded(name))
4651                         has_unincluded = true;
4652                 else
4653                         all_unincluded = false;
4654         }
4655         // Both if all children are included and if none is included
4656         // is equal to "include all" (i.e., omit \includeonly).
4657         if (!has_unincluded || all_unincluded)
4658                 includeonlys_.clear();
4659 }
4660
4661
4662 bool GuiDocument::isBiblatex() const
4663 {
4664         QString const engine =
4665                 biblioModule->citeEngineCO->itemData(
4666                                 biblioModule->citeEngineCO->currentIndex()).toString();
4667
4668         // this can happen if the cite engine is unknown, which can happen
4669         // if one is using a file that came from someone else, etc. in that
4670         // case, we crash if we proceed.
4671         if (engine.isEmpty())
4672             return false;
4673
4674         return theCiteEnginesList[fromqstr(engine)]->getCiteFramework() == "biblatex";
4675 }
4676
4677
4678 void GuiDocument::updateDefaultBiblio(string const & style,
4679                                       string const & which)
4680 {
4681         QString const bibstyle = toqstr(style);
4682         biblioModule->defaultBiblioCO->clear();
4683
4684         int item_nr = -1;
4685
4686         if (isBiblatex()) {
4687                 if (which != "cbx") {
4688                         // First the bbx styles
4689                         biblioModule->biblatexBbxCO->clear();
4690                         QStringList str = texFileList("bbxFiles.lst");
4691                         // test whether we have a valid list, otherwise run rescan
4692                         if (str.isEmpty()) {
4693                                 rescanTexStyles("bbx");
4694                                 str = texFileList("bbxFiles.lst");
4695                         }
4696                         for (int i = 0; i != str.size(); ++i)
4697                                 str[i] = onlyFileName(str[i]);
4698                         // sort on filename only (no path)
4699                         str.sort();
4700
4701                         for (int i = 0; i != str.count(); ++i) {
4702                                 QString item = changeExtension(str[i], "");
4703                                 if (item == bibstyle)
4704                                         item_nr = i;
4705                                 biblioModule->biblatexBbxCO->addItem(item);
4706                         }
4707
4708                         if (item_nr == -1 && !bibstyle.isEmpty()) {
4709                                 biblioModule->biblatexBbxCO->addItem(bibstyle);
4710                                 item_nr = biblioModule->biblatexBbxCO->count() - 1;
4711                         }
4712
4713                         if (item_nr != -1)
4714                                 biblioModule->biblatexBbxCO->setCurrentIndex(item_nr);
4715                         else
4716                                 biblioModule->biblatexBbxCO->clearEditText();
4717                 }
4718
4719                 if (which != "bbx") {
4720                         // now the cbx styles
4721                         biblioModule->biblatexCbxCO->clear();
4722                         QStringList str = texFileList("cbxFiles.lst");
4723                         // test whether we have a valid list, otherwise run rescan
4724                         if (str.isEmpty()) {
4725                                 rescanTexStyles("cbx");
4726                                 str = texFileList("cbxFiles.lst");
4727                         }
4728                         for (int i = 0; i != str.size(); ++i)
4729                                 str[i] = onlyFileName(str[i]);
4730                         // sort on filename only (no path)
4731                         str.sort();
4732
4733                         for (int i = 0; i != str.count(); ++i) {
4734                                 QString item = changeExtension(str[i], "");
4735                                 if (item == bibstyle)
4736                                         item_nr = i;
4737                                 biblioModule->biblatexCbxCO->addItem(item);
4738                         }
4739
4740                         if (item_nr == -1 && !bibstyle.isEmpty()) {
4741                                 biblioModule->biblatexCbxCO->addItem(bibstyle);
4742                                 item_nr = biblioModule->biblatexCbxCO->count() - 1;
4743                         }
4744
4745                         if (item_nr != -1)
4746                                 biblioModule->biblatexCbxCO->setCurrentIndex(item_nr);
4747                         else
4748                                 biblioModule->biblatexCbxCO->clearEditText();
4749                 }
4750         } else {// BibTeX
4751                 biblioModule->biblatexBbxCO->clear();
4752                 biblioModule->biblatexCbxCO->clear();
4753                 QStringList str = texFileList("bstFiles.lst");
4754                 // test whether we have a valid list, otherwise run rescan
4755                 if (str.isEmpty()) {
4756                         rescanTexStyles("bst");
4757                         str = texFileList("bstFiles.lst");
4758                 }
4759                 for (int i = 0; i != str.size(); ++i)
4760                         str[i] = onlyFileName(str[i]);
4761                 // sort on filename only (no path)
4762                 str.sort();
4763
4764                 for (int i = 0; i != str.count(); ++i) {
4765                         QString item = changeExtension(str[i], "");
4766                         if (item == bibstyle)
4767                                 item_nr = i;
4768                         biblioModule->defaultBiblioCO->addItem(item);
4769                 }
4770
4771                 if (item_nr == -1 && !bibstyle.isEmpty()) {
4772                         biblioModule->defaultBiblioCO->addItem(bibstyle);
4773                         item_nr = biblioModule->defaultBiblioCO->count() - 1;
4774                 }
4775
4776                 if (item_nr != -1)
4777                         biblioModule->defaultBiblioCO->setCurrentIndex(item_nr);
4778                 else
4779                         biblioModule->defaultBiblioCO->clearEditText();
4780         }
4781
4782         updateResetDefaultBiblio();
4783 }
4784
4785
4786 void GuiDocument::updateResetDefaultBiblio()
4787 {
4788         QString const engine =
4789                 biblioModule->citeEngineCO->itemData(
4790                                 biblioModule->citeEngineCO->currentIndex()).toString();
4791         CiteEngineType const cet =
4792                 CiteEngineType(biblioModule->citeStyleCO->itemData(
4793                                                           biblioModule->citeStyleCO->currentIndex()).toInt());
4794
4795         string const defbib = theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet);
4796         if (isBiblatex()) {
4797                 QString const bbx = biblioModule->biblatexBbxCO->currentText();
4798                 QString const cbx = biblioModule->biblatexCbxCO->currentText();
4799                 biblioModule->resetCbxPB->setEnabled(defbib != fromqstr(cbx));
4800                 biblioModule->resetBbxPB->setEnabled(defbib != fromqstr(bbx));
4801                 biblioModule->matchBbxPB->setEnabled(bbx != cbx && !cbx.isEmpty()
4802                         && biblioModule->biblatexBbxCO->findText(cbx) != -1);
4803         } else
4804                 biblioModule->resetDefaultBiblioPB->setEnabled(
4805                         defbib != fromqstr(biblioModule->defaultBiblioCO->currentText()));
4806 }
4807
4808
4809 void GuiDocument::matchBiblatexStyles()
4810 {
4811         updateDefaultBiblio(fromqstr(biblioModule->biblatexCbxCO->currentText()), "bbx");
4812         biblioChanged();
4813 }
4814
4815
4816 void GuiDocument::updateContents()
4817 {
4818         // Nothing to do here as the document settings is not cursor dependent.
4819         return;
4820 }
4821
4822
4823 void GuiDocument::useClassDefaults()
4824 {
4825         if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
4826                 int const ret = Alert::prompt(_("Unapplied changes"),
4827                                 _("Some changes in the dialog were not yet applied.\n"
4828                                   "If you do not apply now, they will be lost after this action."),
4829                                 1, 1, _("&Apply"), _("&Dismiss"));
4830                 if (ret == 0)
4831                         applyView();
4832         }
4833
4834         int idx = latexModule->classCO->currentIndex();
4835         string const classname = fromqstr(latexModule->classCO->getData(idx));
4836         if (!bp_.setBaseClass(classname, buffer().layoutPos())) {
4837                 Alert::error(_("Error"), _("Unable to set document class."));
4838                 return;
4839         }
4840         bp_.useClassDefaults();
4841         paramsToDialog();
4842         changed();
4843 }
4844
4845
4846 void GuiDocument::setLayoutComboByIDString(string const & idString)
4847 {
4848         if (!latexModule->classCO->set(toqstr(idString)))
4849                 Alert::warning(_("Can't set layout!"),
4850                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
4851 }
4852
4853
4854 bool GuiDocument::isValid()
4855 {
4856         return
4857                 validateListingsParameters().isEmpty() &&
4858                 localLayout->isValid() &&
4859                 !localLayout->editing() &&
4860                 !preambleModule->editing() &&
4861                 (
4862                         // if we're asking for skips between paragraphs
4863                         !textLayoutModule->skipRB->isChecked() ||
4864                         // then either we haven't chosen custom
4865                         textLayoutModule->skipCO->currentIndex() != 3 ||
4866                         // or else a length has been given
4867                         !textLayoutModule->skipLE->text().isEmpty()
4868                 ) &&
4869                 (
4870                         // if we're asking for indentation
4871                         !textLayoutModule->indentRB->isChecked() ||
4872                         // then either we haven't chosen custom
4873                         textLayoutModule->indentCO->currentIndex() != 1 ||
4874                         // or else a length has been given
4875                         !textLayoutModule->indentLE->text().isEmpty()
4876                 ) &&
4877                 (
4878                         // if we're asking for math indentation
4879                         !mathsModule->MathIndentCB->isChecked() ||
4880                         // then either we haven't chosen custom
4881                         mathsModule->MathIndentCO->currentIndex() != 1 ||
4882                         // or else a length has been given
4883                         !mathsModule->MathIndentLE->text().isEmpty()
4884                 );
4885 }
4886
4887
4888 char const * const GuiDocument::fontfamilies[5] = {
4889         "default", "rmdefault", "sfdefault", "ttdefault", ""
4890 };
4891
4892
4893 char const * GuiDocument::fontfamilies_gui[5] = {
4894         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
4895 };
4896
4897
4898 bool GuiDocument::initialiseParams(string const &)
4899 {
4900         BufferView const * view = bufferview();
4901         if (!view) {
4902                 bp_ = BufferParams();
4903                 paramsToDialog();
4904                 return true;
4905         }
4906         bp_ = view->buffer().params();
4907         loadModuleInfo();
4908         updateAvailableModules();
4909         //FIXME It'd be nice to make sure here that the selected
4910         //modules are consistent: That required modules are actually
4911         //selected, and that we don't have conflicts. If so, we could
4912         //at least pop up a warning.
4913         paramsToDialog();
4914         return true;
4915 }
4916
4917
4918 void GuiDocument::clearParams()
4919 {
4920         bp_ = BufferParams();
4921 }
4922
4923
4924 BufferId GuiDocument::id() const
4925 {
4926         BufferView const * const view = bufferview();
4927         return view? &view->buffer() : nullptr;
4928 }
4929
4930
4931 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
4932 {
4933         return moduleNames_;
4934 }
4935
4936
4937 list<GuiDocument::modInfoStruct> const
4938 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
4939 {
4940         list<modInfoStruct> mInfo;
4941         for (string const & name : mods) {
4942                 modInfoStruct m;
4943                 LyXModule const * const mod = theModuleList[name];
4944                 if (mod)
4945                         m = modInfo(*mod);
4946                 else {
4947                         m.id = name;
4948                         m.name = toqstr(name + " (") + qt_("Not Found") + toqstr(")");
4949                         m.local = false;
4950                         m.missingreqs = true;
4951                 }
4952                 mInfo.push_back(m);
4953         }
4954         return mInfo;
4955 }
4956
4957
4958 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
4959 {
4960         return makeModuleInfo(params().getModules());
4961 }
4962
4963
4964 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
4965 {
4966         return makeModuleInfo(params().baseClass()->providedModules());
4967 }
4968
4969
4970 DocumentClass const & GuiDocument::documentClass() const
4971 {
4972         return bp_.documentClass();
4973 }
4974
4975
4976 static void dispatch_bufferparams(Dialog const & dialog,
4977         BufferParams const & bp, FuncCode lfun, Buffer const * buf)
4978 {
4979         ostringstream ss;
4980         ss << "\\begin_header\n";
4981         bp.writeFile(ss, buf);
4982         ss << "\\end_header\n";
4983         dialog.dispatch(FuncRequest(lfun, ss.str()));
4984 }
4985
4986
4987 void GuiDocument::dispatchParams()
4988 {
4989         // We need a non-const buffer object.
4990         Buffer & buf = const_cast<BufferView *>(bufferview())->buffer();
4991         // There may be several undo records; group them (bug #8998)
4992         // This handles undo groups automagically
4993         UndoGroupHelper ugh(&buf);
4994
4995         // This must come first so that a language change is correctly noticed
4996         setLanguage();
4997
4998         // We need to load the master before we formally update the params,
4999         // since otherwise we run updateBuffer, etc, before the child's master
5000         // has been set.
5001         if (!params().master.empty()) {
5002                 FileName const master_file = support::makeAbsPath(params().master,
5003                            support::onlyPath(buffer().absFileName()));
5004                 if (isLyXFileName(master_file.absFileName())) {
5005                         Buffer * master = checkAndLoadLyXFile(master_file, true);
5006                         if (master) {
5007                                 if (master->isChild(const_cast<Buffer *>(&buffer())))
5008                                         const_cast<Buffer &>(buffer()).setParent(master);
5009                                 else
5010                                         Alert::warning(_("Assigned master does not include this file"),
5011                                                 bformat(_("You must include this file in the document\n"
5012                                                           "'%1$s' in order to use the master document\n"
5013                                                           "feature."), from_utf8(params().master)));
5014                         } else
5015                                 Alert::warning(_("Could not load master"),
5016                                                 bformat(_("The master document '%1$s'\n"
5017                                                            "could not be loaded."),
5018                                                            from_utf8(params().master)));
5019                 }
5020         }
5021
5022         // Apply the BufferParams. Note that this will set the base class
5023         // and then update the buffer's layout.
5024         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY, &buffer());
5025
5026         // Generate the colours requested by each new branch.
5027         BranchList & branchlist = params().branchlist();
5028         if (!branchlist.empty()) {
5029                 BranchList::const_iterator it = branchlist.begin();
5030                 BranchList::const_iterator const end = branchlist.end();
5031                 for (; it != end; ++it) {
5032                         docstring const & current_branch = it->branch();
5033                         Branch const * branch = branchlist.find(current_branch);
5034                         string const bcolor = branch->color();
5035                         RGBColor rgbcol;
5036                         if (bcolor.size() == 7 && bcolor[0] == '#')
5037                                 rgbcol = lyx::rgbFromHexName(bcolor);
5038                         else
5039                                 guiApp->getRgbColor(lcolor.getFromLyXName(bcolor), rgbcol);
5040                         string const x11hexname = X11hexname(rgbcol);
5041                         // display the new color
5042                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
5043                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
5044                 }
5045         }
5046         // rename branches in the document
5047         executeBranchRenaming();
5048         // and clear changed branches cache
5049         changedBranches_.clear();
5050
5051         // Generate the colours requested by indices.
5052         IndicesList & indiceslist = params().indiceslist();
5053         if (!indiceslist.empty()) {
5054                 IndicesList::const_iterator it = indiceslist.begin();
5055                 IndicesList::const_iterator const end = indiceslist.end();
5056                 for (; it != end; ++it) {
5057                         docstring const & current_index = it->shortcut();
5058                         Index const * index = indiceslist.findShortcut(current_index);
5059                         string const x11hexname = X11hexname(index->color());
5060                         // display the new color
5061                         docstring const str = current_index + ' ' + from_ascii(x11hexname);
5062                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
5063                 }
5064         }
5065         // FIXME LFUN
5066         // If we used an LFUN, we would not need these two lines:
5067         BufferView * bv = const_cast<BufferView *>(bufferview());
5068         bv->processUpdateFlags(Update::Force | Update::FitCursor);
5069 }
5070
5071
5072 void GuiDocument::setLanguage() const
5073 {
5074         Language const * const newL = bp_.language;
5075         if (buffer().params().language == newL)
5076                 return;
5077
5078         string const & lang_name = newL->lang();
5079         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
5080 }
5081
5082
5083 void GuiDocument::saveAsDefault() const
5084 {
5085         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT, &buffer());
5086 }
5087
5088
5089 bool GuiDocument::providesOSF(QString const & font) const
5090 {
5091         if (fontModule->osFontsCB->isChecked())
5092                 // FIXME: we should check if the fonts really
5093                 // have OSF support. But how?
5094                 return true;
5095         return theLaTeXFonts().getLaTeXFont(
5096                                 qstring_to_ucs4(font)).providesOSF(ot1(),
5097                                                                    completeFontset(),
5098                                                                    noMathFont());
5099 }
5100
5101
5102 bool GuiDocument::providesSC(QString const & font) const
5103 {
5104         if (fontModule->osFontsCB->isChecked())
5105                 return false;
5106         return theLaTeXFonts().getLaTeXFont(
5107                                 qstring_to_ucs4(font)).providesSC(ot1(),
5108                                                                   completeFontset(),
5109                                                                   noMathFont());
5110 }
5111
5112
5113 bool GuiDocument::providesScale(QString const & font) const
5114 {
5115         if (fontModule->osFontsCB->isChecked())
5116                 return true;
5117         return theLaTeXFonts().getLaTeXFont(
5118                                 qstring_to_ucs4(font)).providesScale(ot1(),
5119                                                                      completeFontset(),
5120                                                                      noMathFont());
5121 }
5122
5123
5124 bool GuiDocument::providesExtraOpts(QString const & font) const
5125 {
5126         if (fontModule->osFontsCB->isChecked())
5127                 return true;
5128         return theLaTeXFonts().getLaTeXFont(
5129                                 qstring_to_ucs4(font)).providesMoreOptions(ot1(),
5130                                                                      completeFontset(),
5131                                                                      noMathFont());
5132 }
5133
5134
5135 bool GuiDocument::providesNoMath(QString const & font) const
5136 {
5137         if (fontModule->osFontsCB->isChecked())
5138                 return false;
5139         return theLaTeXFonts().getLaTeXFont(
5140                                 qstring_to_ucs4(font)).providesNoMath(ot1(),
5141                                                                       completeFontset());
5142 }
5143
5144
5145 bool GuiDocument::hasMonolithicExpertSet(QString const & font) const
5146 {
5147         if (fontModule->osFontsCB->isChecked())
5148                 return false;
5149         return theLaTeXFonts().getLaTeXFont(
5150                                 qstring_to_ucs4(font)).hasMonolithicExpertSet(ot1(),
5151                                                                               completeFontset(),
5152                                                                               noMathFont());
5153 }
5154
5155
5156 //static
5157 GuiDocument::modInfoStruct GuiDocument::modInfo(LyXModule const & mod)
5158 {
5159         // FIXME Unicode: docstrings would be better for these parameters but this
5160         // change requires a lot of others
5161         modInfoStruct m;
5162         m.id = mod.getID();
5163         QString const guiname = toqstr(translateIfPossible(from_utf8(mod.getName())));
5164         m.missingreqs = !isModuleAvailable(mod.getID());
5165         if (m.missingreqs) {
5166                 m.name = QString(qt_("%1 (missing req.)")).arg(guiname);
5167         } else
5168                 m.name = guiname;
5169         m.category = mod.category().empty() ? qt_("Miscellaneous")
5170                                             : toqstr(translateIfPossible(from_utf8(mod.category())));
5171         QString desc = toqstr(translateIfPossible(from_utf8(mod.getDescription())));
5172         // Find the first sentence of the description
5173         QTextBoundaryFinder bf(QTextBoundaryFinder::Sentence, desc);
5174         int pos = bf.toNextBoundary();
5175         if (pos > 0)
5176                 desc.truncate(pos);
5177         m.local = mod.isLocal();
5178         QString const mtype = m.local ? qt_("personal module") : qt_("distributed module");
5179         QString modulename = QString(qt_("<b>Module name:</b> <i>%1</i> (%2)")).arg(toqstr(m.id)).arg(mtype);
5180         // Tooltip is the desc followed by the module name and the type
5181         m.description = QString("%1%2")
5182                 .arg(desc.isEmpty() ? QString() : QString("<p>%1</p>").arg(desc),
5183                      modulename);
5184         if (m.missingreqs)
5185                 m.description += QString("<p>%1</p>").arg(qt_("<b>Note:</b> Some requirements for this module are missing!"));
5186         return m;
5187 }
5188
5189
5190 void GuiDocument::loadModuleInfo()
5191 {
5192         moduleNames_.clear();
5193         for (LyXModule const & mod : theModuleList)
5194                 moduleNames_.push_back(modInfo(mod));
5195 }
5196
5197
5198 void GuiDocument::updateUnknownBranches()
5199 {
5200         if (!bufferview())
5201                 return;
5202         list<docstring> used_branches;
5203         buffer().getUsedBranches(used_branches);
5204         list<docstring>::const_iterator it = used_branches.begin();
5205         QStringList unknown_branches;
5206         for (; it != used_branches.end() ; ++it) {
5207                 if (!buffer().params().branchlist().find(*it))
5208                         unknown_branches.append(toqstr(*it));
5209         }
5210         branchesModule->setUnknownBranches(unknown_branches);
5211 }
5212
5213
5214 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
5215 {
5216         map<docstring, docstring>::iterator it = changedBranches_.begin();
5217         for (; it != changedBranches_.end() ; ++it) {
5218                 if (it->second == oldname) {
5219                         // branch has already been renamed
5220                         it->second = newname;
5221                         return;
5222                 }
5223         }
5224         // store new name
5225         changedBranches_[oldname] = newname;
5226 }
5227
5228
5229 void GuiDocument::executeBranchRenaming() const
5230 {
5231         map<docstring, docstring>::const_iterator it = changedBranches_.begin();
5232         for (; it != changedBranches_.end() ; ++it) {
5233                 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
5234                 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
5235         }
5236 }
5237
5238
5239 void GuiDocument::allPackagesAuto()
5240 {
5241         allPackages(1);
5242 }
5243
5244
5245 void GuiDocument::allPackagesAlways()
5246 {
5247         allPackages(2);
5248 }
5249
5250
5251 void GuiDocument::allPackagesNot()
5252 {
5253         allPackages(3);
5254 }
5255
5256
5257 void GuiDocument::allPackages(int col)
5258 {
5259         for (int row = 0; row < mathsModule->packagesTW->rowCount(); ++row) {
5260                 QRadioButton * rb =
5261                         (QRadioButton*)mathsModule->packagesTW->cellWidget(row, col)->layout()->itemAt(0)->widget();
5262                 rb->setChecked(true);
5263         }
5264 }
5265
5266
5267 void GuiDocument::linenoToggled(bool on)
5268 {
5269         numberingModule->linenoLE->setEnabled(on);
5270         numberingModule->linenoLA->setEnabled(on);
5271 }
5272
5273
5274 void GuiDocument::outputChangesToggled(bool on)
5275 {
5276         changesModule->changeBarsCB->setEnabled(on);
5277         change_adaptor();
5278 }
5279
5280 void GuiDocument::setOutputSync(bool on)
5281 {
5282         outputModule->synccustomCB->setEnabled(on);
5283         outputModule->synccustomLA->setEnabled(on);
5284         change_adaptor();
5285 }
5286
5287
5288 } // namespace frontend
5289 } // namespace lyx
5290
5291 #include "moc_GuiDocument.cpp"