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