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