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