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