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