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