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