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