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