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