]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiDocument.cpp
GuiDocument.cpp: change back alignment for column with package names
[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                 QTextCursor 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         Encodings::const_iterator it = encodings.begin();
1080         Encodings::const_iterator const end = encodings.end();
1081         for (; it != end; ++it)
1082                 if (!it->unsafe())
1083                         encodinglist.append(qt_(it->guiName()));
1084         encodinglist.sort();
1085         langModule->encodingCO->addItems(encodinglist);
1086
1087         langModule->languagePackageCO->addItem(
1088                 qt_("Default"), toqstr("default"));
1089         langModule->languagePackageCO->addItem(
1090                 qt_("Automatic"), toqstr("auto"));
1091         langModule->languagePackageCO->addItem(
1092                 qt_("Always Babel"), toqstr("babel"));
1093         langModule->languagePackageCO->addItem(
1094                 qt_("Custom"), toqstr("custom"));
1095         langModule->languagePackageCO->addItem(
1096                 qt_("None[[language package]]"), toqstr("none"));
1097
1098
1099         // color
1100         colorModule = new UiWidget<Ui::ColorUi>(this);
1101         connect(colorModule->fontColorPB, SIGNAL(clicked()),
1102                 this, SLOT(changeFontColor()));
1103         connect(colorModule->delFontColorTB, SIGNAL(clicked()),
1104                 this, SLOT(deleteFontColor()));
1105         connect(colorModule->noteFontColorPB, SIGNAL(clicked()),
1106                 this, SLOT(changeNoteFontColor()));
1107         connect(colorModule->delNoteFontColorTB, SIGNAL(clicked()),
1108                 this, SLOT(deleteNoteFontColor()));
1109         connect(colorModule->backgroundPB, SIGNAL(clicked()),
1110                 this, SLOT(changeBackgroundColor()));
1111         connect(colorModule->delBackgroundTB, SIGNAL(clicked()),
1112                 this, SLOT(deleteBackgroundColor()));
1113         connect(colorModule->boxBackgroundPB, SIGNAL(clicked()),
1114                 this, SLOT(changeBoxBackgroundColor()));
1115         connect(colorModule->delBoxBackgroundTB, SIGNAL(clicked()),
1116                 this, SLOT(deleteBoxBackgroundColor()));
1117
1118
1119         // numbering
1120         numberingModule = new UiWidget<Ui::NumberingUi>(this);
1121         connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
1122                 this, SLOT(change_adaptor()));
1123         connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
1124                 this, SLOT(change_adaptor()));
1125         connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
1126                 this, SLOT(updateNumbering()));
1127         connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
1128                 this, SLOT(updateNumbering()));
1129         numberingModule->tocTW->setColumnCount(3);
1130         numberingModule->tocTW->headerItem()->setText(0, qt_("Example"));
1131         numberingModule->tocTW->headerItem()->setText(1, qt_("Numbered"));
1132         numberingModule->tocTW->headerItem()->setText(2, qt_("Appears in TOC"));
1133         setSectionResizeMode(numberingModule->tocTW->header(), QHeaderView::ResizeToContents);
1134
1135         // biblio
1136         biblioModule = new UiWidget<Ui::BiblioUi>(this);
1137         connect(biblioModule->citeEngineCO, SIGNAL(activated(int)),
1138                 this, SLOT(citeEngineChanged(int)));
1139         connect(biblioModule->citeStyleCO, SIGNAL(activated(int)),
1140                 this, SLOT(citeStyleChanged()));
1141         connect(biblioModule->bibtopicCB, SIGNAL(clicked()),
1142                 this, SLOT(biblioChanged()));
1143         connect(biblioModule->bibunitsCO, SIGNAL(activated(int)),
1144                 this, SLOT(biblioChanged()));
1145         connect(biblioModule->bibtexCO, SIGNAL(activated(int)),
1146                 this, SLOT(bibtexChanged(int)));
1147         connect(biblioModule->bibtexOptionsLE, SIGNAL(textChanged(QString)),
1148                 this, SLOT(biblioChanged()));
1149         connect(biblioModule->citePackageOptionsLE, SIGNAL(textChanged(QString)),
1150                 this, SLOT(biblioChanged()));
1151         connect(biblioModule->defaultBiblioCO, SIGNAL(activated(int)),
1152                 this, SLOT(biblioChanged()));
1153         connect(biblioModule->defaultBiblioCO, SIGNAL(editTextChanged(QString)),
1154                 this, SLOT(biblioChanged()));
1155         connect(biblioModule->defaultBiblioCO, SIGNAL(editTextChanged(QString)),
1156                 this, SLOT(updateResetDefaultBiblio()));
1157         connect(biblioModule->biblatexBbxCO, SIGNAL(activated(int)),
1158                 this, SLOT(biblioChanged()));
1159         connect(biblioModule->biblatexBbxCO, SIGNAL(editTextChanged(QString)),
1160                 this, SLOT(updateResetDefaultBiblio()));
1161         connect(biblioModule->biblatexCbxCO, SIGNAL(activated(int)),
1162                 this, SLOT(biblioChanged()));
1163         connect(biblioModule->biblatexCbxCO, SIGNAL(editTextChanged(QString)),
1164                 this, SLOT(updateResetDefaultBiblio()));
1165         connect(biblioModule->rescanBibliosPB, SIGNAL(clicked()),
1166                 this, SLOT(rescanBibFiles()));
1167         connect(biblioModule->resetDefaultBiblioPB, SIGNAL(clicked()),
1168                 this, SLOT(resetDefaultBibfile()));
1169         connect(biblioModule->resetCbxPB, SIGNAL(clicked()),
1170                 this, SLOT(resetDefaultCbxBibfile()));
1171         connect(biblioModule->resetBbxPB, SIGNAL(clicked()),
1172                 this, SLOT(resetDefaultBbxBibfile()));
1173         connect(biblioModule->matchBbxPB, SIGNAL(clicked()),
1174                 this, SLOT(matchBiblatexStyles()));
1175
1176         biblioModule->citeEngineCO->clear();
1177         for (LyXCiteEngine const & cet : theCiteEnginesList) {
1178                 biblioModule->citeEngineCO->addItem(qt_(cet.getName()), toqstr(cet.getID()));
1179                 int const i = biblioModule->citeEngineCO->findData(toqstr(cet.getID()));
1180                 biblioModule->citeEngineCO->setItemData(i, qt_(cet.getDescription()),
1181                                                         Qt::ToolTipRole);
1182         }
1183
1184         biblioModule->bibtexOptionsLE->setValidator(new NoNewLineValidator(
1185                 biblioModule->bibtexOptionsLE));
1186         biblioModule->defaultBiblioCO->lineEdit()->setValidator(new NoNewLineValidator(
1187                 biblioModule->defaultBiblioCO->lineEdit()));
1188         biblioModule->citePackageOptionsLE->setValidator(new NoNewLineValidator(
1189                 biblioModule->citePackageOptionsLE));
1190
1191         // NOTE: we do not provide "custom" here for security reasons!
1192         biblioModule->bibtexCO->clear();
1193         biblioModule->bibtexCO->addItem(qt_("Default"), QString("default"));
1194         for (set<string>::const_iterator it = lyxrc.bibtex_alternatives.begin();
1195                              it != lyxrc.bibtex_alternatives.end(); ++it) {
1196                 QString const command = toqstr(*it).left(toqstr(*it).indexOf(" "));
1197                 biblioModule->bibtexCO->addItem(command, command);
1198         }
1199
1200
1201         // indices
1202         indicesModule = new GuiIndices;
1203         connect(indicesModule, SIGNAL(changed()),
1204                 this, SLOT(change_adaptor()));
1205
1206
1207         // maths
1208         mathsModule = new UiWidget<Ui::MathsUi>(this);
1209         QStringList headers;
1210         headers << qt_("Package") << qt_("Load automatically")
1211                 << qt_("Load always") << qt_("Do not load");
1212         mathsModule->packagesTW->setHorizontalHeaderLabels(headers);
1213         setSectionResizeMode(mathsModule->packagesTW->horizontalHeader(), QHeaderView::ResizeToContents);
1214         map<string, string> const & packages = BufferParams::auto_packages();
1215         mathsModule->packagesTW->setRowCount(packages.size());
1216         int i = 0;
1217         for (map<string, string>::const_iterator it = packages.begin();
1218              it != packages.end(); ++it) {
1219                 docstring const package = from_ascii(it->first);
1220                 QString autoTooltip = qt_(it->second);
1221                 QString alwaysTooltip;
1222                 if (package == "amsmath")
1223                         alwaysTooltip =
1224                                 qt_("The AMS LaTeX packages are always used");
1225                 else
1226                         alwaysTooltip = toqstr(bformat(
1227                                 _("The LaTeX package %1$s is always used"),
1228                                 package));
1229                 QString neverTooltip;
1230                 if (package == "amsmath")
1231                         neverTooltip =
1232                                 qt_("The AMS LaTeX packages are never used");
1233                 else
1234                         neverTooltip = toqstr(bformat(
1235                                 _("The LaTeX package %1$s is never used"),
1236                                 package));
1237                 QRadioButton * autoRB = new QRadioButton(mathsModule);
1238                 QRadioButton * alwaysRB = new QRadioButton(mathsModule);
1239                 QRadioButton * neverRB = new QRadioButton(mathsModule);
1240                 QButtonGroup * packageGroup = new QButtonGroup(mathsModule);
1241                 packageGroup->addButton(autoRB);
1242                 packageGroup->addButton(alwaysRB);
1243                 packageGroup->addButton(neverRB);
1244                 autoRB->setToolTip(autoTooltip);
1245                 alwaysRB->setToolTip(alwaysTooltip);
1246                 neverRB->setToolTip(neverTooltip);
1247                 QTableWidgetItem * pack = new QTableWidgetItem(toqstr(package));
1248                 mathsModule->packagesTW->setItem(i, 0, pack);
1249                 mathsModule->packagesTW->setCellWidget(i, 1, autoRB);
1250                 mathsModule->packagesTW->setCellWidget(i, 2, alwaysRB);
1251                 mathsModule->packagesTW->setCellWidget(i, 3, neverRB);
1252                 //center the radio buttons
1253                 autoRB->setStyleSheet("margin-left:50%; margin-right:50%;");
1254                 alwaysRB->setStyleSheet("margin-left:50%; margin-right:50%;");
1255                 neverRB->setStyleSheet("margin-left:50%; margin-right:50%;");
1256
1257                 connect(autoRB, SIGNAL(clicked()),
1258                         this, SLOT(change_adaptor()));
1259                 connect(alwaysRB, SIGNAL(clicked()),
1260                         this, SLOT(change_adaptor()));
1261                 connect(neverRB, SIGNAL(clicked()),
1262                         this, SLOT(change_adaptor()));
1263                 ++i;
1264         }
1265         connect(mathsModule->allPackagesAutoPB, SIGNAL(clicked()),
1266                 this, SLOT(allPackagesAuto()));
1267         connect(mathsModule->allPackagesAlwaysPB, SIGNAL(clicked()),
1268                 this, SLOT(allPackagesAlways()));
1269         connect(mathsModule->allPackagesNotPB, SIGNAL(clicked()),
1270                 this, SLOT(allPackagesNot()));
1271         connect(mathsModule->allPackagesAutoPB, SIGNAL(clicked()),
1272                 this, SLOT(change_adaptor()));
1273         connect(mathsModule->allPackagesAlwaysPB, SIGNAL(clicked()),
1274                 this, SLOT(change_adaptor()));
1275         connect(mathsModule->allPackagesNotPB, SIGNAL(clicked()),
1276                 this, SLOT(change_adaptor()));
1277         connect(mathsModule->MathNumberingPosCO, SIGNAL(activated(int)),
1278                 this, SLOT(change_adaptor()));
1279
1280         connect(mathsModule->MathIndentCB, SIGNAL(toggled(bool)),
1281                 this, SLOT(change_adaptor()));
1282         connect(mathsModule->MathIndentCB, SIGNAL(toggled(bool)),
1283                 this, SLOT(allowMathIndent()));
1284         connect(mathsModule->MathIndentCO, SIGNAL(activated(int)),
1285                 this, SLOT(change_adaptor()));
1286         connect(mathsModule->MathIndentCO, SIGNAL(activated(int)),
1287                 this, SLOT(enableMathIndent(int)));
1288         connect(mathsModule->MathIndentLE, SIGNAL(textChanged(const QString &)),
1289                 this, SLOT(change_adaptor()));
1290         connect(mathsModule->MathIndentLengthCO, SIGNAL(activated(int)),
1291                 this, SLOT(change_adaptor()));
1292
1293
1294         mathsModule->MathIndentCO->addItem(qt_("Default"));
1295         mathsModule->MathIndentCO->addItem(qt_("Custom"));
1296         mathsModule->MathIndentLE->setValidator(new LengthValidator(
1297                 mathsModule->MathIndentLE));
1298         // initialize the length validator
1299         bc().addCheckedLineEdit(mathsModule->MathIndentLE);
1300         mathsModule->MathNumberingPosCO->addItem(qt_("Left"));
1301         mathsModule->MathNumberingPosCO->addItem(qt_("Default"));
1302         mathsModule->MathNumberingPosCO->addItem(qt_("Right"));
1303         mathsModule->MathNumberingPosCO->setCurrentIndex(1);
1304
1305
1306         // latex class
1307         latexModule = new UiWidget<Ui::LaTeXUi>(this);
1308         connect(latexModule->optionsLE, SIGNAL(textChanged(QString)),
1309                 this, SLOT(change_adaptor()));
1310         connect(latexModule->defaultOptionsCB, SIGNAL(clicked()),
1311                 this, SLOT(change_adaptor()));
1312         connect(latexModule->psdriverCO, SIGNAL(activated(int)),
1313                 this, SLOT(change_adaptor()));
1314         connect(latexModule->classCO, SIGNAL(activated(int)),
1315                 this, SLOT(classChanged_adaptor()));
1316         connect(latexModule->classCO, SIGNAL(activated(int)),
1317                 this, SLOT(change_adaptor()));
1318         connect(latexModule->layoutPB, SIGNAL(clicked()),
1319                 this, SLOT(browseLayout()));
1320         connect(latexModule->layoutPB, SIGNAL(clicked()),
1321                 this, SLOT(change_adaptor()));
1322         connect(latexModule->childDocGB, SIGNAL(clicked()),
1323                 this, SLOT(change_adaptor()));
1324         connect(latexModule->childDocLE, SIGNAL(textChanged(QString)),
1325                 this, SLOT(change_adaptor()));
1326         connect(latexModule->childDocPB, SIGNAL(clicked()),
1327                 this, SLOT(browseMaster()));
1328         connect(latexModule->suppressDateCB, SIGNAL(clicked()),
1329                 this, SLOT(change_adaptor()));
1330         connect(latexModule->refstyleCB, SIGNAL(clicked()),
1331                 this, SLOT(change_adaptor()));
1332
1333         latexModule->optionsLE->setValidator(new NoNewLineValidator(
1334                 latexModule->optionsLE));
1335         latexModule->childDocLE->setValidator(new NoNewLineValidator(
1336                 latexModule->childDocLE));
1337
1338         // postscript drivers
1339         for (int n = 0; tex_graphics[n][0]; ++n) {
1340                 QString enc = qt_(tex_graphics_gui[n]);
1341                 latexModule->psdriverCO->addItem(enc);
1342         }
1343         // latex classes
1344         LayoutFileList const & bcl = LayoutFileList::get();
1345         vector<LayoutFileIndex> classList = bcl.classList();
1346         sort(classList.begin(), classList.end(), less_textclass_avail_desc());
1347
1348         vector<LayoutFileIndex>::const_iterator cit  = classList.begin();
1349         vector<LayoutFileIndex>::const_iterator cen = classList.end();
1350         for (int i = 0; cit != cen; ++cit, ++i) {
1351                 LayoutFile const & tc = bcl[*cit];
1352                 bool const available = tc.isTeXClassAvailable();
1353                 docstring const guiname = translateIfPossible(from_utf8(tc.description()));
1354                 // tooltip sensu "KOMA-Script Article [Class 'scrartcl']"
1355                 QString tooltip = toqstr(bformat(_("%1$s [Class '%2$s']"), guiname, from_utf8(tc.latexname())));
1356                 if (!available) {
1357                         docstring const output_type = (tc.outputType() == lyx::DOCBOOK) ? _("DocBook") : _("LaTeX");
1358                         tooltip += '\n' + toqstr(bformat(_("Class not found by LyX. "
1359                                                            "Please check if you have the matching %1$s class "
1360                                                            "and all required packages (%2$s) installed."),
1361                                                          output_type, from_utf8(tc.prerequisites(", "))));
1362                 }
1363                 latexModule->classCO->addItemSort(toqstr(tc.name()),
1364                                                   toqstr(guiname),
1365                                                   toqstr(translateIfPossible(from_utf8(tc.category()))),
1366                                                   tooltip,
1367                                                   true, true, true, available);
1368         }
1369
1370
1371         // branches
1372         branchesModule = new GuiBranches(this);
1373         connect(branchesModule, SIGNAL(changed()),
1374                 this, SLOT(change_adaptor()));
1375         connect(branchesModule, SIGNAL(renameBranches(docstring const &, docstring const &)),
1376                 this, SLOT(branchesRename(docstring const &, docstring const &)));
1377         connect(branchesModule, SIGNAL(okPressed()), this, SLOT(slotOK()));
1378         updateUnknownBranches();
1379
1380
1381         // preamble
1382         preambleModule = new PreambleModule(this);
1383         connect(preambleModule, SIGNAL(changed()),
1384                 this, SLOT(change_adaptor()));
1385
1386         localLayout = new LocalLayout(this);
1387         connect(localLayout, SIGNAL(changed()),
1388                 this, SLOT(change_adaptor()));
1389
1390
1391         // bullets
1392         bulletsModule = new BulletsModule(this);
1393         connect(bulletsModule, SIGNAL(changed()),
1394                 this, SLOT(change_adaptor()));
1395
1396
1397         // Modules
1398         modulesModule = new UiWidget<Ui::ModulesUi>(this);
1399         modulesModule->availableLV->header()->setVisible(false);
1400         setSectionResizeMode(modulesModule->availableLV->header(), QHeaderView::ResizeToContents);
1401         modulesModule->availableLV->header()->setStretchLastSection(false);
1402         selectionManager =
1403                 new ModuleSelectionManager(this, modulesModule->availableLV,
1404                                            modulesModule->selectedLV,
1405                                            modulesModule->addPB,
1406                                            modulesModule->deletePB,
1407                                            modulesModule->upPB,
1408                                            modulesModule->downPB,
1409                                            availableModel(), selectedModel(), this);
1410         connect(selectionManager, SIGNAL(updateHook()),
1411                 this, SLOT(updateModuleInfo()));
1412         connect(selectionManager, SIGNAL(selectionChanged()),
1413                 this, SLOT(modulesChanged()));
1414
1415
1416         // PDF support
1417         pdfSupportModule = new UiWidget<Ui::PDFSupportUi>(this);
1418         connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
1419                 this, SLOT(change_adaptor()));
1420         connect(pdfSupportModule->titleLE, SIGNAL(textChanged(QString)),
1421                 this, SLOT(change_adaptor()));
1422         connect(pdfSupportModule->authorLE, SIGNAL(textChanged(QString)),
1423                 this, SLOT(change_adaptor()));
1424         connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(QString)),
1425                 this, SLOT(change_adaptor()));
1426         connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(QString)),
1427                 this, SLOT(change_adaptor()));
1428         connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
1429                 this, SLOT(change_adaptor()));
1430         connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
1431                 this, SLOT(change_adaptor()));
1432         connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
1433                 this, SLOT(change_adaptor()));
1434         connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
1435                 this, SLOT(change_adaptor()));
1436         connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
1437                 this, SLOT(change_adaptor()));
1438         connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
1439                 this, SLOT(change_adaptor()));
1440         connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
1441                 this, SLOT(change_adaptor()));
1442         connect(pdfSupportModule->backrefCO, SIGNAL(activated(int)),
1443                 this, SLOT(change_adaptor()));
1444         connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
1445                 this, SLOT(change_adaptor()));
1446         connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
1447                 this, SLOT(change_adaptor()));
1448         connect(pdfSupportModule->optionsLE, SIGNAL(textChanged(QString)),
1449                 this, SLOT(change_adaptor()));
1450
1451         pdfSupportModule->titleLE->setValidator(new NoNewLineValidator(
1452                 pdfSupportModule->titleLE));
1453         pdfSupportModule->authorLE->setValidator(new NoNewLineValidator(
1454                 pdfSupportModule->authorLE));
1455         pdfSupportModule->subjectLE->setValidator(new NoNewLineValidator(
1456                 pdfSupportModule->subjectLE));
1457         pdfSupportModule->keywordsLE->setValidator(new NoNewLineValidator(
1458                 pdfSupportModule->keywordsLE));
1459         pdfSupportModule->optionsLE->setValidator(new NoNewLineValidator(
1460                 pdfSupportModule->optionsLE));
1461
1462         for (int i = 0; backref_opts[i][0]; ++i)
1463                 pdfSupportModule->backrefCO->addItem(qt_(backref_opts_gui[i]));
1464
1465
1466         // float
1467         floatModule = new FloatPlacement;
1468         connect(floatModule, SIGNAL(changed()),
1469                 this, SLOT(change_adaptor()));
1470
1471
1472         // listings
1473         listingsModule = new UiWidget<Ui::ListingsSettingsUi>(this);
1474         connect(listingsModule->listingsED, SIGNAL(textChanged()),
1475                 this, SLOT(change_adaptor()));
1476         connect(listingsModule->bypassCB, SIGNAL(clicked()),
1477                 this, SLOT(change_adaptor()));
1478         connect(listingsModule->bypassCB, SIGNAL(clicked()),
1479                 this, SLOT(setListingsMessage()));
1480         connect(listingsModule->packageCO, SIGNAL(activated(int)),
1481                 this, SLOT(change_adaptor()));
1482         connect(listingsModule->packageCO, SIGNAL(activated(int)),
1483                 this, SLOT(listingsPackageChanged(int)));
1484         connect(listingsModule->listingsED, SIGNAL(textChanged()),
1485                 this, SLOT(setListingsMessage()));
1486         listingsModule->listingsTB->setPlainText(
1487                 qt_("Input listings parameters below. Enter ? for a list of parameters."));
1488
1489         for (int i = 0; lst_packages[i][0]; ++i)
1490             listingsModule->packageCO->addItem(lst_packages[i]);
1491
1492
1493         // add the panels
1494         docPS->addPanel(latexModule, N_("Document Class"));
1495         docPS->addPanel(masterChildModule, N_("Child Documents"));
1496         docPS->addPanel(modulesModule, N_("Modules"));
1497         docPS->addPanel(localLayout, N_("Local Layout"));
1498         docPS->addPanel(fontModule, N_("Fonts"));
1499         docPS->addPanel(textLayoutModule, N_("Text Layout"));
1500         docPS->addPanel(pageLayoutModule, N_("Page Layout"));
1501         docPS->addPanel(marginsModule, N_("Page Margins"));
1502         docPS->addPanel(langModule, N_("Language"));
1503         docPS->addPanel(colorModule, N_("Colors"));
1504         docPS->addPanel(numberingModule, N_("Numbering & TOC"));
1505         docPS->addPanel(biblioModule, N_("Bibliography"));
1506         docPS->addPanel(indicesModule, N_("Indexes"));
1507         docPS->addPanel(pdfSupportModule, N_("PDF Properties"));
1508         docPS->addPanel(mathsModule, N_("Math Options"));
1509         docPS->addPanel(floatModule, N_("Float Placement"));
1510         docPS->addPanel(listingsModule, N_("Listings[[inset]]"));
1511         docPS->addPanel(bulletsModule, N_("Bullets"));
1512         docPS->addPanel(branchesModule, N_("Branches"));
1513         docPS->addPanel(outputModule, N_("Formats[[output]]"));
1514         docPS->addPanel(preambleModule, N_("LaTeX Preamble"));
1515         docPS->setCurrentPanel("Document Class");
1516 // FIXME: hack to work around resizing bug in Qt >= 4.2
1517 // bug verified with Qt 4.2.{0-3} (JSpitzm)
1518 #if QT_VERSION >= 0x040200
1519         docPS->updateGeometry();
1520 #endif
1521 }
1522
1523
1524 void GuiDocument::onBufferViewChanged()
1525 {
1526         if (isVisibleView())
1527                 initialiseParams("");
1528 }
1529
1530
1531 void GuiDocument::saveDefaultClicked()
1532 {
1533         saveDocDefault();
1534 }
1535
1536
1537 void GuiDocument::useDefaultsClicked()
1538 {
1539         useClassDefaults();
1540 }
1541
1542
1543 void GuiDocument::change_adaptor()
1544 {
1545         nonModuleChanged_ = true;
1546         changed();
1547 }
1548
1549
1550 void GuiDocument::shellescapeChanged()
1551 {
1552         shellescapeChanged_ = true;
1553         changed();
1554 }
1555
1556
1557 void GuiDocument::slotApply()
1558 {
1559         bool only_shellescape_changed = !nonModuleChanged_ && !modulesChanged_;
1560         bool wasclean = buffer().isClean();
1561         GuiDialog::slotApply();
1562         if (wasclean && only_shellescape_changed)
1563                 buffer().markClean();
1564         modulesChanged_ = false;
1565 }
1566
1567
1568 void GuiDocument::slotOK()
1569 {
1570         bool only_shellescape_changed = !nonModuleChanged_ && !modulesChanged_;
1571         bool wasclean = buffer().isClean();
1572         GuiDialog::slotOK();
1573         if (wasclean && only_shellescape_changed)
1574                 buffer().markClean();
1575         modulesChanged_ = false;
1576 }
1577
1578
1579 void GuiDocument::includeonlyClicked(QTreeWidgetItem * item, int)
1580 {
1581         if (item == 0)
1582                 return;
1583
1584         string child = fromqstr(item->text(0));
1585         if (child.empty())
1586                 return;
1587
1588         if (std::find(includeonlys_.begin(),
1589                       includeonlys_.end(), child) != includeonlys_.end())
1590                 includeonlys_.remove(child);
1591         else
1592                 includeonlys_.push_back(child);
1593
1594         updateIncludeonlys();
1595         change_adaptor();
1596 }
1597
1598
1599 QString GuiDocument::validateListingsParameters()
1600 {
1601         if (listingsModule->bypassCB->isChecked())
1602                 return QString();
1603         string const package =
1604             lst_packages[listingsModule->packageCO->currentIndex()];
1605         string params = fromqstr(listingsModule->listingsED->toPlainText());
1606         InsetListingsParams lstparams(params);
1607         lstparams.setMinted(package == "Minted");
1608         return toqstr(lstparams.validate());
1609 }
1610
1611
1612 void GuiDocument::setListingsMessage()
1613 {
1614         // FIXME THREAD
1615         static bool isOK = true;
1616         QString msg = validateListingsParameters();
1617         if (msg.isEmpty()) {
1618                 if (isOK)
1619                         return;
1620                 isOK = true;
1621                 // listingsTB->setTextColor("black");
1622                 listingsModule->listingsTB->setPlainText(
1623                         qt_("Input listings parameters below. "
1624                             "Enter ? for a list of parameters."));
1625         } else {
1626                 isOK = false;
1627                 // listingsTB->setTextColor("red");
1628                 listingsModule->listingsTB->setPlainText(msg);
1629         }
1630 }
1631
1632
1633 void GuiDocument::listingsPackageChanged(int index)
1634 {
1635         string const package = lst_packages[index];
1636         if (package == "Minted" && lyxrc.pygmentize_command.empty()) {
1637                 Alert::warning(_("Pygments driver command not found!"),
1638                     _("The driver command necessary to use the minted package\n"
1639                       "(pygmentize) has not been found. Make sure you have\n"
1640                       "the python-pygments module installed or, if the driver\n"
1641                       "is named differently, to add the following line to the\n"
1642                       "document preamble:\n\n"
1643                       "\\AtBeginDocument{\\renewcommand{\\MintedPygmentize}{driver}}\n\n"
1644                       "where 'driver' is name of the driver command."));
1645         }
1646 }
1647
1648
1649 void GuiDocument::setLSpacing(int item)
1650 {
1651         textLayoutModule->lspacingLE->setEnabled(item == 3);
1652 }
1653
1654
1655 void GuiDocument::setIndent(int item)
1656 {
1657         bool const enable = (item == 1);
1658         textLayoutModule->indentLE->setEnabled(enable);
1659         textLayoutModule->indentLengthCO->setEnabled(enable);
1660         textLayoutModule->skipLE->setEnabled(false);
1661         textLayoutModule->skipLengthCO->setEnabled(false);
1662         isValid();
1663 }
1664
1665
1666 void GuiDocument::enableIndent(bool indent)
1667 {
1668         textLayoutModule->skipLE->setEnabled(!indent);
1669         textLayoutModule->skipLengthCO->setEnabled(!indent);
1670         if (indent)
1671                 setIndent(textLayoutModule->indentCO->currentIndex());
1672 }
1673
1674
1675 void GuiDocument::setSkip(int item)
1676 {
1677         bool const enable = (item == 3);
1678         textLayoutModule->skipLE->setEnabled(enable);
1679         textLayoutModule->skipLengthCO->setEnabled(enable);
1680         isValid();
1681 }
1682
1683
1684 void GuiDocument::enableSkip(bool skip)
1685 {
1686         textLayoutModule->indentLE->setEnabled(!skip);
1687         textLayoutModule->indentLengthCO->setEnabled(!skip);
1688         if (skip)
1689                 setSkip(textLayoutModule->skipCO->currentIndex());
1690 }
1691
1692 void GuiDocument::allowMathIndent() {
1693         // only disable when not checked, checked does not always allow enabling
1694         if (!mathsModule->MathIndentCB->isChecked()) {
1695                 mathsModule->MathIndentLE->setEnabled(false);
1696                 mathsModule->MathIndentLengthCO->setEnabled(false);
1697         }
1698         if (mathsModule->MathIndentCB->isChecked()
1699             && mathsModule->MathIndentCO->currentIndex() == 1) {
1700                         mathsModule->MathIndentLE->setEnabled(true);
1701                         mathsModule->MathIndentLengthCO->setEnabled(true);
1702         }
1703         isValid();
1704 }
1705
1706 void GuiDocument::enableMathIndent(int item)
1707 {
1708         bool const enable = (item == 1);
1709         mathsModule->MathIndentLE->setEnabled(enable);
1710         mathsModule->MathIndentLengthCO->setEnabled(enable);
1711         isValid();
1712 }
1713
1714
1715 void GuiDocument::setMargins()
1716 {
1717         bool const extern_geometry =
1718                 documentClass().provides("geometry");
1719         marginsModule->marginCB->setEnabled(!extern_geometry);
1720         if (extern_geometry) {
1721                 marginsModule->marginCB->setChecked(false);
1722                 setCustomMargins(true);
1723         } else {
1724                 marginsModule->marginCB->setChecked(!bp_.use_geometry);
1725                 setCustomMargins(!bp_.use_geometry);
1726         }
1727 }
1728
1729
1730 void GuiDocument::papersizeChanged(int paper_size)
1731 {
1732         setCustomPapersize(paper_size == 1);
1733 }
1734
1735
1736 void GuiDocument::setCustomPapersize(bool custom)
1737 {
1738         pageLayoutModule->paperwidthL->setEnabled(custom);
1739         pageLayoutModule->paperwidthLE->setEnabled(custom);
1740         pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
1741         pageLayoutModule->paperheightL->setEnabled(custom);
1742         pageLayoutModule->paperheightLE->setEnabled(custom);
1743         pageLayoutModule->paperheightLE->setFocus();
1744         pageLayoutModule->paperheightUnitCO->setEnabled(custom);
1745 }
1746
1747
1748 void GuiDocument::setColSep()
1749 {
1750         setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
1751 }
1752
1753
1754 void GuiDocument::setCustomMargins(bool custom)
1755 {
1756         marginsModule->topL->setEnabled(!custom);
1757         marginsModule->topLE->setEnabled(!custom);
1758         marginsModule->topUnit->setEnabled(!custom);
1759
1760         marginsModule->bottomL->setEnabled(!custom);
1761         marginsModule->bottomLE->setEnabled(!custom);
1762         marginsModule->bottomUnit->setEnabled(!custom);
1763
1764         marginsModule->innerL->setEnabled(!custom);
1765         marginsModule->innerLE->setEnabled(!custom);
1766         marginsModule->innerUnit->setEnabled(!custom);
1767
1768         marginsModule->outerL->setEnabled(!custom);
1769         marginsModule->outerLE->setEnabled(!custom);
1770         marginsModule->outerUnit->setEnabled(!custom);
1771
1772         marginsModule->headheightL->setEnabled(!custom);
1773         marginsModule->headheightLE->setEnabled(!custom);
1774         marginsModule->headheightUnit->setEnabled(!custom);
1775
1776         marginsModule->headsepL->setEnabled(!custom);
1777         marginsModule->headsepLE->setEnabled(!custom);
1778         marginsModule->headsepUnit->setEnabled(!custom);
1779
1780         marginsModule->footskipL->setEnabled(!custom);
1781         marginsModule->footskipLE->setEnabled(!custom);
1782         marginsModule->footskipUnit->setEnabled(!custom);
1783
1784         bool const enableColSep = !custom &&
1785                         textLayoutModule->twoColumnCB->checkState() == Qt::Checked;
1786         marginsModule->columnsepL->setEnabled(enableColSep);
1787         marginsModule->columnsepLE->setEnabled(enableColSep);
1788         marginsModule->columnsepUnit->setEnabled(enableColSep);
1789 }
1790
1791
1792 void GuiDocument::changeBackgroundColor()
1793 {
1794         QColor const & newColor = QColorDialog::getColor(
1795                 rgb2qcolor(set_backgroundcolor), asQWidget());
1796         if (!newColor.isValid())
1797                 return;
1798         // set the button color and text
1799         colorModule->backgroundPB->setStyleSheet(
1800                 colorButtonStyleSheet(newColor));
1801         colorModule->backgroundPB->setText(qt_("&Change..."));
1802         // save color
1803         set_backgroundcolor = rgbFromHexName(fromqstr(newColor.name()));
1804         is_backgroundcolor = true;
1805         change_adaptor();
1806 }
1807
1808
1809 void GuiDocument::deleteBackgroundColor()
1810 {
1811         // set the button color back to default by setting an empty StyleSheet
1812         colorModule->backgroundPB->setStyleSheet(QLatin1String(""));
1813         // change button text
1814         colorModule->backgroundPB->setText(qt_("&Default..."));
1815         // save default color (white)
1816         set_backgroundcolor = rgbFromHexName("#ffffff");
1817         is_backgroundcolor = false;
1818         change_adaptor();
1819 }
1820
1821
1822 void GuiDocument::changeFontColor()
1823 {
1824         QColor const & newColor = QColorDialog::getColor(
1825                 rgb2qcolor(set_fontcolor), asQWidget());
1826         if (!newColor.isValid())
1827                 return;
1828         // set the button color and text
1829         colorModule->fontColorPB->setStyleSheet(
1830                 colorButtonStyleSheet(newColor));
1831         colorModule->fontColorPB->setText(qt_("&Change..."));
1832         // save color
1833         set_fontcolor = rgbFromHexName(fromqstr(newColor.name()));
1834         is_fontcolor = true;
1835         change_adaptor();
1836 }
1837
1838
1839 void GuiDocument::deleteFontColor()
1840 {
1841         // set the button color back to default by setting an empty StyleSheet
1842         colorModule->fontColorPB->setStyleSheet(QLatin1String(""));
1843         // change button text
1844         colorModule->fontColorPB->setText(qt_("&Default..."));
1845         // save default color (black)
1846         set_fontcolor = rgbFromHexName("#000000");
1847         is_fontcolor = false;
1848         change_adaptor();
1849 }
1850
1851
1852 void GuiDocument::changeNoteFontColor()
1853 {
1854         QColor const & newColor = QColorDialog::getColor(
1855                 rgb2qcolor(set_notefontcolor), asQWidget());
1856         if (!newColor.isValid())
1857                 return;
1858         // set the button color
1859         colorModule->noteFontColorPB->setStyleSheet(
1860                 colorButtonStyleSheet(newColor));
1861         // save color
1862         set_notefontcolor = rgbFromHexName(fromqstr(newColor.name()));
1863         change_adaptor();
1864 }
1865
1866
1867 void GuiDocument::deleteNoteFontColor()
1868 {
1869         // set the button color back to pref
1870         theApp()->getRgbColor(Color_greyedouttext, set_notefontcolor);
1871         colorModule->noteFontColorPB->setStyleSheet(
1872                 colorButtonStyleSheet(rgb2qcolor(set_notefontcolor)));
1873         change_adaptor();
1874 }
1875
1876
1877 void GuiDocument::changeBoxBackgroundColor()
1878 {
1879         QColor const & newColor = QColorDialog::getColor(
1880                 rgb2qcolor(set_boxbgcolor), asQWidget());
1881         if (!newColor.isValid())
1882                 return;
1883         // set the button color
1884         colorModule->boxBackgroundPB->setStyleSheet(
1885                 colorButtonStyleSheet(newColor));
1886         // save color
1887         set_boxbgcolor = rgbFromHexName(fromqstr(newColor.name()));
1888         change_adaptor();
1889 }
1890
1891
1892 void GuiDocument::deleteBoxBackgroundColor()
1893 {
1894         // set the button color back to pref
1895         theApp()->getRgbColor(Color_shadedbg, set_boxbgcolor);
1896         colorModule->boxBackgroundPB->setStyleSheet(
1897                 colorButtonStyleSheet(rgb2qcolor(set_boxbgcolor)));
1898         change_adaptor();
1899 }
1900
1901
1902 void GuiDocument::updateQuoteStyles(bool const set)
1903 {
1904         Language const * lang = lyx::languages.getLanguage(
1905                 fromqstr(langModule->languageCO->itemData(
1906                         langModule->languageCO->currentIndex()).toString()));
1907
1908         InsetQuotesParams::QuoteStyle def = bp_.getQuoteStyle(lang->quoteStyle());
1909
1910         langModule->quoteStyleCO->clear();
1911
1912         bool has_default = false;
1913         for (int i = 0; i < quoteparams.stylescount(); ++i) {
1914                 InsetQuotesParams::QuoteStyle qs = InsetQuotesParams::QuoteStyle(i);
1915                 if (qs == InsetQuotesParams::DynamicQuotes)
1916                         continue;
1917                 bool const langdef = (qs == def);
1918                 if (langdef) {
1919                         // add the default style on top
1920                         langModule->quoteStyleCO->insertItem(0,
1921                                 toqstr(quoteparams.getGuiLabel(qs, langdef)), qs);
1922                         has_default = true;
1923                 }
1924                 else
1925                         langModule->quoteStyleCO->addItem(
1926                                 toqstr(quoteparams.getGuiLabel(qs, langdef)), qs);
1927         }
1928         if (set && has_default)
1929                 // (re)set to the default style
1930                 langModule->quoteStyleCO->setCurrentIndex(0);
1931 }
1932
1933
1934 void GuiDocument::languageChanged(int i)
1935 {
1936         // some languages only work with polyglossia
1937         Language const * lang = lyx::languages.getLanguage(
1938                 fromqstr(langModule->languageCO->itemData(i).toString()));
1939         if (lang->babel().empty() && !lang->polyglossia().empty()) {
1940                         // If we force to switch fontspec on, store
1941                         // current state (#8717)
1942                         if (fontModule->osFontsCB->isEnabled())
1943                                 forced_fontspec_activation =
1944                                         !fontModule->osFontsCB->isChecked();
1945                         fontModule->osFontsCB->setChecked(true);
1946                         fontModule->osFontsCB->setEnabled(false);
1947         }
1948         else {
1949                 fontModule->osFontsCB->setEnabled(true);
1950                 // If we have forced to switch fontspec on,
1951                 // restore previous state (#8717)
1952                 if (forced_fontspec_activation)
1953                         fontModule->osFontsCB->setChecked(false);
1954                 forced_fontspec_activation = false;
1955         }
1956
1957         // set appropriate quotation mark style
1958         updateQuoteStyles(true);
1959 }
1960
1961
1962 void GuiDocument::osFontsChanged(bool nontexfonts)
1963 {
1964         bool const tex_fonts = !nontexfonts;
1965         // store current fonts
1966         QString const font_roman = fontModule->fontsRomanCO->itemData(
1967                         fontModule->fontsRomanCO->currentIndex()).toString();
1968         QString const font_sans = fontModule->fontsSansCO->itemData(
1969                         fontModule->fontsSansCO->currentIndex()).toString();
1970         QString const font_typewriter = fontModule->fontsTypewriterCO->itemData(
1971                         fontModule->fontsTypewriterCO->currentIndex()).toString();
1972         QString const font_math = fontModule->fontsMathCO->itemData(
1973                         fontModule->fontsMathCO->currentIndex()).toString();
1974         int const font_sf_scale = fontModule->scaleSansSB->value();
1975         int const font_tt_scale = fontModule->scaleTypewriterSB->value();
1976
1977         updateFontlist();
1978         // store default format
1979         QString const dformat = outputModule->defaultFormatCO->itemData(
1980                 outputModule->defaultFormatCO->currentIndex()).toString();
1981         updateDefaultFormat();
1982         // try to restore default format
1983         int index = outputModule->defaultFormatCO->findData(dformat);
1984         // set to default if format is not found
1985         if (index == -1)
1986                 index = 0;
1987         outputModule->defaultFormatCO->setCurrentIndex(index);
1988
1989         // try to restore fonts which were selected two toggles ago
1990         index = fontModule->fontsRomanCO->findData(fontModule->font_roman);
1991         if (index != -1)
1992                 fontModule->fontsRomanCO->setCurrentIndex(index);
1993         index = fontModule->fontsSansCO->findData(fontModule->font_sans);
1994         if (index != -1)
1995                 fontModule->fontsSansCO->setCurrentIndex(index);
1996         index = fontModule->fontsTypewriterCO->findData(fontModule->font_typewriter);
1997         if (index != -1)
1998                 fontModule->fontsTypewriterCO->setCurrentIndex(index);
1999         index = fontModule->fontsMathCO->findData(fontModule->font_math);
2000         if (index != -1)
2001                 fontModule->fontsMathCO->setCurrentIndex(index);
2002         // save fonts for next next toggle
2003         fontModule->font_roman = font_roman;
2004         fontModule->font_sans = font_sans;
2005         fontModule->font_typewriter = font_typewriter;
2006         fontModule->font_math = font_math;
2007         fontModule->font_sf_scale = font_sf_scale;
2008         fontModule->font_tt_scale = font_tt_scale;
2009
2010         langModule->encodingCO->setEnabled(tex_fonts &&
2011                 !langModule->defaultencodingRB->isChecked());
2012         langModule->defaultencodingRB->setEnabled(tex_fonts);
2013         langModule->otherencodingRB->setEnabled(tex_fonts);
2014
2015         fontModule->fontsDefaultCO->setEnabled(tex_fonts);
2016         fontModule->fontsDefaultLA->setEnabled(tex_fonts);
2017         fontModule->cjkFontLE->setEnabled(tex_fonts);
2018         fontModule->cjkFontLA->setEnabled(tex_fonts);
2019
2020         updateFontOptions();
2021
2022         fontModule->fontencLA->setEnabled(tex_fonts);
2023         fontModule->fontencCO->setEnabled(tex_fonts);
2024         if (!tex_fonts)
2025                 fontModule->fontencLE->setEnabled(false);
2026         else
2027                 fontencChanged(fontModule->fontencCO->currentIndex());
2028 }
2029
2030
2031 void GuiDocument::mathFontChanged(int)
2032 {
2033         updateFontOptions();
2034 }
2035
2036
2037 void GuiDocument::fontOsfToggled(bool state)
2038 {
2039         if (fontModule->osFontsCB->isChecked())
2040                 return;
2041         QString font = fontModule->fontsRomanCO->itemData(
2042                         fontModule->fontsRomanCO->currentIndex()).toString();
2043         if (hasMonolithicExpertSet(font))
2044                 fontModule->fontScCB->setChecked(state);
2045 }
2046
2047
2048 void GuiDocument::fontScToggled(bool state)
2049 {
2050         if (fontModule->osFontsCB->isChecked())
2051                 return;
2052         QString font = fontModule->fontsRomanCO->itemData(
2053                         fontModule->fontsRomanCO->currentIndex()).toString();
2054         if (hasMonolithicExpertSet(font))
2055                 fontModule->fontOsfCB->setChecked(state);
2056 }
2057
2058
2059 void GuiDocument::updateFontOptions()
2060 {
2061         bool const tex_fonts = !fontModule->osFontsCB->isChecked();
2062         QString font;
2063         if (tex_fonts)
2064                 font = fontModule->fontsSansCO->itemData(
2065                                 fontModule->fontsSansCO->currentIndex()).toString();
2066         bool scaleable = providesScale(font);
2067         fontModule->scaleSansSB->setEnabled(scaleable);
2068         fontModule->scaleSansLA->setEnabled(scaleable);
2069         if (tex_fonts)
2070                 font = fontModule->fontsTypewriterCO->itemData(
2071                                 fontModule->fontsTypewriterCO->currentIndex()).toString();
2072         scaleable = providesScale(font);
2073         fontModule->scaleTypewriterSB->setEnabled(scaleable);
2074         fontModule->scaleTypewriterLA->setEnabled(scaleable);
2075         if (tex_fonts)
2076                 font = fontModule->fontsRomanCO->itemData(
2077                                 fontModule->fontsRomanCO->currentIndex()).toString();
2078         fontModule->fontScCB->setEnabled(providesSC(font));
2079         fontModule->fontOsfCB->setEnabled(providesOSF(font));
2080         fontModule->dashesCB->setEnabled(tex_fonts);
2081         updateMathFonts(font);
2082 }
2083
2084
2085 void GuiDocument::updateFontsize(string const & items, string const & sel)
2086 {
2087         fontModule->fontsizeCO->clear();
2088         fontModule->fontsizeCO->addItem(qt_("Default"));
2089
2090         for (int n = 0; !token(items,'|',n).empty(); ++n)
2091                 fontModule->fontsizeCO->
2092                         addItem(toqstr(token(items,'|',n)));
2093
2094         for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
2095                 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
2096                         fontModule->fontsizeCO->setCurrentIndex(n);
2097                         break;
2098                 }
2099         }
2100 }
2101
2102
2103 bool GuiDocument::ot1() const
2104 {
2105         QString const fontenc =
2106                 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
2107         return (fontenc == "default"
2108                 || (fontenc == "global" && (lyxrc.fontenc == "default" || lyxrc.fontenc == "OT1"))
2109                 || (fontenc == "custom" && fontModule->fontencLE->text() == "OT1"));
2110 }
2111
2112
2113 bool GuiDocument::completeFontset() const
2114 {
2115         return (fontModule->fontsSansCO->itemData(
2116                         fontModule->fontsSansCO->currentIndex()).toString() == "default"
2117                 && fontModule->fontsSansCO->itemData(
2118                         fontModule->fontsTypewriterCO->currentIndex()).toString() == "default");
2119 }
2120
2121
2122 bool GuiDocument::noMathFont() const
2123 {
2124         return (fontModule->fontsMathCO->itemData(
2125                 fontModule->fontsMathCO->currentIndex()).toString() == "default");
2126 }
2127
2128
2129 void GuiDocument::updateTexFonts()
2130 {
2131         LaTeXFonts::TexFontMap texfontmap = theLaTeXFonts().getLaTeXFonts();
2132
2133         LaTeXFonts::TexFontMap::const_iterator it = texfontmap.begin();
2134         LaTeXFonts::TexFontMap::const_iterator end = texfontmap.end();
2135         for (; it != end; ++it) {
2136                 LaTeXFont lf = it->second;
2137                 if (lf.name().empty()) {
2138                         LYXERR0("Error: Unnamed font: " << it->first);
2139                         continue;
2140                 }
2141                 docstring const family = lf.family();
2142                 docstring guiname = translateIfPossible(lf.guiname());
2143                 if (!lf.available(ot1(), noMathFont()))
2144                         guiname += _(" (not installed)");
2145                 if (family == "rm")
2146                         rmfonts_.insert(toqstr(guiname), toqstr(it->first));
2147                 else if (family == "sf")
2148                         sffonts_.insert(toqstr(guiname), toqstr(it->first));
2149                 else if (family == "tt")
2150                         ttfonts_.insert(toqstr(guiname), toqstr(it->first));
2151                 else if (family == "math")
2152                         mathfonts_.insert(toqstr(guiname), toqstr(it->first));
2153         }
2154 }
2155
2156
2157 void GuiDocument::updateFontlist()
2158 {
2159         fontModule->fontsRomanCO->clear();
2160         fontModule->fontsSansCO->clear();
2161         fontModule->fontsTypewriterCO->clear();
2162         fontModule->fontsMathCO->clear();
2163
2164         // With fontspec (XeTeX, LuaTeX), we have access to all system fonts, but not the LaTeX fonts
2165         if (fontModule->osFontsCB->isChecked()) {
2166                 fontModule->fontsRomanCO->addItem(qt_("Default"), QString("default"));
2167                 fontModule->fontsSansCO->addItem(qt_("Default"), QString("default"));
2168                 fontModule->fontsTypewriterCO->addItem(qt_("Default"), QString("default"));
2169                 QString unimath = qt_("Non-TeX Fonts Default");
2170                 if (!LaTeXFeatures::isAvailable("unicode-math"))
2171                         unimath += qt_(" (not available)");
2172                 fontModule->fontsMathCO->addItem(qt_("Class Default (TeX Fonts)"), QString("auto"));
2173                 fontModule->fontsMathCO->addItem(unimath, QString("default"));
2174
2175                 QFontDatabase fontdb;
2176                 QStringList families(fontdb.families());
2177                 for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
2178                         fontModule->fontsRomanCO->addItem(*it, *it);
2179                         fontModule->fontsSansCO->addItem(*it, *it);
2180                         fontModule->fontsTypewriterCO->addItem(*it, *it);
2181                 }
2182                 return;
2183         }
2184
2185         if (rmfonts_.empty())
2186                 updateTexFonts();
2187
2188         fontModule->fontsRomanCO->addItem(qt_("Default"), QString("default"));
2189         QMap<QString, QString>::const_iterator rmi = rmfonts_.constBegin();
2190         while (rmi != rmfonts_.constEnd()) {
2191                 fontModule->fontsRomanCO->addItem(rmi.key(), rmi.value());
2192                 ++rmi;
2193         }
2194
2195         fontModule->fontsSansCO->addItem(qt_("Default"), QString("default"));
2196         QMap<QString, QString>::const_iterator sfi = sffonts_.constBegin();
2197         while (sfi != sffonts_.constEnd()) {
2198                 fontModule->fontsSansCO->addItem(sfi.key(), sfi.value());
2199                 ++sfi;
2200         }
2201
2202         fontModule->fontsTypewriterCO->addItem(qt_("Default"), QString("default"));
2203         QMap<QString, QString>::const_iterator tti = ttfonts_.constBegin();
2204         while (tti != ttfonts_.constEnd()) {
2205                 fontModule->fontsTypewriterCO->addItem(tti.key(), tti.value());
2206                 ++tti;
2207         }
2208
2209         fontModule->fontsMathCO->addItem(qt_("Automatic"), QString("auto"));
2210         fontModule->fontsMathCO->addItem(qt_("Class Default"), QString("default"));
2211         QMap<QString, QString>::const_iterator mmi = mathfonts_.constBegin();
2212         while (mmi != mathfonts_.constEnd()) {
2213                 fontModule->fontsMathCO->addItem(mmi.key(), mmi.value());
2214                 ++mmi;
2215         }
2216 }
2217
2218
2219 void GuiDocument::fontencChanged(int item)
2220 {
2221         fontModule->fontencLE->setEnabled(
2222                 fontModule->fontencCO->itemData(item).toString() == "custom");
2223         // The availability of TeX fonts depends on the font encoding
2224         updateTexFonts();
2225         updateFontOptions();
2226 }
2227
2228
2229 void GuiDocument::updateMathFonts(QString const & rm)
2230 {
2231         if (fontModule->osFontsCB->isChecked())
2232                 return;
2233         QString const math =
2234                 fontModule->fontsMathCO->itemData(fontModule->fontsMathCO->currentIndex()).toString();
2235         int const i = fontModule->fontsMathCO->findData("default");
2236         if (providesNoMath(rm) && i == -1)
2237                 fontModule->fontsMathCO->insertItem(1, qt_("Class Default"), QString("default"));
2238         else if (!providesNoMath(rm) && i != -1) {
2239                 int const c = fontModule->fontsMathCO->currentIndex();
2240                 fontModule->fontsMathCO->removeItem(i);
2241                 if (c == i)
2242                         fontModule->fontsMathCO->setCurrentIndex(0);
2243         }
2244 }
2245
2246
2247 void GuiDocument::romanChanged(int item)
2248 {
2249         if (fontModule->osFontsCB->isChecked())
2250                 return;
2251         QString const font =
2252                 fontModule->fontsRomanCO->itemData(item).toString();
2253         fontModule->fontScCB->setEnabled(providesSC(font));
2254         fontModule->fontOsfCB->setEnabled(providesOSF(font));
2255         updateMathFonts(font);
2256 }
2257
2258
2259 void GuiDocument::sansChanged(int item)
2260 {
2261         if (fontModule->osFontsCB->isChecked())
2262                 return;
2263         QString const font =
2264                 fontModule->fontsSansCO->itemData(item).toString();
2265         bool scaleable = providesScale(font);
2266         fontModule->scaleSansSB->setEnabled(scaleable);
2267         fontModule->scaleSansLA->setEnabled(scaleable);
2268 }
2269
2270
2271 void GuiDocument::ttChanged(int item)
2272 {
2273         if (fontModule->osFontsCB->isChecked())
2274                 return;
2275         QString const font =
2276                 fontModule->fontsTypewriterCO->itemData(item).toString();
2277         bool scaleable = providesScale(font);
2278         fontModule->scaleTypewriterSB->setEnabled(scaleable);
2279         fontModule->scaleTypewriterLA->setEnabled(scaleable);
2280 }
2281
2282
2283 void GuiDocument::updatePagestyle(string const & items, string const & sel)
2284 {
2285         pagestyles.clear();
2286         pageLayoutModule->pagestyleCO->clear();
2287         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
2288
2289         for (int n = 0; !token(items, '|', n).empty(); ++n) {
2290                 string style = token(items, '|', n);
2291                 QString style_gui = qt_(style);
2292                 pagestyles.push_back(pair<string, QString>(style, style_gui));
2293                 pageLayoutModule->pagestyleCO->addItem(style_gui);
2294         }
2295
2296         if (sel == "default") {
2297                 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
2298                 return;
2299         }
2300
2301         int nn = 0;
2302
2303         for (size_t i = 0; i < pagestyles.size(); ++i)
2304                 if (pagestyles[i].first == sel)
2305                         nn = pageLayoutModule->pagestyleCO->findText(pagestyles[i].second);
2306
2307         if (nn > 0)
2308                 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
2309 }
2310
2311
2312 void GuiDocument::browseLayout()
2313 {
2314         QString const label1 = qt_("Layouts|#o#O");
2315         QString const dir1 = toqstr(lyxrc.document_path);
2316         QStringList const filter(qt_("LyX Layout (*.layout)"));
2317         QString file = browseRelToParent(QString(), bufferFilePath(),
2318                 qt_("Local layout file"), filter, false,
2319                 label1, dir1);
2320
2321         if (!file.endsWith(".layout"))
2322                 return;
2323
2324         FileName layoutFile = support::makeAbsPath(fromqstr(file),
2325                 fromqstr(bufferFilePath()));
2326
2327         int const ret = Alert::prompt(_("Local layout file"),
2328                 _("The layout file you have selected is a local layout\n"
2329                   "file, not one in the system or user directory.\n"
2330                   "Your document will not work with this layout if you\n"
2331                   "move the layout file to a different directory."),
2332                   1, 1, _("&Set Layout"), _("&Cancel"));
2333         if (ret == 1)
2334                 return;
2335
2336         // load the layout file
2337         LayoutFileList & bcl = LayoutFileList::get();
2338         string classname = layoutFile.onlyFileName();
2339         // this will update an existing layout if that layout has been loaded before.
2340         LayoutFileIndex name = support::onlyFileName(bcl.addLocalLayout(
2341                 classname.substr(0, classname.size() - 7),
2342                 layoutFile.onlyPath().absFileName()));
2343
2344         if (name.empty()) {
2345                 Alert::error(_("Error"),
2346                         _("Unable to read local layout file."));
2347                 return;
2348         }
2349
2350         const_cast<Buffer &>(buffer()).setLayoutPos(layoutFile.onlyPath().absFileName());
2351
2352         // do not trigger classChanged if there is no change.
2353         if (latexModule->classCO->currentText() == toqstr(name))
2354                 return;
2355
2356         // add to combo box
2357         bool const avail = latexModule->classCO->set(toqstr(name));
2358         if (!avail) {
2359                 LayoutFile const & tc = bcl[name];
2360                 docstring const guiname = translateIfPossible(from_utf8(tc.description()));
2361                 // tooltip sensu "KOMA-Script Article [Class 'scrartcl']"
2362                 QString tooltip = toqstr(bformat(_("%1$s [Class '%2$s']"), guiname, from_utf8(tc.latexname())));
2363                 tooltip += '\n' + qt_("This is a local layout file.");
2364                 latexModule->classCO->addItemSort(toqstr(tc.name()), toqstr(guiname),
2365                                                   toqstr(translateIfPossible(from_utf8(tc.category()))),
2366                                                   tooltip,
2367                                                   true, true, true, true);
2368                 latexModule->classCO->set(toqstr(name));
2369         }
2370
2371         classChanged();
2372 }
2373
2374
2375 void GuiDocument::browseMaster()
2376 {
2377         QString const title = qt_("Select master document");
2378         QString const dir1 = toqstr(lyxrc.document_path);
2379         QString const old = latexModule->childDocLE->text();
2380         QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
2381         QStringList const filter(qt_("LyX Files (*.lyx)"));
2382         QString file = browseRelToSub(old, docpath, title, filter, false,
2383                 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
2384
2385         if (!file.isEmpty())
2386                 latexModule->childDocLE->setText(file);
2387 }
2388
2389
2390 void GuiDocument::classChanged_adaptor()
2391 {
2392         const_cast<Buffer &>(buffer()).setLayoutPos(string());
2393         classChanged();
2394 }
2395
2396
2397 void GuiDocument::classChanged()
2398 {
2399         int idx = latexModule->classCO->currentIndex();
2400         if (idx < 0)
2401                 return;
2402         string const classname = fromqstr(latexModule->classCO->getData(idx));
2403
2404         if (applyPB->isEnabled()) {
2405                 int const ret = Alert::prompt(_("Unapplied changes"),
2406                                 _("Some changes in the dialog were not yet applied.\n"
2407                                 "If you do not apply now, they will be lost after this action."),
2408                                 1, 1, _("&Apply"), _("&Dismiss"));
2409                 if (ret == 0)
2410                         applyView();
2411         }
2412
2413         // We load the TextClass as soon as it is selected. This is
2414         // necessary so that other options in the dialog can be updated
2415         // according to the new class. Note, however, that, if you use
2416         // the scroll wheel when sitting on the combo box, we'll load a
2417         // lot of TextClass objects very quickly....
2418         if (!bp_.setBaseClass(classname)) {
2419                 Alert::error(_("Error"), _("Unable to set document class."));
2420                 return;
2421         }
2422         if (lyxrc.auto_reset_options)
2423                 bp_.useClassDefaults();
2424
2425         // With the introduction of modules came a distinction between the base
2426         // class and the document class. The former corresponds to the main layout
2427         // file; the latter is that plus the modules (or the document-specific layout,
2428         // or  whatever else there could be). Our parameters come from the document
2429         // class. So when we set the base class, we also need to recreate the document
2430         // class. Otherwise, we still have the old one.
2431         bp_.makeDocumentClass();
2432         paramsToDialog();
2433 }
2434
2435
2436 void GuiDocument::languagePackageChanged(int i)
2437 {
2438          langModule->languagePackageLE->setEnabled(
2439                 langModule->languagePackageCO->itemData(i).toString() == "custom");
2440 }
2441
2442
2443 void GuiDocument::biblioChanged()
2444 {
2445         biblioChanged_ = true;
2446         change_adaptor();
2447 }
2448
2449
2450 void GuiDocument::rescanBibFiles()
2451 {
2452         if (isBiblatex())
2453                 rescanTexStyles("bbx cbx");
2454         else
2455                 rescanTexStyles("bst");
2456 }
2457
2458
2459 void GuiDocument::resetDefaultBibfile(string const & which)
2460 {
2461         QString const engine =
2462                 biblioModule->citeEngineCO->itemData(
2463                                 biblioModule->citeEngineCO->currentIndex()).toString();
2464
2465         CiteEngineType const cet =
2466                 CiteEngineType(biblioModule->citeStyleCO->itemData(
2467                                                           biblioModule->citeStyleCO->currentIndex()).toInt());
2468
2469         updateDefaultBiblio(theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet), which);
2470 }
2471
2472
2473 void GuiDocument::resetDefaultBbxBibfile()
2474 {
2475         resetDefaultBibfile("bbx");
2476 }
2477
2478
2479 void GuiDocument::resetDefaultCbxBibfile()
2480 {
2481         resetDefaultBibfile("cbx");
2482 }
2483
2484
2485 void GuiDocument::citeEngineChanged(int n)
2486 {
2487         QString const engine =
2488                 biblioModule->citeEngineCO->itemData(n).toString();
2489
2490         vector<string> const engs =
2491                 theCiteEnginesList[fromqstr(engine)]->getEngineType();
2492
2493         updateCiteStyles(engs);
2494         updateEngineDependends();
2495         resetDefaultBibfile();
2496         biblioChanged();
2497 }
2498
2499
2500 void GuiDocument::updateEngineDependends()
2501 {
2502         bool const biblatex = isBiblatex();
2503
2504         // These are only useful with BibTeX
2505         biblioModule->defaultBiblioCO->setEnabled(!biblatex);
2506         biblioModule->bibtexStyleLA->setEnabled(!biblatex);
2507         biblioModule->resetDefaultBiblioPB->setEnabled(!biblatex);
2508         biblioModule->bibtopicCB->setEnabled(!biblatex);
2509
2510         // These are only useful with Biblatex
2511         biblioModule->biblatexBbxCO->setEnabled(biblatex);
2512         biblioModule->biblatexBbxLA->setEnabled(biblatex);
2513         biblioModule->biblatexCbxCO->setEnabled(biblatex);
2514         biblioModule->biblatexCbxLA->setEnabled(biblatex);
2515         biblioModule->resetBbxPB->setEnabled(biblatex);
2516         biblioModule->resetCbxPB->setEnabled(biblatex);
2517         biblioModule->matchBbxPB->setEnabled(biblatex);
2518
2519         // These are useful with biblatex, jurabib and natbib
2520         QString const engine =
2521                 biblioModule->citeEngineCO->itemData(
2522                                 biblioModule->citeEngineCO->currentIndex()).toString();
2523         LyXCiteEngine const * ce = theCiteEnginesList[fromqstr(engine)];
2524
2525         bool const citepack = ce->requires("biblatex.sty") || ce->requires("jurabib.sty")
2526                         || ce->requires("natbib.sty");
2527         biblioModule->citePackageOptionsLE->setEnabled(citepack);
2528         biblioModule->citePackageOptionsL->setEnabled(citepack);
2529 }
2530
2531
2532 void GuiDocument::citeStyleChanged()
2533 {
2534         QString const engine =
2535                 biblioModule->citeEngineCO->itemData(
2536                                 biblioModule->citeEngineCO->currentIndex()).toString();
2537         QString const currentDef = isBiblatex() ?
2538                 biblioModule->biblatexBbxCO->currentText()
2539                 : biblioModule->defaultBiblioCO->currentText();
2540         if (theCiteEnginesList[fromqstr(engine)]->isDefaultBiblio(fromqstr(currentDef)))
2541                 resetDefaultBibfile();
2542
2543         biblioChanged();
2544 }
2545
2546
2547 void GuiDocument::bibtexChanged(int n)
2548 {
2549         biblioModule->bibtexOptionsLE->setEnabled(
2550                 biblioModule->bibtexCO->itemData(n).toString() != "default");
2551         biblioChanged();
2552 }
2553
2554
2555 void GuiDocument::updateCiteStyles(vector<string> const & engs, CiteEngineType const & sel)
2556 {
2557         biblioModule->citeStyleCO->clear();
2558
2559         vector<string>::const_iterator it  = engs.begin();
2560         vector<string>::const_iterator end = engs.end();
2561         for (; it != end; ++it) {
2562                 if (*it == "default")
2563                         biblioModule->citeStyleCO->addItem(qt_("Basic numerical"),
2564                                                            ENGINE_TYPE_DEFAULT);
2565                 else if (*it == "authoryear")
2566                         biblioModule->citeStyleCO->addItem(qt_("Author-year"),
2567                                                            ENGINE_TYPE_AUTHORYEAR);
2568                 else if (*it == "numerical")
2569                         biblioModule->citeStyleCO->addItem(qt_("Author-number"),
2570                                                            ENGINE_TYPE_NUMERICAL);
2571         }
2572         int i = biblioModule->citeStyleCO->findData(sel);
2573         if (biblioModule->citeStyleCO->findData(sel) == -1)
2574                 i = 0;
2575         biblioModule->citeStyleCO->setCurrentIndex(i);
2576
2577         biblioModule->citationStyleL->setEnabled(engs.size() > 1);
2578         biblioModule->citeStyleCO->setEnabled(engs.size() > 1);
2579 }
2580
2581
2582 void GuiDocument::updateEngineType(string const & items, CiteEngineType const & sel)
2583 {
2584         engine_types_.clear();
2585
2586         int nn = 0;
2587
2588         for (int n = 0; !token(items, '|', n).empty(); ++n) {
2589                 nn += 1;
2590                 string style = token(items, '|', n);
2591                 engine_types_.push_back(style);
2592         }
2593
2594         updateCiteStyles(engine_types_, sel);
2595 }
2596
2597
2598 namespace {
2599         // FIXME unicode
2600         // both of these should take a vector<docstring>
2601
2602         // This is an insanely complicated attempt to make this sort of thing
2603         // work with RTL languages.
2604         docstring formatStrVec(vector<string> const & v, docstring const & s)
2605         {
2606                 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
2607                 if (v.empty())
2608                         return docstring();
2609                 if (v.size() == 1)
2610                         return translateIfPossible(from_utf8(v[0]));
2611                 if (v.size() == 2) {
2612                         docstring retval = _("%1$s and %2$s");
2613                         retval = subst(retval, _("and"), s);
2614                         return bformat(retval, translateIfPossible(from_utf8(v[0])),
2615                                        translateIfPossible(from_utf8(v[1])));
2616                 }
2617                 // The idea here is to format all but the last two items...
2618                 int const vSize = v.size();
2619                 docstring t2 = _("%1$s, %2$s");
2620                 docstring retval = translateIfPossible(from_utf8(v[0]));
2621                 for (int i = 1; i < vSize - 2; ++i)
2622                         retval = bformat(t2, retval, translateIfPossible(from_utf8(v[i])));
2623                 //...and then to  plug them, and the last two, into this schema
2624                 docstring t = _("%1$s, %2$s, and %3$s");
2625                 t = subst(t, _("and"), s);
2626                 return bformat(t, retval, translateIfPossible(from_utf8(v[vSize - 2])),
2627                                translateIfPossible(from_utf8(v[vSize - 1])));
2628         }
2629
2630         vector<string> idsToNames(vector<string> const & idList)
2631         {
2632                 vector<string> retval;
2633                 vector<string>::const_iterator it  = idList.begin();
2634                 vector<string>::const_iterator end = idList.end();
2635                 for (; it != end; ++it) {
2636                         LyXModule const * const mod = theModuleList[*it];
2637                         if (!mod)
2638                                 retval.push_back(to_utf8(bformat(_("%1$s (unavailable)"),
2639                                                 translateIfPossible(from_utf8(*it)))));
2640                         else
2641                                 retval.push_back(mod->getName());
2642                 }
2643                 return retval;
2644         }
2645 } // end anonymous namespace
2646
2647
2648 void GuiDocument::modulesToParams(BufferParams & bp)
2649 {
2650         // update list of loaded modules
2651         bp.clearLayoutModules();
2652         int const srows = modules_sel_model_.rowCount();
2653         for (int i = 0; i < srows; ++i)
2654                 bp.addLayoutModule(modules_sel_model_.getIDString(i));
2655
2656         // update the list of removed modules
2657         bp.clearRemovedModules();
2658         LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
2659         list<string>::const_iterator rit = reqmods.begin();
2660         list<string>::const_iterator ren = reqmods.end();
2661
2662         // check each of the default modules
2663         for (; rit != ren; ++rit) {
2664                 list<string>::const_iterator mit = bp.getModules().begin();
2665                 list<string>::const_iterator men = bp.getModules().end();
2666                 bool found = false;
2667                 for (; mit != men; ++mit) {
2668                         if (*rit == *mit) {
2669                                 found = true;
2670                                 break;
2671                         }
2672                 }
2673                 if (!found) {
2674                         // the module isn't present so must have been removed by the user
2675                         bp.addRemovedModule(*rit);
2676                 }
2677         }
2678 }
2679
2680 void GuiDocument::modulesChanged()
2681 {
2682         modulesToParams(bp_);
2683
2684         if (applyPB->isEnabled() && (nonModuleChanged_ || shellescapeChanged_)) {
2685                 int const ret = Alert::prompt(_("Unapplied changes"),
2686                                 _("Some changes in the dialog were not yet applied.\n"
2687                                 "If you do not apply now, they will be lost after this action."),
2688                                 1, 1, _("&Apply"), _("&Dismiss"));
2689                 if (ret == 0)
2690                         applyView();
2691         }
2692
2693         modulesChanged_ = true;
2694         bp_.makeDocumentClass();
2695         paramsToDialog();
2696         changed();
2697 }
2698
2699
2700 void GuiDocument::updateModuleInfo()
2701 {
2702         selectionManager->update();
2703
2704         //Module description
2705         bool const focus_on_selected = selectionManager->selectedFocused();
2706         QAbstractItemView * lv;
2707         if (focus_on_selected)
2708                 lv = modulesModule->selectedLV;
2709         else
2710                 lv = modulesModule->availableLV;
2711         if (lv->selectionModel()->selectedIndexes().isEmpty()) {
2712                 modulesModule->infoML->document()->clear();
2713                 return;
2714         }
2715         QModelIndex const & idx = lv->selectionModel()->currentIndex();
2716         GuiIdListModel const & id_model =
2717                         focus_on_selected  ? modules_sel_model_ : modules_av_model_;
2718         string const modName = id_model.getIDString(idx.row());
2719         docstring desc = getModuleDescription(modName);
2720
2721         LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
2722         if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
2723                 if (!desc.empty())
2724                         desc += "\n";
2725                 desc += _("Module provided by document class.");
2726         }
2727
2728         docstring cat = getModuleCategory(modName);
2729         if (!cat.empty()) {
2730                 if (!desc.empty())
2731                         desc += "\n";
2732                 desc += bformat(_("Category: %1$s."), cat);
2733         }
2734
2735         vector<string> pkglist = getPackageList(modName);
2736         docstring pkgdesc = formatStrVec(pkglist, _("and"));
2737         if (!pkgdesc.empty()) {
2738                 if (!desc.empty())
2739                         desc += "\n";
2740                 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
2741         }
2742
2743         pkglist = getRequiredList(modName);
2744         if (!pkglist.empty()) {
2745                 vector<string> const reqdescs = idsToNames(pkglist);
2746                 pkgdesc = formatStrVec(reqdescs, _("or"));
2747                 if (!desc.empty())
2748                         desc += "\n";
2749                 desc += bformat(_("Modules required: %1$s."), pkgdesc);
2750         }
2751
2752         pkglist = getExcludedList(modName);
2753         if (!pkglist.empty()) {
2754                 vector<string> const reqdescs = idsToNames(pkglist);
2755                 pkgdesc = formatStrVec(reqdescs, _( "and"));
2756                 if (!desc.empty())
2757                         desc += "\n";
2758                 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
2759         }
2760
2761         if (!isModuleAvailable(modName)) {
2762                 if (!desc.empty())
2763                         desc += "\n";
2764                 desc += _("WARNING: Some required packages are unavailable!");
2765         }
2766
2767         modulesModule->infoML->document()->setPlainText(toqstr(desc));
2768 }
2769
2770
2771 void GuiDocument::updateNumbering()
2772 {
2773         DocumentClass const & tclass = documentClass();
2774
2775         numberingModule->tocTW->setUpdatesEnabled(false);
2776         numberingModule->tocTW->clear();
2777
2778         int const depth = numberingModule->depthSL->value();
2779         int const toc = numberingModule->tocSL->value();
2780         QString const no = qt_("No");
2781         QString const yes = qt_("Yes");
2782         QTreeWidgetItem * item = 0;
2783
2784         DocumentClass::const_iterator lit = tclass.begin();
2785         DocumentClass::const_iterator len = tclass.end();
2786         for (; lit != len; ++lit) {
2787                 int const toclevel = lit->toclevel;
2788                 if (toclevel != Layout::NOT_IN_TOC && !lit->counter.empty()) {
2789                         item = new QTreeWidgetItem(numberingModule->tocTW);
2790                         item->setText(0, toqstr(translateIfPossible(lit->name())));
2791                         item->setText(1, (toclevel <= depth) ? yes : no);
2792                         item->setText(2, (toclevel <= toc) ? yes : no);
2793                 }
2794         }
2795
2796         numberingModule->tocTW->setUpdatesEnabled(true);
2797         numberingModule->tocTW->update();
2798 }
2799
2800
2801 void GuiDocument::updateDefaultFormat()
2802 {
2803         if (!bufferview())
2804                 return;
2805         // make a copy in order to consider unapplied changes
2806         BufferParams param_copy = buffer().params();
2807         param_copy.useNonTeXFonts = fontModule->osFontsCB->isChecked();
2808         int const idx = latexModule->classCO->currentIndex();
2809         if (idx >= 0) {
2810                 string const classname = fromqstr(latexModule->classCO->getData(idx));
2811                 param_copy.setBaseClass(classname);
2812                 param_copy.makeDocumentClass(true);
2813         }
2814         outputModule->defaultFormatCO->blockSignals(true);
2815         outputModule->defaultFormatCO->clear();
2816         outputModule->defaultFormatCO->addItem(qt_("Default"),
2817                                 QVariant(QString("default")));
2818         FormatList const & formats =
2819                                 param_copy.exportableFormats(true);
2820         for (Format const * f : formats)
2821                 outputModule->defaultFormatCO->addItem
2822                         (toqstr(translateIfPossible(f->prettyname())),
2823                          QVariant(toqstr(f->name())));
2824         outputModule->defaultFormatCO->blockSignals(false);
2825 }
2826
2827
2828 bool GuiDocument::isChildIncluded(string const & child)
2829 {
2830         if (includeonlys_.empty())
2831                 return false;
2832         return (std::find(includeonlys_.begin(),
2833                           includeonlys_.end(), child) != includeonlys_.end());
2834 }
2835
2836
2837 void GuiDocument::applyView()
2838 {
2839         // preamble
2840         preambleModule->apply(bp_);
2841         localLayout->apply(bp_);
2842
2843         // date
2844         bp_.suppress_date = latexModule->suppressDateCB->isChecked();
2845         bp_.use_refstyle  = latexModule->refstyleCB->isChecked();
2846
2847         // biblio
2848         string const engine =
2849                 fromqstr(biblioModule->citeEngineCO->itemData(
2850                                 biblioModule->citeEngineCO->currentIndex()).toString());
2851         bp_.setCiteEngine(engine);
2852
2853         CiteEngineType const style = CiteEngineType(biblioModule->citeStyleCO->itemData(
2854                 biblioModule->citeStyleCO->currentIndex()).toInt());
2855         if (theCiteEnginesList[engine]->hasEngineType(style))
2856                 bp_.setCiteEngineType(style);
2857         else
2858                 bp_.setCiteEngineType(ENGINE_TYPE_DEFAULT);
2859
2860         bp_.splitbib(biblioModule->bibtopicCB->isChecked());
2861
2862         bp_.multibib = fromqstr(biblioModule->bibunitsCO->itemData(
2863                                 biblioModule->bibunitsCO->currentIndex()).toString());
2864
2865         bp_.setDefaultBiblioStyle(fromqstr(biblioModule->defaultBiblioCO->currentText()));
2866
2867         bp_.biblatex_bibstyle = fromqstr(biblioModule->biblatexBbxCO->currentText());
2868         bp_.biblatex_citestyle = fromqstr(biblioModule->biblatexCbxCO->currentText());
2869         bp_.biblio_opts = fromqstr(biblioModule->citePackageOptionsLE->text());
2870
2871         string const bibtex_command =
2872                 fromqstr(biblioModule->bibtexCO->itemData(
2873                         biblioModule->bibtexCO->currentIndex()).toString());
2874         string const bibtex_options =
2875                 fromqstr(biblioModule->bibtexOptionsLE->text());
2876         if (bibtex_command == "default" || bibtex_options.empty())
2877                 bp_.bibtex_command = bibtex_command;
2878         else
2879                 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
2880
2881         if (biblioChanged_) {
2882                 buffer().invalidateBibinfoCache();
2883                 buffer().removeBiblioTempFiles();
2884         }
2885
2886         // Indices
2887         indicesModule->apply(bp_);
2888
2889         // language & quotes
2890         if (langModule->defaultencodingRB->isChecked()) {
2891                 bp_.inputenc = "auto";
2892         } else {
2893                 int i = langModule->encodingCO->currentIndex();
2894                 if (i == 0)
2895                         bp_.inputenc = "default";
2896                 else {
2897                         QString const enc_gui =
2898                                 langModule->encodingCO->currentText();
2899                         Encodings::const_iterator it = encodings.begin();
2900                         Encodings::const_iterator const end = encodings.end();
2901                         bool found = false;
2902                         for (; it != end; ++it) {
2903                                 if (qt_(it->guiName()) == enc_gui &&
2904                                     !it->unsafe()) {
2905                                         bp_.inputenc = it->name();
2906                                         found = true;
2907                                         break;
2908                                 }
2909                         }
2910                         if (!found) {
2911                                 // should not happen
2912                                 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
2913                                 bp_.inputenc = "default";
2914                         }
2915                 }
2916         }
2917
2918         bp_.quotes_style = (InsetQuotesParams::QuoteStyle) langModule->quoteStyleCO->itemData(
2919                 langModule->quoteStyleCO->currentIndex()).toInt();
2920         bp_.dynamic_quotes = langModule->dynamicQuotesCB->isChecked();
2921
2922         QString const langname = langModule->languageCO->itemData(
2923                 langModule->languageCO->currentIndex()).toString();
2924         Language const * newlang = lyx::languages.getLanguage(fromqstr(langname));
2925         Cursor & cur = const_cast<BufferView *>(bufferview())->cursor();
2926         // If current cursor language was the document language, then update it too.
2927         if (cur.current_font.language() == bp_.language) {
2928                 cur.current_font.setLanguage(newlang);
2929                 cur.real_current_font.setLanguage(newlang);
2930         }
2931         bp_.language = newlang;
2932
2933         QString const pack = langModule->languagePackageCO->itemData(
2934                 langModule->languagePackageCO->currentIndex()).toString();
2935         if (pack == "custom")
2936                 bp_.lang_package =
2937                         fromqstr(langModule->languagePackageLE->text());
2938         else
2939                 bp_.lang_package = fromqstr(pack);
2940
2941         //color
2942         bp_.backgroundcolor = set_backgroundcolor;
2943         bp_.isbackgroundcolor = is_backgroundcolor;
2944         bp_.fontcolor = set_fontcolor;
2945         bp_.isfontcolor = is_fontcolor;
2946         bp_.notefontcolor = set_notefontcolor;
2947         bp_.boxbgcolor = set_boxbgcolor;
2948
2949         // numbering
2950         if (bp_.documentClass().hasTocLevels()) {
2951                 bp_.tocdepth = numberingModule->tocSL->value();
2952                 bp_.secnumdepth = numberingModule->depthSL->value();
2953         }
2954
2955         // bullets
2956         bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
2957         bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
2958         bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
2959         bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
2960
2961         // packages
2962         bp_.graphics_driver =
2963                 tex_graphics[latexModule->psdriverCO->currentIndex()];
2964
2965         // text layout
2966         int idx = latexModule->classCO->currentIndex();
2967         if (idx >= 0) {
2968                 string const classname = fromqstr(latexModule->classCO->getData(idx));
2969                 bp_.setBaseClass(classname);
2970         }
2971
2972         // Modules
2973         modulesToParams(bp_);
2974
2975         // Math
2976         map<string, string> const & packages = BufferParams::auto_packages();
2977         for (map<string, string>::const_iterator it = packages.begin();
2978              it != packages.end(); ++it) {
2979                 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
2980                 if (!item)
2981                         continue;
2982                 int row = mathsModule->packagesTW->row(item);
2983                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1);
2984                 if (rb->isChecked()) {
2985                         bp_.use_package(it->first, BufferParams::package_auto);
2986                         continue;
2987                 }
2988                 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2);
2989                 if (rb->isChecked()) {
2990                         bp_.use_package(it->first, BufferParams::package_on);
2991                         continue;
2992                 }
2993                 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3);
2994                 if (rb->isChecked())
2995                         bp_.use_package(it->first, BufferParams::package_off);
2996         }
2997         // if math is indented
2998         bp_.is_math_indent = mathsModule->MathIndentCB->isChecked();
2999         if (bp_.is_math_indent) {
3000                 // if formulas are indented
3001                 switch (mathsModule->MathIndentCO->currentIndex()) {
3002                 case 0:
3003                         bp_.setMathIndent(Length());
3004                         break;
3005                 case 1: {
3006                         Length mathindent(widgetsToLength(mathsModule->MathIndentLE,
3007                                                           mathsModule->MathIndentLengthCO));
3008                         bp_.setMathIndent(mathindent);
3009                         break;
3010                 }
3011                 default:
3012                         // this should never happen
3013                         bp_.setMathIndent(Length());
3014                         break;
3015                 }
3016         }
3017         switch (mathsModule->MathNumberingPosCO->currentIndex()) {
3018                 case 0:
3019                         bp_.math_numbering_side = BufferParams::LEFT;
3020                         break;
3021                 case 1:
3022                         bp_.math_numbering_side = BufferParams::DEFAULT;
3023                         break;
3024                 case 2:
3025                         bp_.math_numbering_side = BufferParams::RIGHT;
3026                         break;
3027                 default:
3028                         // this should never happen
3029                         bp_.math_numbering_side = BufferParams::DEFAULT;
3030                         break;
3031         }
3032
3033         // Page Layout
3034         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
3035                 bp_.pagestyle = "default";
3036         else {
3037                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
3038                 for (size_t i = 0; i != pagestyles.size(); ++i)
3039                         if (pagestyles[i].second == style_gui)
3040                                 bp_.pagestyle = pagestyles[i].first;
3041         }
3042
3043         // Text Layout
3044         switch (textLayoutModule->lspacingCO->currentIndex()) {
3045         case 0:
3046                 bp_.spacing().set(Spacing::Single);
3047                 break;
3048         case 1:
3049                 bp_.spacing().set(Spacing::Onehalf);
3050                 break;
3051         case 2:
3052                 bp_.spacing().set(Spacing::Double);
3053                 break;
3054         case 3: {
3055                 string s = widgetToDoubleStr(textLayoutModule->lspacingLE);
3056                 if (s.empty())
3057                         bp_.spacing().set(Spacing::Single);
3058                 else
3059                         bp_.spacing().set(Spacing::Other, s);
3060                 break;
3061                 }
3062         }
3063
3064         if (textLayoutModule->twoColumnCB->isChecked())
3065                 bp_.columns = 2;
3066         else
3067                 bp_.columns = 1;
3068
3069         bp_.justification = textLayoutModule->justCB->isChecked();
3070
3071         if (textLayoutModule->indentRB->isChecked()) {
3072                 // if paragraphs are separated by an indentation
3073                 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
3074                 switch (textLayoutModule->indentCO->currentIndex()) {
3075                 case 0:
3076                         bp_.setParIndent(Length());
3077                         break;
3078                 case 1: {
3079                         Length parindent(widgetsToLength(textLayoutModule->indentLE,
3080                                                          textLayoutModule->indentLengthCO));
3081                         bp_.setParIndent(parindent);
3082                         break;
3083                 }
3084                 default:
3085                         // this should never happen
3086                         bp_.setParIndent(Length());
3087                         break;
3088                 }
3089         } else {
3090                 // if paragraphs are separated by a skip
3091                 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
3092                 switch (textLayoutModule->skipCO->currentIndex()) {
3093                 case 0:
3094                         bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
3095                         break;
3096                 case 1:
3097                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
3098                         break;
3099                 case 2:
3100                         bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
3101                         break;
3102                 case 3:
3103                         {
3104                         VSpace vs = VSpace(
3105                                 widgetsToLength(textLayoutModule->skipLE,
3106                                 textLayoutModule->skipLengthCO)
3107                                 );
3108                         bp_.setDefSkip(vs);
3109                         break;
3110                         }
3111                 default:
3112                         // this should never happen
3113                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
3114                         break;
3115                 }
3116         }
3117
3118         bp_.options =
3119                 fromqstr(latexModule->optionsLE->text());
3120
3121         bp_.use_default_options =
3122                 latexModule->defaultOptionsCB->isChecked();
3123
3124         if (latexModule->childDocGB->isChecked())
3125                 bp_.master =
3126                         fromqstr(latexModule->childDocLE->text());
3127         else
3128                 bp_.master = string();
3129
3130         // Master/Child
3131         bp_.clearIncludedChildren();
3132         if (masterChildModule->includeonlyRB->isChecked()) {
3133                 list<string>::const_iterator it = includeonlys_.begin();
3134                 for (; it != includeonlys_.end() ; ++it) {
3135                         bp_.addIncludedChildren(*it);
3136                 }
3137         }
3138         bp_.maintain_unincluded_children =
3139                 masterChildModule->maintainAuxCB->isChecked();
3140
3141         // Float Placement
3142         bp_.float_placement = floatModule->get();
3143
3144         // Listings
3145         // text should have passed validation
3146         idx = listingsModule->packageCO->currentIndex();
3147         bp_.use_minted = string(lst_packages[idx]) == "Minted";
3148         bp_.listings_params =
3149                 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
3150
3151         // Formats
3152         bp_.default_output_format = fromqstr(outputModule->defaultFormatCO->itemData(
3153                 outputModule->defaultFormatCO->currentIndex()).toString());
3154
3155         bool const nontexfonts = fontModule->osFontsCB->isChecked();
3156         bp_.useNonTeXFonts = nontexfonts;
3157
3158         bp_.shell_escape = outputModule->shellescapeCB->isChecked();
3159         if (!bp_.shell_escape)
3160             theSession().shellescapeFiles().remove(buffer().absFileName());
3161         else if (!theSession().shellescapeFiles().find(buffer().absFileName()))
3162             theSession().shellescapeFiles().insert(buffer().absFileName());
3163         Buffer & buf = const_cast<Buffer &>(buffer());
3164         buf.params().shell_escape = bp_.shell_escape;
3165
3166         bp_.output_sync = outputModule->outputsyncCB->isChecked();
3167
3168         bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
3169
3170         int mathfmt = outputModule->mathoutCB->currentIndex();
3171         if (mathfmt == -1)
3172                 mathfmt = 0;
3173         BufferParams::MathOutput const mo =
3174                 static_cast<BufferParams::MathOutput>(mathfmt);
3175         bp_.html_math_output = mo;
3176         bp_.html_be_strict = outputModule->strictCB->isChecked();
3177         bp_.html_css_as_file = outputModule->cssCB->isChecked();
3178         bp_.html_math_img_scale = outputModule->mathimgSB->value();
3179         bp_.display_pixel_ratio = theGuiApp()->pixelRatio();
3180
3181         bp_.save_transient_properties =
3182                 outputModule->saveTransientPropertiesCB->isChecked();
3183
3184         // fonts
3185         bp_.fonts_roman[nontexfonts] =
3186                 fromqstr(fontModule->fontsRomanCO->
3187                         itemData(fontModule->fontsRomanCO->currentIndex()).toString());
3188         bp_.fonts_roman[!nontexfonts] = fromqstr(fontModule->font_roman);
3189
3190         bp_.fonts_sans[nontexfonts] =
3191                 fromqstr(fontModule->fontsSansCO->
3192                         itemData(fontModule->fontsSansCO->currentIndex()).toString());
3193         bp_.fonts_sans[!nontexfonts] = fromqstr(fontModule->font_sans);
3194
3195         bp_.fonts_typewriter[nontexfonts] =
3196                 fromqstr(fontModule->fontsTypewriterCO->
3197                         itemData(fontModule->fontsTypewriterCO->currentIndex()).toString());
3198         bp_.fonts_typewriter[!nontexfonts] = fromqstr(fontModule->font_typewriter);
3199
3200         bp_.fonts_math[nontexfonts] =
3201                 fromqstr(fontModule->fontsMathCO->
3202                         itemData(fontModule->fontsMathCO->currentIndex()).toString());
3203         bp_.fonts_math[!nontexfonts] = fromqstr(fontModule->font_math);
3204
3205         QString const fontenc =
3206                 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
3207         if (fontenc == "custom")
3208                 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
3209         else
3210                 bp_.fontenc = fromqstr(fontenc);
3211
3212         bp_.fonts_cjk =
3213                 fromqstr(fontModule->cjkFontLE->text());
3214
3215         bp_.use_microtype = fontModule->microtypeCB->isChecked();
3216         bp_.use_dash_ligatures = fontModule->dashesCB->isChecked();
3217
3218         bp_.fonts_sans_scale[nontexfonts] = fontModule->scaleSansSB->value();
3219         bp_.fonts_sans_scale[!nontexfonts] = fontModule->font_sf_scale;
3220
3221         bp_.fonts_typewriter_scale[nontexfonts] = fontModule->scaleTypewriterSB->value();
3222         bp_.fonts_typewriter_scale[!nontexfonts] = fontModule->font_tt_scale;
3223
3224         bp_.fonts_expert_sc = fontModule->fontScCB->isChecked();
3225
3226         bp_.fonts_old_figures = fontModule->fontOsfCB->isChecked();
3227
3228         if (nontexfonts)
3229                 bp_.fonts_default_family = "default";
3230         else
3231                 bp_.fonts_default_family = GuiDocument::fontfamilies[
3232                         fontModule->fontsDefaultCO->currentIndex()];
3233
3234         if (fontModule->fontsizeCO->currentIndex() == 0)
3235                 bp_.fontsize = "default";
3236         else
3237                 bp_.fontsize =
3238                         fromqstr(fontModule->fontsizeCO->currentText());
3239
3240         // paper
3241         bp_.papersize = PAPER_SIZE(
3242                 pageLayoutModule->papersizeCO->currentIndex());
3243
3244         bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
3245                 pageLayoutModule->paperwidthUnitCO);
3246
3247         bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
3248                 pageLayoutModule->paperheightUnitCO);
3249
3250         if (pageLayoutModule->facingPagesCB->isChecked())
3251                 bp_.sides = TwoSides;
3252         else
3253                 bp_.sides = OneSide;
3254
3255         if (pageLayoutModule->landscapeRB->isChecked())
3256                 bp_.orientation = ORIENTATION_LANDSCAPE;
3257         else
3258                 bp_.orientation = ORIENTATION_PORTRAIT;
3259
3260         // margins
3261         bp_.use_geometry = !marginsModule->marginCB->isChecked();
3262
3263         Ui::MarginsUi const * m = marginsModule;
3264
3265         bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
3266         bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
3267         bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
3268         bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
3269         bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
3270         bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
3271         bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
3272         bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
3273
3274         // branches
3275         branchesModule->apply(bp_);
3276
3277         // PDF support
3278         PDFOptions & pdf = bp_.pdfoptions();
3279         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
3280         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
3281         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
3282         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
3283         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
3284
3285         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
3286         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
3287         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
3288         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
3289
3290         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
3291         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
3292         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
3293         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
3294         pdf.backref =
3295                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
3296         if (pdfSupportModule->fullscreenCB->isChecked())
3297                 pdf.pagemode = pdf.pagemode_fullscreen;
3298         else
3299                 pdf.pagemode.clear();
3300         pdf.quoted_options = pdf.quoted_options_check(
3301                                 fromqstr(pdfSupportModule->optionsLE->text()));
3302
3303         // reset trackers
3304         nonModuleChanged_ = false;
3305         shellescapeChanged_ = false;
3306 }
3307
3308
3309 void GuiDocument::paramsToDialog()
3310 {
3311         // set the default unit
3312         Length::UNIT const default_unit = Length::defaultUnit();
3313
3314         // preamble
3315         preambleModule->update(bp_, id());
3316         localLayout->update(bp_, id());
3317
3318         // date
3319         latexModule->suppressDateCB->setChecked(bp_.suppress_date);
3320         latexModule->refstyleCB->setChecked(bp_.use_refstyle);
3321
3322         // biblio
3323         string const cite_engine = bp_.citeEngine().list().front();
3324
3325         biblioModule->citeEngineCO->setCurrentIndex(
3326                 biblioModule->citeEngineCO->findData(toqstr(cite_engine)));
3327
3328         updateEngineType(documentClass().opt_enginetype(),
3329                 bp_.citeEngineType());
3330
3331         biblioModule->citeStyleCO->setCurrentIndex(
3332                 biblioModule->citeStyleCO->findData(bp_.citeEngineType()));
3333
3334         biblioModule->bibtopicCB->setChecked(bp_.splitbib());
3335
3336         biblioModule->bibunitsCO->clear();
3337         biblioModule->bibunitsCO->addItem(qt_("No"), QString());
3338         if (documentClass().hasLaTeXLayout("part"))
3339                 biblioModule->bibunitsCO->addItem(qt_("per part"), toqstr("part"));
3340         if (documentClass().hasLaTeXLayout("chapter"))
3341                 biblioModule->bibunitsCO->addItem(qt_("per chapter"), toqstr("chapter"));
3342         if (documentClass().hasLaTeXLayout("section"))
3343                 biblioModule->bibunitsCO->addItem(qt_("per section"), toqstr("section"));
3344         if (documentClass().hasLaTeXLayout("subsection"))
3345                 biblioModule->bibunitsCO->addItem(qt_("per subsection"), toqstr("subsection"));
3346         biblioModule->bibunitsCO->addItem(qt_("per child document"), toqstr("child"));
3347
3348         int const mbpos = biblioModule->bibunitsCO->findData(toqstr(bp_.multibib));
3349         if (mbpos != -1)
3350                 biblioModule->bibunitsCO->setCurrentIndex(mbpos);
3351         else
3352                 biblioModule->bibunitsCO->setCurrentIndex(0);
3353
3354         updateEngineDependends();
3355
3356         if (isBiblatex()) {
3357                 updateDefaultBiblio(bp_.biblatex_bibstyle, "bbx");
3358                 updateDefaultBiblio(bp_.biblatex_citestyle, "cbx");
3359         } else
3360                 updateDefaultBiblio(bp_.defaultBiblioStyle());
3361
3362         biblioModule->citePackageOptionsLE->setText(toqstr(bp_.biblio_opts));
3363
3364         string command;
3365         string options =
3366                 split(bp_.bibtex_command, command, ' ');
3367
3368         int const bpos = biblioModule->bibtexCO->findData(toqstr(command));
3369         if (bpos != -1) {
3370                 biblioModule->bibtexCO->setCurrentIndex(bpos);
3371                 biblioModule->bibtexOptionsLE->setText(toqstr(options).trimmed());
3372         } else {
3373                 // We reset to default if we do not know the specified compiler
3374                 // This is for security reasons
3375                 biblioModule->bibtexCO->setCurrentIndex(
3376                         biblioModule->bibtexCO->findData(toqstr("default")));
3377                 biblioModule->bibtexOptionsLE->clear();
3378         }
3379         biblioModule->bibtexOptionsLE->setEnabled(
3380                 biblioModule->bibtexCO->currentIndex() != 0);
3381
3382         biblioChanged_ = false;
3383
3384         // indices
3385         // We may be called when there is no Buffer, e.g., when
3386         // the last view has just been closed.
3387         bool const isReadOnly = isBufferAvailable() ? buffer().isReadonly() : false;
3388         indicesModule->update(bp_, isReadOnly);
3389
3390         // language & quotes
3391         int const pos = langModule->languageCO->findData(toqstr(
3392                 bp_.language->lang()));
3393         langModule->languageCO->setCurrentIndex(pos);
3394
3395         updateQuoteStyles();
3396
3397         langModule->quoteStyleCO->setCurrentIndex(
3398                 langModule->quoteStyleCO->findData(bp_.quotes_style));
3399         langModule->dynamicQuotesCB->setChecked(bp_.dynamic_quotes);
3400
3401         bool default_enc = true;
3402         if (bp_.inputenc != "auto") {
3403                 default_enc = false;
3404                 if (bp_.inputenc == "default") {
3405                         langModule->encodingCO->setCurrentIndex(0);
3406                 } else {
3407                         string enc_gui;
3408                         Encodings::const_iterator it = encodings.begin();
3409                         Encodings::const_iterator const end = encodings.end();
3410                         for (; it != end; ++it) {
3411                                 if (it->name() == bp_.inputenc &&
3412                                     !it->unsafe()) {
3413                                         enc_gui = it->guiName();
3414                                         break;
3415                                 }
3416                         }
3417                         int const i = langModule->encodingCO->findText(
3418                                         qt_(enc_gui));
3419                         if (i >= 0)
3420                                 langModule->encodingCO->setCurrentIndex(i);
3421                         else
3422                                 // unknown encoding. Set to default.
3423                                 default_enc = true;
3424                 }
3425         }
3426         langModule->defaultencodingRB->setChecked(default_enc);
3427         langModule->otherencodingRB->setChecked(!default_enc);
3428
3429         int const p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
3430         if (p == -1) {
3431                 langModule->languagePackageCO->setCurrentIndex(
3432                           langModule->languagePackageCO->findData("custom"));
3433                 langModule->languagePackageLE->setText(toqstr(bp_.lang_package));
3434         } else {
3435                 langModule->languagePackageCO->setCurrentIndex(p);
3436                 langModule->languagePackageLE->clear();
3437         }
3438
3439         //color
3440         if (bp_.isfontcolor) {
3441                 colorModule->fontColorPB->setStyleSheet(
3442                         colorButtonStyleSheet(rgb2qcolor(bp_.fontcolor)));
3443         }
3444         set_fontcolor = bp_.fontcolor;
3445         is_fontcolor = bp_.isfontcolor;
3446
3447         colorModule->noteFontColorPB->setStyleSheet(
3448                 colorButtonStyleSheet(rgb2qcolor(bp_.notefontcolor)));
3449         set_notefontcolor = bp_.notefontcolor;
3450
3451         if (bp_.isbackgroundcolor) {
3452                 colorModule->backgroundPB->setStyleSheet(
3453                         colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
3454         }
3455         set_backgroundcolor = bp_.backgroundcolor;
3456         is_backgroundcolor = bp_.isbackgroundcolor;
3457
3458         colorModule->boxBackgroundPB->setStyleSheet(
3459                 colorButtonStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
3460         set_boxbgcolor = bp_.boxbgcolor;
3461
3462         // numbering
3463         int const min_toclevel = documentClass().min_toclevel();
3464         int const max_toclevel = documentClass().max_toclevel();
3465         if (documentClass().hasTocLevels()) {
3466                 numberingModule->setEnabled(true);
3467                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
3468                 numberingModule->depthSL->setMaximum(max_toclevel);
3469                 numberingModule->depthSL->setValue(bp_.secnumdepth);
3470                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
3471                 numberingModule->tocSL->setMaximum(max_toclevel);
3472                 numberingModule->tocSL->setValue(bp_.tocdepth);
3473                 updateNumbering();
3474         } else {
3475                 numberingModule->setEnabled(false);
3476                 numberingModule->tocTW->clear();
3477         }
3478
3479         // bullets
3480         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
3481         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
3482         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
3483         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
3484         bulletsModule->init();
3485
3486         // packages
3487         int nitem = findToken(tex_graphics, bp_.graphics_driver);
3488         if (nitem >= 0)
3489                 latexModule->psdriverCO->setCurrentIndex(nitem);
3490         updateModuleInfo();
3491
3492         // math
3493         mathsModule->MathIndentCB->setChecked(bp_.is_math_indent);
3494         if (bp_.is_math_indent) {
3495                 Length const mathindent = bp_.getMathIndent();
3496                 int indent = 0;
3497                 if (!mathindent.empty()) {
3498                         lengthToWidgets(mathsModule->MathIndentLE,
3499                                         mathsModule->MathIndentLengthCO,
3500                                         mathindent, default_unit);
3501                         indent = 1;
3502                 }
3503                 mathsModule->MathIndentCO->setCurrentIndex(indent);
3504                 enableMathIndent(indent);
3505         }
3506         switch(bp_.math_numbering_side) {
3507         case BufferParams::LEFT:
3508                 mathsModule->MathNumberingPosCO->setCurrentIndex(0);
3509                 break;
3510         case BufferParams::DEFAULT:
3511                 mathsModule->MathNumberingPosCO->setCurrentIndex(1);
3512                 break;
3513         case BufferParams::RIGHT:
3514                 mathsModule->MathNumberingPosCO->setCurrentIndex(2);
3515         }
3516
3517         map<string, string> const & packages = BufferParams::auto_packages();
3518         for (map<string, string>::const_iterator it = packages.begin();
3519              it != packages.end(); ++it) {
3520                 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
3521                 if (!item)
3522                         continue;
3523                 int row = mathsModule->packagesTW->row(item);
3524                 switch (bp_.use_package(it->first)) {
3525                         case BufferParams::package_off: {
3526                                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3);
3527                                 rb->setChecked(true);
3528                                 break;
3529                         }
3530                         case BufferParams::package_on: {
3531                                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2);
3532                                 rb->setChecked(true);
3533                                 break;
3534                         }
3535                         case BufferParams::package_auto: {
3536                                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1);
3537                                 rb->setChecked(true);
3538                                 break;
3539                         }
3540                 }
3541         }
3542
3543         switch (bp_.spacing().getSpace()) {
3544                 case Spacing::Other: nitem = 3; break;
3545                 case Spacing::Double: nitem = 2; break;
3546                 case Spacing::Onehalf: nitem = 1; break;
3547                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
3548         }
3549
3550         // text layout
3551         string const & layoutID = bp_.baseClassID();
3552         setLayoutComboByIDString(layoutID);
3553
3554         updatePagestyle(documentClass().opt_pagestyle(),
3555                                  bp_.pagestyle);
3556
3557         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
3558         if (bp_.spacing().getSpace() == Spacing::Other) {
3559                 doubleToWidget(textLayoutModule->lspacingLE,
3560                         bp_.spacing().getValueAsString());
3561         }
3562         setLSpacing(nitem);
3563
3564         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
3565                 textLayoutModule->indentRB->setChecked(true);
3566                 string parindent = bp_.getParIndent().asString();
3567                 int indent = 0;
3568                 if (!parindent.empty()) {
3569                         lengthToWidgets(textLayoutModule->indentLE,
3570                                         textLayoutModule->indentLengthCO,
3571                                         parindent, default_unit);
3572                         indent = 1;
3573                 }
3574                 textLayoutModule->indentCO->setCurrentIndex(indent);
3575                 setIndent(indent);
3576         } else {
3577                 textLayoutModule->skipRB->setChecked(true);
3578                 int skip = 0;
3579                 switch (bp_.getDefSkip().kind()) {
3580                 case VSpace::SMALLSKIP:
3581                         skip = 0;
3582                         break;
3583                 case VSpace::MEDSKIP:
3584                         skip = 1;
3585                         break;
3586                 case VSpace::BIGSKIP:
3587                         skip = 2;
3588                         break;
3589                 case VSpace::LENGTH:
3590                         {
3591                         skip = 3;
3592                         string const length = bp_.getDefSkip().asLyXCommand();
3593                         lengthToWidgets(textLayoutModule->skipLE,
3594                                 textLayoutModule->skipLengthCO,
3595                                 length, default_unit);
3596                         break;
3597                         }
3598                 default:
3599                         skip = 0;
3600                         break;
3601                 }
3602                 textLayoutModule->skipCO->setCurrentIndex(skip);
3603                 setSkip(skip);
3604         }
3605
3606         textLayoutModule->twoColumnCB->setChecked(
3607                 bp_.columns == 2);
3608         textLayoutModule->justCB->setChecked(bp_.justification);
3609
3610         if (!bp_.options.empty()) {
3611                 latexModule->optionsLE->setText(
3612                         toqstr(bp_.options));
3613         } else {
3614                 latexModule->optionsLE->setText(QString());
3615         }
3616
3617         // latex
3618         latexModule->defaultOptionsCB->setChecked(
3619                         bp_.use_default_options);
3620         updateSelectedModules();
3621         selectionManager->updateProvidedModules(
3622                         bp_.baseClass()->providedModules());
3623         selectionManager->updateExcludedModules(
3624                         bp_.baseClass()->excludedModules());
3625
3626         if (!documentClass().options().empty()) {
3627                 latexModule->defaultOptionsLE->setText(
3628                         toqstr(documentClass().options()));
3629         } else {
3630                 latexModule->defaultOptionsLE->setText(
3631                         toqstr(_("[No options predefined]")));
3632         }
3633
3634         latexModule->defaultOptionsLE->setEnabled(
3635                 bp_.use_default_options
3636                 && !documentClass().options().empty());
3637
3638         latexModule->defaultOptionsCB->setEnabled(
3639                 !documentClass().options().empty());
3640
3641         if (!bp_.master.empty()) {
3642                 latexModule->childDocGB->setChecked(true);
3643                 latexModule->childDocLE->setText(
3644                         toqstr(bp_.master));
3645         } else {
3646                 latexModule->childDocLE->setText(QString());
3647                 latexModule->childDocGB->setChecked(false);
3648         }
3649
3650         // Master/Child
3651         if (!bufferview() || !buffer().hasChildren()) {
3652                 masterChildModule->childrenTW->clear();
3653                 includeonlys_.clear();
3654                 docPS->showPanel("Child Documents", false);
3655                 if (docPS->isCurrentPanel("Child Documents"))
3656                         docPS->setCurrentPanel("Document Class");
3657         } else {
3658                 docPS->showPanel("Child Documents", true);
3659                 masterChildModule->setEnabled(true);
3660                 includeonlys_ = bp_.getIncludedChildren();
3661                 updateIncludeonlys();
3662         }
3663         masterChildModule->maintainAuxCB->setChecked(
3664                 bp_.maintain_unincluded_children);
3665
3666         // Float Settings
3667         floatModule->set(bp_.float_placement);
3668
3669         // ListingsSettings
3670         // break listings_params to multiple lines
3671         string lstparams =
3672                 InsetListingsParams(bp_.listings_params).separatedParams();
3673         listingsModule->listingsED->setPlainText(toqstr(lstparams));
3674         int nn = findToken(lst_packages, bp_.use_minted ? "Minted" : "Listings");
3675         if (nn >= 0)
3676                 listingsModule->packageCO->setCurrentIndex(nn);
3677
3678
3679         // Fonts
3680         // some languages only work with polyglossia/XeTeX
3681         Language const * lang = lyx::languages.getLanguage(
3682                 fromqstr(langModule->languageCO->itemData(
3683                         langModule->languageCO->currentIndex()).toString()));
3684         bool const need_fontspec =
3685                 lang->babel().empty() && !lang->polyglossia().empty();
3686         bool const os_fonts_available =
3687                 bp_.baseClass()->outputType() == lyx::LATEX
3688                 && LaTeXFeatures::isAvailable("fontspec");
3689         fontModule->osFontsCB->setEnabled(os_fonts_available && !need_fontspec);
3690         fontModule->osFontsCB->setChecked(
3691                 (os_fonts_available && bp_.useNonTeXFonts) || need_fontspec);
3692         updateFontsize(documentClass().opt_fontsize(),
3693                         bp_.fontsize);
3694
3695         QString font = toqstr(bp_.fontsRoman());
3696         int rpos = fontModule->fontsRomanCO->findData(font);
3697         if (rpos == -1) {
3698                 rpos = fontModule->fontsRomanCO->count();
3699                 fontModule->fontsRomanCO->addItem(font + qt_(" (not installed)"), font);
3700         }
3701         fontModule->fontsRomanCO->setCurrentIndex(rpos);
3702         fontModule->font_roman = toqstr(bp_.fonts_roman[!bp_.useNonTeXFonts]);
3703
3704         font = toqstr(bp_.fontsSans());
3705         int spos = fontModule->fontsSansCO->findData(font);
3706         if (spos == -1) {
3707                 spos = fontModule->fontsSansCO->count();
3708                 fontModule->fontsSansCO->addItem(font + qt_(" (not installed)"), font);
3709         }
3710         fontModule->fontsSansCO->setCurrentIndex(spos);
3711         fontModule->font_sans = toqstr(bp_.fonts_sans[!bp_.useNonTeXFonts]);
3712
3713         font = toqstr(bp_.fontsTypewriter());
3714         int tpos = fontModule->fontsTypewriterCO->findData(font);
3715         if (tpos == -1) {
3716                 tpos = fontModule->fontsTypewriterCO->count();
3717                 fontModule->fontsTypewriterCO->addItem(font + qt_(" (not installed)"), font);
3718         }
3719         fontModule->fontsTypewriterCO->setCurrentIndex(tpos);
3720         fontModule->font_typewriter = toqstr(bp_.fonts_typewriter[!bp_.useNonTeXFonts]);
3721
3722         font = toqstr(bp_.fontsMath());
3723         int mpos = fontModule->fontsMathCO->findData(font);
3724         if (mpos == -1) {
3725                 mpos = fontModule->fontsMathCO->count();
3726                 fontModule->fontsMathCO->addItem(font + qt_(" (not installed)"), font);
3727         }
3728         fontModule->fontsMathCO->setCurrentIndex(mpos);
3729         fontModule->font_math = toqstr(bp_.fonts_math[!bp_.useNonTeXFonts]);
3730
3731         if (bp_.useNonTeXFonts && os_fonts_available) {
3732                 fontModule->fontencLA->setEnabled(false);
3733                 fontModule->fontencCO->setEnabled(false);
3734                 fontModule->fontencLE->setEnabled(false);
3735         } else {
3736                 fontModule->fontencLA->setEnabled(true);
3737                 fontModule->fontencCO->setEnabled(true);
3738                 fontModule->fontencLE->setEnabled(true);
3739                 romanChanged(rpos);
3740                 sansChanged(spos);
3741                 ttChanged(tpos);
3742         }
3743
3744         if (!bp_.fonts_cjk.empty())
3745                 fontModule->cjkFontLE->setText(
3746                         toqstr(bp_.fonts_cjk));
3747         else
3748                 fontModule->cjkFontLE->setText(QString());
3749
3750         fontModule->microtypeCB->setChecked(bp_.use_microtype);
3751         fontModule->dashesCB->setChecked(bp_.use_dash_ligatures);
3752
3753         fontModule->fontScCB->setChecked(bp_.fonts_expert_sc);
3754         fontModule->fontOsfCB->setChecked(bp_.fonts_old_figures);
3755         fontModule->scaleSansSB->setValue(bp_.fontsSansScale());
3756         fontModule->font_sf_scale = bp_.fonts_sans_scale[!bp_.useNonTeXFonts];
3757         fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale());
3758         fontModule->font_tt_scale = bp_.fonts_typewriter_scale[!bp_.useNonTeXFonts];
3759
3760         nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
3761         if (nn >= 0)
3762                 fontModule->fontsDefaultCO->setCurrentIndex(nn);
3763
3764         if (bp_.fontenc == "global" || bp_.fontenc == "default") {
3765                 fontModule->fontencCO->setCurrentIndex(
3766                         fontModule->fontencCO->findData(toqstr(bp_.fontenc)));
3767                 fontModule->fontencLE->setEnabled(false);
3768         } else {
3769                 fontModule->fontencCO->setCurrentIndex(1);
3770                 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
3771         }
3772
3773         // Formats
3774         // This must be set _after_ fonts since updateDefaultFormat()
3775         // checks osFontsCB settings.
3776         // update combobox with formats
3777         updateDefaultFormat();
3778         int index = outputModule->defaultFormatCO->findData(toqstr(
3779                 bp_.default_output_format));
3780         // set to default if format is not found
3781         if (index == -1)
3782                 index = 0;
3783         outputModule->defaultFormatCO->setCurrentIndex(index);
3784
3785         outputModule->shellescapeCB->setChecked(bp_.shell_escape);
3786         outputModule->outputsyncCB->setChecked(bp_.output_sync);
3787         outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
3788
3789         outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
3790         outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
3791         outputModule->strictCB->setChecked(bp_.html_be_strict);
3792         outputModule->cssCB->setChecked(bp_.html_css_as_file);
3793
3794         outputModule->saveTransientPropertiesCB
3795                 ->setChecked(bp_.save_transient_properties);
3796
3797         // paper
3798         bool const extern_geometry =
3799                 documentClass().provides("geometry");
3800         int const psize = bp_.papersize;
3801         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
3802         setCustomPapersize(!extern_geometry && psize == 1);
3803         pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
3804
3805         bool const landscape =
3806                 bp_.orientation == ORIENTATION_LANDSCAPE;
3807         pageLayoutModule->landscapeRB->setChecked(landscape);
3808         pageLayoutModule->portraitRB->setChecked(!landscape);
3809         pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
3810         pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
3811
3812         pageLayoutModule->facingPagesCB->setChecked(
3813                 bp_.sides == TwoSides);
3814
3815         lengthToWidgets(pageLayoutModule->paperwidthLE,
3816                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, default_unit);
3817         lengthToWidgets(pageLayoutModule->paperheightLE,
3818                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, default_unit);
3819
3820         // margins
3821         Ui::MarginsUi * m = marginsModule;
3822
3823         setMargins();
3824
3825         lengthToWidgets(m->topLE, m->topUnit,
3826                 bp_.topmargin, default_unit);
3827
3828         lengthToWidgets(m->bottomLE, m->bottomUnit,
3829                 bp_.bottommargin, default_unit);
3830
3831         lengthToWidgets(m->innerLE, m->innerUnit,
3832                 bp_.leftmargin, default_unit);
3833
3834         lengthToWidgets(m->outerLE, m->outerUnit,
3835                 bp_.rightmargin, default_unit);
3836
3837         lengthToWidgets(m->headheightLE, m->headheightUnit,
3838                 bp_.headheight, default_unit);
3839
3840         lengthToWidgets(m->headsepLE, m->headsepUnit,
3841                 bp_.headsep, default_unit);
3842
3843         lengthToWidgets(m->footskipLE, m->footskipUnit,
3844                 bp_.footskip, default_unit);
3845
3846         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
3847                 bp_.columnsep, default_unit);
3848
3849         // branches
3850         updateUnknownBranches();
3851         branchesModule->update(bp_);
3852
3853         // PDF support
3854         PDFOptions const & pdf = bp_.pdfoptions();
3855         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
3856         if (bp_.documentClass().provides("hyperref"))
3857                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("C&ustomize Hyperref Options"));
3858         else
3859                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("&Use Hyperref Support"));
3860         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
3861         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
3862         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
3863         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
3864
3865         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
3866         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
3867         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
3868
3869         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
3870
3871         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
3872         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
3873         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
3874         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
3875
3876         nn = findToken(backref_opts, pdf.backref);
3877         if (nn >= 0)
3878                 pdfSupportModule->backrefCO->setCurrentIndex(nn);
3879
3880         pdfSupportModule->fullscreenCB->setChecked
3881                 (pdf.pagemode == pdf.pagemode_fullscreen);
3882
3883         pdfSupportModule->optionsLE->setText(
3884                 toqstr(pdf.quoted_options));
3885
3886         // Make sure that the bc is in the INITIAL state
3887         if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
3888                 bc().restore();
3889
3890         // clear changed branches cache
3891         changedBranches_.clear();
3892
3893         // reset trackers
3894         nonModuleChanged_ = false;
3895         shellescapeChanged_ = false;
3896 }
3897
3898
3899 void GuiDocument::saveDocDefault()
3900 {
3901         // we have to apply the params first
3902         applyView();
3903         saveAsDefault();
3904 }
3905
3906
3907 void GuiDocument::updateAvailableModules()
3908 {
3909         modules_av_model_.clear();
3910         list<modInfoStruct> modInfoList = getModuleInfo();
3911         // Sort names according to the locale
3912         modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
3913                         return 0 < b.name.localeAwareCompare(a.name);
3914                 });
3915         int i = 0;
3916         for (modInfoStruct const & m : modInfoList) {
3917                 modules_av_model_.insertRow(i, m.name, m.id, m.description);
3918                 ++i;
3919         }
3920 }
3921
3922
3923 void GuiDocument::updateSelectedModules()
3924 {
3925         modules_sel_model_.clear();
3926         list<modInfoStruct> const selModList = getSelectedModules();
3927         int i = 0;
3928         for (modInfoStruct const & m : selModList) {
3929                 modules_sel_model_.insertRow(i, m.name, m.id, m.description);
3930                 ++i;
3931         }
3932 }
3933
3934
3935 void GuiDocument::updateIncludeonlys()
3936 {
3937         masterChildModule->childrenTW->clear();
3938         QString const no = qt_("No");
3939         QString const yes = qt_("Yes");
3940
3941         if (includeonlys_.empty()) {
3942                 masterChildModule->includeallRB->setChecked(true);
3943                 masterChildModule->childrenTW->setEnabled(false);
3944                 masterChildModule->maintainAuxCB->setEnabled(false);
3945         } else {
3946                 masterChildModule->includeonlyRB->setChecked(true);
3947                 masterChildModule->childrenTW->setEnabled(true);
3948                 masterChildModule->maintainAuxCB->setEnabled(true);
3949         }
3950         ListOfBuffers children = buffer().getChildren();
3951         ListOfBuffers::const_iterator it  = children.begin();
3952         ListOfBuffers::const_iterator end = children.end();
3953         bool has_unincluded = false;
3954         bool all_unincluded = true;
3955         for (; it != end; ++it) {
3956                 QTreeWidgetItem * item = new QTreeWidgetItem(masterChildModule->childrenTW);
3957                 // FIXME Unicode
3958                 string const name =
3959                         to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
3960                                                         from_utf8(buffer().filePath())));
3961                 item->setText(0, toqstr(name));
3962                 item->setText(1, isChildIncluded(name) ? yes : no);
3963                 if (!isChildIncluded(name))
3964                         has_unincluded = true;
3965                 else
3966                         all_unincluded = false;
3967         }
3968         // Both if all childs are included and if none is included
3969         // is equal to "include all" (i.e., omit \includeonly).
3970         // Thus, reset the GUI.
3971         if (!has_unincluded || all_unincluded) {
3972                 masterChildModule->includeallRB->setChecked(true);
3973                 masterChildModule->childrenTW->setEnabled(false);
3974                 includeonlys_.clear();
3975         }
3976         // If all are included, we need to update again.
3977         if (!has_unincluded)
3978                 updateIncludeonlys();
3979 }
3980
3981
3982 bool GuiDocument::isBiblatex() const
3983 {
3984         QString const engine =
3985                 biblioModule->citeEngineCO->itemData(
3986                                 biblioModule->citeEngineCO->currentIndex()).toString();
3987
3988         return theCiteEnginesList[fromqstr(engine)]->getCiteFramework() == "biblatex";
3989 }
3990
3991
3992 void GuiDocument::updateDefaultBiblio(string const & style,
3993                                       string const & which)
3994 {
3995         QString const bibstyle = toqstr(style);
3996         biblioModule->defaultBiblioCO->clear();
3997
3998         int item_nr = -1;
3999
4000         if (isBiblatex()) {
4001                 if (which != "cbx") {
4002                         // First the bbx styles
4003                         biblioModule->biblatexBbxCO->clear();
4004                         QStringList str = texFileList("bbxFiles.lst");
4005                         // test whether we have a valid list, otherwise run rescan
4006                         if (str.isEmpty()) {
4007                                 rescanTexStyles("bbx");
4008                                 str = texFileList("bbxFiles.lst");
4009                         }
4010                         for (int i = 0; i != str.size(); ++i)
4011                                 str[i] = onlyFileName(str[i]);
4012                         // sort on filename only (no path)
4013                         str.sort();
4014
4015                         for (int i = 0; i != str.count(); ++i) {
4016                                 QString item = changeExtension(str[i], "");
4017                                 if (item == bibstyle)
4018                                         item_nr = i;
4019                                 biblioModule->biblatexBbxCO->addItem(item);
4020                         }
4021
4022                         if (item_nr == -1 && !bibstyle.isEmpty()) {
4023                                 biblioModule->biblatexBbxCO->addItem(bibstyle);
4024                                 item_nr = biblioModule->biblatexBbxCO->count() - 1;
4025                         }
4026
4027                         if (item_nr != -1)
4028                                 biblioModule->biblatexBbxCO->setCurrentIndex(item_nr);
4029                         else
4030                                 biblioModule->biblatexBbxCO->clearEditText();
4031                 }
4032
4033                 if (which != "bbx") {
4034                         // now the cbx styles
4035                         biblioModule->biblatexCbxCO->clear();
4036                         QStringList str = texFileList("cbxFiles.lst");
4037                         // test whether we have a valid list, otherwise run rescan
4038                         if (str.isEmpty()) {
4039                                 rescanTexStyles("cbx");
4040                                 str = texFileList("cbxFiles.lst");
4041                         }
4042                         for (int i = 0; i != str.size(); ++i)
4043                                 str[i] = onlyFileName(str[i]);
4044                         // sort on filename only (no path)
4045                         str.sort();
4046
4047                         for (int i = 0; i != str.count(); ++i) {
4048                                 QString item = changeExtension(str[i], "");
4049                                 if (item == bibstyle)
4050                                         item_nr = i;
4051                                 biblioModule->biblatexCbxCO->addItem(item);
4052                         }
4053
4054                         if (item_nr == -1 && !bibstyle.isEmpty()) {
4055                                 biblioModule->biblatexCbxCO->addItem(bibstyle);
4056                                 item_nr = biblioModule->biblatexCbxCO->count() - 1;
4057                         }
4058
4059                         if (item_nr != -1)
4060                                 biblioModule->biblatexCbxCO->setCurrentIndex(item_nr);
4061                         else
4062                                 biblioModule->biblatexCbxCO->clearEditText();
4063                 }
4064         } else {// BibTeX
4065                 biblioModule->biblatexBbxCO->clear();
4066                 biblioModule->biblatexCbxCO->clear();
4067                 QStringList str = texFileList("bstFiles.lst");
4068                 // test whether we have a valid list, otherwise run rescan
4069                 if (str.isEmpty()) {
4070                         rescanTexStyles("bst");
4071                         str = texFileList("bstFiles.lst");
4072                 }
4073                 for (int i = 0; i != str.size(); ++i)
4074                         str[i] = onlyFileName(str[i]);
4075                 // sort on filename only (no path)
4076                 str.sort();
4077
4078                 for (int i = 0; i != str.count(); ++i) {
4079                         QString item = changeExtension(str[i], "");
4080                         if (item == bibstyle)
4081                                 item_nr = i;
4082                         biblioModule->defaultBiblioCO->addItem(item);
4083                 }
4084
4085                 if (item_nr == -1 && !bibstyle.isEmpty()) {
4086                         biblioModule->defaultBiblioCO->addItem(bibstyle);
4087                         item_nr = biblioModule->defaultBiblioCO->count() - 1;
4088                 }
4089
4090                 if (item_nr != -1)
4091                         biblioModule->defaultBiblioCO->setCurrentIndex(item_nr);
4092                 else
4093                         biblioModule->defaultBiblioCO->clearEditText();
4094         }
4095
4096         updateResetDefaultBiblio();
4097 }
4098
4099
4100 void GuiDocument::updateResetDefaultBiblio()
4101 {
4102         QString const engine =
4103                 biblioModule->citeEngineCO->itemData(
4104                                 biblioModule->citeEngineCO->currentIndex()).toString();
4105         CiteEngineType const cet =
4106                 CiteEngineType(biblioModule->citeStyleCO->itemData(
4107                                                           biblioModule->citeStyleCO->currentIndex()).toInt());
4108
4109         string const defbib = theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet);
4110         if (isBiblatex()) {
4111                 QString const bbx = biblioModule->biblatexBbxCO->currentText();
4112                 QString const cbx = biblioModule->biblatexCbxCO->currentText();
4113                 biblioModule->resetCbxPB->setEnabled(defbib != fromqstr(cbx));
4114                 biblioModule->resetBbxPB->setEnabled(defbib != fromqstr(bbx));
4115                 biblioModule->matchBbxPB->setEnabled(bbx != cbx && !cbx.isEmpty()
4116                         && biblioModule->biblatexBbxCO->findText(cbx) != -1);
4117         } else
4118                 biblioModule->resetDefaultBiblioPB->setEnabled(
4119                         defbib != fromqstr(biblioModule->defaultBiblioCO->currentText()));
4120 }
4121
4122
4123 void GuiDocument::matchBiblatexStyles()
4124 {
4125         updateDefaultBiblio(fromqstr(biblioModule->biblatexCbxCO->currentText()), "bbx");
4126         biblioChanged();
4127 }
4128
4129
4130 void GuiDocument::updateContents()
4131 {
4132         // Nothing to do here as the document settings is not cursor dependant.
4133         return;
4134 }
4135
4136
4137 void GuiDocument::useClassDefaults()
4138 {
4139         if (applyPB->isEnabled()) {
4140                 int const ret = Alert::prompt(_("Unapplied changes"),
4141                                 _("Some changes in the dialog were not yet applied.\n"
4142                                   "If you do not apply now, they will be lost after this action."),
4143                                 1, 1, _("&Apply"), _("&Dismiss"));
4144                 if (ret == 0)
4145                         applyView();
4146         }
4147
4148         int idx = latexModule->classCO->currentIndex();
4149         string const classname = fromqstr(latexModule->classCO->getData(idx));
4150         if (!bp_.setBaseClass(classname)) {
4151                 Alert::error(_("Error"), _("Unable to set document class."));
4152                 return;
4153         }
4154         bp_.useClassDefaults();
4155         paramsToDialog();
4156         changed();
4157 }
4158
4159
4160 void GuiDocument::setLayoutComboByIDString(string const & idString)
4161 {
4162         if (!latexModule->classCO->set(toqstr(idString)))
4163                 Alert::warning(_("Can't set layout!"),
4164                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
4165 }
4166
4167
4168 bool GuiDocument::isValid()
4169 {
4170         return
4171                 validateListingsParameters().isEmpty() &&
4172                 localLayout->isValid() &&
4173                 (
4174                         // if we're asking for skips between paragraphs
4175                         !textLayoutModule->skipRB->isChecked() ||
4176                         // then either we haven't chosen custom
4177                         textLayoutModule->skipCO->currentIndex() != 3 ||
4178                         // or else a length has been given
4179                         !textLayoutModule->skipLE->text().isEmpty()
4180                 ) &&
4181                 (
4182                         // if we're asking for indentation
4183                         !textLayoutModule->indentRB->isChecked() ||
4184                         // then either we haven't chosen custom
4185                         textLayoutModule->indentCO->currentIndex() != 1 ||
4186                         // or else a length has been given
4187                         !textLayoutModule->indentLE->text().isEmpty()
4188                 ) &&
4189                 (
4190                         // if we're asking for math indentation
4191                         !mathsModule->MathIndentCB->isChecked() ||
4192                         // then either we haven't chosen custom
4193                         mathsModule->MathIndentCO->currentIndex() != 1 ||
4194                         // or else a length has been given
4195                         !mathsModule->MathIndentLE->text().isEmpty()
4196                 );
4197 }
4198
4199
4200 char const * const GuiDocument::fontfamilies[5] = {
4201         "default", "rmdefault", "sfdefault", "ttdefault", ""
4202 };
4203
4204
4205 char const * GuiDocument::fontfamilies_gui[5] = {
4206         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
4207 };
4208
4209
4210 bool GuiDocument::initialiseParams(string const &)
4211 {
4212         BufferView const * view = bufferview();
4213         if (!view) {
4214                 bp_ = BufferParams();
4215                 paramsToDialog();
4216                 return true;
4217         }
4218         bp_ = view->buffer().params();
4219         loadModuleInfo();
4220         updateAvailableModules();
4221         //FIXME It'd be nice to make sure here that the selected
4222         //modules are consistent: That required modules are actually
4223         //selected, and that we don't have conflicts. If so, we could
4224         //at least pop up a warning.
4225         paramsToDialog();
4226         return true;
4227 }
4228
4229
4230 void GuiDocument::clearParams()
4231 {
4232         bp_ = BufferParams();
4233 }
4234
4235
4236 BufferId GuiDocument::id() const
4237 {
4238         BufferView const * const view = bufferview();
4239         return view? &view->buffer() : 0;
4240 }
4241
4242
4243 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
4244 {
4245         return moduleNames_;
4246 }
4247
4248
4249 list<GuiDocument::modInfoStruct> const
4250 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
4251 {
4252         list<modInfoStruct> mInfo;
4253         for (string const & name : mods) {
4254                 modInfoStruct m;
4255                 LyXModule const * const mod = theModuleList[name];
4256                 if (mod)
4257                         m = modInfo(*mod);
4258                 else {
4259                         m.id = name;
4260                         m.name = toqstr(name + " (") + qt_("Not Found") + toqstr(")");
4261                 }
4262                 mInfo.push_back(m);
4263         }
4264         return mInfo;
4265 }
4266
4267
4268 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
4269 {
4270         return makeModuleInfo(params().getModules());
4271 }
4272
4273
4274 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
4275 {
4276         return makeModuleInfo(params().baseClass()->providedModules());
4277 }
4278
4279
4280 DocumentClass const & GuiDocument::documentClass() const
4281 {
4282         return bp_.documentClass();
4283 }
4284
4285
4286 static void dispatch_bufferparams(Dialog const & dialog,
4287         BufferParams const & bp, FuncCode lfun, Buffer const * buf)
4288 {
4289         ostringstream ss;
4290         ss << "\\begin_header\n";
4291         bp.writeFile(ss, buf);
4292         ss << "\\end_header\n";
4293         dialog.dispatch(FuncRequest(lfun, ss.str()));
4294 }
4295
4296
4297 void GuiDocument::dispatchParams()
4298 {
4299         // We need a non-const buffer object.
4300         Buffer & buf = const_cast<BufferView *>(bufferview())->buffer();
4301         // There may be several undo records; group them (bug #8998)
4302         buf.undo().beginUndoGroup();
4303
4304         // This must come first so that a language change is correctly noticed
4305         setLanguage();
4306
4307         // Apply the BufferParams. Note that this will set the base class
4308         // and then update the buffer's layout.
4309         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY, &buffer());
4310
4311         if (!params().master.empty()) {
4312                 FileName const master_file = support::makeAbsPath(params().master,
4313                            support::onlyPath(buffer().absFileName()));
4314                 if (isLyXFileName(master_file.absFileName())) {
4315                         Buffer * master = checkAndLoadLyXFile(master_file);
4316                         if (master) {
4317                                 if (master->isChild(const_cast<Buffer *>(&buffer())))
4318                                         const_cast<Buffer &>(buffer()).setParent(master);
4319                                 else
4320                                         Alert::warning(_("Assigned master does not include this file"),
4321                                                 bformat(_("You must include this file in the document\n"
4322                                                           "'%1$s' in order to use the master document\n"
4323                                                           "feature."), from_utf8(params().master)));
4324                         } else
4325                                 Alert::warning(_("Could not load master"),
4326                                                 bformat(_("The master document '%1$s'\n"
4327                                                            "could not be loaded."),
4328                                                            from_utf8(params().master)));
4329                 }
4330         }
4331
4332         // Generate the colours requested by each new branch.
4333         BranchList & branchlist = params().branchlist();
4334         if (!branchlist.empty()) {
4335                 BranchList::const_iterator it = branchlist.begin();
4336                 BranchList::const_iterator const end = branchlist.end();
4337                 for (; it != end; ++it) {
4338                         docstring const & current_branch = it->branch();
4339                         Branch const * branch = branchlist.find(current_branch);
4340                         string const x11hexname = X11hexname(branch->color());
4341                         // display the new color
4342                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
4343                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
4344                 }
4345         }
4346         // rename branches in the document
4347         executeBranchRenaming();
4348         // and clear changed branches cache
4349         changedBranches_.clear();
4350
4351         // Generate the colours requested by indices.
4352         IndicesList & indiceslist = params().indiceslist();
4353         if (!indiceslist.empty()) {
4354                 IndicesList::const_iterator it = indiceslist.begin();
4355                 IndicesList::const_iterator const end = indiceslist.end();
4356                 for (; it != end; ++it) {
4357                         docstring const & current_index = it->shortcut();
4358                         Index const * index = indiceslist.findShortcut(current_index);
4359                         string const x11hexname = X11hexname(index->color());
4360                         // display the new color
4361                         docstring const str = current_index + ' ' + from_ascii(x11hexname);
4362                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
4363                 }
4364         }
4365         // FIXME LFUN
4366         // If we used an LFUN, we would not need these two lines:
4367         BufferView * bv = const_cast<BufferView *>(bufferview());
4368         bv->processUpdateFlags(Update::Force | Update::FitCursor);
4369
4370         // Don't forget to close the group. Note that it is important
4371         // to check that there is no early return in the method.
4372         buf.undo().endUndoGroup();
4373 }
4374
4375
4376 void GuiDocument::setLanguage() const
4377 {
4378         Language const * const newL = bp_.language;
4379         if (buffer().params().language == newL)
4380                 return;
4381
4382         string const & lang_name = newL->lang();
4383         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
4384 }
4385
4386
4387 void GuiDocument::saveAsDefault() const
4388 {
4389         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT, &buffer());
4390 }
4391
4392
4393 bool GuiDocument::providesOSF(QString const & font) const
4394 {
4395         if (fontModule->osFontsCB->isChecked())
4396                 // FIXME: we should check if the fonts really
4397                 // have OSF support. But how?
4398                 return true;
4399         return theLaTeXFonts().getLaTeXFont(
4400                                 qstring_to_ucs4(font)).providesOSF(ot1(),
4401                                                                    completeFontset(),
4402                                                                    noMathFont());
4403 }
4404
4405
4406 bool GuiDocument::providesSC(QString const & font) const
4407 {
4408         if (fontModule->osFontsCB->isChecked())
4409                 return false;
4410         return theLaTeXFonts().getLaTeXFont(
4411                                 qstring_to_ucs4(font)).providesSC(ot1(),
4412                                                                   completeFontset(),
4413                                                                   noMathFont());
4414 }
4415
4416
4417 bool GuiDocument::providesScale(QString const & font) const
4418 {
4419         if (fontModule->osFontsCB->isChecked())
4420                 return true;
4421         return theLaTeXFonts().getLaTeXFont(
4422                                 qstring_to_ucs4(font)).providesScale(ot1(),
4423                                                                      completeFontset(),
4424                                                                      noMathFont());
4425 }
4426
4427
4428 bool GuiDocument::providesNoMath(QString const & font) const
4429 {
4430         if (fontModule->osFontsCB->isChecked())
4431                 return false;
4432         return theLaTeXFonts().getLaTeXFont(
4433                                 qstring_to_ucs4(font)).providesNoMath(ot1(),
4434                                                                       completeFontset());
4435 }
4436
4437
4438 bool GuiDocument::hasMonolithicExpertSet(QString const & font) const
4439 {
4440         if (fontModule->osFontsCB->isChecked())
4441                 return false;
4442         return theLaTeXFonts().getLaTeXFont(
4443                                 qstring_to_ucs4(font)).hasMonolithicExpertSet(ot1(),
4444                                                                               completeFontset(),
4445                                                                               noMathFont());
4446 }
4447
4448
4449 //static
4450 GuiDocument::modInfoStruct GuiDocument::modInfo(LyXModule const & mod)
4451 {
4452         // FIXME Unicode: docstrings would be better for these parameters but this
4453         // change requires a lot of others
4454         modInfoStruct m;
4455         m.id = mod.getID();
4456         m.name = toqstr(translateIfPossible(from_utf8(mod.getName())));
4457         QString desc = toqstr(translateIfPossible(from_utf8(mod.getDescription())));
4458         // Find the first sentence of the description
4459         QTextBoundaryFinder bf(QTextBoundaryFinder::Sentence, desc);
4460         int pos = bf.toNextBoundary();
4461         if (pos > 0)
4462                 desc.truncate(pos);
4463         QString modulename = QString(qt_("(Module name: %1)")).arg(toqstr(m.id));
4464         // Tooltip is the desc followed by the module name
4465         m.description = QString("%1<i>%2</i>")
4466                 .arg(desc.isEmpty() ? QString() : QString("<p>%1</p>").arg(desc),
4467                      modulename);
4468         return m;
4469 }
4470
4471
4472 void GuiDocument::loadModuleInfo()
4473 {
4474         moduleNames_.clear();
4475         for (LyXModule const & mod : theModuleList)
4476                 if (mod.category().substr(0, 8) != "Citation")
4477                         moduleNames_.push_back(modInfo(mod));
4478 }
4479
4480
4481 void GuiDocument::updateUnknownBranches()
4482 {
4483         if (!bufferview())
4484                 return;
4485         list<docstring> used_branches;
4486         buffer().getUsedBranches(used_branches);
4487         list<docstring>::const_iterator it = used_branches.begin();
4488         QStringList unknown_branches;
4489         for (; it != used_branches.end() ; ++it) {
4490                 if (!buffer().params().branchlist().find(*it))
4491                         unknown_branches.append(toqstr(*it));
4492         }
4493         branchesModule->setUnknownBranches(unknown_branches);
4494 }
4495
4496
4497 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
4498 {
4499         map<docstring, docstring>::iterator it = changedBranches_.begin();
4500         for (; it != changedBranches_.end() ; ++it) {
4501                 if (it->second == oldname) {
4502                         // branch has already been renamed
4503                         it->second = newname;
4504                         return;
4505                 }
4506         }
4507         // store new name
4508         changedBranches_[oldname] = newname;
4509 }
4510
4511
4512 void GuiDocument::executeBranchRenaming() const
4513 {
4514         map<docstring, docstring>::const_iterator it = changedBranches_.begin();
4515         for (; it != changedBranches_.end() ; ++it) {
4516                 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
4517                 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
4518         }
4519 }
4520
4521
4522 void GuiDocument::allPackagesAuto()
4523 {
4524         allPackages(1);
4525 }
4526
4527
4528 void GuiDocument::allPackagesAlways()
4529 {
4530         allPackages(2);
4531 }
4532
4533
4534 void GuiDocument::allPackagesNot()
4535 {
4536         allPackages(3);
4537 }
4538
4539
4540 void GuiDocument::allPackages(int col)
4541 {
4542         for (int row = 0; row < mathsModule->packagesTW->rowCount(); ++row) {
4543                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, col);
4544                 rb->setChecked(true);
4545         }
4546 }
4547
4548
4549 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
4550
4551
4552 } // namespace frontend
4553 } // namespace lyx
4554
4555 #include "moc_GuiDocument.cpp"