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