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