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