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