]> git.lyx.org Git - features.git/blob - src/frontends/qt/GuiDocument.cpp
Re-initiate module filter after dialog re-opening (#12128)
[features.git] / src / frontends / qt / GuiDocument.cpp
1 /**
2  * \file GuiDocument.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Edwin Leuven
7  * \author Richard Kimberly Heck (modules)
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "GuiDocument.h"
15
16 #include "BulletsModule.h"
17 #include "CategorizedCombo.h"
18 #include "FancyLineEdit.h"
19 #include "GuiApplication.h"
20 #include "GuiBranches.h"
21 #include "GuiIndices.h"
22 #include "GuiSelectionManager.h"
23 #include "LaTeXHighlighter.h"
24 #include "Validator.h"
25
26 #include "LayoutFile.h"
27 #include "BranchList.h"
28 #include "buffer_funcs.h"
29 #include "Buffer.h"
30 #include "BufferView.h"
31 #include "CiteEnginesList.h"
32 #include "Color.h"
33 #include "ColorCache.h"
34 #include "Converter.h"
35 #include "Cursor.h"
36 #include "Encoding.h"
37 #include "FloatPlacement.h"
38 #include "Format.h"
39 #include "FuncRequest.h"
40 #include "IndicesList.h"
41 #include "Language.h"
42 #include "LaTeXFeatures.h"
43 #include "LaTeXFonts.h"
44 #include "Layout.h"
45 #include "LayoutEnums.h"
46 #include "LayoutModuleList.h"
47 #include "LyXRC.h"
48 #include "ModuleList.h"
49 #include "PDFOptions.h"
50 #include "qt_helpers.h"
51 #include "Session.h"
52 #include "Spacing.h"
53 #include "TextClass.h"
54 #include "Undo.h"
55 #include "VSpace.h"
56
57 #include "insets/InsetListingsParams.h"
58 #include "insets/InsetQuotes.h"
59
60 #include "support/debug.h"
61 #include "support/docstream.h"
62 #include "support/FileName.h"
63 #include "support/filetools.h"
64 #include "support/gettext.h"
65 #include "support/lassert.h"
66 #include "support/lstrings.h"
67 #include "support/Package.h"
68 #include "support/TempFile.h"
69
70 #include "frontends/alert.h"
71
72 #include <QAbstractItemModel>
73 #include <QButtonGroup>
74 #include <QColor>
75 #include <QColorDialog>
76 #include <QCloseEvent>
77 #include <QDirIterator>
78 #include <QFontDatabase>
79 #include <QHeaderView>
80 #include <QPixmap>
81 #include <QScrollBar>
82 #include <QTextBoundaryFinder>
83 #include <QTextCursor>
84
85 #include <sstream>
86 #include <vector>
87
88
89 // a style sheet for buttons
90 // this is for example used for the background color setting button
91 static inline QString colorButtonStyleSheet(QColor const & bgColor)
92 {
93         if (bgColor.isValid()) {
94                 QString rc = QLatin1String("background-color:");
95                 rc += bgColor.name();
96                 return rc;
97         }
98         return QString();
99 }
100
101
102 using namespace std;
103 using namespace lyx::support;
104
105
106 namespace {
107
108 char const * const tex_graphics[] =
109 {
110         "default", "dvialw", "dvilaser", "dvipdf", "dvipdfm", "dvipdfmx",
111         "dvips", "dvipsone", "dvitops", "dviwin", "dviwindo", "dvi2ps", "emtex",
112         "ln", "oztex", "pctexhp", "pctexps", "pctexwin", "pctex32", "pdftex",
113         "psprint", "pubps", "tcidvi", "textures", "truetex", "vtex", "xdvi",
114         "xetex", "none", ""
115 };
116
117
118 char const * const tex_graphics_gui[] =
119 {
120         N_("Default"), "dvialw", "DviLaser", "dvipdf", "DVIPDFM", "DVIPDFMx",
121         "Dvips", "DVIPSONE", "DVItoPS", "DVIWIN", "DVIWindo", "dvi2ps", "EmTeX",
122         "LN", "OzTeX", "pctexhp", "pctexps", "pctexwin", "PCTeX32", "pdfTeX",
123         "psprint", "pubps", "tcidvi", "Textures", "TrueTeX", "VTeX", "xdvi",
124         "XeTeX", N_("None"), ""
125 };
126
127
128 char const * backref_opts[] =
129 {
130         "false", "section", "slide", "page", ""
131 };
132
133
134 char const * backref_opts_gui[] =
135 {
136         N_("Off"), N_("Section"), N_("Slide"), N_("Page"), ""
137 };
138
139
140 char const * lst_packages[] =
141 {
142         "Listings", "Minted", ""
143 };
144
145
146 vector<string> engine_types_;
147 vector<pair<string, QString> > pagestyles;
148
149 QMap<QString, QString> rmfonts_;
150 QMap<QString, QString> sffonts_;
151 QMap<QString, QString> ttfonts_;
152 QMap<QString, QString> mathfonts_;
153
154 enum EncodingSets {
155         unicode = 0,
156         legacy = 1,
157         custom = 2
158 };
159
160 lyx::RGBColor set_backgroundcolor;
161 bool is_backgroundcolor;
162 lyx::RGBColor set_fontcolor;
163 bool is_fontcolor;
164 lyx::RGBColor set_notefontcolor;
165 bool is_notefontcolor;
166 lyx::RGBColor set_boxbgcolor;
167 bool is_boxbgcolor;
168 bool forced_fontspec_activation;
169
170 } // anonymous namespace
171
172 namespace lyx {
173
174 namespace {
175 // used when sorting the textclass list.
176 class less_textclass_avail_desc
177 {
178 public:
179         bool operator()(string const & lhs, string const & rhs) const
180         {
181                 // Ordering criteria:
182                 //   1. Availability of text class
183                 //   2. Description (lexicographic)
184                 LayoutFile const & tc1 = LayoutFileList::get()[lhs];
185                 LayoutFile const & tc2 = LayoutFileList::get()[rhs];
186                 int const order = compare_no_case(
187                         translateIfPossible(from_utf8(tc1.description())),
188                         translateIfPossible(from_utf8(tc2.description())));
189                 return (tc1.isTeXClassAvailable() && !tc2.isTeXClassAvailable()) ||
190                         (tc1.isTeXClassAvailable() == tc2.isTeXClassAvailable() && order < 0);
191         }
192 };
193
194 } // namespace
195
196 namespace frontend {
197 namespace {
198
199 vector<string> getRequiredList(string const & modName)
200 {
201         LyXModule const * const mod = theModuleList[modName];
202         if (!mod)
203                 return vector<string>(); //empty such thing
204         return mod->getRequiredModules();
205 }
206
207
208 vector<string> getExcludedList(string const & modName)
209 {
210         LyXModule const * const mod = theModuleList[modName];
211         if (!mod)
212                 return vector<string>(); //empty such thing
213         return mod->getExcludedModules();
214 }
215
216
217 docstring getModuleCategory(string const & modName)
218 {
219         LyXModule const * const mod = theModuleList[modName];
220         if (!mod)
221                 return docstring();
222         return from_utf8(mod->category());
223 }
224
225
226 docstring getModuleDescription(string const & modName)
227 {
228         LyXModule const * const mod = theModuleList[modName];
229         if (!mod)
230                 return _("Module not found!");
231         // FIXME Unicode
232         return translateIfPossible(from_utf8(mod->getDescription()));
233 }
234
235
236 vector<string> getPackageList(string const & modName)
237 {
238         LyXModule const * const mod = theModuleList[modName];
239         if (!mod)
240                 return vector<string>(); //empty such thing
241         return mod->getPackageList();
242 }
243
244
245 bool isModuleAvailable(string const & modName)
246 {
247         LyXModule const * const mod = theModuleList[modName];
248         if (!mod)
249                 return false;
250         return mod->isAvailable();
251 }
252
253 } // anonymous namespace
254
255
256 /////////////////////////////////////////////////////////////////////
257 //
258 // ModuleSelectionManager
259 //
260 /////////////////////////////////////////////////////////////////////
261
262 /// SelectionManager for use with modules
263 class ModuleSelectionManager : public GuiSelectionManager
264 {
265 public:
266         ///
267         ModuleSelectionManager(QObject * parent,
268                                                    QTreeView * availableLVarg,
269                                                    QTreeView * selectedLVarg,
270                                                    QPushButton * addPBarg,
271                                                    QPushButton * delPBarg,
272                                                    QPushButton * upPBarg,
273                                                    QPushButton * downPBarg,
274                                                    QStandardItemModel * availableModelarg,
275                                                    GuiIdListModel * selectedModelarg,
276                                GuiDocument const * container)
277                 : GuiSelectionManager(parent, availableLVarg, selectedLVarg, addPBarg, delPBarg,
278                                                           upPBarg, downPBarg, availableModelarg, selectedModelarg),
279                   container_(container)
280                 {}
281         ///
282         void updateProvidedModules(LayoutModuleList const & pm)
283                         { provided_modules_ = pm.list(); }
284         ///
285         void updateExcludedModules(LayoutModuleList const & em)
286                         { excluded_modules_ = em.list(); }
287 private:
288         ///
289         void updateAddPB() override;
290         ///
291         void updateUpPB() override;
292         ///
293         void updateDownPB() override;
294         ///
295         void updateDelPB() override;
296         /// returns availableModel as a GuiIdListModel
297         QStandardItemModel * getAvailableModel()
298         {
299                 return dynamic_cast<QStandardItemModel *>(availableModel);
300         }
301         /// returns selectedModel as a GuiIdListModel
302         GuiIdListModel * getSelectedModel()
303         {
304                 return dynamic_cast<GuiIdListModel *>(selectedModel);
305         }
306         /// keeps a list of the modules the text class provides
307         list<string> provided_modules_;
308         /// similarly...
309         list<string> excluded_modules_;
310         ///
311         GuiDocument const * container_;
312 };
313
314 void ModuleSelectionManager::updateAddPB()
315 {
316         int const arows = availableModel->rowCount();
317         QModelIndexList const avail_sels =
318                         availableLV->selectionModel()->selectedRows(0);
319
320         // disable if there aren't any modules (?), if none of them is chosen
321         // in the dialog, or if the chosen one is already selected for use.
322         if (arows == 0 || avail_sels.isEmpty() || isSelected(avail_sels.first())) {
323                 addPB->setEnabled(false);
324                 return;
325         }
326
327         QModelIndex const & idx = availableLV->selectionModel()->currentIndex();
328
329         if (getAvailableModel()->itemFromIndex(idx)->hasChildren()) {
330                 // This is a category header
331                 addPB->setEnabled(false);
332                 return;
333         }
334
335         string const modname = fromqstr(getAvailableModel()->data(idx, Qt::UserRole).toString());
336
337         bool const enable =
338                 container_->params().layoutModuleCanBeAdded(modname);
339         addPB->setEnabled(enable);
340 }
341
342
343 void ModuleSelectionManager::updateDownPB()
344 {
345         int const srows = selectedModel->rowCount();
346         if (srows == 0) {
347                 downPB->setEnabled(false);
348                 return;
349         }
350         QModelIndex const & curidx = selectedLV->selectionModel()->currentIndex();
351         int const curRow = curidx.row();
352         if (curRow < 0 || curRow >= srows - 1) { // invalid or last item
353                 downPB->setEnabled(false);
354                 return;
355         }
356
357         // determine whether immediately succeeding element requires this one
358         string const curmodname = getSelectedModel()->getIDString(curRow);
359         string const nextmodname = getSelectedModel()->getIDString(curRow + 1);
360
361         vector<string> reqs = getRequiredList(nextmodname);
362
363         // if it doesn't require anything....
364         if (reqs.empty()) {
365                 downPB->setEnabled(true);
366                 return;
367         }
368
369         // Enable it if this module isn't required.
370         // FIXME This should perhaps be more flexible and check whether, even
371         // if the next one is required, there is also an earlier one that will do.
372         downPB->setEnabled(
373                         find(reqs.begin(), reqs.end(), curmodname) == reqs.end());
374 }
375
376 void ModuleSelectionManager::updateUpPB()
377 {
378         int const srows = selectedModel->rowCount();
379         if (srows == 0) {
380                 upPB->setEnabled(false);
381                 return;
382         }
383
384         QModelIndex const & curIdx = selectedLV->selectionModel()->currentIndex();
385         int curRow = curIdx.row();
386         if (curRow <= 0 || curRow > srows - 1) { // first item or invalid
387                 upPB->setEnabled(false);
388                 return;
389         }
390         string const curmodname = getSelectedModel()->getIDString(curRow);
391
392         // determine whether immediately preceding element is required by this one
393         vector<string> reqs = getRequiredList(curmodname);
394
395         // if this one doesn't require anything....
396         if (reqs.empty()) {
397                 upPB->setEnabled(true);
398                 return;
399         }
400
401
402         // Enable it if the preceding module isn't required.
403         // NOTE This is less flexible than it might be. We could check whether, even
404         // if the previous one is required, there is an earlier one that would do.
405         string const premod = getSelectedModel()->getIDString(curRow - 1);
406         upPB->setEnabled(find(reqs.begin(), reqs.end(), premod) == reqs.end());
407 }
408
409 void ModuleSelectionManager::updateDelPB()
410 {
411         int const srows = selectedModel->rowCount();
412         if (srows == 0) {
413                 deletePB->setEnabled(false);
414                 return;
415         }
416
417         QModelIndex const & curidx =
418                 selectedLV->selectionModel()->currentIndex();
419         int const curRow = curidx.row();
420         if (curRow < 0 || curRow >= srows) { // invalid index?
421                 deletePB->setEnabled(false);
422                 return;
423         }
424
425         string const curmodname = getSelectedModel()->getIDString(curRow);
426
427         // We're looking here for a reason NOT to enable the button. If we
428         // find one, we disable it and return. If we don't, we'll end up at
429         // the end of the function, and then we enable it.
430         for (int i = curRow + 1; i < srows; ++i) {
431                 string const thisMod = getSelectedModel()->getIDString(i);
432                 vector<string> reqs = getRequiredList(thisMod);
433                 //does this one require us?
434                 if (find(reqs.begin(), reqs.end(), curmodname) == reqs.end())
435                         //no...
436                         continue;
437
438                 // OK, so this module requires us
439                 // is there an EARLIER module that also satisfies the require?
440                 // NOTE We demand that it be earlier to keep the list of modules
441                 // consistent with the rule that a module must be proceeded by a
442                 // required module. There would be more flexible ways to proceed,
443                 // but that would be a lot more complicated, and the logic here is
444                 // already complicated. (That's why I've left the debugging code.)
445                 // lyxerr << "Testing " << thisMod << endl;
446                 bool foundone = false;
447                 for (int j = 0; j < curRow; ++j) {
448                         string const mod = getSelectedModel()->getIDString(j);
449                         // lyxerr << "In loop: Testing " << mod << endl;
450                         // do we satisfy the require?
451                         if (find(reqs.begin(), reqs.end(), mod) != reqs.end()) {
452                                 // lyxerr << mod << " does the trick." << endl;
453                                 foundone = true;
454                                 break;
455                         }
456                 }
457                 // did we find a module to satisfy the require?
458                 if (!foundone) {
459                         // lyxerr << "No matching module found." << endl;
460                         deletePB->setEnabled(false);
461                         return;
462                 }
463         }
464         // lyxerr << "All's well that ends well." << endl;
465         deletePB->setEnabled(true);
466 }
467
468
469 /////////////////////////////////////////////////////////////////////
470 //
471 // PreambleModule
472 //
473 /////////////////////////////////////////////////////////////////////
474
475 PreambleModule::PreambleModule(QWidget * parent)
476         : UiWidget<Ui::PreambleUi>(parent), current_id_(nullptr)
477 {
478         // This is not a memory leak. The object will be destroyed
479         // with this.
480         // @ is letter in the LyX user preamble
481         (void) new LaTeXHighlighter(preambleTE->document(), true);
482         preambleTE->setFont(guiApp->typewriterSystemFont());
483         preambleTE->setWordWrapMode(QTextOption::NoWrap);
484         setFocusProxy(preambleTE);
485         connect(preambleTE, SIGNAL(textChanged()), this, SIGNAL(changed()));
486         connect(findLE, SIGNAL(textEdited(const QString &)), this, SLOT(checkFindButton()));
487         connect(findButtonPB, SIGNAL(clicked()), this, SLOT(findText()));
488         connect(editPB, SIGNAL(clicked()), this, SLOT(editExternal()));
489         connect(findLE, SIGNAL(returnPressed()), this, SLOT(findText()));
490         checkFindButton();
491         // https://stackoverflow.com/questions/13027091/how-to-override-tab-width-in-qt
492         const int tabStop = 4;
493         QFontMetrics metrics(preambleTE->currentFont());
494 #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
495         // horizontalAdvance() is available starting in 5.11.0
496         // setTabStopDistance() is available starting in 5.10.0
497         preambleTE->setTabStopDistance(tabStop * metrics.horizontalAdvance(' '));
498 #else
499         preambleTE->setTabStopWidth(tabStop * metrics.width(' '));
500 #endif
501 }
502
503
504 void PreambleModule::checkFindButton()
505 {
506         findButtonPB->setEnabled(!findLE->text().isEmpty());
507 }
508
509
510 void PreambleModule::findText()
511 {
512         bool const found = preambleTE->find(findLE->text());
513         if (!found) {
514                 // wrap
515                 QTextCursor qtcur = preambleTE->textCursor();
516                 qtcur.movePosition(QTextCursor::Start);
517                 preambleTE->setTextCursor(qtcur);
518                 preambleTE->find(findLE->text());
519         }
520 }
521
522
523 void PreambleModule::update(BufferParams const & params, BufferId id)
524 {
525         QString preamble = toqstr(params.preamble);
526         // Nothing to do if the params and preamble are unchanged.
527         if (id == current_id_
528                 && preamble == preambleTE->document()->toPlainText())
529                 return;
530
531         QTextCursor cur = preambleTE->textCursor();
532         // Save the coords before switching to the new one.
533         preamble_coords_[current_id_] =
534                 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
535
536         // Save the params address for further use.
537         current_id_ = id;
538         preambleTE->document()->setPlainText(preamble);
539         Coords::const_iterator it = preamble_coords_.find(current_id_);
540         if (it == preamble_coords_.end())
541                 // First time we open this one.
542                 preamble_coords_[current_id_] = make_pair(0, 0);
543         else {
544                 // Restore saved coords.
545                 cur = preambleTE->textCursor();
546                 cur.setPosition(it->second.first);
547                 preambleTE->setTextCursor(cur);
548                 preambleTE->verticalScrollBar()->setValue(it->second.second);
549         }
550 }
551
552
553 void PreambleModule::apply(BufferParams & params)
554 {
555         params.preamble = qstring_to_ucs4(preambleTE->document()->toPlainText());
556 }
557
558
559 void PreambleModule::closeEvent(QCloseEvent * e)
560 {
561         // Save the coords before closing.
562         QTextCursor cur = preambleTE->textCursor();
563         preamble_coords_[current_id_] =
564                 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
565         e->accept();
566 }
567
568
569 void PreambleModule::editExternal() {
570         if (!current_id_)
571                 return;
572
573         if (tempfile_) {
574                 preambleTE->setReadOnly(false);
575                 FileName const tempfilename = tempfile_->name();
576                 docstring const s = tempfilename.fileContents("UTF-8");
577                 preambleTE->document()->setPlainText(toqstr(s));
578                 tempfile_.reset();
579                 editPB->setText(qt_("&Edit"));
580                 changed();
581                 return;
582         }
583
584         string const format =
585                 current_id_->params().documentClass().outputFormat();
586         string const ext = theFormats().extension(format);
587         tempfile_.reset(new TempFile("preamble_editXXXXXX." + ext));
588         FileName const tempfilename = tempfile_->name();
589         string const name = tempfilename.toFilesystemEncoding();
590         ofdocstream os(name.c_str());
591         os << qstring_to_ucs4(preambleTE->document()->toPlainText());
592         os.close();
593         preambleTE->setReadOnly(true);
594         theFormats().edit(*current_id_, tempfilename, format);
595         editPB->setText(qt_("&End Edit"));
596         changed();
597 }
598
599 /////////////////////////////////////////////////////////////////////
600 //
601 // LocalLayout
602 //
603 /////////////////////////////////////////////////////////////////////
604
605
606 LocalLayout::LocalLayout(QWidget * parent)
607         : UiWidget<Ui::LocalLayoutUi>(parent), current_id_(nullptr), validated_(false)
608 {
609         locallayoutTE->setFont(guiApp->typewriterSystemFont());
610         locallayoutTE->setWordWrapMode(QTextOption::NoWrap);
611         connect(locallayoutTE, SIGNAL(textChanged()), this, SLOT(textChanged()));
612         connect(validatePB, SIGNAL(clicked()), this, SLOT(validatePressed()));
613         connect(convertPB, SIGNAL(clicked()), this, SLOT(convertPressed()));
614         connect(editPB, SIGNAL(clicked()), this, SLOT(editExternal()));
615 }
616
617
618 void LocalLayout::update(BufferParams const & params, BufferId id)
619 {
620         QString layout = toqstr(params.getLocalLayout(false));
621         // Nothing to do if the params and preamble are unchanged.
622         if (id == current_id_
623                 && layout == locallayoutTE->document()->toPlainText())
624                 return;
625
626         // Save the params address for further use.
627         current_id_ = id;
628         locallayoutTE->document()->setPlainText(layout);
629         validate();
630 }
631
632
633 void LocalLayout::apply(BufferParams & params)
634 {
635         docstring const layout =
636                 qstring_to_ucs4(locallayoutTE->document()->toPlainText());
637         params.setLocalLayout(layout, false);
638 }
639
640
641 void LocalLayout::hideConvert()
642 {
643         convertPB->setEnabled(false);
644         convertLB->setText("");
645         convertPB->hide();
646         convertLB->hide();
647 }
648
649
650 void LocalLayout::textChanged()
651 {
652         // Flashy red bold text
653         static const QString ivpar("<p style=\"color: #c00000; font-weight: bold; text-align:left\">"
654                                    "%1</p>");
655         static const QString message = ivpar.arg(qt_("Validation required!"));
656         string const layout =
657                 fromqstr(locallayoutTE->document()->toPlainText().trimmed());
658
659         if (layout.empty()) {
660                 validated_ = true;
661                 validatePB->setEnabled(false);
662                 validLB->setText("");
663                 hideConvert();
664                 changed();
665         } else if (!validatePB->isEnabled()) {
666                 // if that's already enabled, we shouldn't need to do anything.
667                 validated_ = false;
668                 validLB->setText(message);
669                 validatePB->setEnabled(true);
670                 hideConvert();
671                 changed();
672         }
673 }
674
675
676 void LocalLayout::convert() {
677         string const layout =
678                 fromqstr(locallayoutTE->document()->toPlainText().trimmed());
679         string const newlayout = TextClass::convert(layout);
680         if (!newlayout.empty())
681                 locallayoutTE->setPlainText(toqstr(newlayout));
682         validate();
683 }
684
685
686 void LocalLayout::convertPressed() {
687         convert();
688         hideConvert();
689         changed();
690 }
691
692
693 void LocalLayout::validate() {
694         // Bold text
695         static const QString vpar("<p style=\"font-weight: bold; text-align:left\">%1</p>");
696         // Flashy red bold text
697         static const QString ivpar("<p style=\"color: #c00000; font-weight: bold; text-align:left\">"
698                                    "%1</p>");
699         string const layout =
700                 fromqstr(locallayoutTE->document()->toPlainText().trimmed());
701         if (!layout.empty()) {
702                 TextClass::ReturnValues const ret = TextClass::validate(layout);
703                 validated_ = (ret == TextClass::OK) || (ret == TextClass::OK_OLDFORMAT);
704                 validatePB->setEnabled(false);
705                 validLB->setText(validated_ ? vpar.arg(qt_("Layout is valid!"))
706                                             : ivpar.arg(qt_("Layout is invalid!")));
707                 if (ret == TextClass::OK_OLDFORMAT) {
708                         convertPB->show();
709                         // Testing conversion to LYXFILE_LAYOUT_FORMAT at this point
710                         // already.
711                         if (TextClass::convert(layout).empty()) {
712                                 // Conversion failed. If LAYOUT_FORMAT > LYXFILE_LAYOUT_FORMAT,
713                                 // then maybe the layout is still valid, but its format is more
714                                 // recent than LYXFILE_LAYOUT_FORMAT. However, if LAYOUT_FORMAT
715                                 // == LYXFILE_LAYOUT_FORMAT then something is definitely wrong.
716                                 convertPB->setEnabled(false);
717                                 const QString text = (LAYOUT_FORMAT == LYXFILE_LAYOUT_FORMAT)
718                                         ? ivpar.arg(qt_("Conversion to current format impossible!"))
719                                         : vpar.arg(qt_("Conversion to current stable format "
720                                                        "impossible."));
721                                 convertLB->setText(text);
722                         } else {
723                                 convertPB->setEnabled(true);
724                                 convertLB->setText(qt_("Convert to current format"));
725                         }
726                         convertLB->show();
727                 } else {
728                         convertPB->hide();
729                         convertLB->hide();
730                 }
731         }
732 }
733
734
735 void LocalLayout::validatePressed() {
736         validate();
737         changed();
738 }
739
740
741 void LocalLayout::editExternal() {
742         if (!current_id_)
743                 return;
744
745         if (tempfile_) {
746                 locallayoutTE->setReadOnly(false);
747                 FileName const tempfilename = tempfile_->name();
748                 docstring const s = tempfilename.fileContents("UTF-8");
749                 locallayoutTE->document()->setPlainText(toqstr(s));
750                 tempfile_.reset();
751                 editPB->setText(qt_("&Edit"));
752                 changed();
753                 return;
754         }
755
756         string const format =
757                 current_id_->params().documentClass().outputFormat();
758         string const ext = theFormats().extension(format);
759         tempfile_.reset(new TempFile("preamble_editXXXXXX." + ext));
760         FileName const tempfilename = tempfile_->name();
761         string const name = tempfilename.toFilesystemEncoding();
762         ofdocstream os(name.c_str());
763         os << qstring_to_ucs4(locallayoutTE->document()->toPlainText());
764         os.close();
765         locallayoutTE->setReadOnly(true);
766         theFormats().edit(*current_id_, tempfilename, format);
767         editPB->setText(qt_("&End Edit"));
768         validatePB->setEnabled(false);
769         hideConvert();
770         changed();
771 }
772
773 /////////////////////////////////////////////////////////////////////
774 //
775 // DocumentDialog
776 //
777 /////////////////////////////////////////////////////////////////////
778
779
780 GuiDocument::GuiDocument(GuiView & lv)
781         : GuiDialog(lv, "document", qt_("Document Settings")),
782           biblioChanged_(false), nonModuleChanged_(false),
783           modulesChanged_(false), shellescapeChanged_(false)
784 {
785         setupUi(this);
786
787         connect(buttonBox, SIGNAL(clicked(QAbstractButton *)),
788                 this, SLOT(slotButtonBox(QAbstractButton *)));
789
790         connect(savePB, SIGNAL(clicked()), this, SLOT(saveDefaultClicked()));
791         connect(defaultPB, SIGNAL(clicked()), this, SLOT(useDefaultsClicked()));
792
793         // Manage the restore, ok, apply, restore and cancel/close buttons
794         bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
795         bc().setOK(buttonBox->button(QDialogButtonBox::Ok));
796         bc().setApply(buttonBox->button(QDialogButtonBox::Apply));
797         bc().setCancel(buttonBox->button(QDialogButtonBox::Cancel));
798         bc().setRestore(buttonBox->button(QDialogButtonBox::Reset));
799
800
801         // text layout
802         textLayoutModule = new UiWidget<Ui::TextLayoutUi>(this);
803         connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
804                 this, SLOT(change_adaptor()));
805         connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
806                 this, SLOT(setLSpacing(int)));
807         connect(textLayoutModule->lspacingLE, SIGNAL(textChanged(const QString &)),
808                 this, SLOT(change_adaptor()));
809
810         connect(textLayoutModule->indentRB, SIGNAL(clicked()),
811                 this, SLOT(change_adaptor()));
812         connect(textLayoutModule->indentRB, SIGNAL(toggled(bool)),
813                 textLayoutModule->indentCO, SLOT(setEnabled(bool)));
814         connect(textLayoutModule->indentCO, SIGNAL(activated(int)),
815                 this, SLOT(change_adaptor()));
816         connect(textLayoutModule->indentCO, SIGNAL(activated(int)),
817                 this, SLOT(setIndent(int)));
818         connect(textLayoutModule->indentLE, SIGNAL(textChanged(const QString &)),
819                 this, SLOT(change_adaptor()));
820         connect(textLayoutModule->indentLengthCO, SIGNAL(activated(int)),
821                 this, SLOT(change_adaptor()));
822
823         connect(textLayoutModule->skipRB, SIGNAL(clicked()),
824                 this, SLOT(change_adaptor()));
825         connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
826                 textLayoutModule->skipCO, SLOT(setEnabled(bool)));
827         connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
828                 this, SLOT(change_adaptor()));
829         connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
830                 this, SLOT(setSkip(int)));
831         connect(textLayoutModule->skipLE, SIGNAL(textChanged(const QString &)),
832                 this, SLOT(change_adaptor()));
833         connect(textLayoutModule->skipLengthCO, SIGNAL(activated(int)),
834                 this, SLOT(change_adaptor()));
835
836         connect(textLayoutModule->indentRB, SIGNAL(toggled(bool)),
837                 this, SLOT(enableIndent(bool)));
838         connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
839                 this, SLOT(enableSkip(bool)));
840
841         connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
842                 this, SLOT(change_adaptor()));
843         connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
844                 this, SLOT(setColSep()));
845         connect(textLayoutModule->justCB, SIGNAL(clicked()),
846                 this, SLOT(change_adaptor()));
847
848         connect(textLayoutModule->tableStyleCO, SIGNAL(activated(int)),
849                 this, SLOT(change_adaptor()));
850
851         textLayoutModule->lspacingLE->setValidator(new QDoubleValidator(
852                 textLayoutModule->lspacingLE));
853         textLayoutModule->indentLE->setValidator(new LengthValidator(
854                 textLayoutModule->indentLE));
855         textLayoutModule->skipLE->setValidator(new LengthValidator(
856                 textLayoutModule->skipLE));
857
858         textLayoutModule->indentCO->addItem(qt_("Default"));
859         textLayoutModule->indentCO->addItem(qt_("Custom"));
860         textLayoutModule->skipCO->addItem(qt_("Half line height"), VSpace::HALFLINE);
861         textLayoutModule->skipCO->addItem(qt_("Line height"), VSpace::FULLLINE);
862         textLayoutModule->skipCO->addItem(qt_("SmallSkip"), VSpace::SMALLSKIP);
863         textLayoutModule->skipCO->addItem(qt_("MedSkip"), VSpace::MEDSKIP);
864         textLayoutModule->skipCO->addItem(qt_("BigSkip"), VSpace::BIGSKIP);
865         textLayoutModule->skipCO->addItem(qt_("Custom"), VSpace::LENGTH);
866         textLayoutModule->lspacingCO->insertItem(
867                 Spacing::Single, qt_("Single"));
868         textLayoutModule->lspacingCO->insertItem(
869                 Spacing::Onehalf, qt_("OneHalf"));
870         textLayoutModule->lspacingCO->insertItem(
871                 Spacing::Double, qt_("Double"));
872         textLayoutModule->lspacingCO->insertItem(
873                 Spacing::Other, qt_("Custom"));
874         // initialize the length validator
875         bc().addCheckedLineEdit(textLayoutModule->indentLE);
876         bc().addCheckedLineEdit(textLayoutModule->skipLE);
877
878         textLayoutModule->tableStyleCO->addItem(qt_("Default"), toqstr("default"));
879         getTableStyles();
880
881
882         // master/child handling
883         masterChildModule = new UiWidget<Ui::MasterChildUi>(this);
884
885         connect(masterChildModule->childrenTW, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),
886                 this, SLOT(includeonlyClicked(QTreeWidgetItem *, int)));
887         connect(masterChildModule->includeonlyRB, SIGNAL(toggled(bool)),
888                 masterChildModule->childrenTW, SLOT(setEnabled(bool)));
889         connect(masterChildModule->includeonlyRB, SIGNAL(toggled(bool)),
890                 masterChildModule->maintainGB, SLOT(setEnabled(bool)));
891         connect(masterChildModule->includeallRB, SIGNAL(clicked()),
892                 this, SLOT(change_adaptor()));
893         connect(masterChildModule->includeonlyRB, SIGNAL(clicked()),
894                 this, SLOT(change_adaptor()));
895         connect(masterChildModule->maintainCRNoneRB, SIGNAL(clicked()),
896                 this, SLOT(change_adaptor()));
897         connect(masterChildModule->maintainCRMostlyRB, SIGNAL(clicked()),
898                 this, SLOT(change_adaptor()));
899         connect(masterChildModule->maintainCRStrictRB, SIGNAL(clicked()),
900                 this, SLOT(change_adaptor()));
901         masterChildModule->childrenTW->setColumnCount(2);
902         masterChildModule->childrenTW->headerItem()->setText(0, qt_("Child Document"));
903         masterChildModule->childrenTW->headerItem()->setText(1, qt_("Include to Output"));
904 #if (QT_VERSION > 0x050000)
905         masterChildModule->childrenTW->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
906         masterChildModule->childrenTW->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
907 #else
908         masterChildModule->childrenTW->header()->setResizeMode(0, QHeaderView::ResizeToContents);
909         masterChildModule->childrenTW->header()->setResizeMode(1, QHeaderView::ResizeToContents);
910 #endif
911
912         // Formats
913         outputModule = new UiWidget<Ui::OutputUi>(this);
914
915         connect(outputModule->defaultFormatCO, SIGNAL(activated(int)),
916                 this, SLOT(change_adaptor()));
917         connect(outputModule->mathimgSB, SIGNAL(valueChanged(double)),
918                 this, SLOT(change_adaptor()));
919         connect(outputModule->strictCB, SIGNAL(stateChanged(int)),
920                 this, SLOT(change_adaptor()));
921         connect(outputModule->cssCB, SIGNAL(stateChanged(int)),
922                 this, SLOT(change_adaptor()));
923         connect(outputModule->mathoutCB, SIGNAL(currentIndexChanged(int)),
924                 this, SLOT(change_adaptor()));
925         connect(outputModule->tableoutCB, SIGNAL(currentIndexChanged(int)),
926                 this, SLOT(change_adaptor()));
927
928         connect(outputModule->shellescapeCB, SIGNAL(stateChanged(int)),
929                 this, SLOT(shellescapeChanged()));
930         connect(outputModule->outputsyncCB, SIGNAL(toggled(bool)),
931                 this, SLOT(setOutputSync(bool)));
932         connect(outputModule->synccustomCB, SIGNAL(editTextChanged(QString)),
933                 this, SLOT(change_adaptor()));
934         outputModule->synccustomCB->addItem("");
935         outputModule->synccustomCB->addItem("\\synctex=1");
936         outputModule->synccustomCB->addItem("\\synctex=-1");
937         outputModule->synccustomCB->addItem("\\usepackage[active]{srcltx}");
938
939         outputModule->synccustomCB->setValidator(new NoNewLineValidator(
940                 outputModule->synccustomCB));
941
942         connect(outputModule->saveTransientPropertiesCB, SIGNAL(clicked()),
943                 this, SLOT(change_adaptor()));
944         connect(outputModule->postponeFragileCB, SIGNAL(clicked()),
945                 this, SLOT(change_adaptor()));
946
947
948         // language & quote
949         // this must precede font, since fonts depend on this
950         langModule = new UiWidget<Ui::LanguageUi>(this);
951         connect(langModule->languageCO, SIGNAL(activated(int)),
952                 this, SLOT(change_adaptor()));
953         connect(langModule->languageCO, SIGNAL(activated(int)),
954                 this, SLOT(languageChanged(int)));
955         connect(langModule->encodingCO, SIGNAL(activated(int)),
956                 this, SLOT(change_adaptor()));
957         connect(langModule->encodingCO, SIGNAL(activated(int)),
958                 this, SLOT(encodingSwitched(int)));
959         connect(langModule->unicodeEncodingCO, SIGNAL(activated(int)),
960                 this, SLOT(change_adaptor()));
961         connect(langModule->autoEncodingCO, SIGNAL(activated(int)),
962                 this, SLOT(change_adaptor()));
963         connect(langModule->customEncodingCO, SIGNAL(activated(int)),
964                 this, SLOT(change_adaptor()));
965         connect(langModule->quoteStyleCO, SIGNAL(activated(int)),
966                 this, SLOT(change_adaptor()));
967         connect(langModule->languagePackageCO, SIGNAL(activated(int)),
968                 this, SLOT(change_adaptor()));
969         connect(langModule->languagePackageLE, SIGNAL(textChanged(QString)),
970                 this, SLOT(change_adaptor()));
971         connect(langModule->languagePackageCO, SIGNAL(currentIndexChanged(int)),
972                 this, SLOT(languagePackageChanged(int)));
973         connect(langModule->dynamicQuotesCB, SIGNAL(clicked()),
974                 this, SLOT(change_adaptor()));
975
976         langModule->languagePackageLE->setValidator(new NoNewLineValidator(
977                 langModule->languagePackageLE));
978
979         QAbstractItemModel * language_model = guiApp->languageModel();
980         // FIXME: it would be nice if sorting was enabled/disabled via a checkbox.
981         language_model->sort(0);
982         langModule->languageCO->setModel(language_model);
983         langModule->languageCO->setModelColumn(0);
984
985         langModule->encodingCO->addItem(qt_("Unicode (utf8)"));
986         langModule->encodingCO->addItem(qt_("Traditional (auto-selected)"));
987         langModule->encodingCO->addItem(qt_("Custom"));
988         langModule->encodingCO->setItemData(EncodingSets::unicode,
989                 qt_("Select Unicode (utf8) encoding."), Qt::ToolTipRole);
990         langModule->encodingCO->setItemData(EncodingSets::legacy,
991                 qt_("Use language-dependent traditional encodings."), Qt::ToolTipRole);
992         langModule->encodingCO->setItemData(EncodingSets::custom,
993                 qt_("Select a custom, document-wide encoding."), Qt::ToolTipRole);
994
995         // basic Unicode encodings: keep order
996         const QStringList utf8_base_encodings = {"utf8", "utf8-plain", "utf8x"};
997         for (auto const & i : utf8_base_encodings) {
998                 langModule->unicodeEncodingCO->addItem(
999                                         qt_(encodings.fromLyXName(fromqstr(i))->guiName()), i);
1000         }
1001         langModule->unicodeEncodingCO->setItemData(0,
1002                 qt_("Standard Unicode support by the ``inputenc'' package."),
1003                 Qt::ToolTipRole);
1004         langModule->unicodeEncodingCO->setItemData(1,
1005                 qt_("Use UTF-8 'as-is': do not load any supporting packages, "
1006                         "do not convert any characters to LaTeX macros. "
1007                         "For use with non-TeX fonts (XeTeX/LuaTeX) or custom preamble code."),
1008                 Qt::ToolTipRole);
1009         langModule->unicodeEncodingCO->setItemData(2,
1010                 qt_("Load ``inputenc'' with option 'utf8x' "
1011                         "for extended Unicode support by the ``ucs'' package."),
1012                 Qt::ToolTipRole);
1013         langModule->autoEncodingCO->addItem(qt_("Language Default"), toqstr("auto-legacy"));
1014         langModule->autoEncodingCO->addItem(qt_("Language Default (no inputenc)"), toqstr("auto-legacy-plain"));
1015         langModule->autoEncodingCO->setItemData(0,
1016                 qt_("Use the traditional default encoding of the text language. Switch encoding "
1017                         "if a text part is set to a language with different default."),
1018                 Qt::ToolTipRole);
1019         langModule->autoEncodingCO->setItemData(1,
1020                 qt_("Do not load the 'inputenc' package. Switch encoding if required "
1021                         "but do not write input encoding switch commands to the source."),
1022                 Qt::ToolTipRole);
1023         // sort encodings
1024         QMap<QString,QString> encodingmap;
1025         QMap<QString,QString> encodingmap_utf8;
1026         for (auto const & encvar : encodings) {
1027                 if (encvar.unsafe() ||encvar.guiName().empty()
1028                     || utf8_base_encodings.contains(toqstr(encvar.name())))
1029                         continue;
1030                 if (std::string(encvar.name()).find("utf8") == 0)
1031                         encodingmap_utf8.insert(qt_(encvar.guiName()), toqstr(encvar.name()));
1032                 else
1033                         encodingmap.insert(qt_(encvar.guiName()), toqstr(encvar.name()));
1034         }
1035         for (auto const & i : encodingmap_utf8.keys()) {
1036                 langModule->unicodeEncodingCO->addItem(i, encodingmap_utf8.value(i));
1037         }
1038         for (auto const & i : encodingmap.keys()) {
1039                 langModule->customEncodingCO->addItem(i, encodingmap.value(i));
1040         }
1041         // equalise the width of encoding selectors
1042         langModule->autoEncodingCO->setMinimumSize(
1043                 langModule->unicodeEncodingCO->minimumSizeHint());
1044         langModule->customEncodingCO->setMinimumSize(
1045                 langModule->unicodeEncodingCO->minimumSizeHint());
1046
1047         langModule->languagePackageCO->addItem(
1048                 qt_("Default"), toqstr("default"));
1049         langModule->languagePackageCO->addItem(
1050                 qt_("Automatic"), toqstr("auto"));
1051         langModule->languagePackageCO->addItem(
1052                 qt_("Always Babel"), toqstr("babel"));
1053         langModule->languagePackageCO->addItem(
1054                 qt_("Custom"), toqstr("custom"));
1055         langModule->languagePackageCO->addItem(
1056                 qt_("None[[language package]]"), toqstr("none"));
1057
1058
1059         // fonts
1060         fontModule = new FontModule(this);
1061         connect(fontModule->osFontsCB, SIGNAL(clicked()),
1062                 this, SLOT(change_adaptor()));
1063         connect(fontModule->osFontsCB, SIGNAL(toggled(bool)),
1064                 this, SLOT(osFontsChanged(bool)));
1065         connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
1066                 this, SLOT(change_adaptor()));
1067         connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
1068                 this, SLOT(romanChanged(int)));
1069         connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
1070                 this, SLOT(change_adaptor()));
1071         connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
1072                 this, SLOT(sansChanged(int)));
1073         connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
1074                 this, SLOT(change_adaptor()));
1075         connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
1076                 this, SLOT(ttChanged(int)));
1077         connect(fontModule->fontsMathCO, SIGNAL(activated(int)),
1078                 this, SLOT(change_adaptor()));
1079         connect(fontModule->fontsMathCO, SIGNAL(activated(int)),
1080                 this, SLOT(mathFontChanged(int)));
1081         connect(fontModule->fontsDefaultCO, SIGNAL(activated(int)),
1082                 this, SLOT(change_adaptor()));
1083         connect(fontModule->fontencCO, SIGNAL(activated(int)),
1084                 this, SLOT(change_adaptor()));
1085         connect(fontModule->fontencCO, SIGNAL(activated(int)),
1086                 this, SLOT(fontencChanged(int)));
1087         connect(fontModule->fontencLE, SIGNAL(textChanged(const QString &)),
1088                 this, SLOT(change_adaptor()));
1089         connect(fontModule->fontsizeCO, SIGNAL(activated(int)),
1090                 this, SLOT(change_adaptor()));
1091         connect(fontModule->cjkFontLE, SIGNAL(textChanged(const QString &)),
1092                 this, SLOT(change_adaptor()));
1093         connect(fontModule->microtypeCB, SIGNAL(clicked()),
1094                 this, SLOT(change_adaptor()));
1095         connect(fontModule->dashesCB, SIGNAL(clicked()),
1096                 this, SLOT(change_adaptor()));
1097         connect(fontModule->scaleSansSB, SIGNAL(valueChanged(int)),
1098                 this, SLOT(change_adaptor()));
1099         connect(fontModule->scaleTypewriterSB, SIGNAL(valueChanged(int)),
1100                 this, SLOT(change_adaptor()));
1101         connect(fontModule->fontScCB, SIGNAL(clicked()),
1102                 this, SLOT(change_adaptor()));
1103         connect(fontModule->fontScCB, SIGNAL(toggled(bool)),
1104                 this, SLOT(fontScToggled(bool)));
1105         connect(fontModule->fontOsfCB, SIGNAL(clicked()),
1106                 this, SLOT(change_adaptor()));
1107         connect(fontModule->fontOsfCB, SIGNAL(toggled(bool)),
1108                 this, SLOT(fontOsfToggled(bool)));
1109         connect(fontModule->fontSansOsfCB, SIGNAL(clicked()),
1110                 this, SLOT(change_adaptor()));
1111         connect(fontModule->fontTypewriterOsfCB, SIGNAL(clicked()),
1112                 this, SLOT(change_adaptor()));
1113         connect(fontModule->fontspecRomanLE, SIGNAL(textChanged(const QString &)),
1114                 this, SLOT(change_adaptor()));
1115         connect(fontModule->fontspecSansLE, SIGNAL(textChanged(const QString &)),
1116                 this, SLOT(change_adaptor()));
1117         connect(fontModule->fontspecTypewriterLE, SIGNAL(textChanged(const QString &)),
1118                 this, SLOT(change_adaptor()));
1119
1120         fontModule->fontencLE->setValidator(new NoNewLineValidator(
1121                 fontModule->fontencLE));
1122         fontModule->cjkFontLE->setValidator(new NoNewLineValidator(
1123                 fontModule->cjkFontLE));
1124         fontModule->fontspecRomanLE->setValidator(new NoNewLineValidator(
1125                 fontModule->fontspecRomanLE));
1126         fontModule->fontspecSansLE->setValidator(new NoNewLineValidator(
1127                 fontModule->fontspecSansLE));
1128         fontModule->fontspecTypewriterLE->setValidator(new NoNewLineValidator(
1129                 fontModule->fontspecTypewriterLE));
1130
1131         updateFontlist();
1132
1133         fontModule->fontsizeCO->addItem(qt_("Default"));
1134         fontModule->fontsizeCO->addItem(qt_("10"));
1135         fontModule->fontsizeCO->addItem(qt_("11"));
1136         fontModule->fontsizeCO->addItem(qt_("12"));
1137
1138         fontModule->fontencCO->addItem(qt_("Automatic[[encoding]]"), QString("auto"));
1139         fontModule->fontencCO->addItem(qt_("Class Default"), QString("default"));
1140         fontModule->fontencCO->addItem(qt_("Custom"), QString("custom"));
1141
1142         for (int n = 0; GuiDocument::fontfamilies_gui[n][0]; ++n)
1143                 fontModule->fontsDefaultCO->addItem(
1144                         qt_(GuiDocument::fontfamilies_gui[n]));
1145
1146         if (!LaTeXFeatures::isAvailable("fontspec"))
1147                 fontModule->osFontsCB->setToolTip(
1148                         qt_("Use OpenType and TrueType fonts directly (requires XeTeX or LuaTeX)\n"
1149                             "You need to install the package \"fontspec\" to use this feature"));
1150
1151
1152         // page layout
1153         pageLayoutModule = new UiWidget<Ui::PageLayoutUi>(this);
1154         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
1155                 this, SLOT(papersizeChanged(int)));
1156         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
1157                 this, SLOT(papersizeChanged(int)));
1158         connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
1159                 this, SLOT(change_adaptor()));
1160         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
1161                 this, SLOT(change_adaptor()));
1162         connect(pageLayoutModule->paperheightLE, SIGNAL(textChanged(const QString &)),
1163                 this, SLOT(change_adaptor()));
1164         connect(pageLayoutModule->paperwidthLE, SIGNAL(textChanged(const QString &)),
1165                 this, SLOT(change_adaptor()));
1166         connect(pageLayoutModule->paperwidthUnitCO, SIGNAL(activated(int)),
1167                 this, SLOT(change_adaptor()));
1168         connect(pageLayoutModule->paperheightUnitCO, SIGNAL(activated(int)),
1169                 this, SLOT(change_adaptor()));
1170         connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
1171                 this, SLOT(change_adaptor()));
1172         connect(pageLayoutModule->landscapeRB, SIGNAL(clicked()),
1173                 this, SLOT(change_adaptor()));
1174         connect(pageLayoutModule->facingPagesCB, SIGNAL(clicked()),
1175                 this, SLOT(change_adaptor()));
1176         connect(pageLayoutModule->pagestyleCO, SIGNAL(activated(int)),
1177                 this, SLOT(change_adaptor()));
1178
1179         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1180         pageLayoutModule->pagestyleCO->addItem(qt_("empty"));
1181         pageLayoutModule->pagestyleCO->addItem(qt_("plain"));
1182         pageLayoutModule->pagestyleCO->addItem(qt_("headings"));
1183         pageLayoutModule->pagestyleCO->addItem(qt_("fancy"));
1184         bc().addCheckedLineEdit(pageLayoutModule->paperheightLE,
1185                 pageLayoutModule->paperheightL);
1186         bc().addCheckedLineEdit(pageLayoutModule->paperwidthLE,
1187                 pageLayoutModule->paperwidthL);
1188
1189         QComboBox * cb = pageLayoutModule->papersizeCO;
1190         cb->addItem(qt_("Default"));
1191         cb->addItem(qt_("Custom"));
1192         cb->addItem(qt_("US letter"));
1193         cb->addItem(qt_("US legal"));
1194         cb->addItem(qt_("US executive"));
1195         cb->addItem(qt_("A0"));
1196         cb->addItem(qt_("A1"));
1197         cb->addItem(qt_("A2"));
1198         cb->addItem(qt_("A3"));
1199         cb->addItem(qt_("A4"));
1200         cb->addItem(qt_("A5"));
1201         cb->addItem(qt_("A6"));
1202         cb->addItem(qt_("B0"));
1203         cb->addItem(qt_("B1"));
1204         cb->addItem(qt_("B2"));
1205         cb->addItem(qt_("B3"));
1206         cb->addItem(qt_("B4"));
1207         cb->addItem(qt_("B5"));
1208         cb->addItem(qt_("B6"));
1209         cb->addItem(qt_("C0"));
1210         cb->addItem(qt_("C1"));
1211         cb->addItem(qt_("C2"));
1212         cb->addItem(qt_("C3"));
1213         cb->addItem(qt_("C4"));
1214         cb->addItem(qt_("C5"));
1215         cb->addItem(qt_("C6"));
1216         cb->addItem(qt_("JIS B0"));
1217         cb->addItem(qt_("JIS B1"));
1218         cb->addItem(qt_("JIS B2"));
1219         cb->addItem(qt_("JIS B3"));
1220         cb->addItem(qt_("JIS B4"));
1221         cb->addItem(qt_("JIS B5"));
1222         cb->addItem(qt_("JIS B6"));
1223         // remove the %-items from the unit choice
1224         pageLayoutModule->paperwidthUnitCO->noPercents();
1225         pageLayoutModule->paperheightUnitCO->noPercents();
1226         pageLayoutModule->paperheightLE->setValidator(unsignedLengthValidator(
1227                 pageLayoutModule->paperheightLE));
1228         pageLayoutModule->paperwidthLE->setValidator(unsignedLengthValidator(
1229                 pageLayoutModule->paperwidthLE));
1230
1231
1232         // margins
1233         marginsModule = new UiWidget<Ui::MarginsUi>(this);
1234         connect(marginsModule->marginCB, SIGNAL(toggled(bool)),
1235                 this, SLOT(setCustomMargins(bool)));
1236         connect(marginsModule->marginCB, SIGNAL(clicked()),
1237                 this, SLOT(change_adaptor()));
1238         connect(marginsModule->topLE, SIGNAL(textChanged(QString)),
1239                 this, SLOT(change_adaptor()));
1240         connect(marginsModule->topUnit, SIGNAL(activated(int)),
1241                 this, SLOT(change_adaptor()));
1242         connect(marginsModule->bottomLE, SIGNAL(textChanged(QString)),
1243                 this, SLOT(change_adaptor()));
1244         connect(marginsModule->bottomUnit, SIGNAL(activated(int)),
1245                 this, SLOT(change_adaptor()));
1246         connect(marginsModule->innerLE, SIGNAL(textChanged(QString)),
1247                 this, SLOT(change_adaptor()));
1248         connect(marginsModule->innerUnit, SIGNAL(activated(int)),
1249                 this, SLOT(change_adaptor()));
1250         connect(marginsModule->outerLE, SIGNAL(textChanged(QString)),
1251                 this, SLOT(change_adaptor()));
1252         connect(marginsModule->outerUnit, SIGNAL(activated(int)),
1253                 this, SLOT(change_adaptor()));
1254         connect(marginsModule->headheightLE, SIGNAL(textChanged(QString)),
1255                 this, SLOT(change_adaptor()));
1256         connect(marginsModule->headheightUnit, SIGNAL(activated(int)),
1257                 this, SLOT(change_adaptor()));
1258         connect(marginsModule->headsepLE, SIGNAL(textChanged(QString)),
1259                 this, SLOT(change_adaptor()));
1260         connect(marginsModule->headsepUnit, SIGNAL(activated(int)),
1261                 this, SLOT(change_adaptor()));
1262         connect(marginsModule->footskipLE, SIGNAL(textChanged(QString)),
1263                 this, SLOT(change_adaptor()));
1264         connect(marginsModule->footskipUnit, SIGNAL(activated(int)),
1265                 this, SLOT(change_adaptor()));
1266         connect(marginsModule->columnsepLE, SIGNAL(textChanged(QString)),
1267                 this, SLOT(change_adaptor()));
1268         connect(marginsModule->columnsepUnit, SIGNAL(activated(int)),
1269                 this, SLOT(change_adaptor()));
1270         marginsModule->topLE->setValidator(new LengthValidator(
1271                 marginsModule->topLE));
1272         marginsModule->bottomLE->setValidator(new LengthValidator(
1273                 marginsModule->bottomLE));
1274         marginsModule->innerLE->setValidator(new LengthValidator(
1275                 marginsModule->innerLE));
1276         marginsModule->outerLE->setValidator(new LengthValidator(
1277                 marginsModule->outerLE));
1278         marginsModule->headsepLE->setValidator(new LengthValidator(
1279                 marginsModule->headsepLE));
1280         marginsModule->headheightLE->setValidator(new LengthValidator(
1281                 marginsModule->headheightLE));
1282         marginsModule->footskipLE->setValidator(new LengthValidator(
1283                 marginsModule->footskipLE));
1284         marginsModule->columnsepLE->setValidator(new LengthValidator(
1285                 marginsModule->columnsepLE));
1286
1287         bc().addCheckedLineEdit(marginsModule->topLE,
1288                 marginsModule->topL);
1289         bc().addCheckedLineEdit(marginsModule->bottomLE,
1290                 marginsModule->bottomL);
1291         bc().addCheckedLineEdit(marginsModule->innerLE,
1292                 marginsModule->innerL);
1293         bc().addCheckedLineEdit(marginsModule->outerLE,
1294                 marginsModule->outerL);
1295         bc().addCheckedLineEdit(marginsModule->headsepLE,
1296                 marginsModule->headsepL);
1297         bc().addCheckedLineEdit(marginsModule->headheightLE,
1298                 marginsModule->headheightL);
1299         bc().addCheckedLineEdit(marginsModule->footskipLE,
1300                 marginsModule->footskipL);
1301         bc().addCheckedLineEdit(marginsModule->columnsepLE,
1302                 marginsModule->columnsepL);
1303
1304
1305         // color
1306         colorModule = new UiWidget<Ui::ColorUi>(this);
1307         connect(colorModule->fontColorPB, SIGNAL(clicked()),
1308                 this, SLOT(changeFontColor()));
1309         connect(colorModule->delFontColorTB, SIGNAL(clicked()),
1310                 this, SLOT(deleteFontColor()));
1311         connect(colorModule->noteFontColorPB, SIGNAL(clicked()),
1312                 this, SLOT(changeNoteFontColor()));
1313         connect(colorModule->delNoteFontColorTB, SIGNAL(clicked()),
1314                 this, SLOT(deleteNoteFontColor()));
1315         connect(colorModule->backgroundPB, SIGNAL(clicked()),
1316                 this, SLOT(changeBackgroundColor()));
1317         connect(colorModule->delBackgroundTB, SIGNAL(clicked()),
1318                 this, SLOT(deleteBackgroundColor()));
1319         connect(colorModule->boxBackgroundPB, SIGNAL(clicked()),
1320                 this, SLOT(changeBoxBackgroundColor()));
1321         connect(colorModule->delBoxBackgroundTB, SIGNAL(clicked()),
1322                 this, SLOT(deleteBoxBackgroundColor()));
1323
1324         // change tracking
1325         changesModule = new UiWidget<Ui::ChangeTrackingUi>(this);
1326         connect(changesModule->trackChangesCB, SIGNAL(clicked()),
1327                 this, SLOT(change_adaptor()));
1328         connect(changesModule->outputChangesCB, SIGNAL(toggled(bool)),
1329                 this, SLOT(outputChangesToggled(bool)));
1330         connect(changesModule->changeBarsCB, SIGNAL(clicked()),
1331                 this, SLOT(change_adaptor()));
1332
1333         // numbering
1334         numberingModule = new UiWidget<Ui::NumberingUi>(this);
1335         connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
1336                 this, SLOT(change_adaptor()));
1337         connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
1338                 this, SLOT(change_adaptor()));
1339         connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
1340                 this, SLOT(updateNumbering()));
1341         connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
1342                 this, SLOT(updateNumbering()));
1343         numberingModule->tocTW->setColumnCount(3);
1344         numberingModule->tocTW->headerItem()->setText(0, qt_("Example"));
1345         numberingModule->tocTW->headerItem()->setText(1, qt_("Numbered"));
1346         numberingModule->tocTW->headerItem()->setText(2, qt_("Appears in TOC"));
1347         setSectionResizeMode(numberingModule->tocTW->header(), QHeaderView::ResizeToContents);
1348         connect(numberingModule->linenoCB, SIGNAL(toggled(bool)),
1349                 this, SLOT(linenoToggled(bool)));
1350         connect(numberingModule->linenoCB, SIGNAL(clicked()),
1351                 this, SLOT(change_adaptor()));
1352         connect(numberingModule->linenoLE, SIGNAL(textChanged(QString)),
1353                 this, SLOT(change_adaptor()));
1354
1355
1356         // biblio
1357         biblioModule = new UiWidget<Ui::BiblioUi>(this);
1358         connect(biblioModule->citeEngineCO, SIGNAL(activated(int)),
1359                 this, SLOT(citeEngineChanged(int)));
1360         connect(biblioModule->citeStyleCO, SIGNAL(activated(int)),
1361                 this, SLOT(citeStyleChanged()));
1362         connect(biblioModule->bibtopicCB, SIGNAL(clicked()),
1363                 this, SLOT(biblioChanged()));
1364         connect(biblioModule->bibunitsCO, SIGNAL(activated(int)),
1365                 this, SLOT(biblioChanged()));
1366         connect(biblioModule->bibtexCO, SIGNAL(activated(int)),
1367                 this, SLOT(bibtexChanged(int)));
1368         connect(biblioModule->bibtexOptionsLE, SIGNAL(textChanged(QString)),
1369                 this, SLOT(biblioChanged()));
1370         connect(biblioModule->citePackageOptionsLE, SIGNAL(textChanged(QString)),
1371                 this, SLOT(biblioChanged()));
1372         connect(biblioModule->defaultBiblioCO, SIGNAL(activated(int)),
1373                 this, SLOT(biblioChanged()));
1374         connect(biblioModule->defaultBiblioCO, SIGNAL(editTextChanged(QString)),
1375                 this, SLOT(biblioChanged()));
1376         connect(biblioModule->defaultBiblioCO, SIGNAL(editTextChanged(QString)),
1377                 this, SLOT(updateResetDefaultBiblio()));
1378         connect(biblioModule->biblatexBbxCO, SIGNAL(activated(int)),
1379                 this, SLOT(biblioChanged()));
1380         connect(biblioModule->biblatexBbxCO, SIGNAL(editTextChanged(QString)),
1381                 this, SLOT(biblioChanged()));
1382         connect(biblioModule->biblatexBbxCO, SIGNAL(editTextChanged(QString)),
1383                 this, SLOT(updateResetDefaultBiblio()));
1384         connect(biblioModule->biblatexCbxCO, SIGNAL(activated(int)),
1385                 this, SLOT(biblioChanged()));
1386         connect(biblioModule->biblatexCbxCO, SIGNAL(editTextChanged(QString)),
1387                 this, SLOT(biblioChanged()));
1388         connect(biblioModule->biblatexCbxCO, SIGNAL(editTextChanged(QString)),
1389                 this, SLOT(updateResetDefaultBiblio()));
1390         connect(biblioModule->rescanBibliosPB, SIGNAL(clicked()),
1391                 this, SLOT(rescanBibFiles()));
1392         connect(biblioModule->resetDefaultBiblioPB, SIGNAL(clicked()),
1393                 this, SLOT(resetDefaultBibfile()));
1394         connect(biblioModule->resetCbxPB, SIGNAL(clicked()),
1395                 this, SLOT(resetDefaultCbxBibfile()));
1396         connect(biblioModule->resetBbxPB, SIGNAL(clicked()),
1397                 this, SLOT(resetDefaultBbxBibfile()));
1398         connect(biblioModule->matchBbxPB, SIGNAL(clicked()),
1399                 this, SLOT(matchBiblatexStyles()));
1400
1401         biblioModule->citeEngineCO->clear();
1402         for (LyXCiteEngine const & cet : theCiteEnginesList) {
1403                 biblioModule->citeEngineCO->addItem(qt_(cet.getName()), toqstr(cet.getID()));
1404                 int const i = biblioModule->citeEngineCO->findData(toqstr(cet.getID()));
1405                 biblioModule->citeEngineCO->setItemData(i, qt_(cet.getDescription()),
1406                                                         Qt::ToolTipRole);
1407         }
1408
1409         biblioModule->bibtexOptionsLE->setValidator(new NoNewLineValidator(
1410                 biblioModule->bibtexOptionsLE));
1411         biblioModule->defaultBiblioCO->lineEdit()->setValidator(new NoNewLineValidator(
1412                 biblioModule->defaultBiblioCO->lineEdit()));
1413         biblioModule->citePackageOptionsLE->setValidator(new NoNewLineValidator(
1414                 biblioModule->citePackageOptionsLE));
1415
1416         // NOTE: we do not provide "custom" here for security reasons!
1417         biblioModule->bibtexCO->clear();
1418         biblioModule->bibtexCO->addItem(qt_("Default"), QString("default"));
1419         for (auto const & alts : lyxrc.bibtex_alternatives) {
1420                 QString const command = toqstr(alts).left(toqstr(alts).indexOf(" "));
1421                 biblioModule->bibtexCO->addItem(command, command);
1422         }
1423
1424
1425         // indices
1426         indicesModule = new GuiIndices;
1427         connect(indicesModule, SIGNAL(changed()),
1428                 this, SLOT(change_adaptor()));
1429
1430
1431         // maths
1432         mathsModule = new UiWidget<Ui::MathsUi>(this);
1433         QStringList headers;
1434         headers << qt_("Package") << qt_("Load automatically")
1435                 << qt_("Load always") << qt_("Do not load");
1436         mathsModule->packagesTW->setHorizontalHeaderLabels(headers);
1437         setSectionResizeMode(mathsModule->packagesTW->horizontalHeader(), QHeaderView::Stretch);
1438         map<string, string> const & packages = BufferParams::auto_packages();
1439         mathsModule->packagesTW->setRowCount(packages.size());
1440         int packnum = 0;
1441         for (auto const & pkgvar : packages) {
1442                 docstring const package = from_ascii(pkgvar.first);
1443                 QString autoTooltip = qt_(pkgvar.second);
1444                 QString alwaysTooltip;
1445                 if (package == "amsmath")
1446                         alwaysTooltip =
1447                                 qt_("The AMS LaTeX packages are always used");
1448                 else
1449                         alwaysTooltip = toqstr(bformat(
1450                                 _("The LaTeX package %1$s is always used"),
1451                                 package));
1452                 QString neverTooltip;
1453                 if (package == "amsmath")
1454                         neverTooltip =
1455                                 qt_("The AMS LaTeX packages are never used");
1456                 else
1457                         neverTooltip = toqstr(bformat(
1458                                 _("The LaTeX package %1$s is never used"),
1459                                 package));
1460                 QRadioButton * autoRB = new QRadioButton(mathsModule);
1461                 QRadioButton * alwaysRB = new QRadioButton(mathsModule);
1462                 QRadioButton * neverRB = new QRadioButton(mathsModule);
1463                 QButtonGroup * packageGroup = new QButtonGroup(mathsModule);
1464                 packageGroup->addButton(autoRB);
1465                 packageGroup->addButton(alwaysRB);
1466                 packageGroup->addButton(neverRB);
1467                 autoRB->setToolTip(autoTooltip);
1468                 alwaysRB->setToolTip(alwaysTooltip);
1469                 neverRB->setToolTip(neverTooltip);
1470
1471                 // Pack the buttons in a layout in order to get proper alignment
1472                 QWidget * autoRBWidget = new QWidget();
1473                 QHBoxLayout * autoRBLayout = new QHBoxLayout(autoRBWidget);
1474                 autoRBLayout->addWidget(autoRB);
1475                 autoRBLayout->setAlignment(Qt::AlignCenter);
1476                 autoRBLayout->setContentsMargins(0, 0, 0, 0);
1477                 autoRBWidget->setLayout(autoRBLayout);
1478
1479                 QWidget * alwaysRBWidget = new QWidget();
1480                 QHBoxLayout * alwaysRBLayout = new QHBoxLayout(alwaysRBWidget);
1481                 alwaysRBLayout->addWidget(alwaysRB);
1482                 alwaysRBLayout->setAlignment(Qt::AlignCenter);
1483                 alwaysRBLayout->setContentsMargins(0, 0, 0, 0);
1484                 alwaysRBWidget->setLayout(alwaysRBLayout);
1485
1486                 QWidget * neverRBWidget = new QWidget();
1487                 QHBoxLayout * neverRBLayout = new QHBoxLayout(neverRBWidget);
1488                 neverRBLayout->addWidget(neverRB);
1489                 neverRBLayout->setAlignment(Qt::AlignCenter);
1490                 neverRBLayout->setContentsMargins(0, 0, 0, 0);
1491                 neverRBWidget->setLayout(neverRBLayout);
1492
1493                 QTableWidgetItem * pack = new QTableWidgetItem(toqstr(package));
1494                 mathsModule->packagesTW->setItem(packnum, 0, pack);
1495                 mathsModule->packagesTW->setCellWidget(packnum, 1, autoRBWidget);
1496                 mathsModule->packagesTW->setCellWidget(packnum, 2, alwaysRBWidget);
1497                 mathsModule->packagesTW->setCellWidget(packnum, 3, neverRBWidget);
1498
1499                 connect(autoRB, SIGNAL(clicked()),
1500                         this, SLOT(change_adaptor()));
1501                 connect(alwaysRB, SIGNAL(clicked()),
1502                         this, SLOT(change_adaptor()));
1503                 connect(neverRB, SIGNAL(clicked()),
1504                         this, SLOT(change_adaptor()));
1505                 ++packnum;
1506         }
1507         connect(mathsModule->allPackagesAutoPB, SIGNAL(clicked()),
1508                 this, SLOT(allPackagesAuto()));
1509         connect(mathsModule->allPackagesAlwaysPB, SIGNAL(clicked()),
1510                 this, SLOT(allPackagesAlways()));
1511         connect(mathsModule->allPackagesNotPB, SIGNAL(clicked()),
1512                 this, SLOT(allPackagesNot()));
1513         connect(mathsModule->allPackagesAutoPB, SIGNAL(clicked()),
1514                 this, SLOT(change_adaptor()));
1515         connect(mathsModule->allPackagesAlwaysPB, SIGNAL(clicked()),
1516                 this, SLOT(change_adaptor()));
1517         connect(mathsModule->allPackagesNotPB, SIGNAL(clicked()),
1518                 this, SLOT(change_adaptor()));
1519         connect(mathsModule->MathNumberingPosCO, SIGNAL(activated(int)),
1520                 this, SLOT(change_adaptor()));
1521
1522         connect(mathsModule->MathIndentCB, SIGNAL(toggled(bool)),
1523                 this, SLOT(change_adaptor()));
1524         connect(mathsModule->MathIndentCB, SIGNAL(toggled(bool)),
1525                 this, SLOT(allowMathIndent()));
1526         connect(mathsModule->MathIndentCO, SIGNAL(activated(int)),
1527                 this, SLOT(change_adaptor()));
1528         connect(mathsModule->MathIndentCO, SIGNAL(activated(int)),
1529                 this, SLOT(enableMathIndent(int)));
1530         connect(mathsModule->MathIndentLE, SIGNAL(textChanged(const QString &)),
1531                 this, SLOT(change_adaptor()));
1532         connect(mathsModule->MathIndentLengthCO, SIGNAL(activated(int)),
1533                 this, SLOT(change_adaptor()));
1534
1535
1536         mathsModule->MathIndentCO->addItem(qt_("Default"));
1537         mathsModule->MathIndentCO->addItem(qt_("Custom"));
1538         mathsModule->MathIndentLE->setValidator(new LengthValidator(
1539                 mathsModule->MathIndentLE));
1540         // initialize the length validator
1541         bc().addCheckedLineEdit(mathsModule->MathIndentLE);
1542         mathsModule->MathNumberingPosCO->addItem(qt_("Left"));
1543         mathsModule->MathNumberingPosCO->addItem(qt_("Default"));
1544         mathsModule->MathNumberingPosCO->addItem(qt_("Right"));
1545         mathsModule->MathNumberingPosCO->setCurrentIndex(1);
1546
1547
1548         // latex class
1549         latexModule = new UiWidget<Ui::LaTeXUi>(this);
1550         connect(latexModule->optionsLE, SIGNAL(textChanged(QString)),
1551                 this, SLOT(change_adaptor()));
1552         connect(latexModule->defaultOptionsCB, SIGNAL(clicked()),
1553                 this, SLOT(change_adaptor()));
1554         connect(latexModule->psdriverCO, SIGNAL(activated(int)),
1555                 this, SLOT(change_adaptor()));
1556         connect(latexModule->classCO, SIGNAL(activated(int)),
1557                 this, SLOT(classChanged_adaptor()));
1558         connect(latexModule->classCO, SIGNAL(activated(int)),
1559                 this, SLOT(change_adaptor()));
1560         connect(latexModule->layoutPB, SIGNAL(clicked()),
1561                 this, SLOT(browseLayout()));
1562         connect(latexModule->layoutPB, SIGNAL(clicked()),
1563                 this, SLOT(change_adaptor()));
1564         connect(latexModule->childDocGB, SIGNAL(clicked()),
1565                 this, SLOT(change_adaptor()));
1566         connect(latexModule->childDocLE, SIGNAL(textChanged(QString)),
1567                 this, SLOT(change_adaptor()));
1568         connect(latexModule->childDocPB, SIGNAL(clicked()),
1569                 this, SLOT(browseMaster()));
1570         connect(latexModule->suppressDateCB, SIGNAL(clicked()),
1571                 this, SLOT(change_adaptor()));
1572         connect(latexModule->refstyleCB, SIGNAL(clicked()),
1573                 this, SLOT(change_adaptor()));
1574
1575         latexModule->optionsLE->setValidator(new NoNewLineValidator(
1576                 latexModule->optionsLE));
1577         latexModule->childDocLE->setValidator(new NoNewLineValidator(
1578                 latexModule->childDocLE));
1579
1580         // postscript drivers
1581         for (int n = 0; tex_graphics[n][0]; ++n) {
1582                 QString enc = qt_(tex_graphics_gui[n]);
1583                 latexModule->psdriverCO->addItem(enc);
1584         }
1585         // latex classes
1586         LayoutFileList const & bcl = LayoutFileList::get();
1587         vector<LayoutFileIndex> classList = bcl.classList();
1588         sort(classList.begin(), classList.end(), less_textclass_avail_desc());
1589
1590         for (auto const & cvar : classList) {
1591                 LayoutFile const & tc = bcl[cvar];
1592                 bool const available = tc.isTeXClassAvailable();
1593                 docstring const guiname = translateIfPossible(from_utf8(tc.description()));
1594                 // tooltip sensu "KOMA-Script Article [Class 'scrartcl']"
1595                 QString tooltip = toqstr(bformat(_("%1$s [Class '%2$s']"), guiname, from_utf8(tc.latexname())));
1596                 if (!available) {
1597                         docstring const output_type = _("LaTeX");
1598                         tooltip += '\n' + toqstr(bformat(_("Class not found by LyX. "
1599                                                            "Please check if you have the matching %1$s class "
1600                                                            "and all required packages (%2$s) installed."),
1601                                                          output_type, from_utf8(tc.prerequisites(", "))));
1602                 }
1603                 latexModule->classCO->addItemSort(toqstr(tc.name()),
1604                                                   toqstr(guiname),
1605                                                   toqstr(translateIfPossible(from_utf8(tc.category()))),
1606                                                   tooltip,
1607                                                   true, true, true, available);
1608         }
1609
1610
1611         // branches
1612         branchesModule = new GuiBranches(this);
1613         connect(branchesModule, SIGNAL(changed()),
1614                 this, SLOT(change_adaptor()));
1615         connect(branchesModule, SIGNAL(renameBranches(docstring const &, docstring const &)),
1616                 this, SLOT(branchesRename(docstring const &, docstring const &)));
1617         connect(branchesModule, SIGNAL(okPressed()), this, SLOT(slotOK()));
1618         updateUnknownBranches();
1619
1620
1621         // preamble
1622         preambleModule = new PreambleModule(this);
1623         connect(preambleModule, SIGNAL(changed()),
1624                 this, SLOT(change_adaptor()));
1625
1626         localLayout = new LocalLayout(this);
1627         connect(localLayout, SIGNAL(changed()),
1628                 this, SLOT(change_adaptor()));
1629
1630
1631         // bullets
1632         bulletsModule = new BulletsModule(this);
1633         connect(bulletsModule, SIGNAL(changed()),
1634                 this, SLOT(change_adaptor()));
1635
1636
1637         // Modules
1638         modulesModule = new UiWidget<Ui::ModulesUi>(this);
1639         modulesModule->availableLV->header()->setVisible(false);
1640         setSectionResizeMode(modulesModule->availableLV->header(), QHeaderView::ResizeToContents);
1641         modulesModule->availableLV->header()->setStretchLastSection(false);
1642         modulesModule->selectedLV->header()->setVisible(false);
1643         setSectionResizeMode(modulesModule->selectedLV->header(), QHeaderView::ResizeToContents);
1644         modulesModule->selectedLV->header()->setStretchLastSection(false);
1645         selectionManager =
1646                 new ModuleSelectionManager(this, modulesModule->availableLV,
1647                                            modulesModule->selectedLV,
1648                                            modulesModule->addPB,
1649                                            modulesModule->deletePB,
1650                                            modulesModule->upPB,
1651                                            modulesModule->downPB,
1652                                            availableModel(), selectedModel(), this);
1653         connect(selectionManager, SIGNAL(updateHook()),
1654                 this, SLOT(updateModuleInfo()));
1655         connect(selectionManager, SIGNAL(selectionChanged()),
1656                 this, SLOT(modulesChanged()));
1657         // The filter bar
1658         filter_ = new FancyLineEdit(this);
1659         filter_->setButtonPixmap(FancyLineEdit::Right, getPixmap("images/", "editclear", "svgz,png"));
1660         filter_->setButtonVisible(FancyLineEdit::Right, true);
1661         filter_->setButtonToolTip(FancyLineEdit::Right, qt_("Clear text"));
1662         filter_->setAutoHideButton(FancyLineEdit::Right, true);
1663         filter_->setPlaceholderText(qt_("All avail. modules"));
1664         modulesModule->moduleFilterBarL->addWidget(filter_, 0);
1665         modulesModule->findModulesLA->setBuddy(filter_);
1666
1667         connect(filter_, SIGNAL(rightButtonClicked()),
1668                 this, SLOT(resetModuleFilter()));
1669         connect(filter_, SIGNAL(textEdited(QString)),
1670                 this, SLOT(moduleFilterChanged(QString)));
1671         connect(filter_, SIGNAL(returnPressed()),
1672                 this, SLOT(moduleFilterPressed()));
1673 #if (QT_VERSION < 0x050000)
1674         connect(filter_, SIGNAL(downPressed()),
1675                 modulesModule->availableLV, SLOT(setFocus()));
1676 #else
1677         connect(filter_, &FancyLineEdit::downPressed,
1678                 modulesModule->availableLV, [this](){ focusAndHighlight(modulesModule->availableLV); });
1679 #endif
1680
1681
1682         // PDF support
1683         pdfSupportModule = new UiWidget<Ui::PDFSupportUi>(this);
1684         connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
1685                 this, SLOT(change_adaptor()));
1686         connect(pdfSupportModule->titleLE, SIGNAL(textChanged(QString)),
1687                 this, SLOT(change_adaptor()));
1688         connect(pdfSupportModule->authorLE, SIGNAL(textChanged(QString)),
1689                 this, SLOT(change_adaptor()));
1690         connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(QString)),
1691                 this, SLOT(change_adaptor()));
1692         connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(QString)),
1693                 this, SLOT(change_adaptor()));
1694         connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
1695                 this, SLOT(change_adaptor()));
1696         connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
1697                 this, SLOT(change_adaptor()));
1698         connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
1699                 this, SLOT(change_adaptor()));
1700         connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
1701                 this, SLOT(bookmarksopenChanged(bool)));
1702         connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
1703                 this, SLOT(change_adaptor()));
1704         connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
1705                 this, SLOT(change_adaptor()));
1706         connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
1707                 this, SLOT(change_adaptor()));
1708         connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
1709                 this, SLOT(change_adaptor()));
1710         connect(pdfSupportModule->backrefCO, SIGNAL(activated(int)),
1711                 this, SLOT(change_adaptor()));
1712         connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
1713                 this, SLOT(change_adaptor()));
1714         connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
1715                 this, SLOT(change_adaptor()));
1716         connect(pdfSupportModule->optionsLE, SIGNAL(textChanged(QString)),
1717                 this, SLOT(change_adaptor()));
1718
1719         pdfSupportModule->titleLE->setValidator(new NoNewLineValidator(
1720                 pdfSupportModule->titleLE));
1721         pdfSupportModule->authorLE->setValidator(new NoNewLineValidator(
1722                 pdfSupportModule->authorLE));
1723         pdfSupportModule->subjectLE->setValidator(new NoNewLineValidator(
1724                 pdfSupportModule->subjectLE));
1725         pdfSupportModule->keywordsLE->setValidator(new NoNewLineValidator(
1726                 pdfSupportModule->keywordsLE));
1727         pdfSupportModule->optionsLE->setValidator(new NoNewLineValidator(
1728                 pdfSupportModule->optionsLE));
1729
1730         for (int i = 0; backref_opts[i][0]; ++i)
1731                 pdfSupportModule->backrefCO->addItem(qt_(backref_opts_gui[i]));
1732
1733
1734         // float
1735         floatModule = new FloatPlacement;
1736         connect(floatModule, SIGNAL(changed()),
1737                 this, SLOT(change_adaptor()));
1738
1739
1740         // listings
1741         listingsModule = new UiWidget<Ui::ListingsSettingsUi>(this);
1742         connect(listingsModule->listingsED, SIGNAL(textChanged()),
1743                 this, SLOT(change_adaptor()));
1744         connect(listingsModule->bypassCB, SIGNAL(clicked()),
1745                 this, SLOT(change_adaptor()));
1746         connect(listingsModule->bypassCB, SIGNAL(clicked()),
1747                 this, SLOT(setListingsMessage()));
1748         connect(listingsModule->packageCO, SIGNAL(activated(int)),
1749                 this, SLOT(change_adaptor()));
1750         connect(listingsModule->packageCO, SIGNAL(activated(int)),
1751                 this, SLOT(listingsPackageChanged(int)));
1752         connect(listingsModule->listingsED, SIGNAL(textChanged()),
1753                 this, SLOT(setListingsMessage()));
1754         listingsModule->listingsTB->setPlainText(
1755                 qt_("Input listings parameters below. Enter ? for a list of parameters."));
1756
1757         for (int i = 0; lst_packages[i][0]; ++i)
1758             listingsModule->packageCO->addItem(lst_packages[i]);
1759
1760
1761         // add the panels
1762         docPS->addPanel(latexModule, N_("Document Class"));
1763         docPS->addPanel(masterChildModule, N_("Child Documents"));
1764         docPS->addPanel(modulesModule, N_("Modules"));
1765         docPS->addPanel(localLayout, N_("Local Layout"));
1766         docPS->addPanel(fontModule, N_("Fonts"));
1767         docPS->addPanel(textLayoutModule, N_("Text Layout"));
1768         docPS->addPanel(pageLayoutModule, N_("Page Layout"));
1769         docPS->addPanel(marginsModule, N_("Page Margins"));
1770         docPS->addPanel(langModule, N_("Language"));
1771         docPS->addPanel(colorModule, N_("Colors"));
1772         docPS->addPanel(changesModule, N_("Change Tracking"));
1773         docPS->addPanel(numberingModule, N_("Numbering & TOC"));
1774         docPS->addPanel(biblioModule, N_("Bibliography"));
1775         docPS->addPanel(indicesModule, N_("Indexes"));
1776         docPS->addPanel(pdfSupportModule, N_("PDF Properties"));
1777         docPS->addPanel(mathsModule, N_("Math Options"));
1778         docPS->addPanel(floatModule, N_("Float Settings"));
1779         docPS->addPanel(listingsModule, N_("Listings[[inset]]"));
1780         docPS->addPanel(bulletsModule, N_("Bullets"));
1781         docPS->addPanel(branchesModule, N_("Branches"));
1782         docPS->addPanel(outputModule, N_("Formats[[output]]"));
1783         docPS->addPanel(preambleModule, N_("LaTeX Preamble"));
1784         docPS->setCurrentPanel("Document Class");
1785 // FIXME: hack to work around resizing bug in Qt >= 4.2
1786 // bug verified with Qt 4.2.{0-3} (JSpitzm)
1787 #if QT_VERSION >= 0x040200
1788         docPS->updateGeometry();
1789 #endif
1790 }
1791
1792
1793 void GuiDocument::onBufferViewChanged()
1794 {
1795         if (isVisibleView())
1796                 initialiseParams("");
1797 }
1798
1799
1800 void GuiDocument::saveDefaultClicked()
1801 {
1802         saveDocDefault();
1803 }
1804
1805
1806 void GuiDocument::useDefaultsClicked()
1807 {
1808         useClassDefaults();
1809 }
1810
1811
1812 void GuiDocument::change_adaptor()
1813 {
1814         nonModuleChanged_ = true;
1815         changed();
1816 }
1817
1818
1819 void GuiDocument::shellescapeChanged()
1820 {
1821         shellescapeChanged_ = true;
1822         changed();
1823 }
1824
1825 void GuiDocument::bookmarksopenChanged(bool state)
1826 {
1827         pdfSupportModule->bookmarksopenlevelSB->setEnabled(state);
1828         pdfSupportModule->bookmarksopenlevelLA->setEnabled(state);
1829 }
1830
1831
1832 void GuiDocument::slotApply()
1833 {
1834         bool only_shellescape_changed = !nonModuleChanged_ && !modulesChanged_;
1835         bool wasclean = buffer().isClean();
1836         GuiDialog::slotApply();
1837         if (wasclean && only_shellescape_changed)
1838                 buffer().markClean();
1839         modulesChanged_ = false;
1840 }
1841
1842
1843 void GuiDocument::slotOK()
1844 {
1845         bool only_shellescape_changed = !nonModuleChanged_ && !modulesChanged_;
1846         bool wasclean = buffer().isClean();
1847         GuiDialog::slotOK();
1848         if (wasclean && only_shellescape_changed)
1849                 buffer().markClean();
1850         modulesChanged_ = false;
1851 }
1852
1853
1854 void GuiDocument::slotButtonBox(QAbstractButton * button)
1855 {
1856         switch (buttonBox->standardButton(button)) {
1857         case QDialogButtonBox::Ok:
1858                 slotOK();
1859                 break;
1860         case QDialogButtonBox::Apply:
1861                 slotApply();
1862                 break;
1863         case QDialogButtonBox::Cancel:
1864                 slotClose();
1865                 break;
1866         case QDialogButtonBox::Reset:
1867         case QDialogButtonBox::RestoreDefaults:
1868                 slotRestore();
1869                 break;
1870         default:
1871                 break;
1872         }
1873 }
1874
1875
1876 void GuiDocument::filterModules(QString const & str)
1877 {
1878         updateAvailableModules();
1879         if (str.isEmpty())
1880                 return;
1881
1882         modules_av_model_.clear();
1883         list<modInfoStruct> modInfoList = getModuleInfo();
1884         // Sort names according to the locale
1885         modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
1886                         return 0 < b.name.localeAwareCompare(a.name);
1887                 });
1888
1889         QIcon user_icon(getPixmap("images/", "lyxfiles-user", "svgz,png"));
1890         QIcon system_icon(getPixmap("images/", "lyxfiles-system", "svgz,png"));
1891
1892         int i = 0;
1893         for (modInfoStruct const & m : modInfoList) {
1894                 if (m.name.contains(str, Qt::CaseInsensitive) || contains(m.id, fromqstr(str))) {
1895                         QStandardItem * item = new QStandardItem();
1896                         item->setData(m.name, Qt::DisplayRole);
1897                         item->setData(toqstr(m.id), Qt::UserRole);
1898                         item->setData(m.description, Qt::ToolTipRole);
1899                         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         bp_.boxbgcolor = set_boxbgcolor;
3528         bp_.isboxbgcolor = is_boxbgcolor;
3529
3530         // numbering
3531         if (bp_.documentClass().hasTocLevels()) {
3532                 bp_.tocdepth = numberingModule->tocSL->value();
3533                 bp_.secnumdepth = numberingModule->depthSL->value();
3534         }
3535         bp_.use_lineno = numberingModule->linenoCB->isChecked();
3536         bp_.lineno_opts = fromqstr(numberingModule->linenoLE->text());
3537
3538         // bullets
3539         bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
3540         bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
3541         bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
3542         bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
3543
3544         // packages
3545         bp_.graphics_driver =
3546                 tex_graphics[latexModule->psdriverCO->currentIndex()];
3547
3548         // text layout
3549         int idx = latexModule->classCO->currentIndex();
3550         if (idx >= 0) {
3551                 string const classname = fromqstr(latexModule->classCO->getData(idx));
3552                 bp_.setBaseClass(classname, buffer().layoutPos());
3553         }
3554
3555         // Modules
3556         modulesToParams(bp_);
3557
3558         // Math
3559         map<string, string> const & packages = BufferParams::auto_packages();
3560         for (map<string, string>::const_iterator it = packages.begin();
3561              it != packages.end(); ++it) {
3562                 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
3563                 if (!item)
3564                         continue;
3565                 int row = mathsModule->packagesTW->row(item);
3566
3567                 QRadioButton * rb =
3568                         (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1)->layout()->itemAt(0)->widget();
3569                 if (rb->isChecked()) {
3570                         bp_.use_package(it->first, BufferParams::package_auto);
3571                         continue;
3572                 }
3573                 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2)->layout()->itemAt(0)->widget();
3574                 if (rb->isChecked()) {
3575                         bp_.use_package(it->first, BufferParams::package_on);
3576                         continue;
3577                 }
3578                 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3)->layout()->itemAt(0)->widget();
3579                 if (rb->isChecked())
3580                         bp_.use_package(it->first, BufferParams::package_off);
3581         }
3582         // if math is indented
3583         bp_.is_math_indent = mathsModule->MathIndentCB->isChecked();
3584         if (bp_.is_math_indent) {
3585                 // if formulas are indented
3586                 switch (mathsModule->MathIndentCO->currentIndex()) {
3587                 case 0:
3588                         bp_.setMathIndent(Length());
3589                         break;
3590                 case 1: {
3591                         Length mathindent(widgetsToLength(mathsModule->MathIndentLE,
3592                                                           mathsModule->MathIndentLengthCO));
3593                         bp_.setMathIndent(mathindent);
3594                         break;
3595                 }
3596                 default:
3597                         // this should never happen
3598                         bp_.setMathIndent(Length());
3599                         break;
3600                 }
3601         }
3602         switch (mathsModule->MathNumberingPosCO->currentIndex()) {
3603                 case 0:
3604                         bp_.math_numbering_side = BufferParams::LEFT;
3605                         break;
3606                 case 1:
3607                         bp_.math_numbering_side = BufferParams::DEFAULT;
3608                         break;
3609                 case 2:
3610                         bp_.math_numbering_side = BufferParams::RIGHT;
3611                         break;
3612                 default:
3613                         // this should never happen
3614                         bp_.math_numbering_side = BufferParams::DEFAULT;
3615                         break;
3616         }
3617
3618         // Page Layout
3619         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
3620                 bp_.pagestyle = "default";
3621         else {
3622                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
3623                 for (size_t i = 0; i != pagestyles.size(); ++i)
3624                         if (pagestyles[i].second == style_gui)
3625                                 bp_.pagestyle = pagestyles[i].first;
3626         }
3627
3628         // Text Layout
3629         switch (textLayoutModule->lspacingCO->currentIndex()) {
3630         case 0:
3631                 bp_.spacing().set(Spacing::Single);
3632                 break;
3633         case 1:
3634                 bp_.spacing().set(Spacing::Onehalf);
3635                 break;
3636         case 2:
3637                 bp_.spacing().set(Spacing::Double);
3638                 break;
3639         case 3: {
3640                 string s = widgetToDoubleStr(textLayoutModule->lspacingLE);
3641                 if (s.empty())
3642                         bp_.spacing().set(Spacing::Single);
3643                 else
3644                         bp_.spacing().set(Spacing::Other, s);
3645                 break;
3646                 }
3647         }
3648
3649         if (textLayoutModule->twoColumnCB->isChecked())
3650                 bp_.columns = 2;
3651         else
3652                 bp_.columns = 1;
3653
3654         bp_.justification = textLayoutModule->justCB->isChecked();
3655
3656         if (textLayoutModule->indentRB->isChecked()) {
3657                 // if paragraphs are separated by an indentation
3658                 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
3659                 switch (textLayoutModule->indentCO->currentIndex()) {
3660                 case 0:
3661                         bp_.setParIndent(Length());
3662                         break;
3663                 case 1: {
3664                         Length parindent(widgetsToLength(textLayoutModule->indentLE,
3665                                                          textLayoutModule->indentLengthCO));
3666                         bp_.setParIndent(parindent);
3667                         break;
3668                 }
3669                 default:
3670                         // this should never happen
3671                         bp_.setParIndent(Length());
3672                         break;
3673                 }
3674         } else {
3675                 // if paragraphs are separated by a skip
3676                 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
3677                 VSpace::VSpaceKind spacekind =
3678                         VSpace::VSpaceKind(textLayoutModule->skipCO->itemData(textLayoutModule->skipCO->currentIndex()).toInt());
3679                 switch (spacekind) {
3680                 case VSpace::SMALLSKIP:
3681                 case VSpace::MEDSKIP:
3682                 case VSpace::BIGSKIP:
3683                 case VSpace::HALFLINE:
3684                 case VSpace::FULLLINE:
3685                         bp_.setDefSkip(VSpace(spacekind));
3686                         break;
3687                 case VSpace::LENGTH: {
3688                         VSpace vs = VSpace(
3689                                 widgetsToLength(textLayoutModule->skipLE,
3690                                 textLayoutModule->skipLengthCO)
3691                                 );
3692                         bp_.setDefSkip(vs);
3693                         break;
3694                 }
3695                 default:
3696                         // this should never happen
3697                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
3698                         break;
3699                 }
3700         }
3701         bp_.tablestyle = fromqstr(textLayoutModule->tableStyleCO->itemData(
3702                                       textLayoutModule->tableStyleCO->currentIndex()).toString());
3703
3704         bp_.options =
3705                 fromqstr(latexModule->optionsLE->text());
3706
3707         bp_.use_default_options =
3708                 latexModule->defaultOptionsCB->isChecked();
3709
3710         if (latexModule->childDocGB->isChecked())
3711                 bp_.master =
3712                         fromqstr(latexModule->childDocLE->text());
3713         else
3714                 bp_.master = string();
3715
3716         // Master/Child
3717         bp_.clearIncludedChildren();
3718         if (masterChildModule->includeonlyRB->isChecked()) {
3719                 list<string>::const_iterator it = includeonlys_.begin();
3720                 for (; it != includeonlys_.end() ; ++it) {
3721                         bp_.addIncludedChildren(*it);
3722                 }
3723         }
3724         if (masterChildModule->maintainCRNoneRB->isChecked())
3725                 bp_.maintain_unincluded_children =
3726                         BufferParams::CM_None;
3727         else if (masterChildModule->maintainCRMostlyRB->isChecked())
3728                 bp_.maintain_unincluded_children =
3729                         BufferParams::CM_Mostly;
3730         else
3731                 bp_.maintain_unincluded_children =
3732                         BufferParams::CM_Strict;
3733         updateIncludeonlyDisplay();
3734
3735         // Float Settings
3736         bp_.float_placement = floatModule->getPlacement();
3737         bp_.float_alignment = floatModule->getAlignment();
3738
3739         // Listings
3740         // text should have passed validation
3741         idx = listingsModule->packageCO->currentIndex();
3742         bp_.use_minted = string(lst_packages[idx]) == "Minted";
3743         bp_.listings_params =
3744                 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
3745
3746         // Formats
3747         bp_.default_output_format = fromqstr(outputModule->defaultFormatCO->itemData(
3748                 outputModule->defaultFormatCO->currentIndex()).toString());
3749
3750         bool const nontexfonts = fontModule->osFontsCB->isChecked();
3751         bp_.useNonTeXFonts = nontexfonts;
3752
3753         bp_.shell_escape = outputModule->shellescapeCB->isChecked();
3754         if (!bp_.shell_escape)
3755             theSession().shellescapeFiles().remove(buffer().absFileName());
3756         else if (!theSession().shellescapeFiles().find(buffer().absFileName()))
3757             theSession().shellescapeFiles().insert(buffer().absFileName());
3758         Buffer & buf = const_cast<Buffer &>(buffer());
3759         buf.params().shell_escape = bp_.shell_escape;
3760
3761         bp_.output_sync = outputModule->outputsyncCB->isChecked();
3762
3763         bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
3764
3765         int mathfmt = outputModule->mathoutCB->currentIndex();
3766         if (mathfmt == -1)
3767                 mathfmt = 0;
3768         BufferParams::MathOutput const mo =
3769                 static_cast<BufferParams::MathOutput>(mathfmt);
3770         bp_.html_math_output = mo;
3771         bp_.html_be_strict = outputModule->strictCB->isChecked();
3772         bp_.html_css_as_file = outputModule->cssCB->isChecked();
3773         bp_.html_math_img_scale = outputModule->mathimgSB->value();
3774         bp_.display_pixel_ratio = theGuiApp()->pixelRatio();
3775
3776         int tablefmt = outputModule->tableoutCB->currentIndex();
3777         if (tablefmt == -1)
3778                 tablefmt = 0;
3779         BufferParams::TableOutput const to =
3780                         static_cast<BufferParams::TableOutput>(tablefmt);
3781         bp_.docbook_table_output = to;
3782
3783         bp_.save_transient_properties =
3784                 outputModule->saveTransientPropertiesCB->isChecked();
3785         bp_.postpone_fragile_content =
3786                 outputModule->postponeFragileCB->isChecked();
3787
3788         // fonts
3789         bp_.fonts_roman[nontexfonts] =
3790                 fromqstr(fontModule->fontsRomanCO->
3791                         itemData(fontModule->fontsRomanCO->currentIndex()).toString());
3792         bp_.fonts_roman[!nontexfonts] = fromqstr(fontModule->font_roman);
3793         bp_.font_roman_opts = fromqstr(fontModule->fontspecRomanLE->text());
3794
3795         bp_.fonts_sans[nontexfonts] =
3796                 fromqstr(fontModule->fontsSansCO->
3797                         itemData(fontModule->fontsSansCO->currentIndex()).toString());
3798         bp_.fonts_sans[!nontexfonts] = fromqstr(fontModule->font_sans);
3799         bp_.font_sans_opts = fromqstr(fontModule->fontspecSansLE->text());
3800
3801         bp_.fonts_typewriter[nontexfonts] =
3802                 fromqstr(fontModule->fontsTypewriterCO->
3803                         itemData(fontModule->fontsTypewriterCO->currentIndex()).toString());
3804         bp_.fonts_typewriter[!nontexfonts] = fromqstr(fontModule->font_typewriter);
3805         bp_.font_typewriter_opts = fromqstr(fontModule->fontspecTypewriterLE->text());
3806
3807         bp_.fonts_math[nontexfonts] =
3808                 fromqstr(fontModule->fontsMathCO->
3809                         itemData(fontModule->fontsMathCO->currentIndex()).toString());
3810         bp_.fonts_math[!nontexfonts] = fromqstr(fontModule->font_math);
3811
3812         QString const fontenc =
3813                 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
3814         if (fontenc == "custom")
3815                 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
3816         else
3817                 bp_.fontenc = fromqstr(fontenc);
3818
3819         bp_.fonts_cjk =
3820                 fromqstr(fontModule->cjkFontLE->text());
3821
3822         bp_.use_microtype = fontModule->microtypeCB->isChecked();
3823         bp_.use_dash_ligatures = !fontModule->dashesCB->isChecked();
3824
3825         bp_.fonts_sans_scale[nontexfonts] = fontModule->scaleSansSB->value();
3826         bp_.fonts_sans_scale[!nontexfonts] = fontModule->font_sf_scale;
3827
3828         bp_.fonts_typewriter_scale[nontexfonts] = fontModule->scaleTypewriterSB->value();
3829         bp_.fonts_typewriter_scale[!nontexfonts] = fontModule->font_tt_scale;
3830
3831         bp_.fonts_expert_sc = fontModule->fontScCB->isChecked();
3832
3833         bp_.fonts_roman_osf = fontModule->fontOsfCB->isChecked();
3834         bp_.fonts_sans_osf = fontModule->fontSansOsfCB->isChecked();
3835         bp_.fonts_typewriter_osf = fontModule->fontTypewriterOsfCB->isChecked();
3836
3837         if (nontexfonts)
3838                 bp_.fonts_default_family = "default";
3839         else
3840                 bp_.fonts_default_family = GuiDocument::fontfamilies[
3841                         fontModule->fontsDefaultCO->currentIndex()];
3842
3843         if (fontModule->fontsizeCO->currentIndex() == 0)
3844                 bp_.fontsize = "default";
3845         else
3846                 bp_.fontsize =
3847                         fromqstr(fontModule->fontsizeCO->currentText());
3848
3849         // paper
3850         bp_.papersize = PAPER_SIZE(
3851                 pageLayoutModule->papersizeCO->currentIndex());
3852
3853         bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
3854                 pageLayoutModule->paperwidthUnitCO);
3855
3856         bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
3857                 pageLayoutModule->paperheightUnitCO);
3858
3859         if (pageLayoutModule->facingPagesCB->isChecked())
3860                 bp_.sides = TwoSides;
3861         else
3862                 bp_.sides = OneSide;
3863
3864         if (pageLayoutModule->landscapeRB->isChecked())
3865                 bp_.orientation = ORIENTATION_LANDSCAPE;
3866         else
3867                 bp_.orientation = ORIENTATION_PORTRAIT;
3868
3869         // margins
3870         bp_.use_geometry = !marginsModule->marginCB->isChecked();
3871
3872         Ui::MarginsUi const * m = marginsModule;
3873
3874         bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
3875         bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
3876         bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
3877         bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
3878         bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
3879         bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
3880         bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
3881         bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
3882
3883         // branches
3884         branchesModule->apply(bp_);
3885
3886         // PDF support
3887         PDFOptions & pdf = bp_.pdfoptions();
3888         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
3889         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
3890         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
3891         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
3892         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
3893
3894         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
3895         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
3896         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
3897         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
3898
3899         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
3900         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
3901         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
3902         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
3903         pdf.backref =
3904                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
3905         if (pdfSupportModule->fullscreenCB->isChecked())
3906                 pdf.pagemode = pdf.pagemode_fullscreen;
3907         else
3908                 pdf.pagemode.clear();
3909         pdf.quoted_options = pdf.quoted_options_check(
3910                                 fromqstr(pdfSupportModule->optionsLE->text()));
3911
3912         // change tracking
3913         bp_.track_changes = changesModule->trackChangesCB->isChecked();
3914         bp_.output_changes = changesModule->outputChangesCB->isChecked();
3915         bool const cb_switched_off = (bp_.change_bars
3916                                       && !changesModule->changeBarsCB->isChecked());
3917         bp_.change_bars = changesModule->changeBarsCB->isChecked();
3918         if (cb_switched_off)
3919                 // if change bars have been switched off,
3920                 // we need to ditch the aux file
3921                 buffer().requireFreshStart(true);
3922
3923         // reset trackers
3924         nonModuleChanged_ = false;
3925         shellescapeChanged_ = false;
3926 }
3927
3928
3929 void GuiDocument::paramsToDialog()
3930 {
3931         // set the default unit
3932         Length::UNIT const default_unit = Length::defaultUnit();
3933
3934         // preamble
3935         preambleModule->update(bp_, id());
3936         localLayout->update(bp_, id());
3937
3938         // date
3939         latexModule->suppressDateCB->setChecked(bp_.suppress_date);
3940         latexModule->refstyleCB->setChecked(bp_.use_refstyle);
3941
3942         // biblio
3943         string const cite_engine = bp_.citeEngine();
3944
3945         biblioModule->citeEngineCO->setCurrentIndex(
3946                 biblioModule->citeEngineCO->findData(toqstr(cite_engine)));
3947
3948         updateEngineType(documentClass().opt_enginetype(),
3949                 bp_.citeEngineType());
3950
3951         checkPossibleCiteEngines();
3952
3953         biblioModule->citeStyleCO->setCurrentIndex(
3954                 biblioModule->citeStyleCO->findData(bp_.citeEngineType()));
3955
3956         biblioModule->bibtopicCB->setChecked(bp_.splitbib());
3957
3958         biblioModule->bibunitsCO->clear();
3959         biblioModule->bibunitsCO->addItem(qt_("No"), QString());
3960         if (documentClass().hasLaTeXLayout("part"))
3961                 biblioModule->bibunitsCO->addItem(qt_("per part"), toqstr("part"));
3962         if (documentClass().hasLaTeXLayout("chapter"))
3963                 biblioModule->bibunitsCO->addItem(qt_("per chapter"), toqstr("chapter"));
3964         if (documentClass().hasLaTeXLayout("section"))
3965                 biblioModule->bibunitsCO->addItem(qt_("per section"), toqstr("section"));
3966         if (documentClass().hasLaTeXLayout("subsection"))
3967                 biblioModule->bibunitsCO->addItem(qt_("per subsection"), toqstr("subsection"));
3968         biblioModule->bibunitsCO->addItem(qt_("per child document"), toqstr("child"));
3969
3970         int const mbpos = biblioModule->bibunitsCO->findData(toqstr(bp_.multibib));
3971         if (mbpos != -1)
3972                 biblioModule->bibunitsCO->setCurrentIndex(mbpos);
3973         else
3974                 biblioModule->bibunitsCO->setCurrentIndex(0);
3975
3976         updateEngineDependends();
3977
3978         if (isBiblatex()) {
3979                 updateDefaultBiblio(bp_.biblatex_bibstyle, "bbx");
3980                 updateDefaultBiblio(bp_.biblatex_citestyle, "cbx");
3981         } else
3982                 updateDefaultBiblio(bp_.defaultBiblioStyle());
3983
3984         biblioModule->citePackageOptionsLE->setText(toqstr(bp_.biblio_opts));
3985
3986         string command;
3987         string options =
3988                 split(bp_.bibtex_command, command, ' ');
3989
3990         int const bpos = biblioModule->bibtexCO->findData(toqstr(command));
3991         if (bpos != -1) {
3992                 biblioModule->bibtexCO->setCurrentIndex(bpos);
3993                 biblioModule->bibtexOptionsLE->setText(toqstr(options).trimmed());
3994         } else {
3995                 // We reset to default if we do not know the specified compiler
3996                 // This is for security reasons
3997                 biblioModule->bibtexCO->setCurrentIndex(
3998                         biblioModule->bibtexCO->findData(toqstr("default")));
3999                 biblioModule->bibtexOptionsLE->clear();
4000         }
4001         biblioModule->bibtexOptionsLE->setEnabled(
4002                 biblioModule->bibtexCO->currentIndex() != 0);
4003
4004         biblioChanged_ = false;
4005
4006         // indices
4007         // We may be called when there is no Buffer, e.g., when
4008         // the last view has just been closed.
4009         bool const isReadOnly = isBufferAvailable() ? buffer().isReadonly() : false;
4010         indicesModule->update(bp_, isReadOnly);
4011
4012         // language & quotes
4013         int const pos = langModule->languageCO->findData(toqstr(
4014                 bp_.language->lang()));
4015         langModule->languageCO->setCurrentIndex(pos);
4016
4017         updateQuoteStyles();
4018
4019         langModule->quoteStyleCO->setCurrentIndex(
4020                 langModule->quoteStyleCO->findData(static_cast<int>(bp_.quotes_style)));
4021         langModule->dynamicQuotesCB->setChecked(bp_.dynamic_quotes);
4022
4023         // LaTeX input encoding: set after the fonts (see below)
4024
4025         int p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
4026         if (p == -1) {
4027                 langModule->languagePackageCO->setCurrentIndex(
4028                           langModule->languagePackageCO->findData("custom"));
4029                 langModule->languagePackageLE->setText(toqstr(bp_.lang_package));
4030         } else {
4031                 langModule->languagePackageCO->setCurrentIndex(p);
4032                 langModule->languagePackageLE->clear();
4033         }
4034
4035         //color
4036         if (bp_.isfontcolor) {
4037                 colorModule->fontColorPB->setStyleSheet(
4038                         colorButtonStyleSheet(rgb2qcolor(bp_.fontcolor)));
4039         }
4040         set_fontcolor = bp_.fontcolor;
4041         is_fontcolor = bp_.isfontcolor;
4042
4043         colorModule->noteFontColorPB->setStyleSheet(
4044                 colorButtonStyleSheet(rgb2qcolor(bp_.notefontcolor)));
4045         set_notefontcolor = bp_.notefontcolor;
4046         is_notefontcolor = bp_.isnotefontcolor;
4047
4048         if (bp_.isbackgroundcolor) {
4049                 colorModule->backgroundPB->setStyleSheet(
4050                         colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
4051         }
4052         set_backgroundcolor = bp_.backgroundcolor;
4053         is_backgroundcolor = bp_.isbackgroundcolor;
4054
4055         colorModule->boxBackgroundPB->setStyleSheet(
4056                 colorButtonStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
4057         set_boxbgcolor = bp_.boxbgcolor;
4058         is_boxbgcolor = bp_.isboxbgcolor;
4059
4060         // numbering
4061         int const min_toclevel = documentClass().min_toclevel();
4062         int const max_toclevel = documentClass().max_toclevel();
4063         if (documentClass().hasTocLevels()) {
4064                 numberingModule->setEnabled(true);
4065                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
4066                 numberingModule->depthSL->setMaximum(max_toclevel);
4067                 numberingModule->depthSL->setValue(bp_.secnumdepth);
4068                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
4069                 numberingModule->tocSL->setMaximum(max_toclevel);
4070                 numberingModule->tocSL->setValue(bp_.tocdepth);
4071                 updateNumbering();
4072         } else {
4073                 numberingModule->setEnabled(false);
4074                 numberingModule->tocTW->clear();
4075         }
4076
4077         numberingModule->linenoCB->setChecked(bp_.use_lineno);
4078         numberingModule->linenoLE->setEnabled(bp_.use_lineno);
4079         numberingModule->linenoLA->setEnabled(bp_.use_lineno);
4080         numberingModule->linenoLE->setText(toqstr(bp_.lineno_opts));
4081
4082         // bullets
4083         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
4084         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
4085         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
4086         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
4087         bulletsModule->init();
4088
4089         // packages
4090         int nitem = findToken(tex_graphics, bp_.graphics_driver);
4091         if (nitem >= 0)
4092                 latexModule->psdriverCO->setCurrentIndex(nitem);
4093         updateModuleInfo();
4094
4095         // math
4096         mathsModule->MathIndentCB->setChecked(bp_.is_math_indent);
4097         if (bp_.is_math_indent) {
4098                 Length const mathindent = bp_.getMathIndent();
4099                 int indent = 0;
4100                 if (!mathindent.empty()) {
4101                         lengthToWidgets(mathsModule->MathIndentLE,
4102                                         mathsModule->MathIndentLengthCO,
4103                                         mathindent, default_unit);
4104                         indent = 1;
4105                 }
4106                 mathsModule->MathIndentCO->setCurrentIndex(indent);
4107                 enableMathIndent(indent);
4108         }
4109         switch(bp_.math_numbering_side) {
4110         case BufferParams::LEFT:
4111                 mathsModule->MathNumberingPosCO->setCurrentIndex(0);
4112                 break;
4113         case BufferParams::DEFAULT:
4114                 mathsModule->MathNumberingPosCO->setCurrentIndex(1);
4115                 break;
4116         case BufferParams::RIGHT:
4117                 mathsModule->MathNumberingPosCO->setCurrentIndex(2);
4118         }
4119
4120         map<string, string> const & packages = BufferParams::auto_packages();
4121         for (map<string, string>::const_iterator it = packages.begin();
4122              it != packages.end(); ++it) {
4123                 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
4124                 if (!item)
4125                         continue;
4126                 int row = mathsModule->packagesTW->row(item);
4127                 switch (bp_.use_package(it->first)) {
4128                         case BufferParams::package_off: {
4129                                 QRadioButton * rb =
4130                                         (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3)->layout()->itemAt(0)->widget();
4131                                 rb->setChecked(true);
4132                                 break;
4133                         }
4134                         case BufferParams::package_on: {
4135                                 QRadioButton * rb =
4136                                         (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2)->layout()->itemAt(0)->widget();
4137                                 rb->setChecked(true);
4138                                 break;
4139                         }
4140                         case BufferParams::package_auto: {
4141                                 QRadioButton * rb =
4142                                         (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1)->layout()->itemAt(0)->widget();
4143                                 rb->setChecked(true);
4144                                 break;
4145                         }
4146                 }
4147         }
4148
4149         switch (bp_.spacing().getSpace()) {
4150                 case Spacing::Other: nitem = 3; break;
4151                 case Spacing::Double: nitem = 2; break;
4152                 case Spacing::Onehalf: nitem = 1; break;
4153                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
4154         }
4155
4156         // text layout
4157         string const & layoutID = bp_.baseClassID();
4158         setLayoutComboByIDString(layoutID);
4159
4160         updatePagestyle(documentClass().opt_pagestyle(),
4161                                  bp_.pagestyle);
4162
4163         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
4164         if (bp_.spacing().getSpace() == Spacing::Other) {
4165                 doubleToWidget(textLayoutModule->lspacingLE,
4166                         bp_.spacing().getValueAsString());
4167         }
4168         setLSpacing(nitem);
4169         int ts = textLayoutModule->tableStyleCO->findData(toqstr(bp_.tablestyle));
4170         if (ts != -1)
4171                 textLayoutModule->tableStyleCO->setCurrentIndex(ts);
4172
4173         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
4174                 textLayoutModule->indentRB->setChecked(true);
4175                 string parindent = bp_.getParIndent().asString();
4176                 int indent = 0;
4177                 if (!parindent.empty()) {
4178                         lengthToWidgets(textLayoutModule->indentLE,
4179                                         textLayoutModule->indentLengthCO,
4180                                         parindent, default_unit);
4181                         indent = 1;
4182                 }
4183                 textLayoutModule->indentCO->setCurrentIndex(indent);
4184                 setIndent(indent);
4185         } else {
4186                 textLayoutModule->skipRB->setChecked(true);
4187                 VSpace::VSpaceKind skip = bp_.getDefSkip().kind();
4188                 textLayoutModule->skipCO->setCurrentIndex(textLayoutModule->skipCO->findData(skip));
4189                 if (skip == VSpace::LENGTH) {
4190                         string const length = bp_.getDefSkip().asLyXCommand();
4191                         lengthToWidgets(textLayoutModule->skipLE,
4192                                 textLayoutModule->skipLengthCO,
4193                                 length, default_unit);
4194                 }
4195                 setSkip(textLayoutModule->skipCO->currentIndex());
4196         }
4197
4198         textLayoutModule->twoColumnCB->setChecked(
4199                 bp_.columns == 2);
4200         textLayoutModule->justCB->setChecked(bp_.justification);
4201
4202         if (!bp_.options.empty()) {
4203                 latexModule->optionsLE->setText(
4204                         toqstr(bp_.options));
4205         } else {
4206                 latexModule->optionsLE->setText(QString());
4207         }
4208
4209         // latex
4210         latexModule->defaultOptionsCB->setChecked(
4211                         bp_.use_default_options);
4212         updateSelectedModules();
4213         selectionManager->updateProvidedModules(
4214                         bp_.baseClass()->providedModules());
4215         selectionManager->updateExcludedModules(
4216                         bp_.baseClass()->excludedModules());
4217
4218         if (!documentClass().options().empty()) {
4219                 latexModule->defaultOptionsLE->setText(
4220                         toqstr(documentClass().options()));
4221         } else {
4222                 latexModule->defaultOptionsLE->setText(
4223                         toqstr(_("[No options predefined]")));
4224         }
4225
4226         latexModule->defaultOptionsLE->setEnabled(
4227                 bp_.use_default_options
4228                 && !documentClass().options().empty());
4229
4230         latexModule->defaultOptionsCB->setEnabled(
4231                 !documentClass().options().empty());
4232
4233         if (!bp_.master.empty()) {
4234                 latexModule->childDocGB->setChecked(true);
4235                 latexModule->childDocLE->setText(
4236                         toqstr(bp_.master));
4237         } else {
4238                 latexModule->childDocLE->setText(QString());
4239                 latexModule->childDocGB->setChecked(false);
4240         }
4241
4242         // Master/Child
4243         if (!bufferview() || !buffer().hasChildren()) {
4244                 masterChildModule->childrenTW->clear();
4245                 includeonlys_.clear();
4246                 docPS->showPanel("Child Documents", false);
4247                 if (docPS->isCurrentPanel("Child Documents"))
4248                         docPS->setCurrentPanel("Document Class");
4249         } else {
4250                 docPS->showPanel("Child Documents", true);
4251                 masterChildModule->setEnabled(true);
4252                 includeonlys_ = bp_.getIncludedChildren();
4253                 updateIncludeonlys();
4254                 updateIncludeonlyDisplay();
4255         }
4256         switch (bp_.maintain_unincluded_children) {
4257         case BufferParams::CM_None:
4258                 masterChildModule->maintainCRNoneRB->setChecked(true);
4259                 break;
4260         case BufferParams::CM_Mostly:
4261                 masterChildModule->maintainCRMostlyRB->setChecked(true);
4262                 break;
4263         case BufferParams::CM_Strict:
4264         default:
4265                 masterChildModule->maintainCRStrictRB->setChecked(true);
4266                 break;
4267         }
4268
4269         // Float Settings
4270         floatModule->setPlacement(bp_.float_placement);
4271         floatModule->setAlignment(bp_.float_alignment);
4272
4273         // ListingsSettings
4274         // break listings_params to multiple lines
4275         string lstparams =
4276                 InsetListingsParams(bp_.listings_params).separatedParams();
4277         listingsModule->listingsED->setPlainText(toqstr(lstparams));
4278         int nn = findToken(lst_packages, bp_.use_minted ? "Minted" : "Listings");
4279         if (nn >= 0)
4280                 listingsModule->packageCO->setCurrentIndex(nn);
4281
4282         // Fonts
4283         // some languages only work with Polyglossia (which requires non-TeX fonts)
4284         Language const * lang = lyx::languages.getLanguage(
4285                 fromqstr(langModule->languageCO->itemData(
4286                         langModule->languageCO->currentIndex()).toString()));
4287         bool const need_fontspec =
4288                 lang->babel().empty() && !lang->polyglossia().empty()
4289                 && lang->required() != "CJK" && lang->required() != "japanese";
4290         bool const os_fonts_available =
4291                 bp_.baseClass()->outputType() == lyx::LATEX
4292                 && LaTeXFeatures::isAvailable("fontspec");
4293         fontModule->osFontsCB->setEnabled(os_fonts_available && !need_fontspec);
4294         fontModule->osFontsCB->setChecked(
4295                 (os_fonts_available && bp_.useNonTeXFonts) || need_fontspec);
4296         updateFontsize(documentClass().opt_fontsize(),
4297                         bp_.fontsize);
4298
4299         QString font = toqstr(bp_.fontsRoman());
4300         int rpos = fontModule->fontsRomanCO->findData(font);
4301         if (rpos == -1) {
4302                 rpos = fontModule->fontsRomanCO->count();
4303                 fontModule->fontsRomanCO->addItem(font + qt_(" (not installed)"), font);
4304         }
4305         fontModule->fontsRomanCO->setCurrentIndex(rpos);
4306         fontModule->font_roman = toqstr(bp_.fonts_roman[!bp_.useNonTeXFonts]);
4307
4308         font = toqstr(bp_.fontsSans());
4309         int spos = fontModule->fontsSansCO->findData(font);
4310         if (spos == -1) {
4311                 spos = fontModule->fontsSansCO->count();
4312                 fontModule->fontsSansCO->addItem(font + qt_(" (not installed)"), font);
4313         }
4314         fontModule->fontsSansCO->setCurrentIndex(spos);
4315         fontModule->font_sans = toqstr(bp_.fonts_sans[!bp_.useNonTeXFonts]);
4316
4317         font = toqstr(bp_.fontsTypewriter());
4318         int tpos = fontModule->fontsTypewriterCO->findData(font);
4319         if (tpos == -1) {
4320                 tpos = fontModule->fontsTypewriterCO->count();
4321                 fontModule->fontsTypewriterCO->addItem(font + qt_(" (not installed)"), font);
4322         }
4323         fontModule->fontsTypewriterCO->setCurrentIndex(tpos);
4324         fontModule->font_typewriter = toqstr(bp_.fonts_typewriter[!bp_.useNonTeXFonts]);
4325
4326         font = toqstr(bp_.fontsMath());
4327         int mpos = fontModule->fontsMathCO->findData(font);
4328         if (mpos == -1) {
4329                 mpos = fontModule->fontsMathCO->count();
4330                 fontModule->fontsMathCO->addItem(font + qt_(" (not installed)"), font);
4331         }
4332         fontModule->fontsMathCO->setCurrentIndex(mpos);
4333         fontModule->font_math = toqstr(bp_.fonts_math[!bp_.useNonTeXFonts]);
4334
4335         if (bp_.useNonTeXFonts && os_fonts_available) {
4336                 fontModule->fontencLA->setEnabled(false);
4337                 fontModule->fontencCO->setEnabled(false);
4338                 fontModule->fontencLE->setEnabled(false);
4339         } else {
4340                 fontModule->fontencLA->setEnabled(true);
4341                 fontModule->fontencCO->setEnabled(true);
4342                 fontModule->fontencLE->setEnabled(true);
4343                 romanChanged(rpos);
4344                 sansChanged(spos);
4345                 ttChanged(tpos);
4346         }
4347
4348         if (!bp_.fonts_cjk.empty())
4349                 fontModule->cjkFontLE->setText(
4350                         toqstr(bp_.fonts_cjk));
4351         else
4352                 fontModule->cjkFontLE->setText(QString());
4353
4354         fontModule->microtypeCB->setChecked(bp_.use_microtype);
4355         fontModule->dashesCB->setChecked(!bp_.use_dash_ligatures);
4356
4357         fontModule->fontScCB->setChecked(bp_.fonts_expert_sc);
4358         fontModule->fontOsfCB->setChecked(bp_.fonts_roman_osf);
4359         fontModule->fontSansOsfCB->setChecked(bp_.fonts_sans_osf);
4360         fontModule->fontTypewriterOsfCB->setChecked(bp_.fonts_typewriter_osf);
4361         fontModule->scaleSansSB->setValue(bp_.fontsSansScale());
4362         fontModule->font_sf_scale = bp_.fonts_sans_scale[!bp_.useNonTeXFonts];
4363         fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale());
4364         fontModule->font_tt_scale = bp_.fonts_typewriter_scale[!bp_.useNonTeXFonts];
4365         if (!bp_.font_roman_opts.empty())
4366                 fontModule->fontspecRomanLE->setText(
4367                         toqstr(bp_.font_roman_opts));
4368         else
4369                 fontModule->fontspecRomanLE->setText(QString());
4370         if (!bp_.font_sans_opts.empty())
4371                 fontModule->fontspecSansLE->setText(
4372                         toqstr(bp_.font_sans_opts));
4373         else
4374                 fontModule->fontspecSansLE->setText(QString());
4375         if (!bp_.font_typewriter_opts.empty())
4376                 fontModule->fontspecTypewriterLE->setText(
4377                         toqstr(bp_.font_typewriter_opts));
4378         else
4379                 fontModule->fontspecTypewriterLE->setText(QString());
4380
4381         nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
4382         if (nn >= 0)
4383                 fontModule->fontsDefaultCO->setCurrentIndex(nn);
4384
4385         if (bp_.fontenc == "auto" || bp_.fontenc == "default") {
4386                 fontModule->fontencCO->setCurrentIndex(
4387                         fontModule->fontencCO->findData(toqstr(bp_.fontenc)));
4388                 fontModule->fontencLE->setEnabled(false);
4389         } else {
4390                 fontModule->fontencCO->setCurrentIndex(
4391                                         fontModule->fontencCO->findData("custom"));
4392                 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
4393         }
4394
4395         // LaTeX input encoding
4396         // Set after fonts because non-tex fonts override "\inputencoding".
4397         inputencodingToDialog();
4398
4399         // Formats
4400         // This must be set _after_ fonts since updateDefaultFormat()
4401         // checks osFontsCB settings.
4402         // update combobox with formats
4403         updateDefaultFormat();
4404         int index = outputModule->defaultFormatCO->findData(toqstr(
4405                 bp_.default_output_format));
4406         // set to default if format is not found
4407         if (index == -1)
4408                 index = 0;
4409         outputModule->defaultFormatCO->setCurrentIndex(index);
4410
4411         outputModule->shellescapeCB->setChecked(bp_.shell_escape);
4412         outputModule->outputsyncCB->setChecked(bp_.output_sync);
4413         outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
4414         outputModule->synccustomCB->setEnabled(bp_.output_sync);
4415         outputModule->synccustomLA->setEnabled(bp_.output_sync);
4416
4417         outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
4418         outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
4419         outputModule->strictCB->setChecked(bp_.html_be_strict);
4420         outputModule->cssCB->setChecked(bp_.html_css_as_file);
4421
4422         outputModule->tableoutCB->setCurrentIndex(bp_.docbook_table_output);
4423
4424         outputModule->saveTransientPropertiesCB
4425                 ->setChecked(bp_.save_transient_properties);
4426         outputModule->postponeFragileCB
4427                 ->setChecked(bp_.postpone_fragile_content);
4428
4429         // paper
4430         bool const extern_geometry =
4431                 documentClass().provides("geometry");
4432         int const psize = bp_.papersize;
4433         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
4434         setCustomPapersize(!extern_geometry && psize == 1);
4435         pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
4436
4437         bool const landscape =
4438                 bp_.orientation == ORIENTATION_LANDSCAPE;
4439         pageLayoutModule->landscapeRB->setChecked(landscape);
4440         pageLayoutModule->portraitRB->setChecked(!landscape);
4441         pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
4442         pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
4443
4444         pageLayoutModule->facingPagesCB->setChecked(
4445                 bp_.sides == TwoSides);
4446
4447         lengthToWidgets(pageLayoutModule->paperwidthLE,
4448                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, default_unit);
4449         lengthToWidgets(pageLayoutModule->paperheightLE,
4450                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, default_unit);
4451
4452         // margins
4453         Ui::MarginsUi * m = marginsModule;
4454
4455         setMargins();
4456
4457         lengthToWidgets(m->topLE, m->topUnit,
4458                 bp_.topmargin, default_unit);
4459
4460         lengthToWidgets(m->bottomLE, m->bottomUnit,
4461                 bp_.bottommargin, default_unit);
4462
4463         lengthToWidgets(m->innerLE, m->innerUnit,
4464                 bp_.leftmargin, default_unit);
4465
4466         lengthToWidgets(m->outerLE, m->outerUnit,
4467                 bp_.rightmargin, default_unit);
4468
4469         lengthToWidgets(m->headheightLE, m->headheightUnit,
4470                 bp_.headheight, default_unit);
4471
4472         lengthToWidgets(m->headsepLE, m->headsepUnit,
4473                 bp_.headsep, default_unit);
4474
4475         lengthToWidgets(m->footskipLE, m->footskipUnit,
4476                 bp_.footskip, default_unit);
4477
4478         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
4479                 bp_.columnsep, default_unit);
4480
4481         // branches
4482         updateUnknownBranches();
4483         branchesModule->update(bp_);
4484
4485         // PDF support
4486         PDFOptions const & pdf = bp_.pdfoptions();
4487         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
4488         if (bp_.documentClass().provides("hyperref"))
4489                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("C&ustomize Hyperref Options"));
4490         else
4491                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("&Use Hyperref Support"));
4492         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
4493         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
4494         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
4495         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
4496
4497         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
4498         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
4499         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
4500
4501         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
4502         pdfSupportModule->bookmarksopenlevelSB->setEnabled(pdf.bookmarksopen);
4503         pdfSupportModule->bookmarksopenlevelLA->setEnabled(pdf.bookmarksopen);
4504
4505         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
4506         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
4507         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
4508         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
4509
4510         nn = findToken(backref_opts, pdf.backref);
4511         if (nn >= 0)
4512                 pdfSupportModule->backrefCO->setCurrentIndex(nn);
4513
4514         pdfSupportModule->fullscreenCB->setChecked
4515                 (pdf.pagemode == pdf.pagemode_fullscreen);
4516
4517         pdfSupportModule->optionsLE->setText(
4518                 toqstr(pdf.quoted_options));
4519
4520         // change tracking
4521         changesModule->trackChangesCB->setChecked(bp_.track_changes);
4522         changesModule->outputChangesCB->setChecked(bp_.output_changes);
4523         changesModule->changeBarsCB->setChecked(bp_.change_bars);
4524         changesModule->changeBarsCB->setEnabled(bp_.output_changes);
4525
4526         // Make sure that the bc is in the INITIAL state
4527         if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
4528                 bc().restore();
4529
4530         // clear changed branches cache
4531         changedBranches_.clear();
4532
4533         // re-initiate module filter
4534         if (!filter_->text().isEmpty())
4535                 moduleFilterPressed();
4536
4537         // reset trackers
4538         nonModuleChanged_ = false;
4539         shellescapeChanged_ = false;
4540 }
4541
4542
4543 void GuiDocument::saveDocDefault()
4544 {
4545         // we have to apply the params first
4546         applyView();
4547         saveAsDefault();
4548 }
4549
4550
4551 void GuiDocument::updateAvailableModules()
4552 {
4553         modules_av_model_.clear();
4554         list<modInfoStruct> modInfoList = getModuleInfo();
4555         // Sort names according to the locale
4556         modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
4557                         return 0 < b.name.localeAwareCompare(a.name);
4558                 });
4559         QIcon user_icon(getPixmap("images/", "lyxfiles-user", "svgz,png"));
4560         QIcon system_icon(getPixmap("images/", "lyxfiles-system", "svgz,png"));
4561         int i = 0;
4562         QFont catfont;
4563         catfont.setBold(true);
4564         QBrush unavbrush;
4565         unavbrush.setColor(Qt::gray);
4566         for (modInfoStruct const & m : modInfoList) {
4567                 QStandardItem * item = new QStandardItem();
4568                 QStandardItem * catItem;
4569                 QString const catname = m.category;
4570                 QList<QStandardItem *> fcats = modules_av_model_.findItems(catname, Qt::MatchExactly);
4571                 if (!fcats.empty())
4572                         catItem = fcats.first();
4573                 else {
4574                         catItem = new QStandardItem();
4575                         catItem->setText(catname);
4576                         catItem->setFont(catfont);
4577                         modules_av_model_.insertRow(i, catItem);
4578                         ++i;
4579                 }
4580                 item->setEditable(false);
4581                 catItem->setEditable(false);
4582                 item->setData(m.name, Qt::DisplayRole);
4583                 if (m.missingreqs)
4584                         item->setForeground(unavbrush);
4585                 item->setData(toqstr(m.id), Qt::UserRole);
4586                 item->setData(m.description, Qt::ToolTipRole);
4587                 if (m.local)
4588                         item->setIcon(user_icon);
4589                 else
4590                         item->setIcon(system_icon);
4591                 catItem->appendRow(item);
4592         }
4593         modules_av_model_.sort(0);
4594 }
4595
4596
4597 void GuiDocument::updateSelectedModules()
4598 {
4599         modules_sel_model_.clear();
4600         list<modInfoStruct> const selModList = getSelectedModules();
4601         int i = 0;
4602         for (modInfoStruct const & m : selModList) {
4603                 modules_sel_model_.insertRow(i, m.name, m.id, m.description);
4604                 ++i;
4605         }
4606 }
4607
4608
4609 void GuiDocument::updateIncludeonlyDisplay()
4610 {
4611         if (includeonlys_.empty()) {
4612                 masterChildModule->includeallRB->setChecked(true);
4613                 masterChildModule->childrenTW->setEnabled(false);
4614                 masterChildModule->maintainGB->setEnabled(false);
4615         } else {
4616                 masterChildModule->includeonlyRB->setChecked(true);
4617                 masterChildModule->childrenTW->setEnabled(true);
4618                 masterChildModule->maintainGB->setEnabled(true);
4619         }
4620 }
4621
4622
4623 void GuiDocument::updateIncludeonlys()
4624 {
4625         masterChildModule->childrenTW->clear();
4626         QString const no = qt_("No");
4627         QString const yes = qt_("Yes");
4628
4629         ListOfBuffers children = buffer().getChildren();
4630         ListOfBuffers::const_iterator it  = children.begin();
4631         ListOfBuffers::const_iterator end = children.end();
4632         bool has_unincluded = false;
4633         bool all_unincluded = true;
4634         for (; it != end; ++it) {
4635                 QTreeWidgetItem * item = new QTreeWidgetItem(masterChildModule->childrenTW);
4636                 // FIXME Unicode
4637                 string const name =
4638                         to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
4639                                                         from_utf8(buffer().filePath())));
4640                 item->setText(0, toqstr(name));
4641                 item->setText(1, isChildIncluded(name) ? yes : no);
4642                 if (!isChildIncluded(name))
4643                         has_unincluded = true;
4644                 else
4645                         all_unincluded = false;
4646         }
4647         // Both if all children are included and if none is included
4648         // is equal to "include all" (i.e., omit \includeonly).
4649         if (!has_unincluded || all_unincluded)
4650                 includeonlys_.clear();
4651 }
4652
4653
4654 bool GuiDocument::isBiblatex() const
4655 {
4656         QString const engine =
4657                 biblioModule->citeEngineCO->itemData(
4658                                 biblioModule->citeEngineCO->currentIndex()).toString();
4659
4660         // this can happen if the cite engine is unknown, which can happen
4661         // if one is using a file that came from someone else, etc. in that
4662         // case, we crash if we proceed.
4663         if (engine.isEmpty())
4664             return false;
4665
4666         return theCiteEnginesList[fromqstr(engine)]->getCiteFramework() == "biblatex";
4667 }
4668
4669
4670 void GuiDocument::updateDefaultBiblio(string const & style,
4671                                       string const & which)
4672 {
4673         QString const bibstyle = toqstr(style);
4674         biblioModule->defaultBiblioCO->clear();
4675
4676         int item_nr = -1;
4677
4678         if (isBiblatex()) {
4679                 if (which != "cbx") {
4680                         // First the bbx styles
4681                         biblioModule->biblatexBbxCO->clear();
4682                         QStringList str = texFileList("bbxFiles.lst");
4683                         // test whether we have a valid list, otherwise run rescan
4684                         if (str.isEmpty()) {
4685                                 rescanTexStyles("bbx");
4686                                 str = texFileList("bbxFiles.lst");
4687                         }
4688                         for (int i = 0; i != str.size(); ++i)
4689                                 str[i] = onlyFileName(str[i]);
4690                         // sort on filename only (no path)
4691                         str.sort();
4692
4693                         for (int i = 0; i != str.count(); ++i) {
4694                                 QString item = changeExtension(str[i], "");
4695                                 if (item == bibstyle)
4696                                         item_nr = i;
4697                                 biblioModule->biblatexBbxCO->addItem(item);
4698                         }
4699
4700                         if (item_nr == -1 && !bibstyle.isEmpty()) {
4701                                 biblioModule->biblatexBbxCO->addItem(bibstyle);
4702                                 item_nr = biblioModule->biblatexBbxCO->count() - 1;
4703                         }
4704
4705                         if (item_nr != -1)
4706                                 biblioModule->biblatexBbxCO->setCurrentIndex(item_nr);
4707                         else
4708                                 biblioModule->biblatexBbxCO->clearEditText();
4709                 }
4710
4711                 if (which != "bbx") {
4712                         // now the cbx styles
4713                         biblioModule->biblatexCbxCO->clear();
4714                         QStringList str = texFileList("cbxFiles.lst");
4715                         // test whether we have a valid list, otherwise run rescan
4716                         if (str.isEmpty()) {
4717                                 rescanTexStyles("cbx");
4718                                 str = texFileList("cbxFiles.lst");
4719                         }
4720                         for (int i = 0; i != str.size(); ++i)
4721                                 str[i] = onlyFileName(str[i]);
4722                         // sort on filename only (no path)
4723                         str.sort();
4724
4725                         for (int i = 0; i != str.count(); ++i) {
4726                                 QString item = changeExtension(str[i], "");
4727                                 if (item == bibstyle)
4728                                         item_nr = i;
4729                                 biblioModule->biblatexCbxCO->addItem(item);
4730                         }
4731
4732                         if (item_nr == -1 && !bibstyle.isEmpty()) {
4733                                 biblioModule->biblatexCbxCO->addItem(bibstyle);
4734                                 item_nr = biblioModule->biblatexCbxCO->count() - 1;
4735                         }
4736
4737                         if (item_nr != -1)
4738                                 biblioModule->biblatexCbxCO->setCurrentIndex(item_nr);
4739                         else
4740                                 biblioModule->biblatexCbxCO->clearEditText();
4741                 }
4742         } else {// BibTeX
4743                 biblioModule->biblatexBbxCO->clear();
4744                 biblioModule->biblatexCbxCO->clear();
4745                 QStringList str = texFileList("bstFiles.lst");
4746                 // test whether we have a valid list, otherwise run rescan
4747                 if (str.isEmpty()) {
4748                         rescanTexStyles("bst");
4749                         str = texFileList("bstFiles.lst");
4750                 }
4751                 for (int i = 0; i != str.size(); ++i)
4752                         str[i] = onlyFileName(str[i]);
4753                 // sort on filename only (no path)
4754                 str.sort();
4755
4756                 for (int i = 0; i != str.count(); ++i) {
4757                         QString item = changeExtension(str[i], "");
4758                         if (item == bibstyle)
4759                                 item_nr = i;
4760                         biblioModule->defaultBiblioCO->addItem(item);
4761                 }
4762
4763                 if (item_nr == -1 && !bibstyle.isEmpty()) {
4764                         biblioModule->defaultBiblioCO->addItem(bibstyle);
4765                         item_nr = biblioModule->defaultBiblioCO->count() - 1;
4766                 }
4767
4768                 if (item_nr != -1)
4769                         biblioModule->defaultBiblioCO->setCurrentIndex(item_nr);
4770                 else
4771                         biblioModule->defaultBiblioCO->clearEditText();
4772         }
4773
4774         updateResetDefaultBiblio();
4775 }
4776
4777
4778 void GuiDocument::updateResetDefaultBiblio()
4779 {
4780         QString const engine =
4781                 biblioModule->citeEngineCO->itemData(
4782                                 biblioModule->citeEngineCO->currentIndex()).toString();
4783         CiteEngineType const cet =
4784                 CiteEngineType(biblioModule->citeStyleCO->itemData(
4785                                                           biblioModule->citeStyleCO->currentIndex()).toInt());
4786
4787         string const defbib = theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet);
4788         if (isBiblatex()) {
4789                 QString const bbx = biblioModule->biblatexBbxCO->currentText();
4790                 QString const cbx = biblioModule->biblatexCbxCO->currentText();
4791                 biblioModule->resetCbxPB->setEnabled(defbib != fromqstr(cbx));
4792                 biblioModule->resetBbxPB->setEnabled(defbib != fromqstr(bbx));
4793                 biblioModule->matchBbxPB->setEnabled(bbx != cbx && !cbx.isEmpty()
4794                         && biblioModule->biblatexBbxCO->findText(cbx) != -1);
4795         } else
4796                 biblioModule->resetDefaultBiblioPB->setEnabled(
4797                         defbib != fromqstr(biblioModule->defaultBiblioCO->currentText()));
4798 }
4799
4800
4801 void GuiDocument::matchBiblatexStyles()
4802 {
4803         updateDefaultBiblio(fromqstr(biblioModule->biblatexCbxCO->currentText()), "bbx");
4804         biblioChanged();
4805 }
4806
4807
4808 void GuiDocument::updateContents()
4809 {
4810         // Nothing to do here as the document settings is not cursor dependent.
4811         return;
4812 }
4813
4814
4815 void GuiDocument::useClassDefaults()
4816 {
4817         if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
4818                 int const ret = Alert::prompt(_("Unapplied changes"),
4819                                 _("Some changes in the dialog were not yet applied.\n"
4820                                   "If you do not apply now, they will be lost after this action."),
4821                                 1, 1, _("&Apply"), _("&Dismiss"));
4822                 if (ret == 0)
4823                         applyView();
4824         }
4825
4826         int idx = latexModule->classCO->currentIndex();
4827         string const classname = fromqstr(latexModule->classCO->getData(idx));
4828         if (!bp_.setBaseClass(classname, buffer().layoutPos())) {
4829                 Alert::error(_("Error"), _("Unable to set document class."));
4830                 return;
4831         }
4832         bp_.useClassDefaults();
4833         paramsToDialog();
4834         changed();
4835 }
4836
4837
4838 void GuiDocument::setLayoutComboByIDString(string const & idString)
4839 {
4840         if (!latexModule->classCO->set(toqstr(idString)))
4841                 Alert::warning(_("Can't set layout!"),
4842                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
4843 }
4844
4845
4846 bool GuiDocument::isValid()
4847 {
4848         return
4849                 validateListingsParameters().isEmpty() &&
4850                 localLayout->isValid() &&
4851                 !localLayout->editing() &&
4852                 !preambleModule->editing() &&
4853                 (
4854                         // if we're asking for skips between paragraphs
4855                         !textLayoutModule->skipRB->isChecked() ||
4856                         // then either we haven't chosen custom
4857                         textLayoutModule->skipCO->currentIndex() != 3 ||
4858                         // or else a length has been given
4859                         !textLayoutModule->skipLE->text().isEmpty()
4860                 ) &&
4861                 (
4862                         // if we're asking for indentation
4863                         !textLayoutModule->indentRB->isChecked() ||
4864                         // then either we haven't chosen custom
4865                         textLayoutModule->indentCO->currentIndex() != 1 ||
4866                         // or else a length has been given
4867                         !textLayoutModule->indentLE->text().isEmpty()
4868                 ) &&
4869                 (
4870                         // if we're asking for math indentation
4871                         !mathsModule->MathIndentCB->isChecked() ||
4872                         // then either we haven't chosen custom
4873                         mathsModule->MathIndentCO->currentIndex() != 1 ||
4874                         // or else a length has been given
4875                         !mathsModule->MathIndentLE->text().isEmpty()
4876                 );
4877 }
4878
4879
4880 char const * const GuiDocument::fontfamilies[5] = {
4881         "default", "rmdefault", "sfdefault", "ttdefault", ""
4882 };
4883
4884
4885 char const * GuiDocument::fontfamilies_gui[5] = {
4886         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
4887 };
4888
4889
4890 bool GuiDocument::initialiseParams(string const &)
4891 {
4892         BufferView const * view = bufferview();
4893         if (!view) {
4894                 bp_ = BufferParams();
4895                 paramsToDialog();
4896                 return true;
4897         }
4898         bp_ = view->buffer().params();
4899         loadModuleInfo();
4900         updateAvailableModules();
4901         //FIXME It'd be nice to make sure here that the selected
4902         //modules are consistent: That required modules are actually
4903         //selected, and that we don't have conflicts. If so, we could
4904         //at least pop up a warning.
4905         paramsToDialog();
4906         return true;
4907 }
4908
4909
4910 void GuiDocument::clearParams()
4911 {
4912         bp_ = BufferParams();
4913 }
4914
4915
4916 BufferId GuiDocument::id() const
4917 {
4918         BufferView const * const view = bufferview();
4919         return view? &view->buffer() : nullptr;
4920 }
4921
4922
4923 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
4924 {
4925         return moduleNames_;
4926 }
4927
4928
4929 list<GuiDocument::modInfoStruct> const
4930 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
4931 {
4932         list<modInfoStruct> mInfo;
4933         for (string const & name : mods) {
4934                 modInfoStruct m;
4935                 LyXModule const * const mod = theModuleList[name];
4936                 if (mod)
4937                         m = modInfo(*mod);
4938                 else {
4939                         m.id = name;
4940                         m.name = toqstr(name + " (") + qt_("Not Found") + toqstr(")");
4941                         m.local = false;
4942                         m.missingreqs = true;
4943                 }
4944                 mInfo.push_back(m);
4945         }
4946         return mInfo;
4947 }
4948
4949
4950 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
4951 {
4952         return makeModuleInfo(params().getModules());
4953 }
4954
4955
4956 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
4957 {
4958         return makeModuleInfo(params().baseClass()->providedModules());
4959 }
4960
4961
4962 DocumentClass const & GuiDocument::documentClass() const
4963 {
4964         return bp_.documentClass();
4965 }
4966
4967
4968 static void dispatch_bufferparams(Dialog const & dialog,
4969         BufferParams const & bp, FuncCode lfun, Buffer const * buf)
4970 {
4971         ostringstream ss;
4972         ss << "\\begin_header\n";
4973         bp.writeFile(ss, buf);
4974         ss << "\\end_header\n";
4975         dialog.dispatch(FuncRequest(lfun, ss.str()));
4976 }
4977
4978
4979 void GuiDocument::dispatchParams()
4980 {
4981         // We need a non-const buffer object.
4982         Buffer & buf = const_cast<BufferView *>(bufferview())->buffer();
4983         // There may be several undo records; group them (bug #8998)
4984         // This handles undo groups automagically
4985         UndoGroupHelper ugh(&buf);
4986
4987         // This must come first so that a language change is correctly noticed
4988         setLanguage();
4989
4990         // We need to load the master before we formally update the params,
4991         // since otherwise we run updateBuffer, etc, before the child's master
4992         // has been set.
4993         if (!params().master.empty()) {
4994                 FileName const master_file = support::makeAbsPath(params().master,
4995                            support::onlyPath(buffer().absFileName()));
4996                 if (isLyXFileName(master_file.absFileName())) {
4997                         Buffer * master = checkAndLoadLyXFile(master_file, true);
4998                         if (master) {
4999                                 if (master->isChild(const_cast<Buffer *>(&buffer())))
5000                                         const_cast<Buffer &>(buffer()).setParent(master);
5001                                 else
5002                                         Alert::warning(_("Assigned master does not include this file"),
5003                                                 bformat(_("You must include this file in the document\n"
5004                                                           "'%1$s' in order to use the master document\n"
5005                                                           "feature."), from_utf8(params().master)));
5006                         } else
5007                                 Alert::warning(_("Could not load master"),
5008                                                 bformat(_("The master document '%1$s'\n"
5009                                                            "could not be loaded."),
5010                                                            from_utf8(params().master)));
5011                 }
5012         }
5013
5014         // Apply the BufferParams. Note that this will set the base class
5015         // and then update the buffer's layout.
5016         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY, &buffer());
5017
5018         // Generate the colours requested by each new branch.
5019         BranchList & branchlist = params().branchlist();
5020         if (!branchlist.empty()) {
5021                 BranchList::const_iterator it = branchlist.begin();
5022                 BranchList::const_iterator const end = branchlist.end();
5023                 for (; it != end; ++it) {
5024                         docstring const & current_branch = it->branch();
5025                         Branch const * branch = branchlist.find(current_branch);
5026                         string const bcolor = branch->color();
5027                         RGBColor rgbcol;
5028                         if (bcolor.size() == 7 && bcolor[0] == '#')
5029                                 rgbcol = lyx::rgbFromHexName(bcolor);
5030                         else
5031                                 guiApp->getRgbColor(lcolor.getFromLyXName(bcolor), rgbcol);
5032                         string const x11hexname = X11hexname(rgbcol);
5033                         // display the new color
5034                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
5035                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
5036                 }
5037         }
5038         // rename branches in the document
5039         executeBranchRenaming();
5040         // and clear changed branches cache
5041         changedBranches_.clear();
5042
5043         // Generate the colours requested by indices.
5044         IndicesList & indiceslist = params().indiceslist();
5045         if (!indiceslist.empty()) {
5046                 IndicesList::const_iterator it = indiceslist.begin();
5047                 IndicesList::const_iterator const end = indiceslist.end();
5048                 for (; it != end; ++it) {
5049                         docstring const & current_index = it->shortcut();
5050                         Index const * index = indiceslist.findShortcut(current_index);
5051                         string const x11hexname = X11hexname(index->color());
5052                         // display the new color
5053                         docstring const str = current_index + ' ' + from_ascii(x11hexname);
5054                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
5055                 }
5056         }
5057         // FIXME LFUN
5058         // If we used an LFUN, we would not need these two lines:
5059         BufferView * bv = const_cast<BufferView *>(bufferview());
5060         bv->processUpdateFlags(Update::Force | Update::FitCursor);
5061 }
5062
5063
5064 void GuiDocument::setLanguage() const
5065 {
5066         Language const * const newL = bp_.language;
5067         if (buffer().params().language == newL)
5068                 return;
5069
5070         string const & lang_name = newL->lang();
5071         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
5072 }
5073
5074
5075 void GuiDocument::saveAsDefault() const
5076 {
5077         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT, &buffer());
5078 }
5079
5080
5081 bool GuiDocument::providesOSF(QString const & font) const
5082 {
5083         if (fontModule->osFontsCB->isChecked())
5084                 // FIXME: we should check if the fonts really
5085                 // have OSF support. But how?
5086                 return true;
5087         return theLaTeXFonts().getLaTeXFont(
5088                                 qstring_to_ucs4(font)).providesOSF(ot1(),
5089                                                                    completeFontset(),
5090                                                                    noMathFont());
5091 }
5092
5093
5094 bool GuiDocument::providesSC(QString const & font) const
5095 {
5096         if (fontModule->osFontsCB->isChecked())
5097                 return false;
5098         return theLaTeXFonts().getLaTeXFont(
5099                                 qstring_to_ucs4(font)).providesSC(ot1(),
5100                                                                   completeFontset(),
5101                                                                   noMathFont());
5102 }
5103
5104
5105 bool GuiDocument::providesScale(QString const & font) const
5106 {
5107         if (fontModule->osFontsCB->isChecked())
5108                 return true;
5109         return theLaTeXFonts().getLaTeXFont(
5110                                 qstring_to_ucs4(font)).providesScale(ot1(),
5111                                                                      completeFontset(),
5112                                                                      noMathFont());
5113 }
5114
5115
5116 bool GuiDocument::providesExtraOpts(QString const & font) const
5117 {
5118         if (fontModule->osFontsCB->isChecked())
5119                 return true;
5120         return theLaTeXFonts().getLaTeXFont(
5121                                 qstring_to_ucs4(font)).providesMoreOptions(ot1(),
5122                                                                      completeFontset(),
5123                                                                      noMathFont());
5124 }
5125
5126
5127 bool GuiDocument::providesNoMath(QString const & font) const
5128 {
5129         if (fontModule->osFontsCB->isChecked())
5130                 return false;
5131         return theLaTeXFonts().getLaTeXFont(
5132                                 qstring_to_ucs4(font)).providesNoMath(ot1(),
5133                                                                       completeFontset());
5134 }
5135
5136
5137 bool GuiDocument::hasMonolithicExpertSet(QString const & font) const
5138 {
5139         if (fontModule->osFontsCB->isChecked())
5140                 return false;
5141         return theLaTeXFonts().getLaTeXFont(
5142                                 qstring_to_ucs4(font)).hasMonolithicExpertSet(ot1(),
5143                                                                               completeFontset(),
5144                                                                               noMathFont());
5145 }
5146
5147
5148 //static
5149 GuiDocument::modInfoStruct GuiDocument::modInfo(LyXModule const & mod)
5150 {
5151         // FIXME Unicode: docstrings would be better for these parameters but this
5152         // change requires a lot of others
5153         modInfoStruct m;
5154         m.id = mod.getID();
5155         QString const guiname = toqstr(translateIfPossible(from_utf8(mod.getName())));
5156         m.missingreqs = !isModuleAvailable(mod.getID());
5157         if (m.missingreqs) {
5158                 m.name = QString(qt_("%1 (missing req.)")).arg(guiname);
5159         } else
5160                 m.name = guiname;
5161         m.category = mod.category().empty() ? qt_("Miscellaneous")
5162                                             : toqstr(translateIfPossible(from_utf8(mod.category())));
5163         QString desc = toqstr(translateIfPossible(from_utf8(mod.getDescription())));
5164         // Find the first sentence of the description
5165         QTextBoundaryFinder bf(QTextBoundaryFinder::Sentence, desc);
5166         int pos = bf.toNextBoundary();
5167         if (pos > 0)
5168                 desc.truncate(pos);
5169         m.local = mod.isLocal();
5170         QString const mtype = m.local ? qt_("personal module") : qt_("distributed module");
5171         QString modulename = QString(qt_("<b>Module name:</b> <i>%1</i> (%2)")).arg(toqstr(m.id)).arg(mtype);
5172         // Tooltip is the desc followed by the module name and the type
5173         m.description = QString("%1%2")
5174                 .arg(desc.isEmpty() ? QString() : QString("<p>%1</p>").arg(desc),
5175                      modulename);
5176         if (m.missingreqs)
5177                 m.description += QString("<p>%1</p>").arg(qt_("<b>Note:</b> Some requirements for this module are missing!"));
5178         return m;
5179 }
5180
5181
5182 void GuiDocument::loadModuleInfo()
5183 {
5184         moduleNames_.clear();
5185         for (LyXModule const & mod : theModuleList)
5186                 moduleNames_.push_back(modInfo(mod));
5187 }
5188
5189
5190 void GuiDocument::updateUnknownBranches()
5191 {
5192         if (!bufferview())
5193                 return;
5194         list<docstring> used_branches;
5195         buffer().getUsedBranches(used_branches);
5196         list<docstring>::const_iterator it = used_branches.begin();
5197         QStringList unknown_branches;
5198         for (; it != used_branches.end() ; ++it) {
5199                 if (!buffer().params().branchlist().find(*it))
5200                         unknown_branches.append(toqstr(*it));
5201         }
5202         branchesModule->setUnknownBranches(unknown_branches);
5203 }
5204
5205
5206 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
5207 {
5208         map<docstring, docstring>::iterator it = changedBranches_.begin();
5209         for (; it != changedBranches_.end() ; ++it) {
5210                 if (it->second == oldname) {
5211                         // branch has already been renamed
5212                         it->second = newname;
5213                         return;
5214                 }
5215         }
5216         // store new name
5217         changedBranches_[oldname] = newname;
5218 }
5219
5220
5221 void GuiDocument::executeBranchRenaming() const
5222 {
5223         map<docstring, docstring>::const_iterator it = changedBranches_.begin();
5224         for (; it != changedBranches_.end() ; ++it) {
5225                 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
5226                 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
5227         }
5228 }
5229
5230
5231 void GuiDocument::allPackagesAuto()
5232 {
5233         allPackages(1);
5234 }
5235
5236
5237 void GuiDocument::allPackagesAlways()
5238 {
5239         allPackages(2);
5240 }
5241
5242
5243 void GuiDocument::allPackagesNot()
5244 {
5245         allPackages(3);
5246 }
5247
5248
5249 void GuiDocument::allPackages(int col)
5250 {
5251         for (int row = 0; row < mathsModule->packagesTW->rowCount(); ++row) {
5252                 QRadioButton * rb =
5253                         (QRadioButton*)mathsModule->packagesTW->cellWidget(row, col)->layout()->itemAt(0)->widget();
5254                 rb->setChecked(true);
5255         }
5256 }
5257
5258
5259 void GuiDocument::linenoToggled(bool on)
5260 {
5261         numberingModule->linenoLE->setEnabled(on);
5262         numberingModule->linenoLA->setEnabled(on);
5263 }
5264
5265
5266 void GuiDocument::outputChangesToggled(bool on)
5267 {
5268         changesModule->changeBarsCB->setEnabled(on);
5269         change_adaptor();
5270 }
5271
5272 void GuiDocument::setOutputSync(bool on)
5273 {
5274         outputModule->synccustomCB->setEnabled(on);
5275         outputModule->synccustomLA->setEnabled(on);
5276         change_adaptor();
5277 }
5278
5279
5280 } // namespace frontend
5281 } // namespace lyx
5282
5283 #include "moc_GuiDocument.cpp"