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