]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiDocument.cpp
GuiDocument: support also the class option reqno
[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         textLayoutModule->lspacingLE->setValidator(new QDoubleValidator(
728                 textLayoutModule->lspacingLE));
729         textLayoutModule->indentLE->setValidator(new LengthValidator(
730                 textLayoutModule->indentLE));
731         textLayoutModule->skipLE->setValidator(new LengthValidator(
732                 textLayoutModule->skipLE));
733
734         textLayoutModule->indentCO->addItem(qt_("Default"));
735         textLayoutModule->indentCO->addItem(qt_("Custom"));
736         textLayoutModule->skipCO->addItem(qt_("SmallSkip"));
737         textLayoutModule->skipCO->addItem(qt_("MedSkip"));
738         textLayoutModule->skipCO->addItem(qt_("BigSkip"));
739         textLayoutModule->skipCO->addItem(qt_("Custom"));
740         textLayoutModule->lspacingCO->insertItem(
741                 Spacing::Single, qt_("Single"));
742         textLayoutModule->lspacingCO->insertItem(
743                 Spacing::Onehalf, qt_("OneHalf"));
744         textLayoutModule->lspacingCO->insertItem(
745                 Spacing::Double, qt_("Double"));
746         textLayoutModule->lspacingCO->insertItem(
747                 Spacing::Other, qt_("Custom"));
748         // initialize the length validator
749         bc().addCheckedLineEdit(textLayoutModule->indentLE);
750         bc().addCheckedLineEdit(textLayoutModule->skipLE);
751
752
753         // master/child handling
754         masterChildModule = new UiWidget<Ui::MasterChildUi>(this);
755
756         connect(masterChildModule->childrenTW, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),
757                 this, SLOT(includeonlyClicked(QTreeWidgetItem *, int)));
758         connect(masterChildModule->includeonlyRB, SIGNAL(toggled(bool)),
759                 masterChildModule->childrenTW, SLOT(setEnabled(bool)));
760         connect(masterChildModule->includeonlyRB, SIGNAL(toggled(bool)),
761                 masterChildModule->maintainAuxCB, SLOT(setEnabled(bool)));
762         connect(masterChildModule->includeallRB, SIGNAL(clicked()),
763                 this, SLOT(change_adaptor()));
764         connect(masterChildModule->includeonlyRB, SIGNAL(clicked()),
765                 this, SLOT(change_adaptor()));
766         connect(masterChildModule->maintainAuxCB, SIGNAL(clicked()),
767                 this, SLOT(change_adaptor()));
768         masterChildModule->childrenTW->setColumnCount(2);
769         masterChildModule->childrenTW->headerItem()->setText(0, qt_("Child Document"));
770         masterChildModule->childrenTW->headerItem()->setText(1, qt_("Include to Output"));
771         masterChildModule->childrenTW->resizeColumnToContents(1);
772         masterChildModule->childrenTW->resizeColumnToContents(2);
773
774
775         // Formats
776         outputModule = new UiWidget<Ui::OutputUi>(this);
777
778         connect(outputModule->defaultFormatCO, SIGNAL(activated(int)),
779                 this, SLOT(change_adaptor()));
780         connect(outputModule->mathimgSB, SIGNAL(valueChanged(double)),
781                 this, SLOT(change_adaptor()));
782         connect(outputModule->strictCB, SIGNAL(stateChanged(int)),
783                 this, SLOT(change_adaptor()));
784         connect(outputModule->cssCB, SIGNAL(stateChanged(int)),
785                 this, SLOT(change_adaptor()));
786         connect(outputModule->mathoutCB, SIGNAL(currentIndexChanged(int)),
787                 this, SLOT(change_adaptor()));
788
789         connect(outputModule->outputsyncCB, SIGNAL(clicked()),
790                 this, SLOT(change_adaptor()));
791         connect(outputModule->synccustomCB, SIGNAL(editTextChanged(QString)),
792                 this, SLOT(change_adaptor()));
793         outputModule->synccustomCB->addItem("");
794         outputModule->synccustomCB->addItem("\\synctex=1");
795         outputModule->synccustomCB->addItem("\\synctex=-1");
796         outputModule->synccustomCB->addItem("\\usepackage[active]{srcltx}");
797
798         outputModule->synccustomCB->setValidator(new NoNewLineValidator(
799                 outputModule->synccustomCB));
800
801         connect(outputModule->saveTransientPropertiesCB, SIGNAL(clicked()),
802                 this, SLOT(change_adaptor()));
803
804         // fonts
805         fontModule = new FontModule(this);
806         connect(fontModule->osFontsCB, SIGNAL(clicked()),
807                 this, SLOT(change_adaptor()));
808         connect(fontModule->osFontsCB, SIGNAL(toggled(bool)),
809                 this, SLOT(osFontsChanged(bool)));
810         connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
811                 this, SLOT(change_adaptor()));
812         connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
813                 this, SLOT(romanChanged(int)));
814         connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
815                 this, SLOT(change_adaptor()));
816         connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
817                 this, SLOT(sansChanged(int)));
818         connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
819                 this, SLOT(change_adaptor()));
820         connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
821                 this, SLOT(ttChanged(int)));
822         connect(fontModule->fontsMathCO, SIGNAL(activated(int)),
823                 this, SLOT(change_adaptor()));
824         connect(fontModule->fontsMathCO, SIGNAL(activated(int)),
825                 this, SLOT(mathFontChanged(int)));
826         connect(fontModule->fontsDefaultCO, SIGNAL(activated(int)),
827                 this, SLOT(change_adaptor()));
828         connect(fontModule->fontencCO, SIGNAL(activated(int)),
829                 this, SLOT(change_adaptor()));
830         connect(fontModule->fontencCO, SIGNAL(activated(int)),
831                 this, SLOT(fontencChanged(int)));
832         connect(fontModule->fontencLE, SIGNAL(textChanged(const QString &)),
833                 this, SLOT(change_adaptor()));
834         connect(fontModule->fontsizeCO, SIGNAL(activated(int)),
835                 this, SLOT(change_adaptor()));
836         connect(fontModule->cjkFontLE, SIGNAL(textChanged(const QString &)),
837                 this, SLOT(change_adaptor()));
838         connect(fontModule->microtypeCB, SIGNAL(clicked()),
839                 this, SLOT(change_adaptor()));
840         connect(fontModule->dashesCB, SIGNAL(clicked()),
841                 this, SLOT(change_adaptor()));
842         connect(fontModule->scaleSansSB, SIGNAL(valueChanged(int)),
843                 this, SLOT(change_adaptor()));
844         connect(fontModule->scaleTypewriterSB, SIGNAL(valueChanged(int)),
845                 this, SLOT(change_adaptor()));
846         connect(fontModule->fontScCB, SIGNAL(clicked()),
847                 this, SLOT(change_adaptor()));
848         connect(fontModule->fontScCB, SIGNAL(toggled(bool)),
849                 this, SLOT(fontScToggled(bool)));
850         connect(fontModule->fontOsfCB, SIGNAL(clicked()),
851                 this, SLOT(change_adaptor()));
852         connect(fontModule->fontOsfCB, SIGNAL(toggled(bool)),
853                 this, SLOT(fontOsfToggled(bool)));
854
855         fontModule->fontencLE->setValidator(new NoNewLineValidator(
856                 fontModule->fontencLE));
857         fontModule->cjkFontLE->setValidator(new NoNewLineValidator(
858                 fontModule->cjkFontLE));
859
860         updateFontlist();
861
862         fontModule->fontsizeCO->addItem(qt_("Default"));
863         fontModule->fontsizeCO->addItem(qt_("10"));
864         fontModule->fontsizeCO->addItem(qt_("11"));
865         fontModule->fontsizeCO->addItem(qt_("12"));
866
867         fontModule->fontencCO->addItem(qt_("Default"), QString("global"));
868         fontModule->fontencCO->addItem(qt_("Custom"), QString("custom"));
869         fontModule->fontencCO->addItem(qt_("None (no fontenc)"), QString("default"));
870
871         for (int n = 0; GuiDocument::fontfamilies_gui[n][0]; ++n)
872                 fontModule->fontsDefaultCO->addItem(
873                         qt_(GuiDocument::fontfamilies_gui[n]));
874
875         if (!LaTeXFeatures::isAvailable("fontspec"))
876                 fontModule->osFontsCB->setToolTip(
877                         qt_("Use OpenType and TrueType fonts directly (requires XeTeX or LuaTeX)\n"
878                             "You need to install the package \"fontspec\" to use this feature"));
879
880
881         // page layout
882         pageLayoutModule = new UiWidget<Ui::PageLayoutUi>(this);
883         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
884                 this, SLOT(papersizeChanged(int)));
885         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
886                 this, SLOT(papersizeChanged(int)));
887         connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
888                 this, SLOT(change_adaptor()));
889         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
890                 this, SLOT(change_adaptor()));
891         connect(pageLayoutModule->paperheightLE, SIGNAL(textChanged(const QString &)),
892                 this, SLOT(change_adaptor()));
893         connect(pageLayoutModule->paperwidthLE, SIGNAL(textChanged(const QString &)),
894                 this, SLOT(change_adaptor()));
895         connect(pageLayoutModule->paperwidthUnitCO, SIGNAL(activated(int)),
896                 this, SLOT(change_adaptor()));
897         connect(pageLayoutModule->paperheightUnitCO, SIGNAL(activated(int)),
898                 this, SLOT(change_adaptor()));
899         connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
900                 this, SLOT(change_adaptor()));
901         connect(pageLayoutModule->landscapeRB, SIGNAL(clicked()),
902                 this, SLOT(change_adaptor()));
903         connect(pageLayoutModule->facingPagesCB, SIGNAL(clicked()),
904                 this, SLOT(change_adaptor()));
905         connect(pageLayoutModule->pagestyleCO, SIGNAL(activated(int)),
906                 this, SLOT(change_adaptor()));
907
908         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
909         pageLayoutModule->pagestyleCO->addItem(qt_("empty"));
910         pageLayoutModule->pagestyleCO->addItem(qt_("plain"));
911         pageLayoutModule->pagestyleCO->addItem(qt_("headings"));
912         pageLayoutModule->pagestyleCO->addItem(qt_("fancy"));
913         bc().addCheckedLineEdit(pageLayoutModule->paperheightLE,
914                 pageLayoutModule->paperheightL);
915         bc().addCheckedLineEdit(pageLayoutModule->paperwidthLE,
916                 pageLayoutModule->paperwidthL);
917
918         QComboBox * cb = pageLayoutModule->papersizeCO;
919         cb->addItem(qt_("Default"));
920         cb->addItem(qt_("Custom"));
921         cb->addItem(qt_("US letter"));
922         cb->addItem(qt_("US legal"));
923         cb->addItem(qt_("US executive"));
924         cb->addItem(qt_("A0"));
925         cb->addItem(qt_("A1"));
926         cb->addItem(qt_("A2"));
927         cb->addItem(qt_("A3"));
928         cb->addItem(qt_("A4"));
929         cb->addItem(qt_("A5"));
930         cb->addItem(qt_("A6"));
931         cb->addItem(qt_("B0"));
932         cb->addItem(qt_("B1"));
933         cb->addItem(qt_("B2"));
934         cb->addItem(qt_("B3"));
935         cb->addItem(qt_("B4"));
936         cb->addItem(qt_("B5"));
937         cb->addItem(qt_("B6"));
938         cb->addItem(qt_("C0"));
939         cb->addItem(qt_("C1"));
940         cb->addItem(qt_("C2"));
941         cb->addItem(qt_("C3"));
942         cb->addItem(qt_("C4"));
943         cb->addItem(qt_("C5"));
944         cb->addItem(qt_("C6"));
945         cb->addItem(qt_("JIS B0"));
946         cb->addItem(qt_("JIS B1"));
947         cb->addItem(qt_("JIS B2"));
948         cb->addItem(qt_("JIS B3"));
949         cb->addItem(qt_("JIS B4"));
950         cb->addItem(qt_("JIS B5"));
951         cb->addItem(qt_("JIS B6"));
952         // remove the %-items from the unit choice
953         pageLayoutModule->paperwidthUnitCO->noPercents();
954         pageLayoutModule->paperheightUnitCO->noPercents();
955         pageLayoutModule->paperheightLE->setValidator(unsignedLengthValidator(
956                 pageLayoutModule->paperheightLE));
957         pageLayoutModule->paperwidthLE->setValidator(unsignedLengthValidator(
958                 pageLayoutModule->paperwidthLE));
959
960
961         // margins
962         marginsModule = new UiWidget<Ui::MarginsUi>(this);
963         connect(marginsModule->marginCB, SIGNAL(toggled(bool)),
964                 this, SLOT(setCustomMargins(bool)));
965         connect(marginsModule->marginCB, SIGNAL(clicked()),
966                 this, SLOT(change_adaptor()));
967         connect(marginsModule->topLE, SIGNAL(textChanged(QString)),
968                 this, SLOT(change_adaptor()));
969         connect(marginsModule->topUnit, SIGNAL(activated(int)),
970                 this, SLOT(change_adaptor()));
971         connect(marginsModule->bottomLE, SIGNAL(textChanged(QString)),
972                 this, SLOT(change_adaptor()));
973         connect(marginsModule->bottomUnit, SIGNAL(activated(int)),
974                 this, SLOT(change_adaptor()));
975         connect(marginsModule->innerLE, SIGNAL(textChanged(QString)),
976                 this, SLOT(change_adaptor()));
977         connect(marginsModule->innerUnit, SIGNAL(activated(int)),
978                 this, SLOT(change_adaptor()));
979         connect(marginsModule->outerLE, SIGNAL(textChanged(QString)),
980                 this, SLOT(change_adaptor()));
981         connect(marginsModule->outerUnit, SIGNAL(activated(int)),
982                 this, SLOT(change_adaptor()));
983         connect(marginsModule->headheightLE, SIGNAL(textChanged(QString)),
984                 this, SLOT(change_adaptor()));
985         connect(marginsModule->headheightUnit, SIGNAL(activated(int)),
986                 this, SLOT(change_adaptor()));
987         connect(marginsModule->headsepLE, SIGNAL(textChanged(QString)),
988                 this, SLOT(change_adaptor()));
989         connect(marginsModule->headsepUnit, SIGNAL(activated(int)),
990                 this, SLOT(change_adaptor()));
991         connect(marginsModule->footskipLE, SIGNAL(textChanged(QString)),
992                 this, SLOT(change_adaptor()));
993         connect(marginsModule->footskipUnit, SIGNAL(activated(int)),
994                 this, SLOT(change_adaptor()));
995         connect(marginsModule->columnsepLE, SIGNAL(textChanged(QString)),
996                 this, SLOT(change_adaptor()));
997         connect(marginsModule->columnsepUnit, SIGNAL(activated(int)),
998                 this, SLOT(change_adaptor()));
999         marginsModule->topLE->setValidator(new LengthValidator(
1000                 marginsModule->topLE));
1001         marginsModule->bottomLE->setValidator(new LengthValidator(
1002                 marginsModule->bottomLE));
1003         marginsModule->innerLE->setValidator(new LengthValidator(
1004                 marginsModule->innerLE));
1005         marginsModule->outerLE->setValidator(new LengthValidator(
1006                 marginsModule->outerLE));
1007         marginsModule->headsepLE->setValidator(new LengthValidator(
1008                 marginsModule->headsepLE));
1009         marginsModule->headheightLE->setValidator(new LengthValidator(
1010                 marginsModule->headheightLE));
1011         marginsModule->footskipLE->setValidator(new LengthValidator(
1012                 marginsModule->footskipLE));
1013         marginsModule->columnsepLE->setValidator(new LengthValidator(
1014                 marginsModule->columnsepLE));
1015
1016         bc().addCheckedLineEdit(marginsModule->topLE,
1017                 marginsModule->topL);
1018         bc().addCheckedLineEdit(marginsModule->bottomLE,
1019                 marginsModule->bottomL);
1020         bc().addCheckedLineEdit(marginsModule->innerLE,
1021                 marginsModule->innerL);
1022         bc().addCheckedLineEdit(marginsModule->outerLE,
1023                 marginsModule->outerL);
1024         bc().addCheckedLineEdit(marginsModule->headsepLE,
1025                 marginsModule->headsepL);
1026         bc().addCheckedLineEdit(marginsModule->headheightLE,
1027                 marginsModule->headheightL);
1028         bc().addCheckedLineEdit(marginsModule->footskipLE,
1029                 marginsModule->footskipL);
1030         bc().addCheckedLineEdit(marginsModule->columnsepLE,
1031                 marginsModule->columnsepL);
1032
1033
1034         // language & quote
1035         langModule = new UiWidget<Ui::LanguageUi>(this);
1036         connect(langModule->languageCO, SIGNAL(activated(int)),
1037                 this, SLOT(change_adaptor()));
1038         connect(langModule->languageCO, SIGNAL(activated(int)),
1039                 this, SLOT(languageChanged(int)));
1040         connect(langModule->defaultencodingRB, SIGNAL(clicked()),
1041                 this, SLOT(change_adaptor()));
1042         connect(langModule->otherencodingRB, SIGNAL(clicked()),
1043                 this, SLOT(change_adaptor()));
1044         connect(langModule->encodingCO, SIGNAL(activated(int)),
1045                 this, SLOT(change_adaptor()));
1046         connect(langModule->quoteStyleCO, SIGNAL(activated(int)),
1047                 this, SLOT(change_adaptor()));
1048         connect(langModule->languagePackageCO, SIGNAL(activated(int)),
1049                 this, SLOT(change_adaptor()));
1050         connect(langModule->languagePackageLE, SIGNAL(textChanged(QString)),
1051                 this, SLOT(change_adaptor()));
1052         connect(langModule->languagePackageCO, SIGNAL(currentIndexChanged(int)),
1053                 this, SLOT(languagePackageChanged(int)));
1054         connect(langModule->dynamicQuotesCB, SIGNAL(clicked()),
1055                 this, SLOT(change_adaptor()));
1056
1057         langModule->languagePackageLE->setValidator(new NoNewLineValidator(
1058                 langModule->languagePackageLE));
1059
1060         QAbstractItemModel * language_model = guiApp->languageModel();
1061         // FIXME: it would be nice if sorting was enabled/disabled via a checkbox.
1062         language_model->sort(0);
1063         langModule->languageCO->setModel(language_model);
1064         langModule->languageCO->setModelColumn(0);
1065
1066         // Always put the default encoding in the first position.
1067         langModule->encodingCO->addItem(qt_("Language Default (no inputenc)"));
1068         QStringList encodinglist;
1069         Encodings::const_iterator it = encodings.begin();
1070         Encodings::const_iterator const end = encodings.end();
1071         for (; it != end; ++it)
1072                 if (!it->unsafe())
1073                         encodinglist.append(qt_(it->guiName()));
1074         encodinglist.sort();
1075         langModule->encodingCO->addItems(encodinglist);
1076
1077         langModule->languagePackageCO->addItem(
1078                 qt_("Default"), toqstr("default"));
1079         langModule->languagePackageCO->addItem(
1080                 qt_("Automatic"), toqstr("auto"));
1081         langModule->languagePackageCO->addItem(
1082                 qt_("Always Babel"), toqstr("babel"));
1083         langModule->languagePackageCO->addItem(
1084                 qt_("Custom"), toqstr("custom"));
1085         langModule->languagePackageCO->addItem(
1086                 qt_("None[[language package]]"), toqstr("none"));
1087
1088
1089         // color
1090         colorModule = new UiWidget<Ui::ColorUi>(this);
1091         connect(colorModule->fontColorPB, SIGNAL(clicked()),
1092                 this, SLOT(changeFontColor()));
1093         connect(colorModule->delFontColorTB, SIGNAL(clicked()),
1094                 this, SLOT(deleteFontColor()));
1095         connect(colorModule->noteFontColorPB, SIGNAL(clicked()),
1096                 this, SLOT(changeNoteFontColor()));
1097         connect(colorModule->delNoteFontColorTB, SIGNAL(clicked()),
1098                 this, SLOT(deleteNoteFontColor()));
1099         connect(colorModule->backgroundPB, SIGNAL(clicked()),
1100                 this, SLOT(changeBackgroundColor()));
1101         connect(colorModule->delBackgroundTB, SIGNAL(clicked()),
1102                 this, SLOT(deleteBackgroundColor()));
1103         connect(colorModule->boxBackgroundPB, SIGNAL(clicked()),
1104                 this, SLOT(changeBoxBackgroundColor()));
1105         connect(colorModule->delBoxBackgroundTB, SIGNAL(clicked()),
1106                 this, SLOT(deleteBoxBackgroundColor()));
1107
1108
1109         // numbering
1110         numberingModule = new UiWidget<Ui::NumberingUi>(this);
1111         connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
1112                 this, SLOT(change_adaptor()));
1113         connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
1114                 this, SLOT(change_adaptor()));
1115         connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
1116                 this, SLOT(updateNumbering()));
1117         connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
1118                 this, SLOT(updateNumbering()));
1119         numberingModule->tocTW->setColumnCount(3);
1120         numberingModule->tocTW->headerItem()->setText(0, qt_("Example"));
1121         numberingModule->tocTW->headerItem()->setText(1, qt_("Numbered"));
1122         numberingModule->tocTW->headerItem()->setText(2, qt_("Appears in TOC"));
1123         setSectionResizeMode(numberingModule->tocTW->header(), QHeaderView::ResizeToContents);
1124
1125         // biblio
1126         biblioModule = new UiWidget<Ui::BiblioUi>(this);
1127         connect(biblioModule->citeEngineCO, SIGNAL(activated(int)),
1128                 this, SLOT(citeEngineChanged(int)));
1129         connect(biblioModule->citeStyleCO, SIGNAL(activated(int)),
1130                 this, SLOT(citeStyleChanged()));
1131         connect(biblioModule->bibtopicCB, SIGNAL(clicked()),
1132                 this, SLOT(biblioChanged()));
1133         connect(biblioModule->bibunitsCO, SIGNAL(activated(int)),
1134                 this, SLOT(biblioChanged()));
1135         connect(biblioModule->bibtexCO, SIGNAL(activated(int)),
1136                 this, SLOT(bibtexChanged(int)));
1137         connect(biblioModule->bibtexOptionsLE, SIGNAL(textChanged(QString)),
1138                 this, SLOT(biblioChanged()));
1139         connect(biblioModule->citePackageOptionsLE, SIGNAL(textChanged(QString)),
1140                 this, SLOT(biblioChanged()));
1141         connect(biblioModule->defaultBiblioCO, SIGNAL(activated(int)),
1142                 this, SLOT(biblioChanged()));
1143         connect(biblioModule->defaultBiblioCO, SIGNAL(editTextChanged(QString)),
1144                 this, SLOT(biblioChanged()));
1145         connect(biblioModule->defaultBiblioCO, SIGNAL(editTextChanged(QString)),
1146                 this, SLOT(updateResetDefaultBiblio()));
1147         connect(biblioModule->biblatexBbxCO, SIGNAL(activated(int)),
1148                 this, SLOT(biblioChanged()));
1149         connect(biblioModule->biblatexBbxCO, SIGNAL(editTextChanged(QString)),
1150                 this, SLOT(updateResetDefaultBiblio()));
1151         connect(biblioModule->biblatexCbxCO, SIGNAL(activated(int)),
1152                 this, SLOT(biblioChanged()));
1153         connect(biblioModule->biblatexCbxCO, SIGNAL(editTextChanged(QString)),
1154                 this, SLOT(updateResetDefaultBiblio()));
1155         connect(biblioModule->rescanBibliosPB, SIGNAL(clicked()),
1156                 this, SLOT(rescanBibFiles()));
1157         connect(biblioModule->resetDefaultBiblioPB, SIGNAL(clicked()),
1158                 this, SLOT(resetDefaultBibfile()));
1159         connect(biblioModule->resetCbxPB, SIGNAL(clicked()),
1160                 this, SLOT(resetDefaultCbxBibfile()));
1161         connect(biblioModule->resetBbxPB, SIGNAL(clicked()),
1162                 this, SLOT(resetDefaultBbxBibfile()));
1163         connect(biblioModule->matchBbxPB, SIGNAL(clicked()),
1164                 this, SLOT(matchBiblatexStyles()));
1165
1166         biblioModule->citeEngineCO->clear();
1167         for (LyXCiteEngine const & cet : theCiteEnginesList) {
1168                 biblioModule->citeEngineCO->addItem(qt_(cet.getName()), toqstr(cet.getID()));
1169                 int const i = biblioModule->citeEngineCO->findData(toqstr(cet.getID()));
1170                 biblioModule->citeEngineCO->setItemData(i, qt_(cet.getDescription()),
1171                                                         Qt::ToolTipRole);
1172         }
1173
1174         biblioModule->bibtexOptionsLE->setValidator(new NoNewLineValidator(
1175                 biblioModule->bibtexOptionsLE));
1176         biblioModule->defaultBiblioCO->lineEdit()->setValidator(new NoNewLineValidator(
1177                 biblioModule->defaultBiblioCO->lineEdit()));
1178
1179         // NOTE: we do not provide "custom" here for security reasons!
1180         biblioModule->bibtexCO->clear();
1181         biblioModule->bibtexCO->addItem(qt_("Default"), QString("default"));
1182         for (set<string>::const_iterator it = lyxrc.bibtex_alternatives.begin();
1183                              it != lyxrc.bibtex_alternatives.end(); ++it) {
1184                 QString const command = toqstr(*it).left(toqstr(*it).indexOf(" "));
1185                 biblioModule->bibtexCO->addItem(command, command);
1186         }
1187
1188
1189         // indices
1190         indicesModule = new GuiIndices;
1191         connect(indicesModule, SIGNAL(changed()),
1192                 this, SLOT(change_adaptor()));
1193
1194
1195         // maths
1196         mathsModule = new UiWidget<Ui::MathsUi>(this);
1197         QStringList headers;
1198         headers << qt_("Package") << qt_("Load automatically")
1199                 << qt_("Load always") << qt_("Do not load");
1200         mathsModule->packagesTW->setHorizontalHeaderLabels(headers);
1201         setSectionResizeMode(mathsModule->packagesTW->horizontalHeader(), QHeaderView::Stretch);
1202         map<string, string> const & packages = BufferParams::auto_packages();
1203         mathsModule->packagesTW->setRowCount(packages.size());
1204         int i = 0;
1205         for (map<string, string>::const_iterator it = packages.begin();
1206              it != packages.end(); ++it) {
1207                 docstring const package = from_ascii(it->first);
1208                 QString autoTooltip = qt_(it->second);
1209                 QString alwaysTooltip;
1210                 if (package == "amsmath")
1211                         alwaysTooltip =
1212                                 qt_("The AMS LaTeX packages are always used");
1213                 else
1214                         alwaysTooltip = toqstr(bformat(
1215                                 _("The LaTeX package %1$s is always used"),
1216                                 package));
1217                 QString neverTooltip;
1218                 if (package == "amsmath")
1219                         neverTooltip =
1220                                 qt_("The AMS LaTeX packages are never used");
1221                 else
1222                         neverTooltip = toqstr(bformat(
1223                                 _("The LaTeX package %1$s is never used"),
1224                                 package));
1225                 QRadioButton * autoRB = new QRadioButton(mathsModule);
1226                 QRadioButton * alwaysRB = new QRadioButton(mathsModule);
1227                 QRadioButton * neverRB = new QRadioButton(mathsModule);
1228                 QButtonGroup * packageGroup = new QButtonGroup(mathsModule);
1229                 packageGroup->addButton(autoRB);
1230                 packageGroup->addButton(alwaysRB);
1231                 packageGroup->addButton(neverRB);
1232                 autoRB->setToolTip(autoTooltip);
1233                 alwaysRB->setToolTip(alwaysTooltip);
1234                 neverRB->setToolTip(neverTooltip);
1235                 QTableWidgetItem * pack = new QTableWidgetItem(toqstr(package));
1236                 mathsModule->packagesTW->setItem(i, 0, pack);
1237                 mathsModule->packagesTW->setCellWidget(i, 1, autoRB);
1238                 mathsModule->packagesTW->setCellWidget(i, 2, alwaysRB);
1239                 mathsModule->packagesTW->setCellWidget(i, 3, neverRB);
1240
1241                 connect(autoRB, SIGNAL(clicked()),
1242                         this, SLOT(change_adaptor()));
1243                 connect(alwaysRB, SIGNAL(clicked()),
1244                         this, SLOT(change_adaptor()));
1245                 connect(neverRB, SIGNAL(clicked()),
1246                         this, SLOT(change_adaptor()));
1247                 ++i;
1248         }
1249         connect(mathsModule->allPackagesAutoPB, SIGNAL(clicked()),
1250                 this, SLOT(allPackagesAuto()));
1251         connect(mathsModule->allPackagesAlwaysPB, SIGNAL(clicked()),
1252                 this, SLOT(allPackagesAlways()));
1253         connect(mathsModule->allPackagesNotPB, SIGNAL(clicked()),
1254                 this, SLOT(allPackagesNot()));
1255         connect(mathsModule->allPackagesAutoPB, SIGNAL(clicked()),
1256                 this, SLOT(change_adaptor()));
1257         connect(mathsModule->allPackagesAlwaysPB, SIGNAL(clicked()),
1258                 this, SLOT(change_adaptor()));
1259         connect(mathsModule->allPackagesNotPB, SIGNAL(clicked()),
1260                 this, SLOT(change_adaptor()));
1261         connect(mathsModule->MathNumberingPosCO, SIGNAL(activated(int)),
1262                 this, SLOT(change_adaptor()));
1263
1264         connect(mathsModule->MathIndentCB, SIGNAL(toggled(bool)),
1265                 this, SLOT(change_adaptor()));
1266         connect(mathsModule->MathIndentCB, SIGNAL(toggled(bool)),
1267                 this, SLOT(allowMathIndent()));
1268         connect(mathsModule->MathIndentCO, SIGNAL(activated(int)),
1269                 this, SLOT(change_adaptor()));
1270         connect(mathsModule->MathIndentCO, SIGNAL(activated(int)),
1271                 this, SLOT(enableMathIndent(int)));
1272         connect(mathsModule->MathIndentLE, SIGNAL(textChanged(const QString &)),
1273                 this, SLOT(change_adaptor()));
1274         connect(mathsModule->MathIndentLengthCO, SIGNAL(activated(int)),
1275                 this, SLOT(change_adaptor()));
1276
1277         
1278         mathsModule->MathIndentCO->addItem(qt_("Default"));
1279         mathsModule->MathIndentCO->addItem(qt_("Custom"));
1280         mathsModule->MathIndentLE->setValidator(new LengthValidator(
1281                 mathsModule->MathIndentLE));
1282         // initialize the length validator
1283         bc().addCheckedLineEdit(mathsModule->MathIndentLE);
1284         mathsModule->MathNumberingPosCO->addItem(qt_("Left"));
1285         mathsModule->MathNumberingPosCO->addItem(qt_("Default"));
1286         mathsModule->MathNumberingPosCO->addItem(qt_("Right"));
1287         mathsModule->MathNumberingPosCO->setCurrentIndex(1);
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 (!mathsModule->MathIndentCB->isChecked()) {
1623                 mathsModule->MathIndentLE->setEnabled(false);
1624                 mathsModule->MathIndentLengthCO->setEnabled(false);
1625         }
1626         if (mathsModule->MathIndentCB->isChecked()
1627             && mathsModule->MathIndentCO->currentIndex() == 1) {
1628                         mathsModule->MathIndentLE->setEnabled(true);
1629                         mathsModule->MathIndentLengthCO->setEnabled(true);
1630         }
1631         isValid();
1632 }
1633
1634 void GuiDocument::enableMathIndent(int item)
1635 {
1636         bool const enable = (item == 1);
1637         mathsModule->MathIndentLE->setEnabled(enable);
1638         mathsModule->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         // if math is indented
2925         bp_.is_math_indent = mathsModule->MathIndentCB->isChecked();
2926         if (bp_.is_math_indent) {
2927                 // if formulas are indented
2928                 switch (mathsModule->MathIndentCO->currentIndex()) {
2929                 case 0:
2930                         bp_.setMathIndent(Length());
2931                         break;
2932                 case 1: {
2933                         Length mathindent(widgetsToLength(mathsModule->MathIndentLE,
2934                                                           mathsModule->MathIndentLengthCO));
2935                         bp_.setMathIndent(mathindent);
2936                         break;
2937                 }
2938                 default:
2939                         // this should never happen
2940                         bp_.setMathIndent(Length());
2941                         break;
2942                 }
2943         }
2944         switch (mathsModule->MathNumberingPosCO->currentIndex()) {
2945                 case 0:
2946                         bp_.math_number_before = "true";
2947                         break;
2948                 case 1:
2949                         bp_.math_number_before = "default";
2950                         break;
2951                 case 2:
2952                         bp_.math_number_before = "false";
2953                         break;
2954                 default:
2955                         // this should never happen
2956                         bp_.math_number_before = "default";
2957                         break;
2958         }
2959
2960         // Page Layout
2961         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
2962                 bp_.pagestyle = "default";
2963         else {
2964                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
2965                 for (size_t i = 0; i != pagestyles.size(); ++i)
2966                         if (pagestyles[i].second == style_gui)
2967                                 bp_.pagestyle = pagestyles[i].first;
2968         }
2969
2970         // Text Layout
2971         switch (textLayoutModule->lspacingCO->currentIndex()) {
2972         case 0:
2973                 bp_.spacing().set(Spacing::Single);
2974                 break;
2975         case 1:
2976                 bp_.spacing().set(Spacing::Onehalf);
2977                 break;
2978         case 2:
2979                 bp_.spacing().set(Spacing::Double);
2980                 break;
2981         case 3: {
2982                 string s = widgetToDoubleStr(textLayoutModule->lspacingLE);
2983                 if (s.empty())
2984                         bp_.spacing().set(Spacing::Single);
2985                 else
2986                         bp_.spacing().set(Spacing::Other, s);
2987                 break;
2988                 }
2989         }
2990
2991         if (textLayoutModule->twoColumnCB->isChecked())
2992                 bp_.columns = 2;
2993         else
2994                 bp_.columns = 1;
2995
2996         bp_.justification = textLayoutModule->justCB->isChecked();
2997
2998         if (textLayoutModule->indentRB->isChecked()) {
2999                 // if paragraphs are separated by an indentation
3000                 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
3001                 switch (textLayoutModule->indentCO->currentIndex()) {
3002                 case 0:
3003                         bp_.setParIndent(Length());
3004                         break;
3005                 case 1: {
3006                         Length parindent(widgetsToLength(textLayoutModule->indentLE,
3007                                                          textLayoutModule->indentLengthCO));
3008                         bp_.setParIndent(parindent);
3009                         break;
3010                 }
3011                 default:
3012                         // this should never happen
3013                         bp_.setParIndent(Length());
3014                         break;
3015                 }
3016         } else {
3017                 // if paragraphs are separated by a skip
3018                 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
3019                 switch (textLayoutModule->skipCO->currentIndex()) {
3020                 case 0:
3021                         bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
3022                         break;
3023                 case 1:
3024                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
3025                         break;
3026                 case 2:
3027                         bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
3028                         break;
3029                 case 3:
3030                         {
3031                         VSpace vs = VSpace(
3032                                 widgetsToLength(textLayoutModule->skipLE,
3033                                 textLayoutModule->skipLengthCO)
3034                                 );
3035                         bp_.setDefSkip(vs);
3036                         break;
3037                         }
3038                 default:
3039                         // this should never happen
3040                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
3041                         break;
3042                 }
3043         }
3044
3045         bp_.options =
3046                 fromqstr(latexModule->optionsLE->text());
3047
3048         bp_.use_default_options =
3049                 latexModule->defaultOptionsCB->isChecked();
3050
3051         if (latexModule->childDocGB->isChecked())
3052                 bp_.master =
3053                         fromqstr(latexModule->childDocLE->text());
3054         else
3055                 bp_.master = string();
3056
3057         // Master/Child
3058         bp_.clearIncludedChildren();
3059         if (masterChildModule->includeonlyRB->isChecked()) {
3060                 list<string>::const_iterator it = includeonlys_.begin();
3061                 for (; it != includeonlys_.end() ; ++it) {
3062                         bp_.addIncludedChildren(*it);
3063                 }
3064         }
3065         bp_.maintain_unincluded_children =
3066                 masterChildModule->maintainAuxCB->isChecked();
3067
3068         // Float Placement
3069         bp_.float_placement = floatModule->get();
3070
3071         // Listings
3072         // text should have passed validation
3073         bp_.listings_params =
3074                 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
3075
3076         // Formats
3077         bp_.default_output_format = fromqstr(outputModule->defaultFormatCO->itemData(
3078                 outputModule->defaultFormatCO->currentIndex()).toString());
3079
3080         bool const nontexfonts = fontModule->osFontsCB->isChecked();
3081         bp_.useNonTeXFonts = nontexfonts;
3082
3083         bp_.output_sync = outputModule->outputsyncCB->isChecked();
3084
3085         bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
3086
3087         int mathfmt = outputModule->mathoutCB->currentIndex();
3088         if (mathfmt == -1)
3089                 mathfmt = 0;
3090         BufferParams::MathOutput const mo =
3091                 static_cast<BufferParams::MathOutput>(mathfmt);
3092         bp_.html_math_output = mo;
3093         bp_.html_be_strict = outputModule->strictCB->isChecked();
3094         bp_.html_css_as_file = outputModule->cssCB->isChecked();
3095         bp_.html_math_img_scale = outputModule->mathimgSB->value();
3096         bp_.display_pixel_ratio = theGuiApp()->pixelRatio();
3097
3098         bp_.save_transient_properties =
3099                 outputModule->saveTransientPropertiesCB->isChecked();
3100
3101         // fonts
3102         bp_.fonts_roman[nontexfonts] =
3103                 fromqstr(fontModule->fontsRomanCO->
3104                         itemData(fontModule->fontsRomanCO->currentIndex()).toString());
3105         bp_.fonts_roman[!nontexfonts] = fromqstr(fontModule->font_roman);
3106
3107         bp_.fonts_sans[nontexfonts] =
3108                 fromqstr(fontModule->fontsSansCO->
3109                         itemData(fontModule->fontsSansCO->currentIndex()).toString());
3110         bp_.fonts_sans[!nontexfonts] = fromqstr(fontModule->font_sans);
3111
3112         bp_.fonts_typewriter[nontexfonts] =
3113                 fromqstr(fontModule->fontsTypewriterCO->
3114                         itemData(fontModule->fontsTypewriterCO->currentIndex()).toString());
3115         bp_.fonts_typewriter[!nontexfonts] = fromqstr(fontModule->font_typewriter);
3116
3117         bp_.fonts_math[nontexfonts] =
3118                 fromqstr(fontModule->fontsMathCO->
3119                         itemData(fontModule->fontsMathCO->currentIndex()).toString());
3120         bp_.fonts_math[!nontexfonts] = fromqstr(fontModule->font_math);
3121
3122         QString const fontenc =
3123                 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
3124         if (fontenc == "custom")
3125                 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
3126         else
3127                 bp_.fontenc = fromqstr(fontenc);
3128
3129         bp_.fonts_cjk =
3130                 fromqstr(fontModule->cjkFontLE->text());
3131
3132         bp_.use_microtype = fontModule->microtypeCB->isChecked();
3133         bp_.use_dash_ligatures = fontModule->dashesCB->isChecked();
3134
3135         bp_.fonts_sans_scale[nontexfonts] = fontModule->scaleSansSB->value();
3136         bp_.fonts_sans_scale[!nontexfonts] = fontModule->font_sf_scale;
3137
3138         bp_.fonts_typewriter_scale[nontexfonts] = fontModule->scaleTypewriterSB->value();
3139         bp_.fonts_typewriter_scale[!nontexfonts] = fontModule->font_tt_scale;
3140
3141         bp_.fonts_expert_sc = fontModule->fontScCB->isChecked();
3142
3143         bp_.fonts_old_figures = fontModule->fontOsfCB->isChecked();
3144
3145         if (nontexfonts)
3146                 bp_.fonts_default_family = "default";
3147         else
3148                 bp_.fonts_default_family = GuiDocument::fontfamilies[
3149                         fontModule->fontsDefaultCO->currentIndex()];
3150
3151         if (fontModule->fontsizeCO->currentIndex() == 0)
3152                 bp_.fontsize = "default";
3153         else
3154                 bp_.fontsize =
3155                         fromqstr(fontModule->fontsizeCO->currentText());
3156
3157         // paper
3158         bp_.papersize = PAPER_SIZE(
3159                 pageLayoutModule->papersizeCO->currentIndex());
3160
3161         bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
3162                 pageLayoutModule->paperwidthUnitCO);
3163
3164         bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
3165                 pageLayoutModule->paperheightUnitCO);
3166
3167         if (pageLayoutModule->facingPagesCB->isChecked())
3168                 bp_.sides = TwoSides;
3169         else
3170                 bp_.sides = OneSide;
3171
3172         if (pageLayoutModule->landscapeRB->isChecked())
3173                 bp_.orientation = ORIENTATION_LANDSCAPE;
3174         else
3175                 bp_.orientation = ORIENTATION_PORTRAIT;
3176
3177         // margins
3178         bp_.use_geometry = !marginsModule->marginCB->isChecked();
3179
3180         Ui::MarginsUi const * m = marginsModule;
3181
3182         bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
3183         bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
3184         bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
3185         bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
3186         bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
3187         bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
3188         bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
3189         bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
3190
3191         // branches
3192         branchesModule->apply(bp_);
3193
3194         // PDF support
3195         PDFOptions & pdf = bp_.pdfoptions();
3196         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
3197         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
3198         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
3199         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
3200         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
3201
3202         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
3203         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
3204         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
3205         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
3206
3207         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
3208         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
3209         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
3210         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
3211         pdf.backref =
3212                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
3213         if (pdfSupportModule->fullscreenCB->isChecked())
3214                 pdf.pagemode = pdf.pagemode_fullscreen;
3215         else
3216                 pdf.pagemode.clear();
3217         pdf.quoted_options = pdf.quoted_options_check(
3218                                 fromqstr(pdfSupportModule->optionsLE->text()));
3219
3220         // reset tracker
3221         nonModuleChanged_ = false;
3222 }
3223
3224
3225 void GuiDocument::paramsToDialog()
3226 {
3227         // set the default unit
3228         Length::UNIT const default_unit = Length::defaultUnit();
3229
3230         // preamble
3231         preambleModule->update(bp_, id());
3232         localLayout->update(bp_, id());
3233
3234         // date
3235         latexModule->suppressDateCB->setChecked(bp_.suppress_date);
3236         latexModule->refstyleCB->setChecked(bp_.use_refstyle);
3237
3238         // biblio
3239         string const cite_engine = bp_.citeEngine().list().front();
3240
3241         biblioModule->citeEngineCO->setCurrentIndex(
3242                 biblioModule->citeEngineCO->findData(toqstr(cite_engine)));
3243
3244         updateEngineType(documentClass().opt_enginetype(),
3245                 bp_.citeEngineType());
3246
3247         biblioModule->citeStyleCO->setCurrentIndex(
3248                 biblioModule->citeStyleCO->findData(bp_.citeEngineType()));
3249
3250         biblioModule->bibtopicCB->setChecked(bp_.splitbib());
3251
3252         biblioModule->bibunitsCO->clear();
3253         biblioModule->bibunitsCO->addItem(qt_("No"), QString());
3254         if (documentClass().hasLaTeXLayout("part"))
3255                 biblioModule->bibunitsCO->addItem(qt_("per part"), toqstr("part"));
3256         if (documentClass().hasLaTeXLayout("chapter"))
3257                 biblioModule->bibunitsCO->addItem(qt_("per chapter"), toqstr("chapter"));
3258         if (documentClass().hasLaTeXLayout("section"))
3259                 biblioModule->bibunitsCO->addItem(qt_("per section"), toqstr("section"));
3260         if (documentClass().hasLaTeXLayout("subsection"))
3261                 biblioModule->bibunitsCO->addItem(qt_("per subsection"), toqstr("subsection"));
3262         biblioModule->bibunitsCO->addItem(qt_("per child document"), toqstr("child"));
3263
3264         int const mbpos = biblioModule->bibunitsCO->findData(toqstr(bp_.multibib));
3265         if (mbpos != -1)
3266                 biblioModule->bibunitsCO->setCurrentIndex(mbpos);
3267         else
3268                 biblioModule->bibunitsCO->setCurrentIndex(0);
3269
3270         updateEngineDependends();
3271
3272         if (isBiblatex()) {
3273                 updateDefaultBiblio(bp_.biblatex_bibstyle, "bbx");
3274                 updateDefaultBiblio(bp_.biblatex_citestyle, "cbx");
3275         } else
3276                 updateDefaultBiblio(bp_.defaultBiblioStyle());
3277
3278         biblioModule->citePackageOptionsLE->setText(toqstr(bp_.biblio_opts));
3279
3280         string command;
3281         string options =
3282                 split(bp_.bibtex_command, command, ' ');
3283
3284         int const bpos = biblioModule->bibtexCO->findData(toqstr(command));
3285         if (bpos != -1) {
3286                 biblioModule->bibtexCO->setCurrentIndex(bpos);
3287                 biblioModule->bibtexOptionsLE->setText(toqstr(options).trimmed());
3288         } else {
3289                 // We reset to default if we do not know the specified compiler
3290                 // This is for security reasons
3291                 biblioModule->bibtexCO->setCurrentIndex(
3292                         biblioModule->bibtexCO->findData(toqstr("default")));
3293                 biblioModule->bibtexOptionsLE->clear();
3294         }
3295         biblioModule->bibtexOptionsLE->setEnabled(
3296                 biblioModule->bibtexCO->currentIndex() != 0);
3297
3298         biblioChanged_ = false;
3299
3300         // indices
3301         // We may be called when there is no Buffer, e.g., when 
3302         // the last view has just been closed.
3303         bool const isReadOnly = isBufferAvailable() ? buffer().isReadonly() : false;
3304         indicesModule->update(bp_, isReadOnly);
3305
3306         // language & quotes
3307         int const pos = langModule->languageCO->findData(toqstr(
3308                 bp_.language->lang()));
3309         langModule->languageCO->setCurrentIndex(pos);
3310
3311         updateQuoteStyles();
3312
3313         langModule->quoteStyleCO->setCurrentIndex(
3314                 langModule->quoteStyleCO->findData(bp_.quotes_style));
3315         langModule->dynamicQuotesCB->setChecked(bp_.dynamic_quotes);
3316
3317         bool default_enc = true;
3318         if (bp_.inputenc != "auto") {
3319                 default_enc = false;
3320                 if (bp_.inputenc == "default") {
3321                         langModule->encodingCO->setCurrentIndex(0);
3322                 } else {
3323                         string enc_gui;
3324                         Encodings::const_iterator it = encodings.begin();
3325                         Encodings::const_iterator const end = encodings.end();
3326                         for (; it != end; ++it) {
3327                                 if (it->name() == bp_.inputenc &&
3328                                     !it->unsafe()) {
3329                                         enc_gui = it->guiName();
3330                                         break;
3331                                 }
3332                         }
3333                         int const i = langModule->encodingCO->findText(
3334                                         qt_(enc_gui));
3335                         if (i >= 0)
3336                                 langModule->encodingCO->setCurrentIndex(i);
3337                         else
3338                                 // unknown encoding. Set to default.
3339                                 default_enc = true;
3340                 }
3341         }
3342         langModule->defaultencodingRB->setChecked(default_enc);
3343         langModule->otherencodingRB->setChecked(!default_enc);
3344
3345         int const p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
3346         if (p == -1) {
3347                 langModule->languagePackageCO->setCurrentIndex(
3348                           langModule->languagePackageCO->findData("custom"));
3349                 langModule->languagePackageLE->setText(toqstr(bp_.lang_package));
3350         } else {
3351                 langModule->languagePackageCO->setCurrentIndex(p);
3352                 langModule->languagePackageLE->clear();
3353         }
3354
3355         //color
3356         if (bp_.isfontcolor) {
3357                 colorModule->fontColorPB->setStyleSheet(
3358                         colorButtonStyleSheet(rgb2qcolor(bp_.fontcolor)));
3359         }
3360         set_fontcolor = bp_.fontcolor;
3361         is_fontcolor = bp_.isfontcolor;
3362
3363         colorModule->noteFontColorPB->setStyleSheet(
3364                 colorButtonStyleSheet(rgb2qcolor(bp_.notefontcolor)));
3365         set_notefontcolor = bp_.notefontcolor;
3366
3367         if (bp_.isbackgroundcolor) {
3368                 colorModule->backgroundPB->setStyleSheet(
3369                         colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
3370         }
3371         set_backgroundcolor = bp_.backgroundcolor;
3372         is_backgroundcolor = bp_.isbackgroundcolor;
3373
3374         colorModule->boxBackgroundPB->setStyleSheet(
3375                 colorButtonStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
3376         set_boxbgcolor = bp_.boxbgcolor;
3377
3378         // numbering
3379         int const min_toclevel = documentClass().min_toclevel();
3380         int const max_toclevel = documentClass().max_toclevel();
3381         if (documentClass().hasTocLevels()) {
3382                 numberingModule->setEnabled(true);
3383                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
3384                 numberingModule->depthSL->setMaximum(max_toclevel);
3385                 numberingModule->depthSL->setValue(bp_.secnumdepth);
3386                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
3387                 numberingModule->tocSL->setMaximum(max_toclevel);
3388                 numberingModule->tocSL->setValue(bp_.tocdepth);
3389                 updateNumbering();
3390         } else {
3391                 numberingModule->setEnabled(false);
3392                 numberingModule->tocTW->clear();
3393         }
3394
3395         // bullets
3396         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
3397         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
3398         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
3399         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
3400         bulletsModule->init();
3401
3402         // packages
3403         int nitem = findToken(tex_graphics, bp_.graphics_driver);
3404         if (nitem >= 0)
3405                 latexModule->psdriverCO->setCurrentIndex(nitem);
3406         updateModuleInfo();
3407
3408         // math
3409         mathsModule->MathIndentCB->setChecked(bp_.is_math_indent);
3410         if (bp_.is_math_indent) {
3411                 Length const mathindent = bp_.getMathIndent();
3412                 int indent = 0;
3413                 if (!mathindent.empty()) {
3414                         lengthToWidgets(mathsModule->MathIndentLE,
3415                                         mathsModule->MathIndentLengthCO,
3416                                         mathindent, default_unit);
3417                         indent = 1;
3418                 }
3419                 mathsModule->MathIndentCO->setCurrentIndex(indent);
3420                 enableMathIndent(indent);
3421         }
3422         if (bp_.math_number_before == "true")
3423                 mathsModule->MathNumberingPosCO->setCurrentIndex(0);
3424         else if (bp_.math_number_before == "default")
3425                 mathsModule->MathNumberingPosCO->setCurrentIndex(1);
3426         else if (bp_.math_number_before == "false")
3427                 mathsModule->MathNumberingPosCO->setCurrentIndex(2);
3428
3429         map<string, string> const & packages = BufferParams::auto_packages();
3430         for (map<string, string>::const_iterator it = packages.begin();
3431              it != packages.end(); ++it) {
3432                 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
3433                 if (!item)
3434                         continue;
3435                 int row = mathsModule->packagesTW->row(item);
3436                 switch (bp_.use_package(it->first)) {
3437                         case BufferParams::package_off: {
3438                                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3);
3439                                 rb->setChecked(true);
3440                                 break;
3441                         }
3442                         case BufferParams::package_on: {
3443                                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2);
3444                                 rb->setChecked(true);
3445                                 break;
3446                         }
3447                         case BufferParams::package_auto: {
3448                                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1);
3449                                 rb->setChecked(true);
3450                                 break;
3451                         }
3452                 }
3453         }
3454
3455         switch (bp_.spacing().getSpace()) {
3456                 case Spacing::Other: nitem = 3; break;
3457                 case Spacing::Double: nitem = 2; break;
3458                 case Spacing::Onehalf: nitem = 1; break;
3459                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
3460         }
3461
3462         // text layout
3463         string const & layoutID = bp_.baseClassID();
3464         setLayoutComboByIDString(layoutID);
3465
3466         updatePagestyle(documentClass().opt_pagestyle(),
3467                                  bp_.pagestyle);
3468
3469         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
3470         if (bp_.spacing().getSpace() == Spacing::Other) {
3471                 doubleToWidget(textLayoutModule->lspacingLE,
3472                         bp_.spacing().getValueAsString());
3473         }
3474         setLSpacing(nitem);
3475
3476         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
3477                 textLayoutModule->indentRB->setChecked(true);
3478                 string parindent = bp_.getParIndent().asString();
3479                 int indent = 0;
3480                 if (!parindent.empty()) {
3481                         lengthToWidgets(textLayoutModule->indentLE,
3482                                         textLayoutModule->indentLengthCO,
3483                                         parindent, default_unit);
3484                         indent = 1;
3485                 }
3486                 textLayoutModule->indentCO->setCurrentIndex(indent);
3487                 setIndent(indent);
3488         } else {
3489                 textLayoutModule->skipRB->setChecked(true);
3490                 int skip = 0;
3491                 switch (bp_.getDefSkip().kind()) {
3492                 case VSpace::SMALLSKIP:
3493                         skip = 0;
3494                         break;
3495                 case VSpace::MEDSKIP:
3496                         skip = 1;
3497                         break;
3498                 case VSpace::BIGSKIP:
3499                         skip = 2;
3500                         break;
3501                 case VSpace::LENGTH:
3502                         {
3503                         skip = 3;
3504                         string const length = bp_.getDefSkip().asLyXCommand();
3505                         lengthToWidgets(textLayoutModule->skipLE,
3506                                 textLayoutModule->skipLengthCO,
3507                                 length, default_unit);
3508                         break;
3509                         }
3510                 default:
3511                         skip = 0;
3512                         break;
3513                 }
3514                 textLayoutModule->skipCO->setCurrentIndex(skip);
3515                 setSkip(skip);
3516         }
3517
3518         textLayoutModule->twoColumnCB->setChecked(
3519                 bp_.columns == 2);
3520         textLayoutModule->justCB->setChecked(bp_.justification);
3521
3522         if (!bp_.options.empty()) {
3523                 latexModule->optionsLE->setText(
3524                         toqstr(bp_.options));
3525         } else {
3526                 latexModule->optionsLE->setText(QString());
3527         }
3528
3529         // latex
3530         latexModule->defaultOptionsCB->setChecked(
3531                         bp_.use_default_options);
3532         updateSelectedModules();
3533         selectionManager->updateProvidedModules(
3534                         bp_.baseClass()->providedModules());
3535         selectionManager->updateExcludedModules(
3536                         bp_.baseClass()->excludedModules());
3537
3538         if (!documentClass().options().empty()) {
3539                 latexModule->defaultOptionsLE->setText(
3540                         toqstr(documentClass().options()));
3541         } else {
3542                 latexModule->defaultOptionsLE->setText(
3543                         toqstr(_("[No options predefined]")));
3544         }
3545
3546         latexModule->defaultOptionsLE->setEnabled(
3547                 bp_.use_default_options
3548                 && !documentClass().options().empty());
3549
3550         latexModule->defaultOptionsCB->setEnabled(
3551                 !documentClass().options().empty());
3552
3553         if (!bp_.master.empty()) {
3554                 latexModule->childDocGB->setChecked(true);
3555                 latexModule->childDocLE->setText(
3556                         toqstr(bp_.master));
3557         } else {
3558                 latexModule->childDocLE->setText(QString());
3559                 latexModule->childDocGB->setChecked(false);
3560         }
3561
3562         // Master/Child
3563         if (!bufferview() || !buffer().hasChildren()) {
3564                 masterChildModule->childrenTW->clear();
3565                 includeonlys_.clear();
3566                 docPS->showPanel("Child Documents", false);
3567                 if (docPS->isCurrentPanel("Child Documents"))
3568                         docPS->setCurrentPanel("Document Class");
3569         } else {
3570                 docPS->showPanel("Child Documents", true);
3571                 masterChildModule->setEnabled(true);
3572                 includeonlys_ = bp_.getIncludedChildren();
3573                 updateIncludeonlys();
3574         }
3575         masterChildModule->maintainAuxCB->setChecked(
3576                 bp_.maintain_unincluded_children);
3577
3578         // Float Settings
3579         floatModule->set(bp_.float_placement);
3580
3581         // ListingsSettings
3582         // break listings_params to multiple lines
3583         string lstparams =
3584                 InsetListingsParams(bp_.listings_params).separatedParams();
3585         listingsModule->listingsED->setPlainText(toqstr(lstparams));
3586
3587         // Fonts
3588         // some languages only work with polyglossia/XeTeX
3589         Language const * lang = lyx::languages.getLanguage(
3590                 fromqstr(langModule->languageCO->itemData(
3591                         langModule->languageCO->currentIndex()).toString()));
3592         bool const need_fontspec =
3593                 lang->babel().empty() && !lang->polyglossia().empty();
3594         bool const os_fonts_available =
3595                 bp_.baseClass()->outputType() == lyx::LATEX
3596                 && LaTeXFeatures::isAvailable("fontspec");
3597         fontModule->osFontsCB->setEnabled(os_fonts_available && !need_fontspec);
3598         fontModule->osFontsCB->setChecked(
3599                 (os_fonts_available && bp_.useNonTeXFonts) || need_fontspec);
3600         updateFontsize(documentClass().opt_fontsize(),
3601                         bp_.fontsize);
3602
3603         QString font = toqstr(bp_.fontsRoman());
3604         int rpos = fontModule->fontsRomanCO->findData(font);
3605         if (rpos == -1) {
3606                 rpos = fontModule->fontsRomanCO->count();
3607                 fontModule->fontsRomanCO->addItem(font + qt_(" (not installed)"), font);
3608         }
3609         fontModule->fontsRomanCO->setCurrentIndex(rpos);
3610         fontModule->font_roman = toqstr(bp_.fonts_roman[!bp_.useNonTeXFonts]);
3611
3612         font = toqstr(bp_.fontsSans());
3613         int spos = fontModule->fontsSansCO->findData(font);
3614         if (spos == -1) {
3615                 spos = fontModule->fontsSansCO->count();
3616                 fontModule->fontsSansCO->addItem(font + qt_(" (not installed)"), font);
3617         }
3618         fontModule->fontsSansCO->setCurrentIndex(spos);
3619         fontModule->font_sans = toqstr(bp_.fonts_sans[!bp_.useNonTeXFonts]);
3620
3621         font = toqstr(bp_.fontsTypewriter());
3622         int tpos = fontModule->fontsTypewriterCO->findData(font);
3623         if (tpos == -1) {
3624                 tpos = fontModule->fontsTypewriterCO->count();
3625                 fontModule->fontsTypewriterCO->addItem(font + qt_(" (not installed)"), font);
3626         }
3627         fontModule->fontsTypewriterCO->setCurrentIndex(tpos);
3628         fontModule->font_typewriter = toqstr(bp_.fonts_typewriter[!bp_.useNonTeXFonts]);
3629
3630         font = toqstr(bp_.fontsMath());
3631         int mpos = fontModule->fontsMathCO->findData(font);
3632         if (mpos == -1) {
3633                 mpos = fontModule->fontsMathCO->count();
3634                 fontModule->fontsMathCO->addItem(font + qt_(" (not installed)"), font);
3635         }
3636         fontModule->fontsMathCO->setCurrentIndex(mpos);
3637         fontModule->font_math = toqstr(bp_.fonts_math[!bp_.useNonTeXFonts]);
3638
3639         if (bp_.useNonTeXFonts && os_fonts_available) {
3640                 fontModule->fontencLA->setEnabled(false);
3641                 fontModule->fontencCO->setEnabled(false);
3642                 fontModule->fontencLE->setEnabled(false);
3643         } else {
3644                 fontModule->fontencLA->setEnabled(true);
3645                 fontModule->fontencCO->setEnabled(true);
3646                 fontModule->fontencLE->setEnabled(true);
3647                 romanChanged(rpos);
3648                 sansChanged(spos);
3649                 ttChanged(tpos);
3650         }
3651
3652         if (!bp_.fonts_cjk.empty())
3653                 fontModule->cjkFontLE->setText(
3654                         toqstr(bp_.fonts_cjk));
3655         else
3656                 fontModule->cjkFontLE->setText(QString());
3657         
3658         fontModule->microtypeCB->setChecked(bp_.use_microtype);
3659         fontModule->dashesCB->setChecked(bp_.use_dash_ligatures);
3660
3661         fontModule->fontScCB->setChecked(bp_.fonts_expert_sc);
3662         fontModule->fontOsfCB->setChecked(bp_.fonts_old_figures);
3663         fontModule->scaleSansSB->setValue(bp_.fontsSansScale());
3664         fontModule->font_sf_scale = bp_.fonts_sans_scale[!bp_.useNonTeXFonts];
3665         fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale());
3666         fontModule->font_tt_scale = bp_.fonts_typewriter_scale[!bp_.useNonTeXFonts];
3667
3668         int nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
3669         if (nn >= 0)
3670                 fontModule->fontsDefaultCO->setCurrentIndex(nn);
3671
3672         if (bp_.fontenc == "global" || bp_.fontenc == "default") {
3673                 fontModule->fontencCO->setCurrentIndex(
3674                         fontModule->fontencCO->findData(toqstr(bp_.fontenc)));
3675                 fontModule->fontencLE->setEnabled(false);
3676         } else {
3677                 fontModule->fontencCO->setCurrentIndex(1);
3678                 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
3679         }
3680
3681         // Formats
3682         // This must be set _after_ fonts since updateDefaultFormat()
3683         // checks osFontsCB settings.
3684         // update combobox with formats
3685         updateDefaultFormat();
3686         int index = outputModule->defaultFormatCO->findData(toqstr(
3687                 bp_.default_output_format));
3688         // set to default if format is not found
3689         if (index == -1)
3690                 index = 0;
3691         outputModule->defaultFormatCO->setCurrentIndex(index);
3692
3693         outputModule->outputsyncCB->setChecked(bp_.output_sync);
3694         outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
3695
3696         outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
3697         outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
3698         outputModule->strictCB->setChecked(bp_.html_be_strict);
3699         outputModule->cssCB->setChecked(bp_.html_css_as_file);
3700
3701         outputModule->saveTransientPropertiesCB
3702                 ->setChecked(bp_.save_transient_properties);
3703
3704         // paper
3705         bool const extern_geometry =
3706                 documentClass().provides("geometry");
3707         int const psize = bp_.papersize;
3708         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
3709         setCustomPapersize(!extern_geometry && psize == 1);
3710         pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
3711
3712         bool const landscape =
3713                 bp_.orientation == ORIENTATION_LANDSCAPE;
3714         pageLayoutModule->landscapeRB->setChecked(landscape);
3715         pageLayoutModule->portraitRB->setChecked(!landscape);
3716         pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
3717         pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
3718
3719         pageLayoutModule->facingPagesCB->setChecked(
3720                 bp_.sides == TwoSides);
3721
3722         lengthToWidgets(pageLayoutModule->paperwidthLE,
3723                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, default_unit);
3724         lengthToWidgets(pageLayoutModule->paperheightLE,
3725                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, default_unit);
3726
3727         // margins
3728         Ui::MarginsUi * m = marginsModule;
3729
3730         setMargins();
3731
3732         lengthToWidgets(m->topLE, m->topUnit,
3733                 bp_.topmargin, default_unit);
3734
3735         lengthToWidgets(m->bottomLE, m->bottomUnit,
3736                 bp_.bottommargin, default_unit);
3737
3738         lengthToWidgets(m->innerLE, m->innerUnit,
3739                 bp_.leftmargin, default_unit);
3740
3741         lengthToWidgets(m->outerLE, m->outerUnit,
3742                 bp_.rightmargin, default_unit);
3743
3744         lengthToWidgets(m->headheightLE, m->headheightUnit,
3745                 bp_.headheight, default_unit);
3746
3747         lengthToWidgets(m->headsepLE, m->headsepUnit,
3748                 bp_.headsep, default_unit);
3749
3750         lengthToWidgets(m->footskipLE, m->footskipUnit,
3751                 bp_.footskip, default_unit);
3752
3753         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
3754                 bp_.columnsep, default_unit);
3755
3756         // branches
3757         updateUnknownBranches();
3758         branchesModule->update(bp_);
3759
3760         // PDF support
3761         PDFOptions const & pdf = bp_.pdfoptions();
3762         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
3763         if (bp_.documentClass().provides("hyperref"))
3764                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("C&ustomize Hyperref Options"));
3765         else
3766                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("&Use Hyperref Support"));
3767         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
3768         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
3769         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
3770         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
3771
3772         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
3773         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
3774         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
3775
3776         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
3777
3778         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
3779         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
3780         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
3781         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
3782
3783         nn = findToken(backref_opts, pdf.backref);
3784         if (nn >= 0)
3785                 pdfSupportModule->backrefCO->setCurrentIndex(nn);
3786
3787         pdfSupportModule->fullscreenCB->setChecked
3788                 (pdf.pagemode == pdf.pagemode_fullscreen);
3789
3790         pdfSupportModule->optionsLE->setText(
3791                 toqstr(pdf.quoted_options));
3792
3793         // Make sure that the bc is in the INITIAL state
3794         if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
3795                 bc().restore();
3796
3797         // clear changed branches cache
3798         changedBranches_.clear();
3799
3800         // reset tracker
3801         nonModuleChanged_ = false;
3802 }
3803
3804
3805 void GuiDocument::saveDocDefault()
3806 {
3807         // we have to apply the params first
3808         applyView();
3809         saveAsDefault();
3810 }
3811
3812
3813 void GuiDocument::updateAvailableModules()
3814 {
3815         modules_av_model_.clear();
3816         list<modInfoStruct> modInfoList = getModuleInfo();
3817         // Sort names according to the locale
3818         modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
3819                         return 0 < b.name.localeAwareCompare(a.name);
3820                 });
3821         int i = 0;
3822         for (modInfoStruct const & m : modInfoList) {
3823                 modules_av_model_.insertRow(i, m.name, m.id, m.description);
3824                 ++i;
3825         }
3826 }
3827
3828
3829 void GuiDocument::updateSelectedModules()
3830 {
3831         modules_sel_model_.clear();
3832         list<modInfoStruct> const selModList = getSelectedModules();
3833         int i = 0;
3834         for (modInfoStruct const & m : selModList) {
3835                 modules_sel_model_.insertRow(i, m.name, m.id, m.description);
3836                 ++i;
3837         }
3838 }
3839
3840
3841 void GuiDocument::updateIncludeonlys()
3842 {
3843         masterChildModule->childrenTW->clear();
3844         QString const no = qt_("No");
3845         QString const yes = qt_("Yes");
3846
3847         if (includeonlys_.empty()) {
3848                 masterChildModule->includeallRB->setChecked(true);
3849                 masterChildModule->childrenTW->setEnabled(false);
3850                 masterChildModule->maintainAuxCB->setEnabled(false);
3851         } else {
3852                 masterChildModule->includeonlyRB->setChecked(true);
3853                 masterChildModule->childrenTW->setEnabled(true);
3854                 masterChildModule->maintainAuxCB->setEnabled(true);
3855         }
3856         ListOfBuffers children = buffer().getChildren();
3857         ListOfBuffers::const_iterator it  = children.begin();
3858         ListOfBuffers::const_iterator end = children.end();
3859         bool has_unincluded = false;
3860         bool all_unincluded = true;
3861         for (; it != end; ++it) {
3862                 QTreeWidgetItem * item = new QTreeWidgetItem(masterChildModule->childrenTW);
3863                 // FIXME Unicode
3864                 string const name =
3865                         to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
3866                                                         from_utf8(buffer().filePath())));
3867                 item->setText(0, toqstr(name));
3868                 item->setText(1, isChildIncluded(name) ? yes : no);
3869                 if (!isChildIncluded(name))
3870                         has_unincluded = true;
3871                 else
3872                         all_unincluded = false;
3873         }
3874         // Both if all childs are included and if none is included
3875         // is equal to "include all" (i.e., ommit \includeonly).
3876         // Thus, reset the GUI.
3877         if (!has_unincluded || all_unincluded) {
3878                 masterChildModule->includeallRB->setChecked(true);
3879                 masterChildModule->childrenTW->setEnabled(false);
3880                 includeonlys_.clear();
3881         }
3882         // If all are included, we need to update again.
3883         if (!has_unincluded)
3884                 updateIncludeonlys();
3885 }
3886
3887
3888 bool GuiDocument::isBiblatex() const
3889 {
3890         QString const engine =
3891                 biblioModule->citeEngineCO->itemData(
3892                                 biblioModule->citeEngineCO->currentIndex()).toString();
3893
3894         return theCiteEnginesList[fromqstr(engine)]->getCiteFramework() == "biblatex";
3895 }
3896
3897
3898 void GuiDocument::updateDefaultBiblio(string const & style,
3899                                       string const & which)
3900 {
3901         QString const bibstyle = toqstr(style);
3902         biblioModule->defaultBiblioCO->clear();
3903
3904         int item_nr = -1;
3905
3906         if (isBiblatex()) {
3907                 if (which != "cbx") {
3908                         // First the bbx styles
3909                         biblioModule->biblatexBbxCO->clear();
3910                         QStringList str = texFileList("bbxFiles.lst");
3911                         // test whether we have a valid list, otherwise run rescan
3912                         if (str.isEmpty()) {
3913                                 rescanTexStyles("bbx");
3914                                 str = texFileList("bbxFiles.lst");
3915                         }
3916                         for (int i = 0; i != str.size(); ++i)
3917                                 str[i] = onlyFileName(str[i]);
3918                         // sort on filename only (no path)
3919                         str.sort();
3920
3921                         for (int i = 0; i != str.count(); ++i) {
3922                                 QString item = changeExtension(str[i], "");
3923                                 if (item == bibstyle)
3924                                         item_nr = i;
3925                                 biblioModule->biblatexBbxCO->addItem(item);
3926                         }
3927
3928                         if (item_nr == -1 && !bibstyle.isEmpty()) {
3929                                 biblioModule->biblatexBbxCO->addItem(bibstyle);
3930                                 item_nr = biblioModule->biblatexBbxCO->count() - 1;
3931                         }
3932
3933                         if (item_nr != -1)
3934                                 biblioModule->biblatexBbxCO->setCurrentIndex(item_nr);
3935                         else
3936                                 biblioModule->biblatexBbxCO->clearEditText();
3937                 }
3938
3939                 if (which != "bbx") {
3940                         // now the cbx styles
3941                         biblioModule->biblatexCbxCO->clear();
3942                         QStringList str = texFileList("cbxFiles.lst");
3943                         // test whether we have a valid list, otherwise run rescan
3944                         if (str.isEmpty()) {
3945                                 rescanTexStyles("cbx");
3946                                 str = texFileList("cbxFiles.lst");
3947                         }
3948                         for (int i = 0; i != str.size(); ++i)
3949                                 str[i] = onlyFileName(str[i]);
3950                         // sort on filename only (no path)
3951                         str.sort();
3952
3953                         for (int i = 0; i != str.count(); ++i) {
3954                                 QString item = changeExtension(str[i], "");
3955                                 if (item == bibstyle)
3956                                         item_nr = i;
3957                                 biblioModule->biblatexCbxCO->addItem(item);
3958                         }
3959
3960                         if (item_nr == -1 && !bibstyle.isEmpty()) {
3961                                 biblioModule->biblatexCbxCO->addItem(bibstyle);
3962                                 item_nr = biblioModule->biblatexCbxCO->count() - 1;
3963                         }
3964
3965                         if (item_nr != -1)
3966                                 biblioModule->biblatexCbxCO->setCurrentIndex(item_nr);
3967                         else
3968                                 biblioModule->biblatexCbxCO->clearEditText();
3969                 }
3970         } else {// BibTeX
3971                 biblioModule->biblatexBbxCO->clear();
3972                 biblioModule->biblatexCbxCO->clear();
3973                 QStringList str = texFileList("bstFiles.lst");
3974                 // test whether we have a valid list, otherwise run rescan
3975                 if (str.isEmpty()) {
3976                         rescanTexStyles("bst");
3977                         str = texFileList("bstFiles.lst");
3978                 }
3979                 for (int i = 0; i != str.size(); ++i)
3980                         str[i] = onlyFileName(str[i]);
3981                 // sort on filename only (no path)
3982                 str.sort();
3983
3984                 for (int i = 0; i != str.count(); ++i) {
3985                         QString item = changeExtension(str[i], "");
3986                         if (item == bibstyle)
3987                                 item_nr = i;
3988                         biblioModule->defaultBiblioCO->addItem(item);
3989                 }
3990
3991                 if (item_nr == -1 && !bibstyle.isEmpty()) {
3992                         biblioModule->defaultBiblioCO->addItem(bibstyle);
3993                         item_nr = biblioModule->defaultBiblioCO->count() - 1;
3994                 }
3995
3996                 if (item_nr != -1)
3997                         biblioModule->defaultBiblioCO->setCurrentIndex(item_nr);
3998                 else
3999                         biblioModule->defaultBiblioCO->clearEditText();
4000         }
4001
4002         updateResetDefaultBiblio();
4003 }
4004
4005
4006 void GuiDocument::updateResetDefaultBiblio()
4007 {
4008         QString const engine =
4009                 biblioModule->citeEngineCO->itemData(
4010                                 biblioModule->citeEngineCO->currentIndex()).toString();
4011         CiteEngineType const cet =
4012                 CiteEngineType(biblioModule->citeStyleCO->itemData(
4013                                                           biblioModule->citeStyleCO->currentIndex()).toInt());
4014
4015         string const defbib = theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet);
4016         if (isBiblatex()) {
4017                 QString const bbx = biblioModule->biblatexBbxCO->currentText();
4018                 QString const cbx = biblioModule->biblatexCbxCO->currentText();
4019                 biblioModule->resetCbxPB->setEnabled(defbib != fromqstr(cbx));
4020                 biblioModule->resetBbxPB->setEnabled(defbib != fromqstr(bbx));
4021                 biblioModule->matchBbxPB->setEnabled(bbx != cbx && !cbx.isEmpty()
4022                         && biblioModule->biblatexBbxCO->findText(cbx) != -1);
4023         } else
4024                 biblioModule->resetDefaultBiblioPB->setEnabled(
4025                         defbib != fromqstr(biblioModule->defaultBiblioCO->currentText()));
4026 }
4027
4028
4029 void GuiDocument::matchBiblatexStyles()
4030 {
4031         updateDefaultBiblio(fromqstr(biblioModule->biblatexCbxCO->currentText()), "bbx");
4032         biblioChanged();
4033 }
4034
4035
4036 void GuiDocument::updateContents()
4037 {
4038         // Nothing to do here as the document settings is not cursor dependant.
4039         return;
4040 }
4041
4042
4043 void GuiDocument::useClassDefaults()
4044 {
4045         if (applyPB->isEnabled()) {
4046                 int const ret = Alert::prompt(_("Unapplied changes"),
4047                                 _("Some changes in the dialog were not yet applied.\n"
4048                                   "If you do not apply now, they will be lost after this action."),
4049                                 1, 1, _("&Apply"), _("&Dismiss"));
4050                 if (ret == 0)
4051                         applyView();
4052         }
4053
4054         int idx = latexModule->classCO->currentIndex();
4055         string const classname = fromqstr(latexModule->classCO->getData(idx));
4056         if (!bp_.setBaseClass(classname)) {
4057                 Alert::error(_("Error"), _("Unable to set document class."));
4058                 return;
4059         }
4060         bp_.useClassDefaults();
4061         paramsToDialog();
4062 }
4063
4064
4065 void GuiDocument::setLayoutComboByIDString(string const & idString)
4066 {
4067         if (!latexModule->classCO->set(toqstr(idString)))
4068                 Alert::warning(_("Can't set layout!"),
4069                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
4070 }
4071
4072
4073 bool GuiDocument::isValid()
4074 {
4075         return
4076                 validateListingsParameters().isEmpty() &&
4077                 localLayout->isValid() &&
4078                 (
4079                         // if we're asking for skips between paragraphs
4080                         !textLayoutModule->skipRB->isChecked() ||
4081                         // then either we haven't chosen custom
4082                         textLayoutModule->skipCO->currentIndex() != 3 ||
4083                         // or else a length has been given
4084                         !textLayoutModule->skipLE->text().isEmpty()
4085                 ) &&
4086                 (
4087                         // if we're asking for indentation
4088                         !textLayoutModule->indentRB->isChecked() ||
4089                         // then either we haven't chosen custom
4090                         textLayoutModule->indentCO->currentIndex() != 1 ||
4091                         // or else a length has been given
4092                         !textLayoutModule->indentLE->text().isEmpty()
4093                 ) &&
4094                 (
4095                         // if we're asking for math indentation
4096                         !mathsModule->MathIndentCB->isChecked() ||
4097                         // then either we haven't chosen custom
4098                         mathsModule->MathIndentCO->currentIndex() != 1 ||
4099                         // or else a length has been given
4100                         !mathsModule->MathIndentLE->text().isEmpty()
4101                 );
4102 }
4103
4104
4105 char const * const GuiDocument::fontfamilies[5] = {
4106         "default", "rmdefault", "sfdefault", "ttdefault", ""
4107 };
4108
4109
4110 char const * GuiDocument::fontfamilies_gui[5] = {
4111         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
4112 };
4113
4114
4115 bool GuiDocument::initialiseParams(string const &)
4116 {
4117         BufferView const * view = bufferview();
4118         if (!view) {
4119                 bp_ = BufferParams();
4120                 paramsToDialog();
4121                 return true;
4122         }
4123         bp_ = view->buffer().params();
4124         loadModuleInfo();
4125         updateAvailableModules();
4126         //FIXME It'd be nice to make sure here that the selected
4127         //modules are consistent: That required modules are actually
4128         //selected, and that we don't have conflicts. If so, we could
4129         //at least pop up a warning.
4130         paramsToDialog();
4131         return true;
4132 }
4133
4134
4135 void GuiDocument::clearParams()
4136 {
4137         bp_ = BufferParams();
4138 }
4139
4140
4141 BufferId GuiDocument::id() const
4142 {
4143         BufferView const * const view = bufferview();
4144         return view? &view->buffer() : 0;
4145 }
4146
4147
4148 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
4149 {
4150         return moduleNames_;
4151 }
4152
4153
4154 list<GuiDocument::modInfoStruct> const
4155 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
4156 {
4157         list<modInfoStruct> mInfo;
4158         for (string const & name : mods) {
4159                 modInfoStruct m;
4160                 LyXModule const * const mod = theModuleList[name];
4161                 if (mod)
4162                         m = modInfo(*mod);
4163                 else {
4164                         m.id = name;
4165                         m.name = toqstr(name + " (") + qt_("Not Found") + toqstr(")");
4166                 }
4167                 mInfo.push_back(m);
4168         }
4169         return mInfo;
4170 }
4171
4172
4173 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
4174 {
4175         return makeModuleInfo(params().getModules());
4176 }
4177
4178
4179 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
4180 {
4181         return makeModuleInfo(params().baseClass()->providedModules());
4182 }
4183
4184
4185 DocumentClass const & GuiDocument::documentClass() const
4186 {
4187         return bp_.documentClass();
4188 }
4189
4190
4191 static void dispatch_bufferparams(Dialog const & dialog,
4192         BufferParams const & bp, FuncCode lfun, Buffer const * buf)
4193 {
4194         ostringstream ss;
4195         ss << "\\begin_header\n";
4196         bp.writeFile(ss, buf);
4197         ss << "\\end_header\n";
4198         dialog.dispatch(FuncRequest(lfun, ss.str()));
4199 }
4200
4201
4202 void GuiDocument::dispatchParams()
4203 {
4204         // We need a non-const buffer object.
4205         Buffer & buf = const_cast<BufferView *>(bufferview())->buffer();
4206         // There may be several undo records; group them (bug #8998)
4207         buf.undo().beginUndoGroup();
4208
4209         // This must come first so that a language change is correctly noticed
4210         setLanguage();
4211
4212         // Apply the BufferParams. Note that this will set the base class
4213         // and then update the buffer's layout.
4214         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY, &buffer());
4215
4216         if (!params().master.empty()) {
4217                 FileName const master_file = support::makeAbsPath(params().master,
4218                            support::onlyPath(buffer().absFileName()));
4219                 if (isLyXFileName(master_file.absFileName())) {
4220                         Buffer * master = checkAndLoadLyXFile(master_file);
4221                         if (master) {
4222                                 if (master->isChild(const_cast<Buffer *>(&buffer())))
4223                                         const_cast<Buffer &>(buffer()).setParent(master);
4224                                 else
4225                                         Alert::warning(_("Assigned master does not include this file"),
4226                                                 bformat(_("You must include this file in the document\n"
4227                                                           "'%1$s' in order to use the master document\n"
4228                                                           "feature."), from_utf8(params().master)));
4229                         } else
4230                                 Alert::warning(_("Could not load master"),
4231                                                 bformat(_("The master document '%1$s'\n"
4232                                                            "could not be loaded."),
4233                                                            from_utf8(params().master)));
4234                 }
4235         }
4236
4237         // Generate the colours requested by each new branch.
4238         BranchList & branchlist = params().branchlist();
4239         if (!branchlist.empty()) {
4240                 BranchList::const_iterator it = branchlist.begin();
4241                 BranchList::const_iterator const end = branchlist.end();
4242                 for (; it != end; ++it) {
4243                         docstring const & current_branch = it->branch();
4244                         Branch const * branch = branchlist.find(current_branch);
4245                         string const x11hexname = X11hexname(branch->color());
4246                         // display the new color
4247                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
4248                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
4249                 }
4250         }
4251         // rename branches in the document
4252         executeBranchRenaming();
4253         // and clear changed branches cache
4254         changedBranches_.clear();
4255
4256         // Generate the colours requested by indices.
4257         IndicesList & indiceslist = params().indiceslist();
4258         if (!indiceslist.empty()) {
4259                 IndicesList::const_iterator it = indiceslist.begin();
4260                 IndicesList::const_iterator const end = indiceslist.end();
4261                 for (; it != end; ++it) {
4262                         docstring const & current_index = it->shortcut();
4263                         Index const * index = indiceslist.findShortcut(current_index);
4264                         string const x11hexname = X11hexname(index->color());
4265                         // display the new color
4266                         docstring const str = current_index + ' ' + from_ascii(x11hexname);
4267                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
4268                 }
4269         }
4270         // FIXME LFUN
4271         // If we used an LFUN, we would not need these two lines:
4272         BufferView * bv = const_cast<BufferView *>(bufferview());
4273         bv->processUpdateFlags(Update::Force | Update::FitCursor);
4274
4275         // Don't forget to close the group. Note that it is important
4276         // to check that there is no early return in the method.
4277         buf.undo().endUndoGroup();
4278 }
4279
4280
4281 void GuiDocument::setLanguage() const
4282 {
4283         Language const * const newL = bp_.language;
4284         if (buffer().params().language == newL)
4285                 return;
4286
4287         string const & lang_name = newL->lang();
4288         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
4289 }
4290
4291
4292 void GuiDocument::saveAsDefault() const
4293 {
4294         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT, &buffer());
4295 }
4296
4297
4298 bool GuiDocument::providesOSF(QString const & font) const
4299 {
4300         if (fontModule->osFontsCB->isChecked())
4301                 // FIXME: we should check if the fonts really
4302                 // have OSF support. But how?
4303                 return true;
4304         return theLaTeXFonts().getLaTeXFont(
4305                                 qstring_to_ucs4(font)).providesOSF(ot1(),
4306                                                                    completeFontset(),
4307                                                                    noMathFont());
4308 }
4309
4310
4311 bool GuiDocument::providesSC(QString const & font) const
4312 {
4313         if (fontModule->osFontsCB->isChecked())
4314                 return false;
4315         return theLaTeXFonts().getLaTeXFont(
4316                                 qstring_to_ucs4(font)).providesSC(ot1(),
4317                                                                   completeFontset(),
4318                                                                   noMathFont());
4319 }
4320
4321
4322 bool GuiDocument::providesScale(QString const & font) const
4323 {
4324         if (fontModule->osFontsCB->isChecked())
4325                 return true;
4326         return theLaTeXFonts().getLaTeXFont(
4327                                 qstring_to_ucs4(font)).providesScale(ot1(),
4328                                                                      completeFontset(),
4329                                                                      noMathFont());
4330 }
4331
4332
4333 bool GuiDocument::providesNoMath(QString const & font) const
4334 {
4335         if (fontModule->osFontsCB->isChecked())
4336                 return false;
4337         return theLaTeXFonts().getLaTeXFont(
4338                                 qstring_to_ucs4(font)).providesNoMath(ot1(),
4339                                                                       completeFontset());
4340 }
4341
4342
4343 bool GuiDocument::hasMonolithicExpertSet(QString const & font) const
4344 {
4345         if (fontModule->osFontsCB->isChecked())
4346                 return false;
4347         return theLaTeXFonts().getLaTeXFont(
4348                                 qstring_to_ucs4(font)).hasMonolithicExpertSet(ot1(),
4349                                                                               completeFontset(),
4350                                                                               noMathFont());
4351 }
4352
4353
4354 //static
4355 GuiDocument::modInfoStruct GuiDocument::modInfo(LyXModule const & mod)
4356 {
4357         // FIXME Unicode: docstrings would be better for these parameters but this
4358         // change requires a lot of others
4359         modInfoStruct m;
4360         m.id = mod.getID();
4361         m.name = toqstr(translateIfPossible(from_utf8(mod.getName())));
4362         QString desc = toqstr(translateIfPossible(from_utf8(mod.getDescription())));
4363         // Find the first sentence of the description
4364         QTextBoundaryFinder bf(QTextBoundaryFinder::Sentence, desc);
4365         int pos = bf.toNextBoundary();
4366         if (pos > 0)
4367                 desc.truncate(pos);
4368         QString modulename = QString(qt_("(Module name: %1)")).arg(toqstr(m.id));
4369         // Tooltip is the desc followed by the module name
4370         m.description = QString("%1<i>%2</i>")
4371                 .arg(desc.isEmpty() ? QString() : QString("<p>%1</p>").arg(desc),
4372                      modulename);
4373         return m;
4374 }
4375
4376
4377 void GuiDocument::loadModuleInfo()
4378 {
4379         moduleNames_.clear();
4380         for (LyXModule const & mod : theModuleList)
4381                 if (mod.category().substr(0, 8) != "Citation")
4382                         moduleNames_.push_back(modInfo(mod));
4383 }
4384
4385
4386 void GuiDocument::updateUnknownBranches()
4387 {
4388         if (!bufferview())
4389                 return;
4390         list<docstring> used_branches;
4391         buffer().getUsedBranches(used_branches);
4392         list<docstring>::const_iterator it = used_branches.begin();
4393         QStringList unknown_branches;
4394         for (; it != used_branches.end() ; ++it) {
4395                 if (!buffer().params().branchlist().find(*it))
4396                         unknown_branches.append(toqstr(*it));
4397         }
4398         branchesModule->setUnknownBranches(unknown_branches);
4399 }
4400
4401
4402 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
4403 {
4404         map<docstring, docstring>::iterator it = changedBranches_.begin();
4405         for (; it != changedBranches_.end() ; ++it) {
4406                 if (it->second == oldname) {
4407                         // branch has already been renamed
4408                         it->second = newname;
4409                         return;
4410                 }
4411         }
4412         // store new name
4413         changedBranches_[oldname] = newname;
4414 }
4415
4416
4417 void GuiDocument::executeBranchRenaming() const
4418 {
4419         map<docstring, docstring>::const_iterator it = changedBranches_.begin();
4420         for (; it != changedBranches_.end() ; ++it) {
4421                 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
4422                 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
4423         }
4424 }
4425
4426
4427 void GuiDocument::allPackagesAuto()
4428 {
4429         allPackages(1);
4430 }
4431
4432
4433 void GuiDocument::allPackagesAlways()
4434 {
4435         allPackages(2);
4436 }
4437
4438
4439 void GuiDocument::allPackagesNot()
4440 {
4441         allPackages(3);
4442 }
4443
4444
4445 void GuiDocument::allPackages(int col)
4446 {
4447         for (int row = 0; row < mathsModule->packagesTW->rowCount(); ++row) {
4448                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, col);
4449                 rb->setChecked(true);
4450         }
4451 }
4452
4453
4454 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
4455
4456
4457 } // namespace frontend
4458 } // namespace lyx
4459
4460 #include "moc_GuiDocument.cpp"