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