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