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