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