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