]> git.lyx.org Git - features.git/blob - src/frontends/qt/GuiDocument.cpp
Disable zoom slider when there is no buffer open (#12185)
[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_->setClearButton(true);
1660         filter_->setPlaceholderText(qt_("All avail. modules"));
1661         modulesModule->moduleFilterBarL->addWidget(filter_, 0);
1662         modulesModule->findModulesLA->setBuddy(filter_);
1663
1664         connect(filter_, SIGNAL(rightButtonClicked()),
1665                 this, SLOT(resetModuleFilter()));
1666         connect(filter_, SIGNAL(textEdited(QString)),
1667                 this, SLOT(moduleFilterChanged(QString)));
1668         connect(filter_, SIGNAL(returnPressed()),
1669                 this, SLOT(moduleFilterPressed()));
1670 #if (QT_VERSION < 0x050000)
1671         connect(filter_, SIGNAL(downPressed()),
1672                 modulesModule->availableLV, SLOT(setFocus()));
1673 #else
1674         connect(filter_, &FancyLineEdit::downPressed,
1675                 modulesModule->availableLV, [this](){ focusAndHighlight(modulesModule->availableLV); });
1676 #endif
1677
1678
1679         // PDF support
1680         pdfSupportModule = new UiWidget<Ui::PDFSupportUi>(this);
1681         connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
1682                 this, SLOT(change_adaptor()));
1683         connect(pdfSupportModule->titleLE, SIGNAL(textChanged(QString)),
1684                 this, SLOT(change_adaptor()));
1685         connect(pdfSupportModule->authorLE, SIGNAL(textChanged(QString)),
1686                 this, SLOT(change_adaptor()));
1687         connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(QString)),
1688                 this, SLOT(change_adaptor()));
1689         connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(QString)),
1690                 this, SLOT(change_adaptor()));
1691         connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
1692                 this, SLOT(change_adaptor()));
1693         connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
1694                 this, SLOT(change_adaptor()));
1695         connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
1696                 this, SLOT(change_adaptor()));
1697         connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
1698                 this, SLOT(bookmarksopenChanged(bool)));
1699         connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
1700                 this, SLOT(change_adaptor()));
1701         connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
1702                 this, SLOT(change_adaptor()));
1703         connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
1704                 this, SLOT(change_adaptor()));
1705         connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
1706                 this, SLOT(change_adaptor()));
1707         connect(pdfSupportModule->backrefCO, SIGNAL(activated(int)),
1708                 this, SLOT(change_adaptor()));
1709         connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
1710                 this, SLOT(change_adaptor()));
1711         connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
1712                 this, SLOT(change_adaptor()));
1713         connect(pdfSupportModule->optionsLE, SIGNAL(textChanged(QString)),
1714                 this, SLOT(change_adaptor()));
1715
1716         pdfSupportModule->titleLE->setValidator(new NoNewLineValidator(
1717                 pdfSupportModule->titleLE));
1718         pdfSupportModule->authorLE->setValidator(new NoNewLineValidator(
1719                 pdfSupportModule->authorLE));
1720         pdfSupportModule->subjectLE->setValidator(new NoNewLineValidator(
1721                 pdfSupportModule->subjectLE));
1722         pdfSupportModule->keywordsLE->setValidator(new NoNewLineValidator(
1723                 pdfSupportModule->keywordsLE));
1724         pdfSupportModule->optionsLE->setValidator(new NoNewLineValidator(
1725                 pdfSupportModule->optionsLE));
1726
1727         for (int i = 0; backref_opts[i][0]; ++i)
1728                 pdfSupportModule->backrefCO->addItem(qt_(backref_opts_gui[i]));
1729
1730
1731         // float
1732         floatModule = new FloatPlacement;
1733         connect(floatModule, SIGNAL(changed()),
1734                 this, SLOT(change_adaptor()));
1735
1736
1737         // listings
1738         listingsModule = new UiWidget<Ui::ListingsSettingsUi>(this);
1739         connect(listingsModule->listingsED, SIGNAL(textChanged()),
1740                 this, SLOT(change_adaptor()));
1741         connect(listingsModule->bypassCB, SIGNAL(clicked()),
1742                 this, SLOT(change_adaptor()));
1743         connect(listingsModule->bypassCB, SIGNAL(clicked()),
1744                 this, SLOT(setListingsMessage()));
1745         connect(listingsModule->packageCO, SIGNAL(activated(int)),
1746                 this, SLOT(change_adaptor()));
1747         connect(listingsModule->packageCO, SIGNAL(activated(int)),
1748                 this, SLOT(listingsPackageChanged(int)));
1749         connect(listingsModule->listingsED, SIGNAL(textChanged()),
1750                 this, SLOT(setListingsMessage()));
1751         listingsModule->listingsTB->setPlainText(
1752                 qt_("Input listings parameters below. Enter ? for a list of parameters."));
1753
1754         for (int i = 0; lst_packages[i][0]; ++i)
1755             listingsModule->packageCO->addItem(lst_packages[i]);
1756
1757
1758         // add the panels
1759         docPS->addPanel(latexModule, N_("Document Class"));
1760         docPS->addPanel(masterChildModule, N_("Child Documents"));
1761         docPS->addPanel(modulesModule, N_("Modules"));
1762         docPS->addPanel(localLayout, N_("Local Layout"));
1763         docPS->addPanel(fontModule, N_("Fonts"));
1764         docPS->addPanel(textLayoutModule, N_("Text Layout"));
1765         docPS->addPanel(pageLayoutModule, N_("Page Layout"));
1766         docPS->addPanel(marginsModule, N_("Page Margins"));
1767         docPS->addPanel(langModule, N_("Language"));
1768         docPS->addPanel(colorModule, N_("Colors"));
1769         docPS->addPanel(changesModule, N_("Change Tracking"));
1770         docPS->addPanel(numberingModule, N_("Numbering & TOC"));
1771         docPS->addPanel(biblioModule, N_("Bibliography"));
1772         docPS->addPanel(indicesModule, N_("Indexes"));
1773         docPS->addPanel(pdfSupportModule, N_("PDF Properties"));
1774         docPS->addPanel(mathsModule, N_("Math Options"));
1775         docPS->addPanel(floatModule, N_("Float Settings"));
1776         docPS->addPanel(listingsModule, N_("Listings[[inset]]"));
1777         docPS->addPanel(bulletsModule, N_("Bullets"));
1778         docPS->addPanel(branchesModule, N_("Branches"));
1779         docPS->addPanel(outputModule, N_("Formats[[output]]"));
1780         docPS->addPanel(preambleModule, N_("LaTeX Preamble"));
1781         docPS->setCurrentPanel("Document Class");
1782 // FIXME: hack to work around resizing bug in Qt >= 4.2
1783 // bug verified with Qt 4.2.{0-3} (JSpitzm)
1784 #if QT_VERSION >= 0x040200
1785         docPS->updateGeometry();
1786 #endif
1787 }
1788
1789
1790 void GuiDocument::onBufferViewChanged()
1791 {
1792         if (isVisibleView())
1793                 initialiseParams("");
1794 }
1795
1796
1797 void GuiDocument::saveDefaultClicked()
1798 {
1799         saveDocDefault();
1800 }
1801
1802
1803 void GuiDocument::useDefaultsClicked()
1804 {
1805         useClassDefaults();
1806 }
1807
1808
1809 void GuiDocument::change_adaptor()
1810 {
1811         nonModuleChanged_ = true;
1812         changed();
1813 }
1814
1815
1816 void GuiDocument::shellescapeChanged()
1817 {
1818         shellescapeChanged_ = true;
1819         changed();
1820 }
1821
1822 void GuiDocument::bookmarksopenChanged(bool state)
1823 {
1824         pdfSupportModule->bookmarksopenlevelSB->setEnabled(state);
1825         pdfSupportModule->bookmarksopenlevelLA->setEnabled(state);
1826 }
1827
1828
1829 void GuiDocument::slotApply()
1830 {
1831         bool only_shellescape_changed = !nonModuleChanged_ && !modulesChanged_;
1832         bool wasclean = buffer().isClean();
1833         GuiDialog::slotApply();
1834         if (wasclean && only_shellescape_changed)
1835                 buffer().markClean();
1836         modulesChanged_ = false;
1837 }
1838
1839
1840 void GuiDocument::slotOK()
1841 {
1842         bool only_shellescape_changed = !nonModuleChanged_ && !modulesChanged_;
1843         bool wasclean = buffer().isClean();
1844         GuiDialog::slotOK();
1845         if (wasclean && only_shellescape_changed)
1846                 buffer().markClean();
1847         modulesChanged_ = false;
1848 }
1849
1850
1851 void GuiDocument::slotButtonBox(QAbstractButton * button)
1852 {
1853         switch (buttonBox->standardButton(button)) {
1854         case QDialogButtonBox::Ok:
1855                 slotOK();
1856                 break;
1857         case QDialogButtonBox::Apply:
1858                 slotApply();
1859                 break;
1860         case QDialogButtonBox::Cancel:
1861                 slotClose();
1862                 break;
1863         case QDialogButtonBox::Reset:
1864         case QDialogButtonBox::RestoreDefaults:
1865                 slotRestore();
1866                 break;
1867         default:
1868                 break;
1869         }
1870 }
1871
1872
1873 void GuiDocument::filterModules(QString const & str)
1874 {
1875         updateAvailableModules();
1876         if (str.isEmpty())
1877                 return;
1878
1879         modules_av_model_.clear();
1880         list<modInfoStruct> modInfoList = getModuleInfo();
1881         // Sort names according to the locale
1882         modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
1883                         return 0 < b.name.localeAwareCompare(a.name);
1884                 });
1885
1886         QIcon user_icon(getPixmap("images/", "lyxfiles-user", "svgz,png"));
1887         QIcon system_icon(getPixmap("images/", "lyxfiles-system", "svgz,png"));
1888
1889         int i = 0;
1890         for (modInfoStruct const & m : modInfoList) {
1891                 if (m.name.contains(str, Qt::CaseInsensitive) || contains(m.id, fromqstr(str))) {
1892                         QStandardItem * item = new QStandardItem();
1893                         item->setData(m.name, Qt::DisplayRole);
1894                         item->setData(toqstr(m.id), Qt::UserRole);
1895                         item->setData(m.description, Qt::ToolTipRole);
1896                         item->setEditable(false);
1897                         if (m.local)
1898                                 item->setIcon(user_icon);
1899                         else
1900                                 item->setIcon(system_icon);
1901                         modules_av_model_.insertRow(i, item);
1902                         ++i;
1903                 }
1904         }
1905 }
1906
1907
1908 void GuiDocument::moduleFilterChanged(const QString & text)
1909 {
1910         if (!text.isEmpty()) {
1911                 filterModules(filter_->text());
1912                 return;
1913         }
1914         filterModules(filter_->text());
1915         filter_->setFocus();
1916 }
1917
1918
1919 void GuiDocument::moduleFilterPressed()
1920 {
1921         filterModules(filter_->text());
1922 }
1923
1924
1925 void GuiDocument::resetModuleFilter()
1926 {
1927         filter_->setText(QString());
1928         filterModules(filter_->text());
1929 }
1930
1931
1932 void GuiDocument::includeonlyClicked(QTreeWidgetItem * item, int)
1933 {
1934         if (item == nullptr)
1935                 return;
1936
1937         string child = fromqstr(item->text(0));
1938         if (child.empty())
1939                 return;
1940
1941         if (std::find(includeonlys_.begin(),
1942                       includeonlys_.end(), child) != includeonlys_.end())
1943                 includeonlys_.remove(child);
1944         else
1945                 includeonlys_.push_back(child);
1946
1947         updateIncludeonlys();
1948         change_adaptor();
1949 }
1950
1951
1952 QString GuiDocument::validateListingsParameters()
1953 {
1954         if (listingsModule->bypassCB->isChecked())
1955                 return QString();
1956         string const package =
1957             lst_packages[listingsModule->packageCO->currentIndex()];
1958         string params = fromqstr(listingsModule->listingsED->toPlainText());
1959         InsetListingsParams lstparams(params);
1960         lstparams.setMinted(package == "Minted");
1961         return toqstr(lstparams.validate());
1962 }
1963
1964
1965 void GuiDocument::setListingsMessage()
1966 {
1967         // FIXME THREAD
1968         static bool isOK = true;
1969         QString msg = validateListingsParameters();
1970         if (msg.isEmpty()) {
1971                 if (isOK)
1972                         return;
1973                 isOK = true;
1974                 // listingsModule->listingsTB->setTextColor("black");
1975                 listingsModule->listingsTB->setPlainText(
1976                         qt_("Input listings parameters below. "
1977                             "Enter ? for a list of parameters."));
1978         } else {
1979                 isOK = false;
1980                 // listingsModule->listingsTB->setTextColor("red");
1981                 listingsModule->listingsTB->setPlainText(msg);
1982         }
1983 }
1984
1985
1986 void GuiDocument::listingsPackageChanged(int index)
1987 {
1988         string const package = lst_packages[index];
1989         if (package == "Minted" && lyxrc.pygmentize_command.empty()) {
1990                 Alert::warning(_("Pygments driver command not found!"),
1991                     _("The driver command necessary to use the minted package\n"
1992                       "(pygmentize) has not been found. Make sure you have\n"
1993                       "the python-pygments module installed or, if the driver\n"
1994                       "is named differently, to add the following line to the\n"
1995                       "document preamble:\n\n"
1996                       "\\AtBeginDocument{\\renewcommand{\\MintedPygmentize}{driver}}\n\n"
1997                       "where 'driver' is name of the driver command."));
1998         }
1999 }
2000
2001
2002 void GuiDocument::setLSpacing(int item)
2003 {
2004         textLayoutModule->lspacingLE->setEnabled(item == 3);
2005 }
2006
2007
2008 void GuiDocument::setIndent(int item)
2009 {
2010         bool const enable = (item == 1);
2011         textLayoutModule->indentLE->setEnabled(enable);
2012         textLayoutModule->indentLengthCO->setEnabled(enable);
2013         textLayoutModule->skipLE->setEnabled(false);
2014         textLayoutModule->skipLengthCO->setEnabled(false);
2015         isValid();
2016 }
2017
2018
2019 void GuiDocument::enableIndent(bool indent)
2020 {
2021         textLayoutModule->skipLE->setEnabled(!indent);
2022         textLayoutModule->skipLengthCO->setEnabled(!indent);
2023         if (indent)
2024                 setIndent(textLayoutModule->indentCO->currentIndex());
2025 }
2026
2027
2028 void GuiDocument::setSkip(int item)
2029 {
2030         VSpace::VSpaceKind kind =
2031                 VSpace::VSpaceKind(textLayoutModule->skipCO->itemData(item).toInt());
2032         bool const enable = (kind == VSpace::LENGTH);
2033         textLayoutModule->skipLE->setEnabled(enable);
2034         textLayoutModule->skipLengthCO->setEnabled(enable);
2035         isValid();
2036 }
2037
2038
2039 void GuiDocument::enableSkip(bool skip)
2040 {
2041         textLayoutModule->indentLE->setEnabled(!skip);
2042         textLayoutModule->indentLengthCO->setEnabled(!skip);
2043         if (skip)
2044                 setSkip(textLayoutModule->skipCO->currentIndex());
2045 }
2046
2047 void GuiDocument::allowMathIndent() {
2048         // only disable when not checked, checked does not always allow enabling
2049         if (!mathsModule->MathIndentCB->isChecked()) {
2050                 mathsModule->MathIndentLE->setEnabled(false);
2051                 mathsModule->MathIndentLengthCO->setEnabled(false);
2052         }
2053         if (mathsModule->MathIndentCB->isChecked()
2054             && mathsModule->MathIndentCO->currentIndex() == 1) {
2055                         mathsModule->MathIndentLE->setEnabled(true);
2056                         mathsModule->MathIndentLengthCO->setEnabled(true);
2057         }
2058         isValid();
2059 }
2060
2061 void GuiDocument::enableMathIndent(int item)
2062 {
2063         bool const enable = (item == 1);
2064         mathsModule->MathIndentLE->setEnabled(enable);
2065         mathsModule->MathIndentLengthCO->setEnabled(enable);
2066         isValid();
2067 }
2068
2069
2070 void GuiDocument::setMargins()
2071 {
2072         bool const extern_geometry =
2073                 documentClass().provides("geometry");
2074         marginsModule->marginCB->setEnabled(!extern_geometry);
2075         if (extern_geometry) {
2076                 marginsModule->marginCB->setChecked(false);
2077                 setCustomMargins(true);
2078         } else {
2079                 marginsModule->marginCB->setChecked(!bp_.use_geometry);
2080                 setCustomMargins(!bp_.use_geometry);
2081         }
2082
2083         // set some placeholder text that hint on defaults
2084         QString const placeholder = marginsModule->marginCB->isChecked() ?
2085                 qt_("Class defaults") : qt_("Package defaults");
2086         // set tooltip depending on gemoetry state
2087         QString const tooltip = marginsModule->marginCB->isChecked() ?
2088                 qt_("If no value is given, the defaults as set by the class are used.")
2089                 : qt_("If no value is given, the defaults as set by the geometry package or a package/class overriding geometry's defaults are used.");
2090         marginsModule->topLE->setPlaceholderText(placeholder);
2091         marginsModule->bottomLE->setPlaceholderText(placeholder);
2092         marginsModule->innerLE->setPlaceholderText(placeholder);
2093         marginsModule->outerLE->setPlaceholderText(placeholder);
2094         marginsModule->headheightLE->setPlaceholderText(placeholder);
2095         marginsModule->headsepLE->setPlaceholderText(placeholder);
2096         marginsModule->footskipLE->setPlaceholderText(placeholder);
2097         marginsModule->columnsepLE->setPlaceholderText(placeholder);
2098         marginsModule->topLE->setToolTip(tooltip);
2099         marginsModule->bottomLE->setToolTip(tooltip);
2100         marginsModule->innerLE->setToolTip(tooltip);
2101         marginsModule->outerLE->setToolTip(tooltip);
2102         marginsModule->headheightLE->setToolTip(tooltip);
2103         marginsModule->headsepLE->setToolTip(tooltip);
2104         marginsModule->footskipLE->setToolTip(tooltip);
2105         marginsModule->columnsepLE->setToolTip(tooltip);
2106 }
2107
2108
2109 void GuiDocument::papersizeChanged(int paper_size)
2110 {
2111         setCustomPapersize(paper_size == 1);
2112 }
2113
2114
2115 void GuiDocument::setCustomPapersize(bool custom)
2116 {
2117         pageLayoutModule->paperwidthL->setEnabled(custom);
2118         pageLayoutModule->paperwidthLE->setEnabled(custom);
2119         pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
2120         pageLayoutModule->paperheightL->setEnabled(custom);
2121         pageLayoutModule->paperheightLE->setEnabled(custom);
2122         pageLayoutModule->paperheightLE->setFocus();
2123         pageLayoutModule->paperheightUnitCO->setEnabled(custom);
2124 }
2125
2126
2127 void GuiDocument::setColSep()
2128 {
2129         setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
2130 }
2131
2132
2133 void GuiDocument::setCustomMargins(bool custom)
2134 {
2135         marginsModule->topL->setEnabled(!custom);
2136         marginsModule->topLE->setEnabled(!custom);
2137         marginsModule->topUnit->setEnabled(!custom);
2138
2139         marginsModule->bottomL->setEnabled(!custom);
2140         marginsModule->bottomLE->setEnabled(!custom);
2141         marginsModule->bottomUnit->setEnabled(!custom);
2142
2143         marginsModule->innerL->setEnabled(!custom);
2144         marginsModule->innerLE->setEnabled(!custom);
2145         marginsModule->innerUnit->setEnabled(!custom);
2146
2147         marginsModule->outerL->setEnabled(!custom);
2148         marginsModule->outerLE->setEnabled(!custom);
2149         marginsModule->outerUnit->setEnabled(!custom);
2150
2151         marginsModule->headheightL->setEnabled(!custom);
2152         marginsModule->headheightLE->setEnabled(!custom);
2153         marginsModule->headheightUnit->setEnabled(!custom);
2154
2155         marginsModule->headsepL->setEnabled(!custom);
2156         marginsModule->headsepLE->setEnabled(!custom);
2157         marginsModule->headsepUnit->setEnabled(!custom);
2158
2159         marginsModule->footskipL->setEnabled(!custom);
2160         marginsModule->footskipLE->setEnabled(!custom);
2161         marginsModule->footskipUnit->setEnabled(!custom);
2162
2163         bool const enableColSep = !custom &&
2164                         textLayoutModule->twoColumnCB->checkState() == Qt::Checked;
2165         marginsModule->columnsepL->setEnabled(enableColSep);
2166         marginsModule->columnsepLE->setEnabled(enableColSep);
2167         marginsModule->columnsepUnit->setEnabled(enableColSep);
2168
2169         // set some placeholder text that hint on defaults
2170         QString const placeholder = marginsModule->marginCB->isChecked() ?
2171                 qt_("Class defaults") : qt_("Package defaults");
2172         // set tooltip depending on gemoetry state
2173         QString const tooltip = marginsModule->marginCB->isChecked() ?
2174                 qt_("If no value is given, the defaults as set by the class are used.")
2175                 : qt_("If no value is given, the defaults as set by the geometry package or a package/class overriding geometry's defaults are used.");
2176         marginsModule->topLE->setPlaceholderText(placeholder);
2177         marginsModule->bottomLE->setPlaceholderText(placeholder);
2178         marginsModule->innerLE->setPlaceholderText(placeholder);
2179         marginsModule->outerLE->setPlaceholderText(placeholder);
2180         marginsModule->headheightLE->setPlaceholderText(placeholder);
2181         marginsModule->headsepLE->setPlaceholderText(placeholder);
2182         marginsModule->footskipLE->setPlaceholderText(placeholder);
2183         marginsModule->columnsepLE->setPlaceholderText(placeholder);
2184         marginsModule->topLE->setToolTip(tooltip);
2185         marginsModule->bottomLE->setToolTip(tooltip);
2186         marginsModule->innerLE->setToolTip(tooltip);
2187         marginsModule->outerLE->setToolTip(tooltip);
2188         marginsModule->headheightLE->setToolTip(tooltip);
2189         marginsModule->headsepLE->setToolTip(tooltip);
2190         marginsModule->footskipLE->setToolTip(tooltip);
2191         marginsModule->columnsepLE->setToolTip(tooltip);
2192
2193 }
2194
2195
2196 void GuiDocument::changeBackgroundColor()
2197 {
2198         QColor const & newColor = QColorDialog::getColor(
2199                 rgb2qcolor(set_backgroundcolor), asQWidget());
2200         if (!newColor.isValid())
2201                 return;
2202         // set the button color and text
2203         colorModule->backgroundPB->setStyleSheet(
2204                 colorButtonStyleSheet(newColor));
2205         colorModule->backgroundPB->setText(qt_("&Change..."));
2206         // save color
2207         set_backgroundcolor = rgbFromHexName(fromqstr(newColor.name()));
2208         is_backgroundcolor = true;
2209         change_adaptor();
2210 }
2211
2212
2213 void GuiDocument::deleteBackgroundColor()
2214 {
2215         // set the button color back to default by setting an empty StyleSheet
2216         colorModule->backgroundPB->setStyleSheet(QLatin1String(""));
2217         // change button text
2218         colorModule->backgroundPB->setText(qt_("&Default..."));
2219         // save default color (white)
2220         set_backgroundcolor = rgbFromHexName("#ffffff");
2221         is_backgroundcolor = false;
2222         change_adaptor();
2223 }
2224
2225
2226 void GuiDocument::changeFontColor()
2227 {
2228         QColor const & newColor = QColorDialog::getColor(
2229                 rgb2qcolor(set_fontcolor), asQWidget());
2230         if (!newColor.isValid())
2231                 return;
2232         // set the button color and text
2233         colorModule->fontColorPB->setStyleSheet(
2234                 colorButtonStyleSheet(newColor));
2235         colorModule->fontColorPB->setText(qt_("&Change..."));
2236         // save color
2237         set_fontcolor = rgbFromHexName(fromqstr(newColor.name()));
2238         is_fontcolor = true;
2239         change_adaptor();
2240 }
2241
2242
2243 void GuiDocument::deleteFontColor()
2244 {
2245         // set the button color back to default by setting an empty StyleSheet
2246         colorModule->fontColorPB->setStyleSheet(QLatin1String(""));
2247         // change button text
2248         colorModule->fontColorPB->setText(qt_("&Default..."));
2249         // save default color (black)
2250         set_fontcolor = rgbFromHexName("#000000");
2251         is_fontcolor = false;
2252         change_adaptor();
2253 }
2254
2255
2256 void GuiDocument::changeNoteFontColor()
2257 {
2258         QColor const & newColor = QColorDialog::getColor(
2259                 rgb2qcolor(set_notefontcolor), asQWidget());
2260         if (!newColor.isValid())
2261                 return;
2262         // set the button color
2263         colorModule->noteFontColorPB->setStyleSheet(
2264                 colorButtonStyleSheet(newColor));
2265         // save color
2266         set_notefontcolor = rgbFromHexName(fromqstr(newColor.name()));
2267         is_notefontcolor = true;
2268         change_adaptor();
2269 }
2270
2271
2272 void GuiDocument::deleteNoteFontColor()
2273 {
2274         // set the button color back to pref
2275         theApp()->getRgbColor(Color_greyedouttext, set_notefontcolor);
2276         colorModule->noteFontColorPB->setStyleSheet(
2277                 colorButtonStyleSheet(rgb2qcolor(set_notefontcolor)));
2278         is_notefontcolor = false;
2279         change_adaptor();
2280 }
2281
2282
2283 void GuiDocument::changeBoxBackgroundColor()
2284 {
2285         QColor const & newColor = QColorDialog::getColor(
2286                 rgb2qcolor(set_boxbgcolor), asQWidget());
2287         if (!newColor.isValid())
2288                 return;
2289         // set the button color
2290         colorModule->boxBackgroundPB->setStyleSheet(
2291                 colorButtonStyleSheet(newColor));
2292         // save color
2293         set_boxbgcolor = rgbFromHexName(fromqstr(newColor.name()));
2294         is_boxbgcolor = true;
2295         change_adaptor();
2296 }
2297
2298
2299 void GuiDocument::deleteBoxBackgroundColor()
2300 {
2301         // set the button color back to pref
2302         theApp()->getRgbColor(Color_shadedbg, set_boxbgcolor);
2303         colorModule->boxBackgroundPB->setStyleSheet(
2304                 colorButtonStyleSheet(rgb2qcolor(set_boxbgcolor)));
2305         is_boxbgcolor = false;
2306         change_adaptor();
2307 }
2308
2309
2310 void GuiDocument::updateQuoteStyles(bool const set)
2311 {
2312         Language const * lang = lyx::languages.getLanguage(
2313                 fromqstr(langModule->languageCO->itemData(
2314                         langModule->languageCO->currentIndex()).toString()));
2315
2316         QuoteStyle def = bp_.getQuoteStyle(lang->quoteStyle());
2317
2318         langModule->quoteStyleCO->clear();
2319
2320         bool has_default = false;
2321         for (int i = 0; i < quoteparams.stylescount(); ++i) {
2322                 QuoteStyle qs = QuoteStyle(i);
2323                 if (qs == QuoteStyle::Dynamic)
2324                         continue;
2325                 bool const langdef = (qs == def);
2326                 if (langdef) {
2327                         // add the default style on top
2328                         langModule->quoteStyleCO->insertItem(0,
2329                                 toqstr(quoteparams.getGuiLabel(qs, langdef)), static_cast<int>(qs));
2330                         has_default = true;
2331                 }
2332                 else
2333                         langModule->quoteStyleCO->addItem(
2334                                 toqstr(quoteparams.getGuiLabel(qs, langdef)), static_cast<int>(qs));
2335         }
2336         if (set && has_default)
2337                 // (re)set to the default style
2338                 langModule->quoteStyleCO->setCurrentIndex(0);
2339 }
2340
2341
2342 void GuiDocument::languageChanged(int i)
2343 {
2344         // some languages only work with Polyglossia
2345         Language const * lang = lyx::languages.getLanguage(
2346                 fromqstr(langModule->languageCO->itemData(i).toString()));
2347         if (lang->babel().empty() && !lang->polyglossia().empty()
2348                 && lang->required() != "CJK" && lang->required() != "japanese") {
2349                         // If we force to switch fontspec on, store
2350                         // current state (#8717)
2351                         if (fontModule->osFontsCB->isEnabled())
2352                                 forced_fontspec_activation =
2353                                         !fontModule->osFontsCB->isChecked();
2354                         fontModule->osFontsCB->setChecked(true);
2355                         fontModule->osFontsCB->setEnabled(false);
2356         }
2357         else {
2358                 fontModule->osFontsCB->setEnabled(true);
2359                 // If we have forced to switch fontspec on,
2360                 // restore previous state (#8717)
2361                 if (forced_fontspec_activation)
2362                         fontModule->osFontsCB->setChecked(false);
2363                 forced_fontspec_activation = false;
2364         }
2365
2366         // set appropriate quotation mark style
2367         updateQuoteStyles(true);
2368 }
2369
2370
2371 void GuiDocument::osFontsChanged(bool nontexfonts)
2372 {
2373         bool const tex_fonts = !nontexfonts;
2374         // store current fonts
2375         QString const font_roman = fontModule->fontsRomanCO->itemData(
2376                         fontModule->fontsRomanCO->currentIndex()).toString();
2377         QString const font_sans = fontModule->fontsSansCO->itemData(
2378                         fontModule->fontsSansCO->currentIndex()).toString();
2379         QString const font_typewriter = fontModule->fontsTypewriterCO->itemData(
2380                         fontModule->fontsTypewriterCO->currentIndex()).toString();
2381         QString const font_math = fontModule->fontsMathCO->itemData(
2382                         fontModule->fontsMathCO->currentIndex()).toString();
2383         int const font_sf_scale = fontModule->scaleSansSB->value();
2384         int const font_tt_scale = fontModule->scaleTypewriterSB->value();
2385
2386         updateFontlist();
2387         // store default format
2388         QString const dformat = outputModule->defaultFormatCO->itemData(
2389                 outputModule->defaultFormatCO->currentIndex()).toString();
2390         updateDefaultFormat();
2391         // try to restore default format
2392         int index = outputModule->defaultFormatCO->findData(dformat);
2393         // set to default if format is not found
2394         if (index == -1)
2395                 index = 0;
2396         outputModule->defaultFormatCO->setCurrentIndex(index);
2397
2398         // try to restore fonts which were selected two toggles ago
2399         index = fontModule->fontsRomanCO->findData(fontModule->font_roman);
2400         if (index != -1)
2401                 fontModule->fontsRomanCO->setCurrentIndex(index);
2402         index = fontModule->fontsSansCO->findData(fontModule->font_sans);
2403         if (index != -1)
2404                 fontModule->fontsSansCO->setCurrentIndex(index);
2405         index = fontModule->fontsTypewriterCO->findData(fontModule->font_typewriter);
2406         if (index != -1)
2407                 fontModule->fontsTypewriterCO->setCurrentIndex(index);
2408         index = fontModule->fontsMathCO->findData(fontModule->font_math);
2409         if (index != -1)
2410                 fontModule->fontsMathCO->setCurrentIndex(index);
2411         // save fonts for next next toggle
2412         fontModule->font_roman = font_roman;
2413         fontModule->font_sans = font_sans;
2414         fontModule->font_typewriter = font_typewriter;
2415         fontModule->font_math = font_math;
2416         fontModule->font_sf_scale = font_sf_scale;
2417         fontModule->font_tt_scale = font_tt_scale;
2418
2419         // non-tex fonts override the "\inputencoding" option with "utf8-plain"
2420         langModule->encodingCO->setEnabled(tex_fonts);
2421         inputencodingToDialog();
2422
2423         fontModule->fontsDefaultCO->setEnabled(tex_fonts);
2424         fontModule->fontsDefaultLA->setEnabled(tex_fonts);
2425         fontModule->cjkFontLE->setEnabled(tex_fonts);
2426         fontModule->cjkFontLA->setEnabled(tex_fonts);
2427
2428         updateFontOptions();
2429
2430         fontModule->fontencLA->setEnabled(tex_fonts);
2431         fontModule->fontencCO->setEnabled(tex_fonts);
2432         if (!tex_fonts)
2433                 fontModule->fontencLE->setEnabled(false);
2434         else
2435                 fontencChanged(fontModule->fontencCO->currentIndex());
2436 }
2437
2438
2439 void GuiDocument::encodingSwitched(int i)
2440 {
2441         bool const tex_fonts = !fontModule->osFontsCB->isChecked();
2442         langModule->unicodeEncodingCO->setEnabled(tex_fonts);
2443         langModule->customEncodingCO->setEnabled(tex_fonts);
2444         langModule->autoEncodingCO->setEnabled(tex_fonts);
2445         langModule->unicodeEncodingCO->setVisible(i == EncodingSets::unicode);
2446         langModule->autoEncodingCO->setVisible(i == EncodingSets::legacy);
2447         langModule->customEncodingCO->setVisible(i == EncodingSets::custom);
2448         if (tex_fonts)
2449                 langModule->unicodeEncodingCO->setItemText(1, qt_("Direct (No inputenc)"));
2450         else
2451                 langModule->unicodeEncodingCO->setItemText(1, qt_("Direct (XeTeX/LuaTeX)"));
2452 }
2453
2454 void GuiDocument::inputencodingToDialog()
2455 {
2456         QString inputenc = toqstr(bp_.inputenc);
2457         int p;
2458         if (fontModule->osFontsCB->isChecked()) { // non-tex fonts require utf8-plain
2459                 langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
2460                 langModule->unicodeEncodingCO->setCurrentIndex(
2461                         langModule->unicodeEncodingCO->findData("utf8-plain"));
2462         } else if (inputenc.startsWith("utf8")) {
2463                 langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
2464                 p = langModule->unicodeEncodingCO->findData(inputenc);
2465                 if (p == -1)
2466                         p = 0;
2467                 langModule->unicodeEncodingCO->setCurrentIndex(p);
2468                 langModule->autoEncodingCO->setCurrentIndex(0);
2469                 langModule->customEncodingCO->setCurrentIndex(0);
2470         } else if (inputenc.startsWith("auto")) {
2471                 langModule->encodingCO->setCurrentIndex(EncodingSets::legacy);
2472                 p = langModule->autoEncodingCO->findData(inputenc);
2473                 if (p == -1)
2474                         p = 0;
2475                 langModule->unicodeEncodingCO->setCurrentIndex(0);
2476                 langModule->autoEncodingCO->setCurrentIndex(p);
2477                 langModule->customEncodingCO->setCurrentIndex(0);
2478         } else {
2479                 langModule->encodingCO->setCurrentIndex(EncodingSets::custom);
2480                 p = langModule->customEncodingCO->findData(inputenc);
2481                 if (p == -1) {
2482                         p = 0;
2483                         langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
2484                 }
2485                 langModule->unicodeEncodingCO->setCurrentIndex(0);
2486                 langModule->autoEncodingCO->setCurrentIndex(0);
2487                 langModule->customEncodingCO->setCurrentIndex(p);
2488         }
2489         encodingSwitched(langModule->encodingCO->currentIndex());
2490 }
2491
2492
2493 void GuiDocument::mathFontChanged(int)
2494 {
2495         updateFontOptions();
2496 }
2497
2498 void GuiDocument::fontOsfToggled(bool state)
2499 {
2500         if (fontModule->osFontsCB->isChecked())
2501                 return;
2502         QString font = fontModule->fontsRomanCO->itemData(
2503                         fontModule->fontsRomanCO->currentIndex()).toString();
2504         if (hasMonolithicExpertSet(font))
2505                 fontModule->fontScCB->setChecked(state);
2506 }
2507
2508
2509 void GuiDocument::fontScToggled(bool state)
2510 {
2511         if (fontModule->osFontsCB->isChecked())
2512                 return;
2513         QString font = fontModule->fontsRomanCO->itemData(
2514                         fontModule->fontsRomanCO->currentIndex()).toString();
2515         if (hasMonolithicExpertSet(font))
2516                 fontModule->fontOsfCB->setChecked(state);
2517 }
2518
2519
2520 void GuiDocument::updateExtraOpts()
2521 {
2522         bool const tex_fonts = !fontModule->osFontsCB->isChecked();
2523         QString font;
2524         if (tex_fonts)
2525                 font = fontModule->fontsRomanCO->itemData(
2526                                 fontModule->fontsRomanCO->currentIndex()).toString();
2527         bool const rm_opts = providesExtraOpts(font);
2528         if (tex_fonts)
2529                 font = fontModule->fontsSansCO->itemData(
2530                                 fontModule->fontsSansCO->currentIndex()).toString();
2531         bool const sf_opts = providesExtraOpts(font);
2532         if (tex_fonts)
2533                 font = fontModule->fontsTypewriterCO->itemData(
2534                                 fontModule->fontsTypewriterCO->currentIndex()).toString();
2535         bool const tt_opts = providesExtraOpts(font);
2536         fontModule->fontspecRomanLA->setEnabled(!tex_fonts || rm_opts);
2537         fontModule->fontspecRomanLE->setEnabled(!tex_fonts || rm_opts);
2538         fontModule->fontspecSansLA->setEnabled(!tex_fonts || sf_opts);
2539         fontModule->fontspecSansLE->setEnabled(!tex_fonts || sf_opts);
2540         fontModule->fontspecTypewriterLA->setEnabled(!tex_fonts || tt_opts);
2541         fontModule->fontspecTypewriterLE->setEnabled(!tex_fonts || tt_opts);
2542 }
2543
2544
2545 void GuiDocument::updateFontOptions()
2546 {
2547         bool const tex_fonts = !fontModule->osFontsCB->isChecked();
2548         QString font;
2549         if (tex_fonts)
2550                 font = fontModule->fontsSansCO->itemData(
2551                                 fontModule->fontsSansCO->currentIndex()).toString();
2552         bool scalable = providesScale(font);
2553         fontModule->scaleSansSB->setEnabled(scalable);
2554         fontModule->scaleSansLA->setEnabled(scalable);
2555         fontModule->fontSansOsfCB->setEnabled(providesOSF(font));
2556         if (tex_fonts)
2557                 font = fontModule->fontsTypewriterCO->itemData(
2558                                 fontModule->fontsTypewriterCO->currentIndex()).toString();
2559         scalable = providesScale(font);
2560         fontModule->scaleTypewriterSB->setEnabled(scalable);
2561         fontModule->scaleTypewriterLA->setEnabled(scalable);
2562         fontModule->fontTypewriterOsfCB->setEnabled(providesOSF(font));
2563         if (tex_fonts)
2564                 font = fontModule->fontsRomanCO->itemData(
2565                                 fontModule->fontsRomanCO->currentIndex()).toString();
2566         fontModule->fontScCB->setEnabled(providesSC(font));
2567         fontModule->fontOsfCB->setEnabled(providesOSF(font));
2568         updateExtraOpts();
2569         updateMathFonts(font);
2570 }
2571
2572
2573 void GuiDocument::updateFontsize(string const & items, string const & sel)
2574 {
2575         fontModule->fontsizeCO->clear();
2576         fontModule->fontsizeCO->addItem(qt_("Default"));
2577
2578         for (int n = 0; !token(items,'|',n).empty(); ++n)
2579                 fontModule->fontsizeCO->
2580                         addItem(toqstr(token(items,'|',n)));
2581
2582         for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
2583                 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
2584                         fontModule->fontsizeCO->setCurrentIndex(n);
2585                         break;
2586                 }
2587         }
2588 }
2589
2590
2591 bool GuiDocument::ot1() const
2592 {
2593         QString const fontenc =
2594                 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
2595         int const i = langModule->languageCO->currentIndex();
2596         if (i == -1)
2597                 return false;
2598         QString const langname = langModule->languageCO->itemData(i).toString();
2599         Language const * newlang = lyx::languages.getLanguage(fromqstr(langname));
2600         return (fontenc == "default"
2601                 || (fontenc == "auto" && newlang->fontenc(buffer().params()) == "OT1")
2602                 || (fontenc == "custom" && fontModule->fontencLE->text() == "OT1"));
2603 }
2604
2605
2606 bool GuiDocument::completeFontset() const
2607 {
2608         return (fontModule->fontsSansCO->itemData(
2609                         fontModule->fontsSansCO->currentIndex()).toString() == "default"
2610                 && fontModule->fontsSansCO->itemData(
2611                         fontModule->fontsTypewriterCO->currentIndex()).toString() == "default");
2612 }
2613
2614
2615 bool GuiDocument::noMathFont() const
2616 {
2617         return (fontModule->fontsMathCO->itemData(
2618                 fontModule->fontsMathCO->currentIndex()).toString() == "default");
2619 }
2620
2621
2622 void GuiDocument::updateTexFonts()
2623 {
2624         LaTeXFonts::TexFontMap texfontmap = theLaTeXFonts().getLaTeXFonts();
2625
2626         LaTeXFonts::TexFontMap::const_iterator it = texfontmap.begin();
2627         LaTeXFonts::TexFontMap::const_iterator end = texfontmap.end();
2628         for (; it != end; ++it) {
2629                 LaTeXFont lf = it->second;
2630                 if (lf.name().empty()) {
2631                         LYXERR0("Error: Unnamed font: " << it->first);
2632                         continue;
2633                 }
2634                 docstring const family = lf.family();
2635                 docstring guiname = translateIfPossible(lf.guiname());
2636                 if (!lf.available(ot1(), noMathFont()))
2637                         guiname += _(" (not installed)");
2638                 if (family == "rm")
2639                         rmfonts_.insert(toqstr(guiname), toqstr(it->first));
2640                 else if (family == "sf")
2641                         sffonts_.insert(toqstr(guiname), toqstr(it->first));
2642                 else if (family == "tt")
2643                         ttfonts_.insert(toqstr(guiname), toqstr(it->first));
2644                 else if (family == "math")
2645                         mathfonts_.insert(toqstr(guiname), toqstr(it->first));
2646         }
2647 }
2648
2649
2650 void GuiDocument::updateFontlist()
2651 {
2652         // reset the filters of the CategorizedCombos
2653         fontModule->fontsRomanCO->resetFilter();
2654         fontModule->fontsSansCO->resetFilter();
2655         fontModule->fontsTypewriterCO->resetFilter();
2656         fontModule->fontsRomanCO->clear();
2657         fontModule->fontsSansCO->clear();
2658         fontModule->fontsTypewriterCO->clear();
2659         fontModule->fontsMathCO->clear();
2660
2661         // With fontspec (XeTeX, LuaTeX), we have access to all system fonts, but not the LaTeX fonts
2662         if (fontModule->osFontsCB->isChecked()) {
2663                 fontModule->fontsRomanCO->addItem(qt_("Default"), QString("default"));
2664                 fontModule->fontsSansCO->addItem(qt_("Default"), QString("default"));
2665                 fontModule->fontsTypewriterCO->addItem(qt_("Default"), QString("default"));
2666                 QString unimath = qt_("Non-TeX Fonts Default");
2667                 if (!LaTeXFeatures::isAvailable("unicode-math"))
2668                         unimath += qt_(" (not available)");
2669                 fontModule->fontsMathCO->addItem(qt_("Class Default (TeX Fonts)"), QString("auto"));
2670                 fontModule->fontsMathCO->addItem(unimath, QString("default"));
2671
2672                 QFontDatabase fontdb;
2673                 QStringList families(fontdb.families());
2674                 for (auto const & family : families) {
2675                         fontModule->fontsRomanCO->addItem(family, family);
2676                         fontModule->fontsSansCO->addItem(family, family);
2677                         fontModule->fontsTypewriterCO->addItem(family, family);
2678                 }
2679                 return;
2680         }
2681
2682         if (rmfonts_.empty())
2683                 updateTexFonts();
2684
2685         fontModule->fontsRomanCO->addItem(qt_("Default"), QString("default"));
2686         QMap<QString, QString>::const_iterator rmi = rmfonts_.constBegin();
2687         while (rmi != rmfonts_.constEnd()) {
2688                 fontModule->fontsRomanCO->addItem(rmi.key(), rmi.value());
2689                 ++rmi;
2690         }
2691
2692         fontModule->fontsSansCO->addItem(qt_("Default"), QString("default"));
2693         QMap<QString, QString>::const_iterator sfi = sffonts_.constBegin();
2694         while (sfi != sffonts_.constEnd()) {
2695                 fontModule->fontsSansCO->addItem(sfi.key(), sfi.value());
2696                 ++sfi;
2697         }
2698
2699         fontModule->fontsTypewriterCO->addItem(qt_("Default"), QString("default"));
2700         QMap<QString, QString>::const_iterator tti = ttfonts_.constBegin();
2701         while (tti != ttfonts_.constEnd()) {
2702                 fontModule->fontsTypewriterCO->addItem(tti.key(), tti.value());
2703                 ++tti;
2704         }
2705
2706         fontModule->fontsMathCO->addItem(qt_("Automatic"), QString("auto"));
2707         fontModule->fontsMathCO->addItem(qt_("Class Default"), QString("default"));
2708         QMap<QString, QString>::const_iterator mmi = mathfonts_.constBegin();
2709         while (mmi != mathfonts_.constEnd()) {
2710                 fontModule->fontsMathCO->addItem(mmi.key(), mmi.value());
2711                 ++mmi;
2712         }
2713 }
2714
2715
2716 void GuiDocument::fontencChanged(int item)
2717 {
2718         fontModule->fontencLE->setEnabled(
2719                 fontModule->fontencCO->itemData(item).toString() == "custom");
2720         // The availability of TeX fonts depends on the font encoding
2721         updateTexFonts();
2722         updateFontOptions();
2723 }
2724
2725
2726 void GuiDocument::updateMathFonts(QString const & rm)
2727 {
2728         if (fontModule->osFontsCB->isChecked())
2729                 return;
2730         QString const math =
2731                 fontModule->fontsMathCO->itemData(fontModule->fontsMathCO->currentIndex()).toString();
2732         int const i = fontModule->fontsMathCO->findData("default");
2733         if (providesNoMath(rm) && i == -1)
2734                 fontModule->fontsMathCO->insertItem(1, qt_("Class Default"), QString("default"));
2735         else if (!providesNoMath(rm) && i != -1) {
2736                 int const c = fontModule->fontsMathCO->currentIndex();
2737                 fontModule->fontsMathCO->removeItem(i);
2738                 if (c == i)
2739                         fontModule->fontsMathCO->setCurrentIndex(0);
2740         }
2741 }
2742
2743
2744 void GuiDocument::romanChanged(int item)
2745 {
2746         if (fontModule->osFontsCB->isChecked())
2747                 return;
2748         QString const font =
2749                 fontModule->fontsRomanCO->itemData(item).toString();
2750         fontModule->fontScCB->setEnabled(providesSC(font));
2751         fontModule->fontOsfCB->setEnabled(providesOSF(font));
2752         updateExtraOpts();
2753         updateMathFonts(font);
2754 }
2755
2756
2757 void GuiDocument::sansChanged(int item)
2758 {
2759         if (fontModule->osFontsCB->isChecked())
2760                 return;
2761         QString const font =
2762                 fontModule->fontsSansCO->itemData(item).toString();
2763         bool const scalable = providesScale(font);
2764         fontModule->scaleSansSB->setEnabled(scalable);
2765         fontModule->scaleSansLA->setEnabled(scalable);
2766         fontModule->fontSansOsfCB->setEnabled(providesOSF(font));
2767         updateExtraOpts();
2768 }
2769
2770
2771 void GuiDocument::ttChanged(int item)
2772 {
2773         if (fontModule->osFontsCB->isChecked())
2774                 return;
2775         QString const font =
2776                 fontModule->fontsTypewriterCO->itemData(item).toString();
2777         bool scalable = providesScale(font);
2778         fontModule->scaleTypewriterSB->setEnabled(scalable);
2779         fontModule->scaleTypewriterLA->setEnabled(scalable);
2780         fontModule->fontTypewriterOsfCB->setEnabled(providesOSF(font));
2781         updateExtraOpts();
2782 }
2783
2784
2785 void GuiDocument::updatePagestyle(string const & items, string const & sel)
2786 {
2787         pagestyles.clear();
2788         pageLayoutModule->pagestyleCO->clear();
2789         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
2790
2791         for (int n = 0; !token(items, '|', n).empty(); ++n) {
2792                 string style = token(items, '|', n);
2793                 QString style_gui = qt_(style);
2794                 pagestyles.push_back(pair<string, QString>(style, style_gui));
2795                 pageLayoutModule->pagestyleCO->addItem(style_gui);
2796         }
2797
2798         if (sel == "default") {
2799                 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
2800                 return;
2801         }
2802
2803         int nn = 0;
2804
2805         for (auto const & pagestyle : pagestyles)
2806                 if (pagestyle.first == sel)
2807                         nn = pageLayoutModule->pagestyleCO->findText(pagestyle.second);
2808
2809         if (nn > 0)
2810                 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
2811 }
2812
2813
2814 void GuiDocument::browseLayout()
2815 {
2816         QString const label1 = qt_("Lay&outs");
2817         QString const dir1 = toqstr(lyxrc.document_path);
2818         QStringList const filter(qt_("LyX Layout (*.layout)"));
2819         QString file = browseRelToParent(QString(), bufferFilePath(),
2820                 qt_("Local layout file"), filter, false,
2821                 label1, dir1);
2822
2823         if (!file.endsWith(".layout"))
2824                 return;
2825
2826         FileName layoutFile = support::makeAbsPath(fromqstr(file),
2827                 fromqstr(bufferFilePath()));
2828
2829         int const ret = Alert::prompt(_("Local layout file"),
2830                 _("The layout file you have selected is a local layout\n"
2831                   "file, not one in the system or user directory.\n"
2832                   "Your document will not work with this layout if you\n"
2833                   "move the layout file to a different directory."),
2834                   1, 1, _("&Set Layout"), _("&Cancel"));
2835         if (ret == 1)
2836                 return;
2837
2838         // load the layout file
2839         LayoutFileList & bcl = LayoutFileList::get();
2840         string classname = layoutFile.onlyFileName();
2841         // this will update an existing layout if that layout has been loaded before.
2842         LayoutFileIndex name = support::onlyFileName(bcl.addLocalLayout(
2843                 classname.substr(0, classname.size() - 7),
2844                 layoutFile.onlyPath().absFileName()));
2845
2846         if (name.empty()) {
2847                 Alert::error(_("Error"),
2848                         _("Unable to read local layout file."));
2849                 return;
2850         }
2851
2852         const_cast<Buffer &>(buffer()).setLayoutPos(layoutFile.onlyPath().absFileName());
2853
2854         // do not trigger classChanged if there is no change.
2855         if (latexModule->classCO->currentText() == toqstr(name))
2856                 return;
2857
2858         // add to combo box
2859         bool const avail = latexModule->classCO->set(toqstr(name));
2860         if (!avail) {
2861                 LayoutFile const & tc = bcl[name];
2862                 docstring const guiname = translateIfPossible(from_utf8(tc.description()));
2863                 // tooltip sensu "KOMA-Script Article [Class 'scrartcl']"
2864                 QString tooltip = toqstr(bformat(_("%1$s [Class '%2$s']"), guiname, from_utf8(tc.latexname())));
2865                 tooltip += '\n' + qt_("This is a local layout file.");
2866                 latexModule->classCO->addItemSort(toqstr(tc.name()), toqstr(guiname),
2867                                                   toqstr(translateIfPossible(from_utf8(tc.category()))),
2868                                                   tooltip,
2869                                                   true, true, true, true);
2870                 latexModule->classCO->set(toqstr(name));
2871         }
2872
2873         classChanged();
2874 }
2875
2876
2877 void GuiDocument::browseMaster()
2878 {
2879         QString const title = qt_("Select master document");
2880         QString const dir1 = toqstr(lyxrc.document_path);
2881         QString const old = latexModule->childDocLE->text();
2882         QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
2883         QStringList const filter(qt_("LyX Files (*.lyx)"));
2884         QString file = browseRelToSub(old, docpath, title, filter, false,
2885                 qt_("D&ocuments"), toqstr(lyxrc.document_path));
2886
2887         if (!file.isEmpty())
2888                 latexModule->childDocLE->setText(file);
2889 }
2890
2891
2892 void GuiDocument::classChanged_adaptor()
2893 {
2894         const_cast<Buffer &>(buffer()).setLayoutPos(string());
2895         classChanged();
2896 }
2897
2898
2899 void GuiDocument::classChanged()
2900 {
2901         int idx = latexModule->classCO->currentIndex();
2902         if (idx < 0)
2903                 return;
2904         string const classname = fromqstr(latexModule->classCO->getData(idx));
2905
2906         if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
2907                 int const ret = Alert::prompt(_("Unapplied changes"),
2908                                 _("Some changes in the dialog were not yet applied.\n"
2909                                 "If you do not apply now, they will be lost after this action."),
2910                                 1, 1, _("&Apply"), _("&Dismiss"));
2911                 if (ret == 0)
2912                         applyView();
2913         }
2914
2915         // We load the TextClass as soon as it is selected. This is
2916         // necessary so that other options in the dialog can be updated
2917         // according to the new class. Note, however, that, if you use
2918         // the scroll wheel when sitting on the combo box, we'll load a
2919         // lot of TextClass objects very quickly....
2920         if (!bp_.setBaseClass(classname, buffer().layoutPos())) {
2921                 Alert::error(_("Error"), _("Unable to set document class."));
2922                 return;
2923         }
2924         if (lyxrc.auto_reset_options)
2925                 bp_.useClassDefaults();
2926
2927         // With the introduction of modules came a distinction between the base
2928         // class and the document class. The former corresponds to the main layout
2929         // file; the latter is that plus the modules (or the document-specific layout,
2930         // or  whatever else there could be). Our parameters come from the document
2931         // class. So when we set the base class, we also need to recreate the document
2932         // class. Otherwise, we still have the old one.
2933         bp_.makeDocumentClass();
2934         paramsToDialog();
2935 }
2936
2937
2938 void GuiDocument::languagePackageChanged(int i)
2939 {
2940          langModule->languagePackageLE->setEnabled(
2941                 langModule->languagePackageCO->itemData(i).toString() == "custom");
2942 }
2943
2944
2945 void GuiDocument::biblioChanged()
2946 {
2947         biblioChanged_ = true;
2948         change_adaptor();
2949 }
2950
2951
2952 void GuiDocument::checkPossibleCiteEngines()
2953 {
2954         // Check if the class provides a specific engine,
2955         // and if so, enforce this.
2956         string force_engine;
2957         if (documentClass().provides("natbib")
2958             || documentClass().provides("natbib-internal"))
2959                 force_engine = "natbib";
2960         else if (documentClass().provides("jurabib"))
2961                 force_engine = "jurabib";
2962         else if (documentClass().provides("biblatex"))
2963                 force_engine = "biblatex";
2964         else if (documentClass().provides("biblatex-natbib"))
2965                 force_engine = "biblatex-natbib";
2966
2967         if (!force_engine.empty())
2968                 biblioModule->citeEngineCO->setCurrentIndex(
2969                         biblioModule->citeEngineCO->findData(toqstr(force_engine)));
2970         biblioModule->citeEngineCO->setEnabled(force_engine.empty());
2971 }
2972
2973
2974 void GuiDocument::rescanBibFiles()
2975 {
2976         if (isBiblatex())
2977                 rescanTexStyles("bbx cbx");
2978         else
2979                 rescanTexStyles("bst");
2980 }
2981
2982
2983 void GuiDocument::resetDefaultBibfile(string const & which)
2984 {
2985         QString const engine =
2986                 biblioModule->citeEngineCO->itemData(
2987                                 biblioModule->citeEngineCO->currentIndex()).toString();
2988
2989         CiteEngineType const cet =
2990                 CiteEngineType(biblioModule->citeStyleCO->itemData(
2991                                                           biblioModule->citeStyleCO->currentIndex()).toInt());
2992
2993         updateDefaultBiblio(theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet), which);
2994 }
2995
2996
2997 void GuiDocument::resetDefaultBbxBibfile()
2998 {
2999         resetDefaultBibfile("bbx");
3000 }
3001
3002
3003 void GuiDocument::resetDefaultCbxBibfile()
3004 {
3005         resetDefaultBibfile("cbx");
3006 }
3007
3008
3009 void GuiDocument::citeEngineChanged(int n)
3010 {
3011         QString const engine =
3012                 biblioModule->citeEngineCO->itemData(n).toString();
3013
3014         vector<string> const engs =
3015                 theCiteEnginesList[fromqstr(engine)]->getEngineType();
3016
3017         updateCiteStyles(engs);
3018         updateEngineDependends();
3019         resetDefaultBibfile();
3020         biblioChanged();
3021 }
3022
3023
3024 void GuiDocument::updateEngineDependends()
3025 {
3026         bool const biblatex = isBiblatex();
3027
3028         // These are only useful with BibTeX
3029         biblioModule->defaultBiblioCO->setEnabled(!biblatex);
3030         biblioModule->bibtexStyleLA->setEnabled(!biblatex);
3031         biblioModule->resetDefaultBiblioPB->setEnabled(!biblatex);
3032         biblioModule->bibtopicCB->setEnabled(!biblatex);
3033
3034         // These are only useful with Biblatex
3035         biblioModule->biblatexBbxCO->setEnabled(biblatex);
3036         biblioModule->biblatexBbxLA->setEnabled(biblatex);
3037         biblioModule->biblatexCbxCO->setEnabled(biblatex);
3038         biblioModule->biblatexCbxLA->setEnabled(biblatex);
3039         biblioModule->resetBbxPB->setEnabled(biblatex);
3040         biblioModule->resetCbxPB->setEnabled(biblatex);
3041         biblioModule->matchBbxPB->setEnabled(biblatex);
3042
3043         // These are useful with biblatex, jurabib and natbib
3044         QString const engine =
3045                 biblioModule->citeEngineCO->itemData(
3046                                 biblioModule->citeEngineCO->currentIndex()).toString();
3047         LyXCiteEngine const * ce = theCiteEnginesList[fromqstr(engine)];
3048
3049         bool const citepack = ce->required("biblatex.sty") || ce->required("jurabib.sty")
3050                         || ce->required("natbib.sty");
3051         biblioModule->citePackageOptionsLE->setEnabled(citepack);
3052         biblioModule->citePackageOptionsL->setEnabled(citepack);
3053 }
3054
3055
3056 void GuiDocument::citeStyleChanged()
3057 {
3058         QString const engine =
3059                 biblioModule->citeEngineCO->itemData(
3060                                 biblioModule->citeEngineCO->currentIndex()).toString();
3061         QString const currentDef = isBiblatex() ?
3062                 biblioModule->biblatexBbxCO->currentText()
3063                 : biblioModule->defaultBiblioCO->currentText();
3064         if (theCiteEnginesList[fromqstr(engine)]->isDefaultBiblio(fromqstr(currentDef)))
3065                 resetDefaultBibfile();
3066
3067         biblioChanged();
3068 }
3069
3070
3071 void GuiDocument::bibtexChanged(int n)
3072 {
3073         biblioModule->bibtexOptionsLE->setEnabled(
3074                 biblioModule->bibtexCO->itemData(n).toString() != "default");
3075         biblioChanged();
3076 }
3077
3078
3079 void GuiDocument::updateCiteStyles(vector<string> const & engs, CiteEngineType const & sel)
3080 {
3081         biblioModule->citeStyleCO->clear();
3082
3083         vector<string>::const_iterator it  = engs.begin();
3084         vector<string>::const_iterator end = engs.end();
3085         for (; it != end; ++it) {
3086                 if (*it == "default")
3087                         biblioModule->citeStyleCO->addItem(qt_("Basic numerical"),
3088                                                            ENGINE_TYPE_DEFAULT);
3089                 else if (*it == "authoryear")
3090                         biblioModule->citeStyleCO->addItem(qt_("Author-year"),
3091                                                            ENGINE_TYPE_AUTHORYEAR);
3092                 else if (*it == "numerical")
3093                         biblioModule->citeStyleCO->addItem(qt_("Author-number"),
3094                                                            ENGINE_TYPE_NUMERICAL);
3095         }
3096         int i = biblioModule->citeStyleCO->findData(sel);
3097         if (biblioModule->citeStyleCO->findData(sel) == -1)
3098                 i = 0;
3099         biblioModule->citeStyleCO->setCurrentIndex(i);
3100
3101         biblioModule->citationStyleL->setEnabled(engs.size() > 1);
3102         biblioModule->citeStyleCO->setEnabled(engs.size() > 1);
3103 }
3104
3105
3106 void GuiDocument::updateEngineType(string const & items, CiteEngineType const & sel)
3107 {
3108         engine_types_.clear();
3109
3110         int nn = 0;
3111
3112         for (int n = 0; !token(items, '|', n).empty(); ++n) {
3113                 nn += 1;
3114                 string style = token(items, '|', n);
3115                 engine_types_.push_back(style);
3116         }
3117
3118         updateCiteStyles(engine_types_, sel);
3119 }
3120
3121
3122 namespace {
3123         // FIXME unicode
3124         // both of these should take a vector<docstring>
3125
3126         // This is an insanely complicated attempt to make this sort of thing
3127         // work with RTL languages.
3128         docstring formatStrVec(vector<string> const & v, docstring const & s)
3129         {
3130                 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
3131                 if (v.empty())
3132                         return docstring();
3133                 if (v.size() == 1)
3134                         return translateIfPossible(from_utf8(v[0]));
3135                 if (v.size() == 2) {
3136                         docstring retval = _("%1$s and %2$s");
3137                         retval = subst(retval, _("and"), s);
3138                         return bformat(retval, translateIfPossible(from_utf8(v[0])),
3139                                        translateIfPossible(from_utf8(v[1])));
3140                 }
3141                 // The idea here is to format all but the last two items...
3142                 int const vSize = v.size();
3143                 docstring t2 = _("%1$s, %2$s");
3144                 docstring retval = translateIfPossible(from_utf8(v[0]));
3145                 for (int i = 1; i < vSize - 2; ++i)
3146                         retval = bformat(t2, retval, translateIfPossible(from_utf8(v[i])));
3147                 //...and then to  plug them, and the last two, into this schema
3148                 docstring t = _("%1$s, %2$s, and %3$s");
3149                 t = subst(t, _("and"), s);
3150                 return bformat(t, retval, translateIfPossible(from_utf8(v[vSize - 2])),
3151                                translateIfPossible(from_utf8(v[vSize - 1])));
3152         }
3153
3154         vector<string> idsToNames(vector<string> const & idList)
3155         {
3156                 vector<string> retval;
3157                 vector<string>::const_iterator it  = idList.begin();
3158                 vector<string>::const_iterator end = idList.end();
3159                 for (; it != end; ++it) {
3160                         LyXModule const * const mod = theModuleList[*it];
3161                         if (!mod)
3162                                 retval.push_back(to_utf8(bformat(_("%1$s (unavailable)"),
3163                                                 translateIfPossible(from_utf8(*it)))));
3164                         else
3165                                 retval.push_back(mod->getName());
3166                 }
3167                 return retval;
3168         }
3169 } // end anonymous namespace
3170
3171
3172 void GuiDocument::modulesToParams(BufferParams & bp)
3173 {
3174         // update list of loaded modules
3175         bp.clearLayoutModules();
3176         int const srows = modules_sel_model_.rowCount();
3177         for (int i = 0; i < srows; ++i)
3178                 bp.addLayoutModule(modules_sel_model_.getIDString(i));
3179         updateSelectedModules();
3180
3181         // update the list of removed modules
3182         bp.clearRemovedModules();
3183         LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
3184         list<string>::const_iterator rit = reqmods.begin();
3185         list<string>::const_iterator ren = reqmods.end();
3186
3187         // check each of the default modules
3188         for (; rit != ren; ++rit) {
3189                 list<string>::const_iterator mit = bp.getModules().begin();
3190                 list<string>::const_iterator men = bp.getModules().end();
3191                 bool found = false;
3192                 for (; mit != men; ++mit) {
3193                         if (*rit == *mit) {
3194                                 found = true;
3195                                 break;
3196                         }
3197                 }
3198                 if (!found) {
3199                         // the module isn't present so must have been removed by the user
3200                         bp.addRemovedModule(*rit);
3201                 }
3202         }
3203 }
3204
3205 void GuiDocument::modulesChanged()
3206 {
3207         modulesToParams(bp_);
3208
3209         if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()
3210             && (nonModuleChanged_ || shellescapeChanged_)) {
3211                 int const ret = Alert::prompt(_("Unapplied changes"),
3212                                 _("Some changes in the dialog were not yet applied.\n"
3213                                 "If you do not apply now, they will be lost after this action."),
3214                                 1, 1, _("&Apply"), _("&Dismiss"));
3215                 if (ret == 0)
3216                         applyView();
3217         }
3218
3219         modulesChanged_ = true;
3220         bp_.makeDocumentClass();
3221         paramsToDialog();
3222         changed();
3223 }
3224
3225
3226 void GuiDocument::updateModuleInfo()
3227 {
3228         selectionManager->update();
3229
3230         //Module description
3231         bool const focus_on_selected = selectionManager->selectedFocused();
3232         QAbstractItemView * lv;
3233         bool category = false;
3234         if (focus_on_selected) {
3235                 lv = modulesModule->selectedLV;
3236                 category = true;
3237         } else
3238                 lv = modulesModule->availableLV;
3239         if (lv->selectionModel()->selectedIndexes().isEmpty()) {
3240                 modulesModule->infoML->document()->clear();
3241                 return;
3242         }
3243         QModelIndex const & idx = lv->selectionModel()->currentIndex();
3244
3245         if (!focus_on_selected
3246             && modules_av_model_.itemFromIndex(idx)->hasChildren()) {
3247                 // This is a category header
3248                 modulesModule->infoML->document()->clear();
3249                 return;
3250         }
3251
3252         string const modName = focus_on_selected ?
3253                                 modules_sel_model_.getIDString(idx.row())
3254                               : fromqstr(modules_av_model_.data(idx, Qt::UserRole).toString());
3255         docstring desc = getModuleDescription(modName);
3256
3257         LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
3258         if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
3259                 if (!desc.empty())
3260                         desc += "\n";
3261                 desc += _("Module provided by document class.");
3262         }
3263
3264         if (category) {
3265                 docstring cat = getModuleCategory(modName);
3266                 if (!cat.empty()) {
3267                         if (!desc.empty())
3268                                 desc += "\n";
3269                         desc += bformat(_("<p><b>Category:</b> %1$s.</p>"),
3270                                         translateIfPossible(cat));
3271                 }
3272         }
3273
3274         vector<string> pkglist = getPackageList(modName);
3275         docstring pkgdesc = formatStrVec(pkglist, _("and"));
3276         if (!pkgdesc.empty()) {
3277                 if (!desc.empty())
3278                         desc += "\n";
3279                 desc += bformat(_("<p><b>Package(s) required:</b> %1$s.</p>"), pkgdesc);
3280         }
3281
3282         pkglist = getRequiredList(modName);
3283         if (!pkglist.empty()) {
3284                 vector<string> const reqdescs = idsToNames(pkglist);
3285                 pkgdesc = formatStrVec(reqdescs, _("or"));
3286                 if (!desc.empty())
3287                         desc += "\n";
3288                 desc += bformat(_("<p><b>Modules required:</b> %1$s.</p>"), pkgdesc);
3289         }
3290
3291         pkglist = getExcludedList(modName);
3292         if (!pkglist.empty()) {
3293                 vector<string> const reqdescs = idsToNames(pkglist);
3294                 pkgdesc = formatStrVec(reqdescs, _( "and"));
3295                 if (!desc.empty())
3296                         desc += "\n";
3297                 desc += bformat(_("<p><b>Modules excluded:</b> %1$s.</p>"), pkgdesc);
3298         }
3299
3300         if (!desc.empty())
3301                 desc += "\n";
3302         desc += bformat(_("<p><b>Filename:</b> <tt>%1$s.module</tt>.</p>"), from_utf8(modName));
3303
3304         if (!isModuleAvailable(modName)) {
3305                 if (!desc.empty())
3306                         desc += "\n";
3307                 desc += _("<p><font color=red><b>WARNING: Some required packages are unavailable!</b></font></p>");
3308         }
3309
3310         modulesModule->infoML->document()->setHtml(toqstr(desc));
3311 }
3312
3313
3314 void GuiDocument::updateNumbering()
3315 {
3316         DocumentClass const & tclass = documentClass();
3317
3318         numberingModule->tocTW->setUpdatesEnabled(false);
3319         numberingModule->tocTW->clear();
3320
3321         int const depth = numberingModule->depthSL->value();
3322         int const toc = numberingModule->tocSL->value();
3323         QString const no = qt_("No");
3324         QString const yes = qt_("Yes");
3325         QTreeWidgetItem * item = nullptr;
3326
3327         DocumentClass::const_iterator lit = tclass.begin();
3328         DocumentClass::const_iterator len = tclass.end();
3329         for (; lit != len; ++lit) {
3330                 int const toclevel = lit->toclevel;
3331                 if (toclevel != Layout::NOT_IN_TOC && !lit->counter.empty()) {
3332                         item = new QTreeWidgetItem(numberingModule->tocTW);
3333                         item->setText(0, toqstr(translateIfPossible(lit->name())));
3334                         item->setText(1, (toclevel <= depth) ? yes : no);
3335                         item->setText(2, (toclevel <= toc) ? yes : no);
3336                 }
3337         }
3338
3339         numberingModule->tocTW->setUpdatesEnabled(true);
3340         numberingModule->tocTW->update();
3341 }
3342
3343
3344 void GuiDocument::getTableStyles()
3345 {
3346         // We look for lyx files in the subdirectory dir of
3347         //   1) user_lyxdir
3348         //   2) build_lyxdir (if not empty)
3349         //   3) system_lyxdir
3350         // in this order. Files with a given sub-hierarchy will
3351         // only be listed once.
3352         // We also consider i18n subdirectories and store them separately.
3353         QStringList dirs;
3354
3355         // The three locations to look at.
3356         string const user = addPath(package().user_support().absFileName(), "tabletemplates");
3357         string const build = addPath(package().build_support().absFileName(), "tabletemplates");
3358         string const system = addPath(package().system_support().absFileName(), "tabletemplates");
3359
3360         dirs << toqstr(user)
3361              << toqstr(build)
3362              << toqstr(system);
3363
3364         for (int i = 0; i < dirs.size(); ++i) {
3365                 QString const & dir = dirs.at(i);
3366                 QDirIterator it(dir, QDir::Files, QDirIterator::Subdirectories);
3367                 while (it.hasNext()) {
3368                         QString fn = QFileInfo(it.next()).fileName();
3369                         if (!fn.endsWith(".lyx") || fn.contains("_1x"))
3370                                 continue;
3371                         QString data = fn.left(fn.lastIndexOf(".lyx"));
3372                         QString guiname = data;
3373                         guiname = toqstr(translateIfPossible(qstring_to_ucs4(guiname.replace('_', ' '))));
3374                         QString relpath = toqstr(makeRelPath(qstring_to_ucs4(fn),
3375                                                              qstring_to_ucs4(dir)));
3376                         if (textLayoutModule->tableStyleCO->findData(data) == -1)
3377                                 textLayoutModule->tableStyleCO->addItem(guiname, data);
3378                 }
3379         }
3380 }
3381
3382
3383 void GuiDocument::updateDefaultFormat()
3384 {
3385         if (!bufferview())
3386                 return;
3387         // make a copy in order to consider unapplied changes
3388         BufferParams param_copy = buffer().params();
3389         param_copy.useNonTeXFonts = fontModule->osFontsCB->isChecked();
3390         int const idx = latexModule->classCO->currentIndex();
3391         if (idx >= 0) {
3392                 string const classname = fromqstr(latexModule->classCO->getData(idx));
3393                 param_copy.setBaseClass(classname, buffer().layoutPos());
3394                 param_copy.makeDocumentClass(true);
3395         }
3396         outputModule->defaultFormatCO->blockSignals(true);
3397         outputModule->defaultFormatCO->clear();
3398         outputModule->defaultFormatCO->addItem(qt_("Default"),
3399                                 QVariant(QString("default")));
3400         FormatList const & formats =
3401                                 param_copy.exportableFormats(true);
3402         for (Format const * f : formats)
3403                 outputModule->defaultFormatCO->addItem
3404                         (toqstr(translateIfPossible(f->prettyname())),
3405                          QVariant(toqstr(f->name())));
3406         outputModule->defaultFormatCO->blockSignals(false);
3407 }
3408
3409
3410 bool GuiDocument::isChildIncluded(string const & child)
3411 {
3412         if (includeonlys_.empty())
3413                 return false;
3414         return (std::find(includeonlys_.begin(),
3415                           includeonlys_.end(), child) != includeonlys_.end());
3416 }
3417
3418
3419 void GuiDocument::applyView()
3420 {
3421         // preamble
3422         preambleModule->apply(bp_);
3423         localLayout->apply(bp_);
3424
3425         // date
3426         bp_.suppress_date = latexModule->suppressDateCB->isChecked();
3427         bp_.use_refstyle  = latexModule->refstyleCB->isChecked();
3428
3429         // biblio
3430         string const engine =
3431                 fromqstr(biblioModule->citeEngineCO->itemData(
3432                                 biblioModule->citeEngineCO->currentIndex()).toString());
3433         bp_.setCiteEngine(engine);
3434
3435         CiteEngineType const style = CiteEngineType(biblioModule->citeStyleCO->itemData(
3436                 biblioModule->citeStyleCO->currentIndex()).toInt());
3437         if (theCiteEnginesList[engine]->hasEngineType(style))
3438                 bp_.setCiteEngineType(style);
3439         else
3440                 bp_.setCiteEngineType(ENGINE_TYPE_DEFAULT);
3441
3442         bp_.splitbib(biblioModule->bibtopicCB->isChecked());
3443
3444         bp_.multibib = fromqstr(biblioModule->bibunitsCO->itemData(
3445                                 biblioModule->bibunitsCO->currentIndex()).toString());
3446
3447         bp_.setDefaultBiblioStyle(fromqstr(biblioModule->defaultBiblioCO->currentText()));
3448
3449         bp_.biblatex_bibstyle = fromqstr(biblioModule->biblatexBbxCO->currentText());
3450         bp_.biblatex_citestyle = fromqstr(biblioModule->biblatexCbxCO->currentText());
3451         bp_.biblio_opts = fromqstr(biblioModule->citePackageOptionsLE->text());
3452
3453         string const bibtex_command =
3454                 fromqstr(biblioModule->bibtexCO->itemData(
3455                         biblioModule->bibtexCO->currentIndex()).toString());
3456         string const bibtex_options =
3457                 fromqstr(biblioModule->bibtexOptionsLE->text());
3458         if (bibtex_command == "default" || bibtex_options.empty())
3459                 bp_.bibtex_command = bibtex_command;
3460         else
3461                 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
3462
3463         if (biblioChanged_) {
3464                 buffer().invalidateBibinfoCache();
3465                 buffer().removeBiblioTempFiles();
3466         }
3467
3468         // Indices
3469         indicesModule->apply(bp_);
3470
3471         // language & quotes
3472         switch (langModule->encodingCO->currentIndex()) {
3473                 case EncodingSets::unicode: {
3474                         if (!fontModule->osFontsCB->isChecked())
3475                                 bp_.inputenc = fromqstr(langModule->unicodeEncodingCO->itemData(
3476                                         langModule->unicodeEncodingCO->currentIndex()).toString());
3477                         break;
3478                 }
3479                 case EncodingSets::legacy: {
3480                         bp_.inputenc = "auto-legacy";
3481                         bp_.inputenc = fromqstr(langModule->autoEncodingCO->itemData(
3482                                 langModule->autoEncodingCO->currentIndex()).toString());
3483                         break;
3484                 }
3485                 case EncodingSets::custom: {
3486                         bp_.inputenc = fromqstr(langModule->customEncodingCO->itemData(
3487                                 langModule->customEncodingCO->currentIndex()).toString());
3488                         break;
3489                 }
3490                 default:
3491                         // this should never happen
3492                         bp_.inputenc = "utf8";
3493         }
3494         bp_.quotes_style = QuoteStyle(langModule->quoteStyleCO->itemData(
3495                 langModule->quoteStyleCO->currentIndex()).toInt());
3496         bp_.dynamic_quotes = langModule->dynamicQuotesCB->isChecked();
3497
3498         QString const langname = langModule->languageCO->itemData(
3499                 langModule->languageCO->currentIndex()).toString();
3500         Language const * newlang = lyx::languages.getLanguage(fromqstr(langname));
3501         Cursor & cur = const_cast<BufferView *>(bufferview())->cursor();
3502         // If current cursor language was the document language, then update it too.
3503         if (cur.current_font.language() == bp_.language) {
3504                 cur.current_font.setLanguage(newlang);
3505                 cur.real_current_font.setLanguage(newlang);
3506         }
3507         bp_.language = newlang;
3508
3509         QString const pack = langModule->languagePackageCO->itemData(
3510                 langModule->languagePackageCO->currentIndex()).toString();
3511         if (pack == "custom")
3512                 bp_.lang_package =
3513                         fromqstr(langModule->languagePackageLE->text());
3514         else
3515                 bp_.lang_package = fromqstr(pack);
3516
3517         //color
3518         bp_.backgroundcolor = set_backgroundcolor;
3519         bp_.isbackgroundcolor = is_backgroundcolor;
3520         bp_.fontcolor = set_fontcolor;
3521         bp_.isfontcolor = is_fontcolor;
3522         bp_.notefontcolor = set_notefontcolor;
3523         bp_.isnotefontcolor = is_notefontcolor;
3524         if (is_notefontcolor) {
3525                 // Set information used in statusbar (#12130)
3526                 lcolor.setColor("notefontcolor", lyx::X11hexname(set_notefontcolor));
3527                 lcolor.setGUIName("notefontcolor", N_("greyedout inset text"));
3528         }
3529         bp_.boxbgcolor = set_boxbgcolor;
3530         bp_.isboxbgcolor = is_boxbgcolor;
3531
3532         // numbering
3533         if (bp_.documentClass().hasTocLevels()) {
3534                 bp_.tocdepth = numberingModule->tocSL->value();
3535                 bp_.secnumdepth = numberingModule->depthSL->value();
3536         }
3537         bp_.use_lineno = numberingModule->linenoCB->isChecked();
3538         bp_.lineno_opts = fromqstr(numberingModule->linenoLE->text());
3539
3540         // bullets
3541         bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
3542         bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
3543         bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
3544         bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
3545
3546         // packages
3547         bp_.graphics_driver =
3548                 tex_graphics[latexModule->psdriverCO->currentIndex()];
3549
3550         // text layout
3551         int idx = latexModule->classCO->currentIndex();
3552         if (idx >= 0) {
3553                 string const classname = fromqstr(latexModule->classCO->getData(idx));
3554                 bp_.setBaseClass(classname, buffer().layoutPos());
3555         }
3556
3557         // Modules
3558         modulesToParams(bp_);
3559
3560         // Math
3561         map<string, string> const & packages = BufferParams::auto_packages();
3562         for (map<string, string>::const_iterator it = packages.begin();
3563              it != packages.end(); ++it) {
3564                 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
3565                 if (!item)
3566                         continue;
3567                 int row = mathsModule->packagesTW->row(item);
3568
3569                 QRadioButton * rb =
3570                         (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1)->layout()->itemAt(0)->widget();
3571                 if (rb->isChecked()) {
3572                         bp_.use_package(it->first, BufferParams::package_auto);
3573                         continue;
3574                 }
3575                 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2)->layout()->itemAt(0)->widget();
3576                 if (rb->isChecked()) {
3577                         bp_.use_package(it->first, BufferParams::package_on);
3578                         continue;
3579                 }
3580                 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3)->layout()->itemAt(0)->widget();
3581                 if (rb->isChecked())
3582                         bp_.use_package(it->first, BufferParams::package_off);
3583         }
3584         // if math is indented
3585         bp_.is_math_indent = mathsModule->MathIndentCB->isChecked();
3586         if (bp_.is_math_indent) {
3587                 // if formulas are indented
3588                 switch (mathsModule->MathIndentCO->currentIndex()) {
3589                 case 0:
3590                         bp_.setMathIndent(Length());
3591                         break;
3592                 case 1: {
3593                         Length mathindent(widgetsToLength(mathsModule->MathIndentLE,
3594                                                           mathsModule->MathIndentLengthCO));
3595                         bp_.setMathIndent(mathindent);
3596                         break;
3597                 }
3598                 default:
3599                         // this should never happen
3600                         bp_.setMathIndent(Length());
3601                         break;
3602                 }
3603         }
3604         switch (mathsModule->MathNumberingPosCO->currentIndex()) {
3605                 case 0:
3606                         bp_.math_numbering_side = BufferParams::LEFT;
3607                         break;
3608                 case 1:
3609                         bp_.math_numbering_side = BufferParams::DEFAULT;
3610                         break;
3611                 case 2:
3612                         bp_.math_numbering_side = BufferParams::RIGHT;
3613                         break;
3614                 default:
3615                         // this should never happen
3616                         bp_.math_numbering_side = BufferParams::DEFAULT;
3617                         break;
3618         }
3619
3620         // Page Layout
3621         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
3622                 bp_.pagestyle = "default";
3623         else {
3624                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
3625                 for (size_t i = 0; i != pagestyles.size(); ++i)
3626                         if (pagestyles[i].second == style_gui)
3627                                 bp_.pagestyle = pagestyles[i].first;
3628         }
3629
3630         // Text Layout
3631         switch (textLayoutModule->lspacingCO->currentIndex()) {
3632         case 0:
3633                 bp_.spacing().set(Spacing::Single);
3634                 break;
3635         case 1:
3636                 bp_.spacing().set(Spacing::Onehalf);
3637                 break;
3638         case 2:
3639                 bp_.spacing().set(Spacing::Double);
3640                 break;
3641         case 3: {
3642                 string s = widgetToDoubleStr(textLayoutModule->lspacingLE);
3643                 if (s.empty())
3644                         bp_.spacing().set(Spacing::Single);
3645                 else
3646                         bp_.spacing().set(Spacing::Other, s);
3647                 break;
3648                 }
3649         }
3650
3651         if (textLayoutModule->twoColumnCB->isChecked())
3652                 bp_.columns = 2;
3653         else
3654                 bp_.columns = 1;
3655
3656         bp_.justification = textLayoutModule->justCB->isChecked();
3657
3658         if (textLayoutModule->indentRB->isChecked()) {
3659                 // if paragraphs are separated by an indentation
3660                 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
3661                 switch (textLayoutModule->indentCO->currentIndex()) {
3662                 case 0:
3663                         bp_.setParIndent(Length());
3664                         break;
3665                 case 1: {
3666                         Length parindent(widgetsToLength(textLayoutModule->indentLE,
3667                                                          textLayoutModule->indentLengthCO));
3668                         bp_.setParIndent(parindent);
3669                         break;
3670                 }
3671                 default:
3672                         // this should never happen
3673                         bp_.setParIndent(Length());
3674                         break;
3675                 }
3676         } else {
3677                 // if paragraphs are separated by a skip
3678                 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
3679                 VSpace::VSpaceKind spacekind =
3680                         VSpace::VSpaceKind(textLayoutModule->skipCO->itemData(textLayoutModule->skipCO->currentIndex()).toInt());
3681                 switch (spacekind) {
3682                 case VSpace::SMALLSKIP:
3683                 case VSpace::MEDSKIP:
3684                 case VSpace::BIGSKIP:
3685                 case VSpace::HALFLINE:
3686                 case VSpace::FULLLINE:
3687                         bp_.setDefSkip(VSpace(spacekind));
3688                         break;
3689                 case VSpace::LENGTH: {
3690                         VSpace vs = VSpace(
3691                                 widgetsToLength(textLayoutModule->skipLE,
3692                                 textLayoutModule->skipLengthCO)
3693                                 );
3694                         bp_.setDefSkip(vs);
3695                         break;
3696                 }
3697                 default:
3698                         // this should never happen
3699                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
3700                         break;
3701                 }
3702         }
3703         bp_.tablestyle = fromqstr(textLayoutModule->tableStyleCO->itemData(
3704                                       textLayoutModule->tableStyleCO->currentIndex()).toString());
3705
3706         bp_.options =
3707                 fromqstr(latexModule->optionsLE->text());
3708
3709         bp_.use_default_options =
3710                 latexModule->defaultOptionsCB->isChecked();
3711
3712         if (latexModule->childDocGB->isChecked())
3713                 bp_.master =
3714                         fromqstr(latexModule->childDocLE->text());
3715         else
3716                 bp_.master = string();
3717
3718         // Master/Child
3719         bp_.clearIncludedChildren();
3720         if (masterChildModule->includeonlyRB->isChecked()) {
3721                 list<string>::const_iterator it = includeonlys_.begin();
3722                 for (; it != includeonlys_.end() ; ++it) {
3723                         bp_.addIncludedChildren(*it);
3724                 }
3725         }
3726         if (masterChildModule->maintainCRNoneRB->isChecked())
3727                 bp_.maintain_unincluded_children =
3728                         BufferParams::CM_None;
3729         else if (masterChildModule->maintainCRMostlyRB->isChecked())
3730                 bp_.maintain_unincluded_children =
3731                         BufferParams::CM_Mostly;
3732         else
3733                 bp_.maintain_unincluded_children =
3734                         BufferParams::CM_Strict;
3735         updateIncludeonlyDisplay();
3736
3737         // Float Settings
3738         bp_.float_placement = floatModule->getPlacement();
3739         bp_.float_alignment = floatModule->getAlignment();
3740
3741         // Listings
3742         // text should have passed validation
3743         idx = listingsModule->packageCO->currentIndex();
3744         bp_.use_minted = string(lst_packages[idx]) == "Minted";
3745         bp_.listings_params =
3746                 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
3747
3748         // Formats
3749         bp_.default_output_format = fromqstr(outputModule->defaultFormatCO->itemData(
3750                 outputModule->defaultFormatCO->currentIndex()).toString());
3751
3752         bool const nontexfonts = fontModule->osFontsCB->isChecked();
3753         bp_.useNonTeXFonts = nontexfonts;
3754
3755         bp_.shell_escape = outputModule->shellescapeCB->isChecked();
3756         if (!bp_.shell_escape)
3757             theSession().shellescapeFiles().remove(buffer().absFileName());
3758         else if (!theSession().shellescapeFiles().find(buffer().absFileName()))
3759             theSession().shellescapeFiles().insert(buffer().absFileName());
3760         Buffer & buf = const_cast<Buffer &>(buffer());
3761         buf.params().shell_escape = bp_.shell_escape;
3762
3763         bp_.output_sync = outputModule->outputsyncCB->isChecked();
3764
3765         bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
3766
3767         int mathfmt = outputModule->mathoutCB->currentIndex();
3768         if (mathfmt == -1)
3769                 mathfmt = 0;
3770         BufferParams::MathOutput const mo =
3771                 static_cast<BufferParams::MathOutput>(mathfmt);
3772         bp_.html_math_output = mo;
3773         bp_.html_be_strict = outputModule->strictCB->isChecked();
3774         bp_.html_css_as_file = outputModule->cssCB->isChecked();
3775         bp_.html_math_img_scale = outputModule->mathimgSB->value();
3776         bp_.display_pixel_ratio = theGuiApp()->pixelRatio();
3777
3778         int tablefmt = outputModule->tableoutCB->currentIndex();
3779         if (tablefmt == -1)
3780                 tablefmt = 0;
3781         BufferParams::TableOutput const to =
3782                         static_cast<BufferParams::TableOutput>(tablefmt);
3783         bp_.docbook_table_output = to;
3784
3785         bp_.save_transient_properties =
3786                 outputModule->saveTransientPropertiesCB->isChecked();
3787         bp_.postpone_fragile_content =
3788                 outputModule->postponeFragileCB->isChecked();
3789
3790         // fonts
3791         bp_.fonts_roman[nontexfonts] =
3792                 fromqstr(fontModule->fontsRomanCO->
3793                         itemData(fontModule->fontsRomanCO->currentIndex()).toString());
3794         bp_.fonts_roman[!nontexfonts] = fromqstr(fontModule->font_roman);
3795         bp_.font_roman_opts = fromqstr(fontModule->fontspecRomanLE->text());
3796
3797         bp_.fonts_sans[nontexfonts] =
3798                 fromqstr(fontModule->fontsSansCO->
3799                         itemData(fontModule->fontsSansCO->currentIndex()).toString());
3800         bp_.fonts_sans[!nontexfonts] = fromqstr(fontModule->font_sans);
3801         bp_.font_sans_opts = fromqstr(fontModule->fontspecSansLE->text());
3802
3803         bp_.fonts_typewriter[nontexfonts] =
3804                 fromqstr(fontModule->fontsTypewriterCO->
3805                         itemData(fontModule->fontsTypewriterCO->currentIndex()).toString());
3806         bp_.fonts_typewriter[!nontexfonts] = fromqstr(fontModule->font_typewriter);
3807         bp_.font_typewriter_opts = fromqstr(fontModule->fontspecTypewriterLE->text());
3808
3809         bp_.fonts_math[nontexfonts] =
3810                 fromqstr(fontModule->fontsMathCO->
3811                         itemData(fontModule->fontsMathCO->currentIndex()).toString());
3812         bp_.fonts_math[!nontexfonts] = fromqstr(fontModule->font_math);
3813
3814         QString const fontenc =
3815                 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
3816         if (fontenc == "custom")
3817                 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
3818         else
3819                 bp_.fontenc = fromqstr(fontenc);
3820
3821         bp_.fonts_cjk =
3822                 fromqstr(fontModule->cjkFontLE->text());
3823
3824         bp_.use_microtype = fontModule->microtypeCB->isChecked();
3825         bp_.use_dash_ligatures = !fontModule->dashesCB->isChecked();
3826
3827         bp_.fonts_sans_scale[nontexfonts] = fontModule->scaleSansSB->value();
3828         bp_.fonts_sans_scale[!nontexfonts] = fontModule->font_sf_scale;
3829
3830         bp_.fonts_typewriter_scale[nontexfonts] = fontModule->scaleTypewriterSB->value();
3831         bp_.fonts_typewriter_scale[!nontexfonts] = fontModule->font_tt_scale;
3832
3833         bp_.fonts_expert_sc = fontModule->fontScCB->isChecked();
3834
3835         bp_.fonts_roman_osf = fontModule->fontOsfCB->isChecked();
3836         bp_.fonts_sans_osf = fontModule->fontSansOsfCB->isChecked();
3837         bp_.fonts_typewriter_osf = fontModule->fontTypewriterOsfCB->isChecked();
3838
3839         if (nontexfonts)
3840                 bp_.fonts_default_family = "default";
3841         else
3842                 bp_.fonts_default_family = GuiDocument::fontfamilies[
3843                         fontModule->fontsDefaultCO->currentIndex()];
3844
3845         if (fontModule->fontsizeCO->currentIndex() == 0)
3846                 bp_.fontsize = "default";
3847         else
3848                 bp_.fontsize =
3849                         fromqstr(fontModule->fontsizeCO->currentText());
3850
3851         // paper
3852         bp_.papersize = PAPER_SIZE(
3853                 pageLayoutModule->papersizeCO->currentIndex());
3854
3855         bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
3856                 pageLayoutModule->paperwidthUnitCO);
3857
3858         bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
3859                 pageLayoutModule->paperheightUnitCO);
3860
3861         if (pageLayoutModule->facingPagesCB->isChecked())
3862                 bp_.sides = TwoSides;
3863         else
3864                 bp_.sides = OneSide;
3865
3866         if (pageLayoutModule->landscapeRB->isChecked())
3867                 bp_.orientation = ORIENTATION_LANDSCAPE;
3868         else
3869                 bp_.orientation = ORIENTATION_PORTRAIT;
3870
3871         // margins
3872         bp_.use_geometry = !marginsModule->marginCB->isChecked();
3873
3874         Ui::MarginsUi const * m = marginsModule;
3875
3876         bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
3877         bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
3878         bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
3879         bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
3880         bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
3881         bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
3882         bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
3883         bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
3884
3885         // branches
3886         branchesModule->apply(bp_);
3887
3888         // PDF support
3889         PDFOptions & pdf = bp_.pdfoptions();
3890         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
3891         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
3892         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
3893         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
3894         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
3895
3896         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
3897         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
3898         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
3899         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
3900
3901         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
3902         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
3903         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
3904         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
3905         pdf.backref =
3906                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
3907         if (pdfSupportModule->fullscreenCB->isChecked())
3908                 pdf.pagemode = pdf.pagemode_fullscreen;
3909         else
3910                 pdf.pagemode.clear();
3911         pdf.quoted_options = pdf.quoted_options_check(
3912                                 fromqstr(pdfSupportModule->optionsLE->text()));
3913
3914         // change tracking
3915         bp_.track_changes = changesModule->trackChangesCB->isChecked();
3916         bp_.output_changes = changesModule->outputChangesCB->isChecked();
3917         bool const cb_switched_off = (bp_.change_bars
3918                                       && !changesModule->changeBarsCB->isChecked());
3919         bp_.change_bars = changesModule->changeBarsCB->isChecked();
3920         if (cb_switched_off)
3921                 // if change bars have been switched off,
3922                 // we need to ditch the aux file
3923                 buffer().requireFreshStart(true);
3924
3925         // reset trackers
3926         nonModuleChanged_ = false;
3927         shellescapeChanged_ = false;
3928 }
3929
3930
3931 void GuiDocument::paramsToDialog()
3932 {
3933         // set the default unit
3934         Length::UNIT const default_unit = Length::defaultUnit();
3935
3936         // preamble
3937         preambleModule->update(bp_, id());
3938         localLayout->update(bp_, id());
3939
3940         // date
3941         latexModule->suppressDateCB->setChecked(bp_.suppress_date);
3942         latexModule->refstyleCB->setChecked(bp_.use_refstyle);
3943
3944         // biblio
3945         string const cite_engine = bp_.citeEngine();
3946
3947         biblioModule->citeEngineCO->setCurrentIndex(
3948                 biblioModule->citeEngineCO->findData(toqstr(cite_engine)));
3949
3950         updateEngineType(documentClass().opt_enginetype(),
3951                 bp_.citeEngineType());
3952
3953         checkPossibleCiteEngines();
3954
3955         biblioModule->citeStyleCO->setCurrentIndex(
3956                 biblioModule->citeStyleCO->findData(bp_.citeEngineType()));
3957
3958         biblioModule->bibtopicCB->setChecked(bp_.splitbib());
3959
3960         biblioModule->bibunitsCO->clear();
3961         biblioModule->bibunitsCO->addItem(qt_("No"), QString());
3962         if (documentClass().hasLaTeXLayout("part"))
3963                 biblioModule->bibunitsCO->addItem(qt_("per part"), toqstr("part"));
3964         if (documentClass().hasLaTeXLayout("chapter"))
3965                 biblioModule->bibunitsCO->addItem(qt_("per chapter"), toqstr("chapter"));
3966         if (documentClass().hasLaTeXLayout("section"))
3967                 biblioModule->bibunitsCO->addItem(qt_("per section"), toqstr("section"));
3968         if (documentClass().hasLaTeXLayout("subsection"))
3969                 biblioModule->bibunitsCO->addItem(qt_("per subsection"), toqstr("subsection"));
3970         biblioModule->bibunitsCO->addItem(qt_("per child document"), toqstr("child"));
3971
3972         int const mbpos = biblioModule->bibunitsCO->findData(toqstr(bp_.multibib));
3973         if (mbpos != -1)
3974                 biblioModule->bibunitsCO->setCurrentIndex(mbpos);
3975         else
3976                 biblioModule->bibunitsCO->setCurrentIndex(0);
3977
3978         updateEngineDependends();
3979
3980         if (isBiblatex()) {
3981                 updateDefaultBiblio(bp_.biblatex_bibstyle, "bbx");
3982                 updateDefaultBiblio(bp_.biblatex_citestyle, "cbx");
3983         } else
3984                 updateDefaultBiblio(bp_.defaultBiblioStyle());
3985
3986         biblioModule->citePackageOptionsLE->setText(toqstr(bp_.biblio_opts));
3987
3988         string command;
3989         string options =
3990                 split(bp_.bibtex_command, command, ' ');
3991
3992         int const bpos = biblioModule->bibtexCO->findData(toqstr(command));
3993         if (bpos != -1) {
3994                 biblioModule->bibtexCO->setCurrentIndex(bpos);
3995                 biblioModule->bibtexOptionsLE->setText(toqstr(options).trimmed());
3996         } else {
3997                 // We reset to default if we do not know the specified compiler
3998                 // This is for security reasons
3999                 biblioModule->bibtexCO->setCurrentIndex(
4000                         biblioModule->bibtexCO->findData(toqstr("default")));
4001                 biblioModule->bibtexOptionsLE->clear();
4002         }
4003         biblioModule->bibtexOptionsLE->setEnabled(
4004                 biblioModule->bibtexCO->currentIndex() != 0);
4005
4006         biblioChanged_ = false;
4007
4008         // indices
4009         // We may be called when there is no Buffer, e.g., when
4010         // the last view has just been closed.
4011         bool const isReadOnly = isBufferAvailable() ? buffer().isReadonly() : false;
4012         indicesModule->update(bp_, isReadOnly);
4013
4014         // language & quotes
4015         int const pos = langModule->languageCO->findData(toqstr(
4016                 bp_.language->lang()));
4017         langModule->languageCO->setCurrentIndex(pos);
4018
4019         updateQuoteStyles();
4020
4021         langModule->quoteStyleCO->setCurrentIndex(
4022                 langModule->quoteStyleCO->findData(static_cast<int>(bp_.quotes_style)));
4023         langModule->dynamicQuotesCB->setChecked(bp_.dynamic_quotes);
4024
4025         // LaTeX input encoding: set after the fonts (see below)
4026
4027         int p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
4028         if (p == -1) {
4029                 langModule->languagePackageCO->setCurrentIndex(
4030                           langModule->languagePackageCO->findData("custom"));
4031                 langModule->languagePackageLE->setText(toqstr(bp_.lang_package));
4032         } else {
4033                 langModule->languagePackageCO->setCurrentIndex(p);
4034                 langModule->languagePackageLE->clear();
4035         }
4036
4037         //color
4038         if (bp_.isfontcolor) {
4039                 colorModule->fontColorPB->setStyleSheet(
4040                         colorButtonStyleSheet(rgb2qcolor(bp_.fontcolor)));
4041         }
4042         set_fontcolor = bp_.fontcolor;
4043         is_fontcolor = bp_.isfontcolor;
4044
4045         colorModule->noteFontColorPB->setStyleSheet(
4046                 colorButtonStyleSheet(rgb2qcolor(bp_.notefontcolor)));
4047         set_notefontcolor = bp_.notefontcolor;
4048         is_notefontcolor = bp_.isnotefontcolor;
4049
4050         if (bp_.isbackgroundcolor) {
4051                 colorModule->backgroundPB->setStyleSheet(
4052                         colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
4053         }
4054         set_backgroundcolor = bp_.backgroundcolor;
4055         is_backgroundcolor = bp_.isbackgroundcolor;
4056
4057         colorModule->boxBackgroundPB->setStyleSheet(
4058                 colorButtonStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
4059         set_boxbgcolor = bp_.boxbgcolor;
4060         is_boxbgcolor = bp_.isboxbgcolor;
4061
4062         // numbering
4063         int const min_toclevel = documentClass().min_toclevel();
4064         int const max_toclevel = documentClass().max_toclevel();
4065         if (documentClass().hasTocLevels()) {
4066                 numberingModule->setEnabled(true);
4067                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
4068                 numberingModule->depthSL->setMaximum(max_toclevel);
4069                 numberingModule->depthSL->setValue(bp_.secnumdepth);
4070                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
4071                 numberingModule->tocSL->setMaximum(max_toclevel);
4072                 numberingModule->tocSL->setValue(bp_.tocdepth);
4073                 updateNumbering();
4074         } else {
4075                 numberingModule->setEnabled(false);
4076                 numberingModule->tocTW->clear();
4077         }
4078
4079         numberingModule->linenoCB->setChecked(bp_.use_lineno);
4080         numberingModule->linenoLE->setEnabled(bp_.use_lineno);
4081         numberingModule->linenoLA->setEnabled(bp_.use_lineno);
4082         numberingModule->linenoLE->setText(toqstr(bp_.lineno_opts));
4083
4084         // bullets
4085         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
4086         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
4087         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
4088         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
4089         bulletsModule->init();
4090
4091         // packages
4092         int nitem = findToken(tex_graphics, bp_.graphics_driver);
4093         if (nitem >= 0)
4094                 latexModule->psdriverCO->setCurrentIndex(nitem);
4095         updateModuleInfo();
4096
4097         // math
4098         mathsModule->MathIndentCB->setChecked(bp_.is_math_indent);
4099         if (bp_.is_math_indent) {
4100                 Length const mathindent = bp_.getMathIndent();
4101                 int indent = 0;
4102                 if (!mathindent.empty()) {
4103                         lengthToWidgets(mathsModule->MathIndentLE,
4104                                         mathsModule->MathIndentLengthCO,
4105                                         mathindent, default_unit);
4106                         indent = 1;
4107                 }
4108                 mathsModule->MathIndentCO->setCurrentIndex(indent);
4109                 enableMathIndent(indent);
4110         }
4111         switch(bp_.math_numbering_side) {
4112         case BufferParams::LEFT:
4113                 mathsModule->MathNumberingPosCO->setCurrentIndex(0);
4114                 break;
4115         case BufferParams::DEFAULT:
4116                 mathsModule->MathNumberingPosCO->setCurrentIndex(1);
4117                 break;
4118         case BufferParams::RIGHT:
4119                 mathsModule->MathNumberingPosCO->setCurrentIndex(2);
4120         }
4121
4122         map<string, string> const & packages = BufferParams::auto_packages();
4123         for (map<string, string>::const_iterator it = packages.begin();
4124              it != packages.end(); ++it) {
4125                 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
4126                 if (!item)
4127                         continue;
4128                 int row = mathsModule->packagesTW->row(item);
4129                 switch (bp_.use_package(it->first)) {
4130                         case BufferParams::package_off: {
4131                                 QRadioButton * rb =
4132                                         (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3)->layout()->itemAt(0)->widget();
4133                                 rb->setChecked(true);
4134                                 break;
4135                         }
4136                         case BufferParams::package_on: {
4137                                 QRadioButton * rb =
4138                                         (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2)->layout()->itemAt(0)->widget();
4139                                 rb->setChecked(true);
4140                                 break;
4141                         }
4142                         case BufferParams::package_auto: {
4143                                 QRadioButton * rb =
4144                                         (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1)->layout()->itemAt(0)->widget();
4145                                 rb->setChecked(true);
4146                                 break;
4147                         }
4148                 }
4149         }
4150
4151         switch (bp_.spacing().getSpace()) {
4152                 case Spacing::Other: nitem = 3; break;
4153                 case Spacing::Double: nitem = 2; break;
4154                 case Spacing::Onehalf: nitem = 1; break;
4155                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
4156         }
4157
4158         // text layout
4159         string const & layoutID = bp_.baseClassID();
4160         setLayoutComboByIDString(layoutID);
4161
4162         updatePagestyle(documentClass().opt_pagestyle(),
4163                                  bp_.pagestyle);
4164
4165         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
4166         if (bp_.spacing().getSpace() == Spacing::Other) {
4167                 doubleToWidget(textLayoutModule->lspacingLE,
4168                         bp_.spacing().getValueAsString());
4169         }
4170         setLSpacing(nitem);
4171         int ts = textLayoutModule->tableStyleCO->findData(toqstr(bp_.tablestyle));
4172         if (ts != -1)
4173                 textLayoutModule->tableStyleCO->setCurrentIndex(ts);
4174
4175         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
4176                 textLayoutModule->indentRB->setChecked(true);
4177                 string parindent = bp_.getParIndent().asString();
4178                 int indent = 0;
4179                 if (!parindent.empty()) {
4180                         lengthToWidgets(textLayoutModule->indentLE,
4181                                         textLayoutModule->indentLengthCO,
4182                                         parindent, default_unit);
4183                         indent = 1;
4184                 }
4185                 textLayoutModule->indentCO->setCurrentIndex(indent);
4186                 setIndent(indent);
4187         } else {
4188                 textLayoutModule->skipRB->setChecked(true);
4189                 VSpace::VSpaceKind skip = bp_.getDefSkip().kind();
4190                 textLayoutModule->skipCO->setCurrentIndex(textLayoutModule->skipCO->findData(skip));
4191                 if (skip == VSpace::LENGTH) {
4192                         string const length = bp_.getDefSkip().asLyXCommand();
4193                         lengthToWidgets(textLayoutModule->skipLE,
4194                                 textLayoutModule->skipLengthCO,
4195                                 length, default_unit);
4196                 }
4197                 setSkip(textLayoutModule->skipCO->currentIndex());
4198         }
4199
4200         textLayoutModule->twoColumnCB->setChecked(
4201                 bp_.columns == 2);
4202         textLayoutModule->justCB->setChecked(bp_.justification);
4203
4204         if (!bp_.options.empty()) {
4205                 latexModule->optionsLE->setText(
4206                         toqstr(bp_.options));
4207         } else {
4208                 latexModule->optionsLE->setText(QString());
4209         }
4210
4211         // latex
4212         latexModule->defaultOptionsCB->setChecked(
4213                         bp_.use_default_options);
4214         updateSelectedModules();
4215         selectionManager->updateProvidedModules(
4216                         bp_.baseClass()->providedModules());
4217         selectionManager->updateExcludedModules(
4218                         bp_.baseClass()->excludedModules());
4219
4220         if (!documentClass().options().empty()) {
4221                 latexModule->defaultOptionsLE->setText(
4222                         toqstr(documentClass().options()));
4223         } else {
4224                 latexModule->defaultOptionsLE->setText(
4225                         toqstr(_("[No options predefined]")));
4226         }
4227
4228         latexModule->defaultOptionsLE->setEnabled(
4229                 bp_.use_default_options
4230                 && !documentClass().options().empty());
4231
4232         latexModule->defaultOptionsCB->setEnabled(
4233                 !documentClass().options().empty());
4234
4235         if (!bp_.master.empty()) {
4236                 latexModule->childDocGB->setChecked(true);
4237                 latexModule->childDocLE->setText(
4238                         toqstr(bp_.master));
4239         } else {
4240                 latexModule->childDocLE->setText(QString());
4241                 latexModule->childDocGB->setChecked(false);
4242         }
4243
4244         // Master/Child
4245         if (!bufferview() || !buffer().hasChildren()) {
4246                 masterChildModule->childrenTW->clear();
4247                 includeonlys_.clear();
4248                 docPS->showPanel("Child Documents", false);
4249                 if (docPS->isCurrentPanel("Child Documents"))
4250                         docPS->setCurrentPanel("Document Class");
4251         } else {
4252                 docPS->showPanel("Child Documents", true);
4253                 masterChildModule->setEnabled(true);
4254                 includeonlys_ = bp_.getIncludedChildren();
4255                 updateIncludeonlys();
4256                 updateIncludeonlyDisplay();
4257         }
4258         switch (bp_.maintain_unincluded_children) {
4259         case BufferParams::CM_None:
4260                 masterChildModule->maintainCRNoneRB->setChecked(true);
4261                 break;
4262         case BufferParams::CM_Mostly:
4263                 masterChildModule->maintainCRMostlyRB->setChecked(true);
4264                 break;
4265         case BufferParams::CM_Strict:
4266         default:
4267                 masterChildModule->maintainCRStrictRB->setChecked(true);
4268                 break;
4269         }
4270
4271         // Float Settings
4272         floatModule->setPlacement(bp_.float_placement);
4273         floatModule->setAlignment(bp_.float_alignment);
4274
4275         // ListingsSettings
4276         // break listings_params to multiple lines
4277         string lstparams =
4278                 InsetListingsParams(bp_.listings_params).separatedParams();
4279         listingsModule->listingsED->setPlainText(toqstr(lstparams));
4280         int nn = findToken(lst_packages, bp_.use_minted ? "Minted" : "Listings");
4281         if (nn >= 0)
4282                 listingsModule->packageCO->setCurrentIndex(nn);
4283
4284         // Fonts
4285         // some languages only work with Polyglossia (which requires non-TeX fonts)
4286         Language const * lang = lyx::languages.getLanguage(
4287                 fromqstr(langModule->languageCO->itemData(
4288                         langModule->languageCO->currentIndex()).toString()));
4289         bool const need_fontspec =
4290                 lang->babel().empty() && !lang->polyglossia().empty()
4291                 && lang->required() != "CJK" && lang->required() != "japanese";
4292         bool const os_fonts_available =
4293                 bp_.baseClass()->outputType() == lyx::LATEX
4294                 && LaTeXFeatures::isAvailable("fontspec");
4295         fontModule->osFontsCB->setEnabled(os_fonts_available && !need_fontspec);
4296         fontModule->osFontsCB->setChecked(
4297                 (os_fonts_available && bp_.useNonTeXFonts) || need_fontspec);
4298         updateFontsize(documentClass().opt_fontsize(),
4299                         bp_.fontsize);
4300
4301         QString font = toqstr(bp_.fontsRoman());
4302         int rpos = fontModule->fontsRomanCO->findData(font);
4303         if (rpos == -1) {
4304                 rpos = fontModule->fontsRomanCO->count();
4305                 fontModule->fontsRomanCO->addItem(font + qt_(" (not installed)"), font);
4306         }
4307         fontModule->fontsRomanCO->setCurrentIndex(rpos);
4308         fontModule->font_roman = toqstr(bp_.fonts_roman[!bp_.useNonTeXFonts]);
4309
4310         font = toqstr(bp_.fontsSans());
4311         int spos = fontModule->fontsSansCO->findData(font);
4312         if (spos == -1) {
4313                 spos = fontModule->fontsSansCO->count();
4314                 fontModule->fontsSansCO->addItem(font + qt_(" (not installed)"), font);
4315         }
4316         fontModule->fontsSansCO->setCurrentIndex(spos);
4317         fontModule->font_sans = toqstr(bp_.fonts_sans[!bp_.useNonTeXFonts]);
4318
4319         font = toqstr(bp_.fontsTypewriter());
4320         int tpos = fontModule->fontsTypewriterCO->findData(font);
4321         if (tpos == -1) {
4322                 tpos = fontModule->fontsTypewriterCO->count();
4323                 fontModule->fontsTypewriterCO->addItem(font + qt_(" (not installed)"), font);
4324         }
4325         fontModule->fontsTypewriterCO->setCurrentIndex(tpos);
4326         fontModule->font_typewriter = toqstr(bp_.fonts_typewriter[!bp_.useNonTeXFonts]);
4327
4328         font = toqstr(bp_.fontsMath());
4329         int mpos = fontModule->fontsMathCO->findData(font);
4330         if (mpos == -1) {
4331                 mpos = fontModule->fontsMathCO->count();
4332                 fontModule->fontsMathCO->addItem(font + qt_(" (not installed)"), font);
4333         }
4334         fontModule->fontsMathCO->setCurrentIndex(mpos);
4335         fontModule->font_math = toqstr(bp_.fonts_math[!bp_.useNonTeXFonts]);
4336
4337         if (bp_.useNonTeXFonts && os_fonts_available) {
4338                 fontModule->fontencLA->setEnabled(false);
4339                 fontModule->fontencCO->setEnabled(false);
4340                 fontModule->fontencLE->setEnabled(false);
4341         } else {
4342                 fontModule->fontencLA->setEnabled(true);
4343                 fontModule->fontencCO->setEnabled(true);
4344                 fontModule->fontencLE->setEnabled(true);
4345                 romanChanged(rpos);
4346                 sansChanged(spos);
4347                 ttChanged(tpos);
4348         }
4349
4350         if (!bp_.fonts_cjk.empty())
4351                 fontModule->cjkFontLE->setText(
4352                         toqstr(bp_.fonts_cjk));
4353         else
4354                 fontModule->cjkFontLE->setText(QString());
4355
4356         fontModule->microtypeCB->setChecked(bp_.use_microtype);
4357         fontModule->dashesCB->setChecked(!bp_.use_dash_ligatures);
4358
4359         fontModule->fontScCB->setChecked(bp_.fonts_expert_sc);
4360         fontModule->fontOsfCB->setChecked(bp_.fonts_roman_osf);
4361         fontModule->fontSansOsfCB->setChecked(bp_.fonts_sans_osf);
4362         fontModule->fontTypewriterOsfCB->setChecked(bp_.fonts_typewriter_osf);
4363         fontModule->scaleSansSB->setValue(bp_.fontsSansScale());
4364         fontModule->font_sf_scale = bp_.fonts_sans_scale[!bp_.useNonTeXFonts];
4365         fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale());
4366         fontModule->font_tt_scale = bp_.fonts_typewriter_scale[!bp_.useNonTeXFonts];
4367         if (!bp_.font_roman_opts.empty())
4368                 fontModule->fontspecRomanLE->setText(
4369                         toqstr(bp_.font_roman_opts));
4370         else
4371                 fontModule->fontspecRomanLE->setText(QString());
4372         if (!bp_.font_sans_opts.empty())
4373                 fontModule->fontspecSansLE->setText(
4374                         toqstr(bp_.font_sans_opts));
4375         else
4376                 fontModule->fontspecSansLE->setText(QString());
4377         if (!bp_.font_typewriter_opts.empty())
4378                 fontModule->fontspecTypewriterLE->setText(
4379                         toqstr(bp_.font_typewriter_opts));
4380         else
4381                 fontModule->fontspecTypewriterLE->setText(QString());
4382
4383         nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
4384         if (nn >= 0)
4385                 fontModule->fontsDefaultCO->setCurrentIndex(nn);
4386
4387         if (bp_.fontenc == "auto" || bp_.fontenc == "default") {
4388                 fontModule->fontencCO->setCurrentIndex(
4389                         fontModule->fontencCO->findData(toqstr(bp_.fontenc)));
4390                 fontModule->fontencLE->setEnabled(false);
4391         } else {
4392                 fontModule->fontencCO->setCurrentIndex(
4393                                         fontModule->fontencCO->findData("custom"));
4394                 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
4395         }
4396
4397         // LaTeX input encoding
4398         // Set after fonts because non-tex fonts override "\inputencoding".
4399         inputencodingToDialog();
4400
4401         // Formats
4402         // This must be set _after_ fonts since updateDefaultFormat()
4403         // checks osFontsCB settings.
4404         // update combobox with formats
4405         updateDefaultFormat();
4406         int index = outputModule->defaultFormatCO->findData(toqstr(
4407                 bp_.default_output_format));
4408         // set to default if format is not found
4409         if (index == -1)
4410                 index = 0;
4411         outputModule->defaultFormatCO->setCurrentIndex(index);
4412
4413         outputModule->shellescapeCB->setChecked(bp_.shell_escape);
4414         outputModule->outputsyncCB->setChecked(bp_.output_sync);
4415         outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
4416         outputModule->synccustomCB->setEnabled(bp_.output_sync);
4417         outputModule->synccustomLA->setEnabled(bp_.output_sync);
4418
4419         outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
4420         outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
4421         outputModule->strictCB->setChecked(bp_.html_be_strict);
4422         outputModule->cssCB->setChecked(bp_.html_css_as_file);
4423
4424         outputModule->tableoutCB->setCurrentIndex(bp_.docbook_table_output);
4425
4426         outputModule->saveTransientPropertiesCB
4427                 ->setChecked(bp_.save_transient_properties);
4428         outputModule->postponeFragileCB
4429                 ->setChecked(bp_.postpone_fragile_content);
4430
4431         // paper
4432         bool const extern_geometry =
4433                 documentClass().provides("geometry");
4434         int const psize = bp_.papersize;
4435         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
4436         setCustomPapersize(!extern_geometry && psize == 1);
4437         pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
4438
4439         bool const landscape =
4440                 bp_.orientation == ORIENTATION_LANDSCAPE;
4441         pageLayoutModule->landscapeRB->setChecked(landscape);
4442         pageLayoutModule->portraitRB->setChecked(!landscape);
4443         pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
4444         pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
4445
4446         pageLayoutModule->facingPagesCB->setChecked(
4447                 bp_.sides == TwoSides);
4448
4449         lengthToWidgets(pageLayoutModule->paperwidthLE,
4450                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, default_unit);
4451         lengthToWidgets(pageLayoutModule->paperheightLE,
4452                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, default_unit);
4453
4454         // margins
4455         Ui::MarginsUi * m = marginsModule;
4456
4457         setMargins();
4458
4459         lengthToWidgets(m->topLE, m->topUnit,
4460                 bp_.topmargin, default_unit);
4461
4462         lengthToWidgets(m->bottomLE, m->bottomUnit,
4463                 bp_.bottommargin, default_unit);
4464
4465         lengthToWidgets(m->innerLE, m->innerUnit,
4466                 bp_.leftmargin, default_unit);
4467
4468         lengthToWidgets(m->outerLE, m->outerUnit,
4469                 bp_.rightmargin, default_unit);
4470
4471         lengthToWidgets(m->headheightLE, m->headheightUnit,
4472                 bp_.headheight, default_unit);
4473
4474         lengthToWidgets(m->headsepLE, m->headsepUnit,
4475                 bp_.headsep, default_unit);
4476
4477         lengthToWidgets(m->footskipLE, m->footskipUnit,
4478                 bp_.footskip, default_unit);
4479
4480         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
4481                 bp_.columnsep, default_unit);
4482
4483         // branches
4484         updateUnknownBranches();
4485         branchesModule->update(bp_);
4486
4487         // PDF support
4488         PDFOptions const & pdf = bp_.pdfoptions();
4489         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
4490         if (bp_.documentClass().provides("hyperref"))
4491                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("C&ustomize Hyperref Options"));
4492         else
4493                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("&Use Hyperref Support"));
4494         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
4495         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
4496         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
4497         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
4498
4499         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
4500         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
4501         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
4502
4503         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
4504         pdfSupportModule->bookmarksopenlevelSB->setEnabled(pdf.bookmarksopen);
4505         pdfSupportModule->bookmarksopenlevelLA->setEnabled(pdf.bookmarksopen);
4506
4507         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
4508         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
4509         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
4510         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
4511
4512         nn = findToken(backref_opts, pdf.backref);
4513         if (nn >= 0)
4514                 pdfSupportModule->backrefCO->setCurrentIndex(nn);
4515
4516         pdfSupportModule->fullscreenCB->setChecked
4517                 (pdf.pagemode == pdf.pagemode_fullscreen);
4518
4519         pdfSupportModule->optionsLE->setText(
4520                 toqstr(pdf.quoted_options));
4521
4522         // change tracking
4523         changesModule->trackChangesCB->setChecked(bp_.track_changes);
4524         changesModule->outputChangesCB->setChecked(bp_.output_changes);
4525         changesModule->changeBarsCB->setChecked(bp_.change_bars);
4526         changesModule->changeBarsCB->setEnabled(bp_.output_changes);
4527
4528         // Make sure that the bc is in the INITIAL state
4529         if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
4530                 bc().restore();
4531
4532         // clear changed branches cache
4533         changedBranches_.clear();
4534
4535         // re-initiate module filter
4536         if (!filter_->text().isEmpty())
4537                 moduleFilterPressed();
4538
4539         // reset trackers
4540         nonModuleChanged_ = false;
4541         shellescapeChanged_ = false;
4542 }
4543
4544
4545 void GuiDocument::saveDocDefault()
4546 {
4547         // we have to apply the params first
4548         applyView();
4549         saveAsDefault();
4550 }
4551
4552
4553 void GuiDocument::updateAvailableModules()
4554 {
4555         modules_av_model_.clear();
4556         list<modInfoStruct> modInfoList = getModuleInfo();
4557         // Sort names according to the locale
4558         modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
4559                         return 0 < b.name.localeAwareCompare(a.name);
4560                 });
4561         QIcon user_icon(getPixmap("images/", "lyxfiles-user", "svgz,png"));
4562         QIcon system_icon(getPixmap("images/", "lyxfiles-system", "svgz,png"));
4563         int i = 0;
4564         QFont catfont;
4565         catfont.setBold(true);
4566         QBrush unavbrush;
4567         unavbrush.setColor(Qt::gray);
4568         for (modInfoStruct const & m : modInfoList) {
4569                 QStandardItem * item = new QStandardItem();
4570                 QStandardItem * catItem;
4571                 QString const catname = m.category;
4572                 QList<QStandardItem *> fcats = modules_av_model_.findItems(catname, Qt::MatchExactly);
4573                 if (!fcats.empty())
4574                         catItem = fcats.first();
4575                 else {
4576                         catItem = new QStandardItem();
4577                         catItem->setText(catname);
4578                         catItem->setFont(catfont);
4579                         modules_av_model_.insertRow(i, catItem);
4580                         ++i;
4581                 }
4582                 item->setEditable(false);
4583                 catItem->setEditable(false);
4584                 item->setData(m.name, Qt::DisplayRole);
4585                 if (m.missingreqs)
4586                         item->setForeground(unavbrush);
4587                 item->setData(toqstr(m.id), Qt::UserRole);
4588                 item->setData(m.description, Qt::ToolTipRole);
4589                 if (m.local)
4590                         item->setIcon(user_icon);
4591                 else
4592                         item->setIcon(system_icon);
4593                 catItem->appendRow(item);
4594         }
4595         modules_av_model_.sort(0);
4596 }
4597
4598
4599 void GuiDocument::updateSelectedModules()
4600 {
4601         modules_sel_model_.clear();
4602         list<modInfoStruct> const selModList = getSelectedModules();
4603         int i = 0;
4604         for (modInfoStruct const & m : selModList) {
4605                 modules_sel_model_.insertRow(i, m.name, m.id, m.description);
4606                 ++i;
4607         }
4608 }
4609
4610
4611 void GuiDocument::updateIncludeonlyDisplay()
4612 {
4613         if (includeonlys_.empty()) {
4614                 masterChildModule->includeallRB->setChecked(true);
4615                 masterChildModule->childrenTW->setEnabled(false);
4616                 masterChildModule->maintainGB->setEnabled(false);
4617         } else {
4618                 masterChildModule->includeonlyRB->setChecked(true);
4619                 masterChildModule->childrenTW->setEnabled(true);
4620                 masterChildModule->maintainGB->setEnabled(true);
4621         }
4622 }
4623
4624
4625 void GuiDocument::updateIncludeonlys()
4626 {
4627         masterChildModule->childrenTW->clear();
4628         QString const no = qt_("No");
4629         QString const yes = qt_("Yes");
4630
4631         ListOfBuffers children = buffer().getChildren();
4632         ListOfBuffers::const_iterator it  = children.begin();
4633         ListOfBuffers::const_iterator end = children.end();
4634         bool has_unincluded = false;
4635         bool all_unincluded = true;
4636         for (; it != end; ++it) {
4637                 QTreeWidgetItem * item = new QTreeWidgetItem(masterChildModule->childrenTW);
4638                 // FIXME Unicode
4639                 string const name =
4640                         to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
4641                                                         from_utf8(buffer().filePath())));
4642                 item->setText(0, toqstr(name));
4643                 item->setText(1, isChildIncluded(name) ? yes : no);
4644                 if (!isChildIncluded(name))
4645                         has_unincluded = true;
4646                 else
4647                         all_unincluded = false;
4648         }
4649         // Both if all children are included and if none is included
4650         // is equal to "include all" (i.e., omit \includeonly).
4651         if (!has_unincluded || all_unincluded)
4652                 includeonlys_.clear();
4653 }
4654
4655
4656 bool GuiDocument::isBiblatex() const
4657 {
4658         QString const engine =
4659                 biblioModule->citeEngineCO->itemData(
4660                                 biblioModule->citeEngineCO->currentIndex()).toString();
4661
4662         // this can happen if the cite engine is unknown, which can happen
4663         // if one is using a file that came from someone else, etc. in that
4664         // case, we crash if we proceed.
4665         if (engine.isEmpty())
4666             return false;
4667
4668         return theCiteEnginesList[fromqstr(engine)]->getCiteFramework() == "biblatex";
4669 }
4670
4671
4672 void GuiDocument::updateDefaultBiblio(string const & style,
4673                                       string const & which)
4674 {
4675         QString const bibstyle = toqstr(style);
4676         biblioModule->defaultBiblioCO->clear();
4677
4678         int item_nr = -1;
4679
4680         if (isBiblatex()) {
4681                 if (which != "cbx") {
4682                         // First the bbx styles
4683                         biblioModule->biblatexBbxCO->clear();
4684                         QStringList str = texFileList("bbxFiles.lst");
4685                         // test whether we have a valid list, otherwise run rescan
4686                         if (str.isEmpty()) {
4687                                 rescanTexStyles("bbx");
4688                                 str = texFileList("bbxFiles.lst");
4689                         }
4690                         for (int i = 0; i != str.size(); ++i)
4691                                 str[i] = onlyFileName(str[i]);
4692                         // sort on filename only (no path)
4693                         str.sort();
4694
4695                         for (int i = 0; i != str.count(); ++i) {
4696                                 QString item = changeExtension(str[i], "");
4697                                 if (item == bibstyle)
4698                                         item_nr = i;
4699                                 biblioModule->biblatexBbxCO->addItem(item);
4700                         }
4701
4702                         if (item_nr == -1 && !bibstyle.isEmpty()) {
4703                                 biblioModule->biblatexBbxCO->addItem(bibstyle);
4704                                 item_nr = biblioModule->biblatexBbxCO->count() - 1;
4705                         }
4706
4707                         if (item_nr != -1)
4708                                 biblioModule->biblatexBbxCO->setCurrentIndex(item_nr);
4709                         else
4710                                 biblioModule->biblatexBbxCO->clearEditText();
4711                 }
4712
4713                 if (which != "bbx") {
4714                         // now the cbx styles
4715                         biblioModule->biblatexCbxCO->clear();
4716                         QStringList str = texFileList("cbxFiles.lst");
4717                         // test whether we have a valid list, otherwise run rescan
4718                         if (str.isEmpty()) {
4719                                 rescanTexStyles("cbx");
4720                                 str = texFileList("cbxFiles.lst");
4721                         }
4722                         for (int i = 0; i != str.size(); ++i)
4723                                 str[i] = onlyFileName(str[i]);
4724                         // sort on filename only (no path)
4725                         str.sort();
4726
4727                         for (int i = 0; i != str.count(); ++i) {
4728                                 QString item = changeExtension(str[i], "");
4729                                 if (item == bibstyle)
4730                                         item_nr = i;
4731                                 biblioModule->biblatexCbxCO->addItem(item);
4732                         }
4733
4734                         if (item_nr == -1 && !bibstyle.isEmpty()) {
4735                                 biblioModule->biblatexCbxCO->addItem(bibstyle);
4736                                 item_nr = biblioModule->biblatexCbxCO->count() - 1;
4737                         }
4738
4739                         if (item_nr != -1)
4740                                 biblioModule->biblatexCbxCO->setCurrentIndex(item_nr);
4741                         else
4742                                 biblioModule->biblatexCbxCO->clearEditText();
4743                 }
4744         } else {// BibTeX
4745                 biblioModule->biblatexBbxCO->clear();
4746                 biblioModule->biblatexCbxCO->clear();
4747                 QStringList str = texFileList("bstFiles.lst");
4748                 // test whether we have a valid list, otherwise run rescan
4749                 if (str.isEmpty()) {
4750                         rescanTexStyles("bst");
4751                         str = texFileList("bstFiles.lst");
4752                 }
4753                 for (int i = 0; i != str.size(); ++i)
4754                         str[i] = onlyFileName(str[i]);
4755                 // sort on filename only (no path)
4756                 str.sort();
4757
4758                 for (int i = 0; i != str.count(); ++i) {
4759                         QString item = changeExtension(str[i], "");
4760                         if (item == bibstyle)
4761                                 item_nr = i;
4762                         biblioModule->defaultBiblioCO->addItem(item);
4763                 }
4764
4765                 if (item_nr == -1 && !bibstyle.isEmpty()) {
4766                         biblioModule->defaultBiblioCO->addItem(bibstyle);
4767                         item_nr = biblioModule->defaultBiblioCO->count() - 1;
4768                 }
4769
4770                 if (item_nr != -1)
4771                         biblioModule->defaultBiblioCO->setCurrentIndex(item_nr);
4772                 else
4773                         biblioModule->defaultBiblioCO->clearEditText();
4774         }
4775
4776         updateResetDefaultBiblio();
4777 }
4778
4779
4780 void GuiDocument::updateResetDefaultBiblio()
4781 {
4782         QString const engine =
4783                 biblioModule->citeEngineCO->itemData(
4784                                 biblioModule->citeEngineCO->currentIndex()).toString();
4785         CiteEngineType const cet =
4786                 CiteEngineType(biblioModule->citeStyleCO->itemData(
4787                                                           biblioModule->citeStyleCO->currentIndex()).toInt());
4788
4789         string const defbib = theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet);
4790         if (isBiblatex()) {
4791                 QString const bbx = biblioModule->biblatexBbxCO->currentText();
4792                 QString const cbx = biblioModule->biblatexCbxCO->currentText();
4793                 biblioModule->resetCbxPB->setEnabled(defbib != fromqstr(cbx));
4794                 biblioModule->resetBbxPB->setEnabled(defbib != fromqstr(bbx));
4795                 biblioModule->matchBbxPB->setEnabled(bbx != cbx && !cbx.isEmpty()
4796                         && biblioModule->biblatexBbxCO->findText(cbx) != -1);
4797         } else
4798                 biblioModule->resetDefaultBiblioPB->setEnabled(
4799                         defbib != fromqstr(biblioModule->defaultBiblioCO->currentText()));
4800 }
4801
4802
4803 void GuiDocument::matchBiblatexStyles()
4804 {
4805         updateDefaultBiblio(fromqstr(biblioModule->biblatexCbxCO->currentText()), "bbx");
4806         biblioChanged();
4807 }
4808
4809
4810 void GuiDocument::updateContents()
4811 {
4812         // Nothing to do here as the document settings is not cursor dependent.
4813         return;
4814 }
4815
4816
4817 void GuiDocument::useClassDefaults()
4818 {
4819         if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
4820                 int const ret = Alert::prompt(_("Unapplied changes"),
4821                                 _("Some changes in the dialog were not yet applied.\n"
4822                                   "If you do not apply now, they will be lost after this action."),
4823                                 1, 1, _("&Apply"), _("&Dismiss"));
4824                 if (ret == 0)
4825                         applyView();
4826         }
4827
4828         int idx = latexModule->classCO->currentIndex();
4829         string const classname = fromqstr(latexModule->classCO->getData(idx));
4830         if (!bp_.setBaseClass(classname, buffer().layoutPos())) {
4831                 Alert::error(_("Error"), _("Unable to set document class."));
4832                 return;
4833         }
4834         bp_.useClassDefaults();
4835         paramsToDialog();
4836         changed();
4837 }
4838
4839
4840 void GuiDocument::setLayoutComboByIDString(string const & idString)
4841 {
4842         if (!latexModule->classCO->set(toqstr(idString)))
4843                 Alert::warning(_("Can't set layout!"),
4844                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
4845 }
4846
4847
4848 bool GuiDocument::isValid()
4849 {
4850         return
4851                 validateListingsParameters().isEmpty() &&
4852                 localLayout->isValid() &&
4853                 !localLayout->editing() &&
4854                 !preambleModule->editing() &&
4855                 (
4856                         // if we're asking for skips between paragraphs
4857                         !textLayoutModule->skipRB->isChecked() ||
4858                         // then either we haven't chosen custom
4859                         textLayoutModule->skipCO->currentIndex() != 3 ||
4860                         // or else a length has been given
4861                         !textLayoutModule->skipLE->text().isEmpty()
4862                 ) &&
4863                 (
4864                         // if we're asking for indentation
4865                         !textLayoutModule->indentRB->isChecked() ||
4866                         // then either we haven't chosen custom
4867                         textLayoutModule->indentCO->currentIndex() != 1 ||
4868                         // or else a length has been given
4869                         !textLayoutModule->indentLE->text().isEmpty()
4870                 ) &&
4871                 (
4872                         // if we're asking for math indentation
4873                         !mathsModule->MathIndentCB->isChecked() ||
4874                         // then either we haven't chosen custom
4875                         mathsModule->MathIndentCO->currentIndex() != 1 ||
4876                         // or else a length has been given
4877                         !mathsModule->MathIndentLE->text().isEmpty()
4878                 );
4879 }
4880
4881
4882 char const * const GuiDocument::fontfamilies[5] = {
4883         "default", "rmdefault", "sfdefault", "ttdefault", ""
4884 };
4885
4886
4887 char const * GuiDocument::fontfamilies_gui[5] = {
4888         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
4889 };
4890
4891
4892 bool GuiDocument::initialiseParams(string const &)
4893 {
4894         BufferView const * view = bufferview();
4895         if (!view) {
4896                 bp_ = BufferParams();
4897                 paramsToDialog();
4898                 return true;
4899         }
4900         bp_ = view->buffer().params();
4901         loadModuleInfo();
4902         updateAvailableModules();
4903         //FIXME It'd be nice to make sure here that the selected
4904         //modules are consistent: That required modules are actually
4905         //selected, and that we don't have conflicts. If so, we could
4906         //at least pop up a warning.
4907         paramsToDialog();
4908         return true;
4909 }
4910
4911
4912 void GuiDocument::clearParams()
4913 {
4914         bp_ = BufferParams();
4915 }
4916
4917
4918 BufferId GuiDocument::id() const
4919 {
4920         BufferView const * const view = bufferview();
4921         return view? &view->buffer() : nullptr;
4922 }
4923
4924
4925 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
4926 {
4927         return moduleNames_;
4928 }
4929
4930
4931 list<GuiDocument::modInfoStruct> const
4932 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
4933 {
4934         list<modInfoStruct> mInfo;
4935         for (string const & name : mods) {
4936                 modInfoStruct m;
4937                 LyXModule const * const mod = theModuleList[name];
4938                 if (mod)
4939                         m = modInfo(*mod);
4940                 else {
4941                         m.id = name;
4942                         m.name = toqstr(name + " (") + qt_("Not Found") + toqstr(")");
4943                         m.local = false;
4944                         m.missingreqs = true;
4945                 }
4946                 mInfo.push_back(m);
4947         }
4948         return mInfo;
4949 }
4950
4951
4952 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
4953 {
4954         return makeModuleInfo(params().getModules());
4955 }
4956
4957
4958 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
4959 {
4960         return makeModuleInfo(params().baseClass()->providedModules());
4961 }
4962
4963
4964 DocumentClass const & GuiDocument::documentClass() const
4965 {
4966         return bp_.documentClass();
4967 }
4968
4969
4970 static void dispatch_bufferparams(Dialog const & dialog,
4971         BufferParams const & bp, FuncCode lfun, Buffer const * buf)
4972 {
4973         ostringstream ss;
4974         ss << "\\begin_header\n";
4975         bp.writeFile(ss, buf);
4976         ss << "\\end_header\n";
4977         dialog.dispatch(FuncRequest(lfun, ss.str()));
4978 }
4979
4980
4981 void GuiDocument::dispatchParams()
4982 {
4983         // We need a non-const buffer object.
4984         Buffer & buf = const_cast<BufferView *>(bufferview())->buffer();
4985         // There may be several undo records; group them (bug #8998)
4986         // This handles undo groups automagically
4987         UndoGroupHelper ugh(&buf);
4988
4989         // This must come first so that a language change is correctly noticed
4990         setLanguage();
4991
4992         // We need to load the master before we formally update the params,
4993         // since otherwise we run updateBuffer, etc, before the child's master
4994         // has been set.
4995         if (!params().master.empty()) {
4996                 FileName const master_file = support::makeAbsPath(params().master,
4997                            support::onlyPath(buffer().absFileName()));
4998                 if (isLyXFileName(master_file.absFileName())) {
4999                         Buffer * master = checkAndLoadLyXFile(master_file, true);
5000                         if (master) {
5001                                 if (master->isChild(const_cast<Buffer *>(&buffer())))
5002                                         const_cast<Buffer &>(buffer()).setParent(master);
5003                                 else
5004                                         Alert::warning(_("Assigned master does not include this file"),
5005                                                 bformat(_("You must include this file in the document\n"
5006                                                           "'%1$s' in order to use the master document\n"
5007                                                           "feature."), from_utf8(params().master)));
5008                         } else
5009                                 Alert::warning(_("Could not load master"),
5010                                                 bformat(_("The master document '%1$s'\n"
5011                                                            "could not be loaded."),
5012                                                            from_utf8(params().master)));
5013                 }
5014         }
5015
5016         // Apply the BufferParams. Note that this will set the base class
5017         // and then update the buffer's layout.
5018         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY, &buffer());
5019
5020         // Generate the colours requested by each new branch.
5021         BranchList & branchlist = params().branchlist();
5022         if (!branchlist.empty()) {
5023                 BranchList::const_iterator it = branchlist.begin();
5024                 BranchList::const_iterator const end = branchlist.end();
5025                 for (; it != end; ++it) {
5026                         docstring const & current_branch = it->branch();
5027                         Branch const * branch = branchlist.find(current_branch);
5028                         string const bcolor = branch->color();
5029                         RGBColor rgbcol;
5030                         if (bcolor.size() == 7 && bcolor[0] == '#')
5031                                 rgbcol = lyx::rgbFromHexName(bcolor);
5032                         else
5033                                 guiApp->getRgbColor(lcolor.getFromLyXName(bcolor), rgbcol);
5034                         string const x11hexname = X11hexname(rgbcol);
5035                         // display the new color
5036                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
5037                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
5038                 }
5039         }
5040         // rename branches in the document
5041         executeBranchRenaming();
5042         // and clear changed branches cache
5043         changedBranches_.clear();
5044
5045         // Generate the colours requested by indices.
5046         IndicesList & indiceslist = params().indiceslist();
5047         if (!indiceslist.empty()) {
5048                 IndicesList::const_iterator it = indiceslist.begin();
5049                 IndicesList::const_iterator const end = indiceslist.end();
5050                 for (; it != end; ++it) {
5051                         docstring const & current_index = it->shortcut();
5052                         Index const * index = indiceslist.findShortcut(current_index);
5053                         string const x11hexname = X11hexname(index->color());
5054                         // display the new color
5055                         docstring const str = current_index + ' ' + from_ascii(x11hexname);
5056                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
5057                 }
5058         }
5059         // FIXME LFUN
5060         // If we used an LFUN, we would not need these two lines:
5061         BufferView * bv = const_cast<BufferView *>(bufferview());
5062         bv->processUpdateFlags(Update::Force | Update::FitCursor);
5063 }
5064
5065
5066 void GuiDocument::setLanguage() const
5067 {
5068         Language const * const newL = bp_.language;
5069         if (buffer().params().language == newL)
5070                 return;
5071
5072         string const & lang_name = newL->lang();
5073         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
5074 }
5075
5076
5077 void GuiDocument::saveAsDefault() const
5078 {
5079         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT, &buffer());
5080 }
5081
5082
5083 bool GuiDocument::providesOSF(QString const & font) const
5084 {
5085         if (fontModule->osFontsCB->isChecked())
5086                 // FIXME: we should check if the fonts really
5087                 // have OSF support. But how?
5088                 return true;
5089         return theLaTeXFonts().getLaTeXFont(
5090                                 qstring_to_ucs4(font)).providesOSF(ot1(),
5091                                                                    completeFontset(),
5092                                                                    noMathFont());
5093 }
5094
5095
5096 bool GuiDocument::providesSC(QString const & font) const
5097 {
5098         if (fontModule->osFontsCB->isChecked())
5099                 return false;
5100         return theLaTeXFonts().getLaTeXFont(
5101                                 qstring_to_ucs4(font)).providesSC(ot1(),
5102                                                                   completeFontset(),
5103                                                                   noMathFont());
5104 }
5105
5106
5107 bool GuiDocument::providesScale(QString const & font) const
5108 {
5109         if (fontModule->osFontsCB->isChecked())
5110                 return true;
5111         return theLaTeXFonts().getLaTeXFont(
5112                                 qstring_to_ucs4(font)).providesScale(ot1(),
5113                                                                      completeFontset(),
5114                                                                      noMathFont());
5115 }
5116
5117
5118 bool GuiDocument::providesExtraOpts(QString const & font) const
5119 {
5120         if (fontModule->osFontsCB->isChecked())
5121                 return true;
5122         return theLaTeXFonts().getLaTeXFont(
5123                                 qstring_to_ucs4(font)).providesMoreOptions(ot1(),
5124                                                                      completeFontset(),
5125                                                                      noMathFont());
5126 }
5127
5128
5129 bool GuiDocument::providesNoMath(QString const & font) const
5130 {
5131         if (fontModule->osFontsCB->isChecked())
5132                 return false;
5133         return theLaTeXFonts().getLaTeXFont(
5134                                 qstring_to_ucs4(font)).providesNoMath(ot1(),
5135                                                                       completeFontset());
5136 }
5137
5138
5139 bool GuiDocument::hasMonolithicExpertSet(QString const & font) const
5140 {
5141         if (fontModule->osFontsCB->isChecked())
5142                 return false;
5143         return theLaTeXFonts().getLaTeXFont(
5144                                 qstring_to_ucs4(font)).hasMonolithicExpertSet(ot1(),
5145                                                                               completeFontset(),
5146                                                                               noMathFont());
5147 }
5148
5149
5150 //static
5151 GuiDocument::modInfoStruct GuiDocument::modInfo(LyXModule const & mod)
5152 {
5153         // FIXME Unicode: docstrings would be better for these parameters but this
5154         // change requires a lot of others
5155         modInfoStruct m;
5156         m.id = mod.getID();
5157         QString const guiname = toqstr(translateIfPossible(from_utf8(mod.getName())));
5158         m.missingreqs = !isModuleAvailable(mod.getID());
5159         if (m.missingreqs) {
5160                 m.name = QString(qt_("%1 (missing req.)")).arg(guiname);
5161         } else
5162                 m.name = guiname;
5163         m.category = mod.category().empty() ? qt_("Miscellaneous")
5164                                             : toqstr(translateIfPossible(from_utf8(mod.category())));
5165         QString desc = toqstr(translateIfPossible(from_utf8(mod.getDescription())));
5166         // Find the first sentence of the description
5167         QTextBoundaryFinder bf(QTextBoundaryFinder::Sentence, desc);
5168         int pos = bf.toNextBoundary();
5169         if (pos > 0)
5170                 desc.truncate(pos);
5171         m.local = mod.isLocal();
5172         QString const mtype = m.local ? qt_("personal module") : qt_("distributed module");
5173         QString modulename = QString(qt_("<b>Module name:</b> <i>%1</i> (%2)")).arg(toqstr(m.id)).arg(mtype);
5174         // Tooltip is the desc followed by the module name and the type
5175         m.description = QString("%1%2")
5176                 .arg(desc.isEmpty() ? QString() : QString("<p>%1</p>").arg(desc),
5177                      modulename);
5178         if (m.missingreqs)
5179                 m.description += QString("<p>%1</p>").arg(qt_("<b>Note:</b> Some requirements for this module are missing!"));
5180         return m;
5181 }
5182
5183
5184 void GuiDocument::loadModuleInfo()
5185 {
5186         moduleNames_.clear();
5187         for (LyXModule const & mod : theModuleList)
5188                 moduleNames_.push_back(modInfo(mod));
5189 }
5190
5191
5192 void GuiDocument::updateUnknownBranches()
5193 {
5194         if (!bufferview())
5195                 return;
5196         list<docstring> used_branches;
5197         buffer().getUsedBranches(used_branches);
5198         list<docstring>::const_iterator it = used_branches.begin();
5199         QStringList unknown_branches;
5200         for (; it != used_branches.end() ; ++it) {
5201                 if (!buffer().params().branchlist().find(*it))
5202                         unknown_branches.append(toqstr(*it));
5203         }
5204         branchesModule->setUnknownBranches(unknown_branches);
5205 }
5206
5207
5208 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
5209 {
5210         map<docstring, docstring>::iterator it = changedBranches_.begin();
5211         for (; it != changedBranches_.end() ; ++it) {
5212                 if (it->second == oldname) {
5213                         // branch has already been renamed
5214                         it->second = newname;
5215                         return;
5216                 }
5217         }
5218         // store new name
5219         changedBranches_[oldname] = newname;
5220 }
5221
5222
5223 void GuiDocument::executeBranchRenaming() const
5224 {
5225         map<docstring, docstring>::const_iterator it = changedBranches_.begin();
5226         for (; it != changedBranches_.end() ; ++it) {
5227                 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
5228                 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
5229         }
5230 }
5231
5232
5233 void GuiDocument::allPackagesAuto()
5234 {
5235         allPackages(1);
5236 }
5237
5238
5239 void GuiDocument::allPackagesAlways()
5240 {
5241         allPackages(2);
5242 }
5243
5244
5245 void GuiDocument::allPackagesNot()
5246 {
5247         allPackages(3);
5248 }
5249
5250
5251 void GuiDocument::allPackages(int col)
5252 {
5253         for (int row = 0; row < mathsModule->packagesTW->rowCount(); ++row) {
5254                 QRadioButton * rb =
5255                         (QRadioButton*)mathsModule->packagesTW->cellWidget(row, col)->layout()->itemAt(0)->widget();
5256                 rb->setChecked(true);
5257         }
5258 }
5259
5260
5261 void GuiDocument::linenoToggled(bool on)
5262 {
5263         numberingModule->linenoLE->setEnabled(on);
5264         numberingModule->linenoLA->setEnabled(on);
5265 }
5266
5267
5268 void GuiDocument::outputChangesToggled(bool on)
5269 {
5270         changesModule->changeBarsCB->setEnabled(on);
5271         change_adaptor();
5272 }
5273
5274 void GuiDocument::setOutputSync(bool on)
5275 {
5276         outputModule->synccustomCB->setEnabled(on);
5277         outputModule->synccustomLA->setEnabled(on);
5278         change_adaptor();
5279 }
5280
5281
5282 } // namespace frontend
5283 } // namespace lyx
5284
5285 #include "moc_GuiDocument.cpp"