]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiDocument.cpp
Introducing table templates
[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         // Flashy red bold text
636         static const QString ivpar("<p style=\"color: #c00000; font-weight: bold; text-align:left\">"
637                                    "%1</p>");
638         static const QString message = ivpar.arg(qt_("Validation required!"));
639         string const layout =
640                 fromqstr(locallayoutTE->document()->toPlainText().trimmed());
641
642         if (layout.empty()) {
643                 validated_ = true;
644                 validatePB->setEnabled(false);
645                 validLB->setText("");
646                 hideConvert();
647                 changed();
648         } else if (!validatePB->isEnabled()) {
649                 // if that's already enabled, we shouldn't need to do anything.
650                 validated_ = false;
651                 validLB->setText(message);
652                 validatePB->setEnabled(true);
653                 hideConvert();
654                 changed();
655         }
656 }
657
658
659 void LocalLayout::convert() {
660         string const layout =
661                 fromqstr(locallayoutTE->document()->toPlainText().trimmed());
662         string const newlayout = TextClass::convert(layout);
663         if (!newlayout.empty())
664                 locallayoutTE->setPlainText(toqstr(newlayout));
665         validate();
666 }
667
668
669 void LocalLayout::convertPressed() {
670         convert();
671         hideConvert();
672         changed();
673 }
674
675
676 void LocalLayout::validate() {
677         // Bold text
678         static const QString vpar("<p style=\"font-weight: bold; text-align:left\">%1</p>");
679         // Flashy red bold text
680         static const QString ivpar("<p style=\"color: #c00000; font-weight: bold; text-align:left\">"
681                                    "%1</p>");
682         string const layout =
683                 fromqstr(locallayoutTE->document()->toPlainText().trimmed());
684         if (!layout.empty()) {
685                 TextClass::ReturnValues const ret = TextClass::validate(layout);
686                 validated_ = (ret == TextClass::OK) || (ret == TextClass::OK_OLDFORMAT);
687                 validatePB->setEnabled(false);
688                 validLB->setText(validated_ ? vpar.arg(qt_("Layout is valid!"))
689                                             : ivpar.arg(qt_("Layout is invalid!")));
690                 if (ret == TextClass::OK_OLDFORMAT) {
691                         convertPB->show();
692                         // Testing conversion to LYXFILE_LAYOUT_FORMAT at this point
693                         // already.
694                         if (TextClass::convert(layout).empty()) {
695                                 // Conversion failed. If LAYOUT_FORMAT > LYXFILE_LAYOUT_FORMAT,
696                                 // then maybe the layout is still valid, but its format is more
697                                 // recent than LYXFILE_LAYOUT_FORMAT. However, if LAYOUT_FORMAT
698                                 // == LYXFILE_LAYOUT_FORMAT then something is definitely wrong.
699                                 convertPB->setEnabled(false);
700                                 const QString text = (LAYOUT_FORMAT == LYXFILE_LAYOUT_FORMAT)
701                                         ? ivpar.arg(qt_("Conversion to current format impossible!"))
702                                         : vpar.arg(qt_("Conversion to current stable format "
703                                                        "impossible."));
704                                 convertLB->setText(text);
705                         } else {
706                                 convertPB->setEnabled(true);
707                                 convertLB->setText(qt_("Convert to current format"));
708                         }
709                         convertLB->show();
710                 } else {
711                         convertPB->hide();
712                         convertLB->hide();
713                 }
714         }
715 }
716
717
718 void LocalLayout::validatePressed() {
719         validate();
720         changed();
721 }
722
723
724 void LocalLayout::editExternal() {
725         if (!current_id_)
726                 return;
727
728         if (tempfile_) {
729                 locallayoutTE->setReadOnly(false);
730                 FileName const tempfilename = tempfile_->name();
731                 docstring const s = tempfilename.fileContents("UTF-8");
732                 locallayoutTE->document()->setPlainText(toqstr(s));
733                 tempfile_.reset();
734                 editPB->setText(qt_("&Edit"));
735                 changed();
736                 return;
737         }
738
739         string const format =
740                 current_id_->params().documentClass().outputFormat();
741         string const ext = theFormats().extension(format);
742         tempfile_.reset(new TempFile("preamble_editXXXXXX." + ext));
743         FileName const tempfilename = tempfile_->name();
744         string const name = tempfilename.toFilesystemEncoding();
745         ofdocstream os(name.c_str());
746         os << qstring_to_ucs4(locallayoutTE->document()->toPlainText());
747         os.close();
748         locallayoutTE->setReadOnly(true);
749         theFormats().edit(*current_id_, tempfilename, format);
750         editPB->setText(qt_("&End Edit"));
751         validatePB->setEnabled(false);
752         hideConvert();
753         changed();
754 }
755
756 /////////////////////////////////////////////////////////////////////
757 //
758 // DocumentDialog
759 //
760 /////////////////////////////////////////////////////////////////////
761
762
763 GuiDocument::GuiDocument(GuiView & lv)
764         : GuiDialog(lv, "document", qt_("Document Settings")),
765           biblioChanged_(false), nonModuleChanged_(false),
766           modulesChanged_(false), shellescapeChanged_(false)
767 {
768         setupUi(this);
769
770         connect(buttonBox, SIGNAL(clicked(QAbstractButton *)),
771                 this, SLOT(slotButtonBox(QAbstractButton *)));
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(buttonBox->button(QDialogButtonBox::Ok));
779         bc().setApply(buttonBox->button(QDialogButtonBox::Apply));
780         bc().setCancel(buttonBox->button(QDialogButtonBox::Cancel));
781         bc().setRestore(buttonBox->button(QDialogButtonBox::Reset));
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::slotButtonBox(QAbstractButton * button)
1696 {
1697         switch (buttonBox->standardButton(button)) {
1698         case QDialogButtonBox::Ok:
1699                 slotOK();
1700                 break;
1701         case QDialogButtonBox::Apply:
1702                 slotApply();
1703                 break;
1704         case QDialogButtonBox::Cancel:
1705                 slotClose();
1706                 break;
1707         case QDialogButtonBox::Reset:
1708         case QDialogButtonBox::RestoreDefaults:
1709                 slotRestore();
1710                 break;
1711         default:
1712                 break;
1713         }
1714 }
1715
1716
1717 void GuiDocument::includeonlyClicked(QTreeWidgetItem * item, int)
1718 {
1719         if (item == 0)
1720                 return;
1721
1722         string child = fromqstr(item->text(0));
1723         if (child.empty())
1724                 return;
1725
1726         if (std::find(includeonlys_.begin(),
1727                       includeonlys_.end(), child) != includeonlys_.end())
1728                 includeonlys_.remove(child);
1729         else
1730                 includeonlys_.push_back(child);
1731
1732         updateIncludeonlys();
1733         change_adaptor();
1734 }
1735
1736
1737 QString GuiDocument::validateListingsParameters()
1738 {
1739         if (listingsModule->bypassCB->isChecked())
1740                 return QString();
1741         string const package =
1742             lst_packages[listingsModule->packageCO->currentIndex()];
1743         string params = fromqstr(listingsModule->listingsED->toPlainText());
1744         InsetListingsParams lstparams(params);
1745         lstparams.setMinted(package == "Minted");
1746         return toqstr(lstparams.validate());
1747 }
1748
1749
1750 void GuiDocument::setListingsMessage()
1751 {
1752         // FIXME THREAD
1753         static bool isOK = true;
1754         QString msg = validateListingsParameters();
1755         if (msg.isEmpty()) {
1756                 if (isOK)
1757                         return;
1758                 isOK = true;
1759                 // listingsTB->setTextColor("black");
1760                 listingsModule->listingsTB->setPlainText(
1761                         qt_("Input listings parameters below. "
1762                             "Enter ? for a list of parameters."));
1763         } else {
1764                 isOK = false;
1765                 // listingsTB->setTextColor("red");
1766                 listingsModule->listingsTB->setPlainText(msg);
1767         }
1768 }
1769
1770
1771 void GuiDocument::listingsPackageChanged(int index)
1772 {
1773         string const package = lst_packages[index];
1774         if (package == "Minted" && lyxrc.pygmentize_command.empty()) {
1775                 Alert::warning(_("Pygments driver command not found!"),
1776                     _("The driver command necessary to use the minted package\n"
1777                       "(pygmentize) has not been found. Make sure you have\n"
1778                       "the python-pygments module installed or, if the driver\n"
1779                       "is named differently, to add the following line to the\n"
1780                       "document preamble:\n\n"
1781                       "\\AtBeginDocument{\\renewcommand{\\MintedPygmentize}{driver}}\n\n"
1782                       "where 'driver' is name of the driver command."));
1783         }
1784 }
1785
1786
1787 void GuiDocument::setLSpacing(int item)
1788 {
1789         textLayoutModule->lspacingLE->setEnabled(item == 3);
1790 }
1791
1792
1793 void GuiDocument::setIndent(int item)
1794 {
1795         bool const enable = (item == 1);
1796         textLayoutModule->indentLE->setEnabled(enable);
1797         textLayoutModule->indentLengthCO->setEnabled(enable);
1798         textLayoutModule->skipLE->setEnabled(false);
1799         textLayoutModule->skipLengthCO->setEnabled(false);
1800         isValid();
1801 }
1802
1803
1804 void GuiDocument::enableIndent(bool indent)
1805 {
1806         textLayoutModule->skipLE->setEnabled(!indent);
1807         textLayoutModule->skipLengthCO->setEnabled(!indent);
1808         if (indent)
1809                 setIndent(textLayoutModule->indentCO->currentIndex());
1810 }
1811
1812
1813 void GuiDocument::setSkip(int item)
1814 {
1815         bool const enable = (item == 3);
1816         textLayoutModule->skipLE->setEnabled(enable);
1817         textLayoutModule->skipLengthCO->setEnabled(enable);
1818         isValid();
1819 }
1820
1821
1822 void GuiDocument::enableSkip(bool skip)
1823 {
1824         textLayoutModule->indentLE->setEnabled(!skip);
1825         textLayoutModule->indentLengthCO->setEnabled(!skip);
1826         if (skip)
1827                 setSkip(textLayoutModule->skipCO->currentIndex());
1828 }
1829
1830 void GuiDocument::allowMathIndent() {
1831         // only disable when not checked, checked does not always allow enabling
1832         if (!mathsModule->MathIndentCB->isChecked()) {
1833                 mathsModule->MathIndentLE->setEnabled(false);
1834                 mathsModule->MathIndentLengthCO->setEnabled(false);
1835         }
1836         if (mathsModule->MathIndentCB->isChecked()
1837             && mathsModule->MathIndentCO->currentIndex() == 1) {
1838                         mathsModule->MathIndentLE->setEnabled(true);
1839                         mathsModule->MathIndentLengthCO->setEnabled(true);
1840         }
1841         isValid();
1842 }
1843
1844 void GuiDocument::enableMathIndent(int item)
1845 {
1846         bool const enable = (item == 1);
1847         mathsModule->MathIndentLE->setEnabled(enable);
1848         mathsModule->MathIndentLengthCO->setEnabled(enable);
1849         isValid();
1850 }
1851
1852
1853 void GuiDocument::setMargins()
1854 {
1855         bool const extern_geometry =
1856                 documentClass().provides("geometry");
1857         marginsModule->marginCB->setEnabled(!extern_geometry);
1858         if (extern_geometry) {
1859                 marginsModule->marginCB->setChecked(false);
1860                 setCustomMargins(true);
1861         } else {
1862                 marginsModule->marginCB->setChecked(!bp_.use_geometry);
1863                 setCustomMargins(!bp_.use_geometry);
1864         }
1865 }
1866
1867
1868 void GuiDocument::papersizeChanged(int paper_size)
1869 {
1870         setCustomPapersize(paper_size == 1);
1871 }
1872
1873
1874 void GuiDocument::setCustomPapersize(bool custom)
1875 {
1876         pageLayoutModule->paperwidthL->setEnabled(custom);
1877         pageLayoutModule->paperwidthLE->setEnabled(custom);
1878         pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
1879         pageLayoutModule->paperheightL->setEnabled(custom);
1880         pageLayoutModule->paperheightLE->setEnabled(custom);
1881         pageLayoutModule->paperheightLE->setFocus();
1882         pageLayoutModule->paperheightUnitCO->setEnabled(custom);
1883 }
1884
1885
1886 void GuiDocument::setColSep()
1887 {
1888         setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
1889 }
1890
1891
1892 void GuiDocument::setCustomMargins(bool custom)
1893 {
1894         marginsModule->topL->setEnabled(!custom);
1895         marginsModule->topLE->setEnabled(!custom);
1896         marginsModule->topUnit->setEnabled(!custom);
1897
1898         marginsModule->bottomL->setEnabled(!custom);
1899         marginsModule->bottomLE->setEnabled(!custom);
1900         marginsModule->bottomUnit->setEnabled(!custom);
1901
1902         marginsModule->innerL->setEnabled(!custom);
1903         marginsModule->innerLE->setEnabled(!custom);
1904         marginsModule->innerUnit->setEnabled(!custom);
1905
1906         marginsModule->outerL->setEnabled(!custom);
1907         marginsModule->outerLE->setEnabled(!custom);
1908         marginsModule->outerUnit->setEnabled(!custom);
1909
1910         marginsModule->headheightL->setEnabled(!custom);
1911         marginsModule->headheightLE->setEnabled(!custom);
1912         marginsModule->headheightUnit->setEnabled(!custom);
1913
1914         marginsModule->headsepL->setEnabled(!custom);
1915         marginsModule->headsepLE->setEnabled(!custom);
1916         marginsModule->headsepUnit->setEnabled(!custom);
1917
1918         marginsModule->footskipL->setEnabled(!custom);
1919         marginsModule->footskipLE->setEnabled(!custom);
1920         marginsModule->footskipUnit->setEnabled(!custom);
1921
1922         bool const enableColSep = !custom &&
1923                         textLayoutModule->twoColumnCB->checkState() == Qt::Checked;
1924         marginsModule->columnsepL->setEnabled(enableColSep);
1925         marginsModule->columnsepLE->setEnabled(enableColSep);
1926         marginsModule->columnsepUnit->setEnabled(enableColSep);
1927 }
1928
1929
1930 void GuiDocument::changeBackgroundColor()
1931 {
1932         QColor const & newColor = QColorDialog::getColor(
1933                 rgb2qcolor(set_backgroundcolor), asQWidget());
1934         if (!newColor.isValid())
1935                 return;
1936         // set the button color and text
1937         colorModule->backgroundPB->setStyleSheet(
1938                 colorButtonStyleSheet(newColor));
1939         colorModule->backgroundPB->setText(qt_("&Change..."));
1940         // save color
1941         set_backgroundcolor = rgbFromHexName(fromqstr(newColor.name()));
1942         is_backgroundcolor = true;
1943         change_adaptor();
1944 }
1945
1946
1947 void GuiDocument::deleteBackgroundColor()
1948 {
1949         // set the button color back to default by setting an empty StyleSheet
1950         colorModule->backgroundPB->setStyleSheet(QLatin1String(""));
1951         // change button text
1952         colorModule->backgroundPB->setText(qt_("&Default..."));
1953         // save default color (white)
1954         set_backgroundcolor = rgbFromHexName("#ffffff");
1955         is_backgroundcolor = false;
1956         change_adaptor();
1957 }
1958
1959
1960 void GuiDocument::changeFontColor()
1961 {
1962         QColor const & newColor = QColorDialog::getColor(
1963                 rgb2qcolor(set_fontcolor), asQWidget());
1964         if (!newColor.isValid())
1965                 return;
1966         // set the button color and text
1967         colorModule->fontColorPB->setStyleSheet(
1968                 colorButtonStyleSheet(newColor));
1969         colorModule->fontColorPB->setText(qt_("&Change..."));
1970         // save color
1971         set_fontcolor = rgbFromHexName(fromqstr(newColor.name()));
1972         is_fontcolor = true;
1973         change_adaptor();
1974 }
1975
1976
1977 void GuiDocument::deleteFontColor()
1978 {
1979         // set the button color back to default by setting an empty StyleSheet
1980         colorModule->fontColorPB->setStyleSheet(QLatin1String(""));
1981         // change button text
1982         colorModule->fontColorPB->setText(qt_("&Default..."));
1983         // save default color (black)
1984         set_fontcolor = rgbFromHexName("#000000");
1985         is_fontcolor = false;
1986         change_adaptor();
1987 }
1988
1989
1990 void GuiDocument::changeNoteFontColor()
1991 {
1992         QColor const & newColor = QColorDialog::getColor(
1993                 rgb2qcolor(set_notefontcolor), asQWidget());
1994         if (!newColor.isValid())
1995                 return;
1996         // set the button color
1997         colorModule->noteFontColorPB->setStyleSheet(
1998                 colorButtonStyleSheet(newColor));
1999         // save color
2000         set_notefontcolor = rgbFromHexName(fromqstr(newColor.name()));
2001         change_adaptor();
2002 }
2003
2004
2005 void GuiDocument::deleteNoteFontColor()
2006 {
2007         // set the button color back to pref
2008         theApp()->getRgbColor(Color_greyedouttext, set_notefontcolor);
2009         colorModule->noteFontColorPB->setStyleSheet(
2010                 colorButtonStyleSheet(rgb2qcolor(set_notefontcolor)));
2011         change_adaptor();
2012 }
2013
2014
2015 void GuiDocument::changeBoxBackgroundColor()
2016 {
2017         QColor const & newColor = QColorDialog::getColor(
2018                 rgb2qcolor(set_boxbgcolor), asQWidget());
2019         if (!newColor.isValid())
2020                 return;
2021         // set the button color
2022         colorModule->boxBackgroundPB->setStyleSheet(
2023                 colorButtonStyleSheet(newColor));
2024         // save color
2025         set_boxbgcolor = rgbFromHexName(fromqstr(newColor.name()));
2026         change_adaptor();
2027 }
2028
2029
2030 void GuiDocument::deleteBoxBackgroundColor()
2031 {
2032         // set the button color back to pref
2033         theApp()->getRgbColor(Color_shadedbg, set_boxbgcolor);
2034         colorModule->boxBackgroundPB->setStyleSheet(
2035                 colorButtonStyleSheet(rgb2qcolor(set_boxbgcolor)));
2036         change_adaptor();
2037 }
2038
2039
2040 void GuiDocument::updateQuoteStyles(bool const set)
2041 {
2042         Language const * lang = lyx::languages.getLanguage(
2043                 fromqstr(langModule->languageCO->itemData(
2044                         langModule->languageCO->currentIndex()).toString()));
2045
2046         InsetQuotesParams::QuoteStyle def = bp_.getQuoteStyle(lang->quoteStyle());
2047
2048         langModule->quoteStyleCO->clear();
2049
2050         bool has_default = false;
2051         for (int i = 0; i < quoteparams.stylescount(); ++i) {
2052                 InsetQuotesParams::QuoteStyle qs = InsetQuotesParams::QuoteStyle(i);
2053                 if (qs == InsetQuotesParams::DynamicQuotes)
2054                         continue;
2055                 bool const langdef = (qs == def);
2056                 if (langdef) {
2057                         // add the default style on top
2058                         langModule->quoteStyleCO->insertItem(0,
2059                                 toqstr(quoteparams.getGuiLabel(qs, langdef)), qs);
2060                         has_default = true;
2061                 }
2062                 else
2063                         langModule->quoteStyleCO->addItem(
2064                                 toqstr(quoteparams.getGuiLabel(qs, langdef)), qs);
2065         }
2066         if (set && has_default)
2067                 // (re)set to the default style
2068                 langModule->quoteStyleCO->setCurrentIndex(0);
2069 }
2070
2071
2072 void GuiDocument::languageChanged(int i)
2073 {
2074         // some languages only work with Polyglossia
2075         Language const * lang = lyx::languages.getLanguage(
2076                 fromqstr(langModule->languageCO->itemData(i).toString()));
2077         if (lang->babel().empty() && !lang->polyglossia().empty()) {
2078                         // If we force to switch fontspec on, store
2079                         // current state (#8717)
2080                         if (fontModule->osFontsCB->isEnabled())
2081                                 forced_fontspec_activation =
2082                                         !fontModule->osFontsCB->isChecked();
2083                         fontModule->osFontsCB->setChecked(true);
2084                         fontModule->osFontsCB->setEnabled(false);
2085         }
2086         else {
2087                 fontModule->osFontsCB->setEnabled(true);
2088                 // If we have forced to switch fontspec on,
2089                 // restore previous state (#8717)
2090                 if (forced_fontspec_activation)
2091                         fontModule->osFontsCB->setChecked(false);
2092                 forced_fontspec_activation = false;
2093         }
2094
2095         // set appropriate quotation mark style
2096         updateQuoteStyles(true);
2097 }
2098
2099
2100 void GuiDocument::osFontsChanged(bool nontexfonts)
2101 {
2102         bool const tex_fonts = !nontexfonts;
2103         // store current fonts
2104         QString const font_roman = fontModule->fontsRomanCO->itemData(
2105                         fontModule->fontsRomanCO->currentIndex()).toString();
2106         QString const font_sans = fontModule->fontsSansCO->itemData(
2107                         fontModule->fontsSansCO->currentIndex()).toString();
2108         QString const font_typewriter = fontModule->fontsTypewriterCO->itemData(
2109                         fontModule->fontsTypewriterCO->currentIndex()).toString();
2110         QString const font_math = fontModule->fontsMathCO->itemData(
2111                         fontModule->fontsMathCO->currentIndex()).toString();
2112         int const font_sf_scale = fontModule->scaleSansSB->value();
2113         int const font_tt_scale = fontModule->scaleTypewriterSB->value();
2114
2115         updateFontlist();
2116         // store default format
2117         QString const dformat = outputModule->defaultFormatCO->itemData(
2118                 outputModule->defaultFormatCO->currentIndex()).toString();
2119         updateDefaultFormat();
2120         // try to restore default format
2121         int index = outputModule->defaultFormatCO->findData(dformat);
2122         // set to default if format is not found
2123         if (index == -1)
2124                 index = 0;
2125         outputModule->defaultFormatCO->setCurrentIndex(index);
2126
2127         // try to restore fonts which were selected two toggles ago
2128         index = fontModule->fontsRomanCO->findData(fontModule->font_roman);
2129         if (index != -1)
2130                 fontModule->fontsRomanCO->setCurrentIndex(index);
2131         index = fontModule->fontsSansCO->findData(fontModule->font_sans);
2132         if (index != -1)
2133                 fontModule->fontsSansCO->setCurrentIndex(index);
2134         index = fontModule->fontsTypewriterCO->findData(fontModule->font_typewriter);
2135         if (index != -1)
2136                 fontModule->fontsTypewriterCO->setCurrentIndex(index);
2137         index = fontModule->fontsMathCO->findData(fontModule->font_math);
2138         if (index != -1)
2139                 fontModule->fontsMathCO->setCurrentIndex(index);
2140         // save fonts for next next toggle
2141         fontModule->font_roman = font_roman;
2142         fontModule->font_sans = font_sans;
2143         fontModule->font_typewriter = font_typewriter;
2144         fontModule->font_math = font_math;
2145         fontModule->font_sf_scale = font_sf_scale;
2146         fontModule->font_tt_scale = font_tt_scale;
2147
2148         langModule->encodingCO->setEnabled(tex_fonts &&
2149                 !langModule->defaultencodingRB->isChecked());
2150         langModule->defaultencodingRB->setEnabled(tex_fonts);
2151         langModule->otherencodingRB->setEnabled(tex_fonts);
2152
2153         fontModule->fontsDefaultCO->setEnabled(tex_fonts);
2154         fontModule->fontsDefaultLA->setEnabled(tex_fonts);
2155         fontModule->cjkFontLE->setEnabled(tex_fonts);
2156         fontModule->cjkFontLA->setEnabled(tex_fonts);
2157
2158         updateFontOptions();
2159
2160         fontModule->fontencLA->setEnabled(tex_fonts);
2161         fontModule->fontencCO->setEnabled(tex_fonts);
2162         if (!tex_fonts)
2163                 fontModule->fontencLE->setEnabled(false);
2164         else
2165                 fontencChanged(fontModule->fontencCO->currentIndex());
2166 }
2167
2168
2169 void GuiDocument::mathFontChanged(int)
2170 {
2171         updateFontOptions();
2172 }
2173
2174
2175 void GuiDocument::fontOsfToggled(bool state)
2176 {
2177         if (fontModule->osFontsCB->isChecked())
2178                 return;
2179         QString font = fontModule->fontsRomanCO->itemData(
2180                         fontModule->fontsRomanCO->currentIndex()).toString();
2181         if (hasMonolithicExpertSet(font))
2182                 fontModule->fontScCB->setChecked(state);
2183 }
2184
2185
2186 void GuiDocument::fontScToggled(bool state)
2187 {
2188         if (fontModule->osFontsCB->isChecked())
2189                 return;
2190         QString font = fontModule->fontsRomanCO->itemData(
2191                         fontModule->fontsRomanCO->currentIndex()).toString();
2192         if (hasMonolithicExpertSet(font))
2193                 fontModule->fontOsfCB->setChecked(state);
2194 }
2195
2196
2197 void GuiDocument::updateFontOptions()
2198 {
2199         bool const tex_fonts = !fontModule->osFontsCB->isChecked();
2200         QString font;
2201         if (tex_fonts)
2202                 font = fontModule->fontsSansCO->itemData(
2203                                 fontModule->fontsSansCO->currentIndex()).toString();
2204         bool scaleable = providesScale(font);
2205         fontModule->scaleSansSB->setEnabled(scaleable);
2206         fontModule->scaleSansLA->setEnabled(scaleable);
2207         if (tex_fonts)
2208                 font = fontModule->fontsTypewriterCO->itemData(
2209                                 fontModule->fontsTypewriterCO->currentIndex()).toString();
2210         scaleable = providesScale(font);
2211         fontModule->scaleTypewriterSB->setEnabled(scaleable);
2212         fontModule->scaleTypewriterLA->setEnabled(scaleable);
2213         if (tex_fonts)
2214                 font = fontModule->fontsRomanCO->itemData(
2215                                 fontModule->fontsRomanCO->currentIndex()).toString();
2216         fontModule->fontScCB->setEnabled(providesSC(font));
2217         fontModule->fontOsfCB->setEnabled(providesOSF(font));
2218         updateMathFonts(font);
2219 }
2220
2221
2222 void GuiDocument::updateFontsize(string const & items, string const & sel)
2223 {
2224         fontModule->fontsizeCO->clear();
2225         fontModule->fontsizeCO->addItem(qt_("Default"));
2226
2227         for (int n = 0; !token(items,'|',n).empty(); ++n)
2228                 fontModule->fontsizeCO->
2229                         addItem(toqstr(token(items,'|',n)));
2230
2231         for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
2232                 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
2233                         fontModule->fontsizeCO->setCurrentIndex(n);
2234                         break;
2235                 }
2236         }
2237 }
2238
2239
2240 bool GuiDocument::ot1() const
2241 {
2242         QString const fontenc =
2243                 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
2244         int const i = langModule->languageCO->currentIndex();
2245         if (i == -1)
2246                 return false;
2247         QString const langname = langModule->languageCO->itemData(i).toString();
2248         Language const * newlang = lyx::languages.getLanguage(fromqstr(langname));
2249         return (fontenc == "default"
2250                 || (fontenc == "auto" && newlang->fontenc(buffer().params()) == "OT1")
2251                 || (fontenc == "custom" && fontModule->fontencLE->text() == "OT1"));
2252 }
2253
2254
2255 bool GuiDocument::completeFontset() const
2256 {
2257         return (fontModule->fontsSansCO->itemData(
2258                         fontModule->fontsSansCO->currentIndex()).toString() == "default"
2259                 && fontModule->fontsSansCO->itemData(
2260                         fontModule->fontsTypewriterCO->currentIndex()).toString() == "default");
2261 }
2262
2263
2264 bool GuiDocument::noMathFont() const
2265 {
2266         return (fontModule->fontsMathCO->itemData(
2267                 fontModule->fontsMathCO->currentIndex()).toString() == "default");
2268 }
2269
2270
2271 void GuiDocument::updateTexFonts()
2272 {
2273         LaTeXFonts::TexFontMap texfontmap = theLaTeXFonts().getLaTeXFonts();
2274
2275         LaTeXFonts::TexFontMap::const_iterator it = texfontmap.begin();
2276         LaTeXFonts::TexFontMap::const_iterator end = texfontmap.end();
2277         for (; it != end; ++it) {
2278                 LaTeXFont lf = it->second;
2279                 if (lf.name().empty()) {
2280                         LYXERR0("Error: Unnamed font: " << it->first);
2281                         continue;
2282                 }
2283                 docstring const family = lf.family();
2284                 docstring guiname = translateIfPossible(lf.guiname());
2285                 if (!lf.available(ot1(), noMathFont()))
2286                         guiname += _(" (not installed)");
2287                 if (family == "rm")
2288                         rmfonts_.insert(toqstr(guiname), toqstr(it->first));
2289                 else if (family == "sf")
2290                         sffonts_.insert(toqstr(guiname), toqstr(it->first));
2291                 else if (family == "tt")
2292                         ttfonts_.insert(toqstr(guiname), toqstr(it->first));
2293                 else if (family == "math")
2294                         mathfonts_.insert(toqstr(guiname), toqstr(it->first));
2295         }
2296 }
2297
2298
2299 void GuiDocument::updateFontlist()
2300 {
2301         fontModule->fontsRomanCO->clear();
2302         fontModule->fontsSansCO->clear();
2303         fontModule->fontsTypewriterCO->clear();
2304         fontModule->fontsMathCO->clear();
2305
2306         // With fontspec (XeTeX, LuaTeX), we have access to all system fonts, but not the LaTeX fonts
2307         if (fontModule->osFontsCB->isChecked()) {
2308                 fontModule->fontsRomanCO->addItem(qt_("Default"), QString("default"));
2309                 fontModule->fontsSansCO->addItem(qt_("Default"), QString("default"));
2310                 fontModule->fontsTypewriterCO->addItem(qt_("Default"), QString("default"));
2311                 QString unimath = qt_("Non-TeX Fonts Default");
2312                 if (!LaTeXFeatures::isAvailable("unicode-math"))
2313                         unimath += qt_(" (not available)");
2314                 fontModule->fontsMathCO->addItem(qt_("Class Default (TeX Fonts)"), QString("auto"));
2315                 fontModule->fontsMathCO->addItem(unimath, QString("default"));
2316
2317                 QFontDatabase fontdb;
2318                 QStringList families(fontdb.families());
2319                 for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
2320                         fontModule->fontsRomanCO->addItem(*it, *it);
2321                         fontModule->fontsSansCO->addItem(*it, *it);
2322                         fontModule->fontsTypewriterCO->addItem(*it, *it);
2323                 }
2324                 return;
2325         }
2326
2327         if (rmfonts_.empty())
2328                 updateTexFonts();
2329
2330         fontModule->fontsRomanCO->addItem(qt_("Default"), QString("default"));
2331         QMap<QString, QString>::const_iterator rmi = rmfonts_.constBegin();
2332         while (rmi != rmfonts_.constEnd()) {
2333                 fontModule->fontsRomanCO->addItem(rmi.key(), rmi.value());
2334                 ++rmi;
2335         }
2336
2337         fontModule->fontsSansCO->addItem(qt_("Default"), QString("default"));
2338         QMap<QString, QString>::const_iterator sfi = sffonts_.constBegin();
2339         while (sfi != sffonts_.constEnd()) {
2340                 fontModule->fontsSansCO->addItem(sfi.key(), sfi.value());
2341                 ++sfi;
2342         }
2343
2344         fontModule->fontsTypewriterCO->addItem(qt_("Default"), QString("default"));
2345         QMap<QString, QString>::const_iterator tti = ttfonts_.constBegin();
2346         while (tti != ttfonts_.constEnd()) {
2347                 fontModule->fontsTypewriterCO->addItem(tti.key(), tti.value());
2348                 ++tti;
2349         }
2350
2351         fontModule->fontsMathCO->addItem(qt_("Automatic"), QString("auto"));
2352         fontModule->fontsMathCO->addItem(qt_("Class Default"), QString("default"));
2353         QMap<QString, QString>::const_iterator mmi = mathfonts_.constBegin();
2354         while (mmi != mathfonts_.constEnd()) {
2355                 fontModule->fontsMathCO->addItem(mmi.key(), mmi.value());
2356                 ++mmi;
2357         }
2358 }
2359
2360
2361 void GuiDocument::fontencChanged(int item)
2362 {
2363         fontModule->fontencLE->setEnabled(
2364                 fontModule->fontencCO->itemData(item).toString() == "custom");
2365         // The availability of TeX fonts depends on the font encoding
2366         updateTexFonts();
2367         updateFontOptions();
2368 }
2369
2370
2371 void GuiDocument::updateMathFonts(QString const & rm)
2372 {
2373         if (fontModule->osFontsCB->isChecked())
2374                 return;
2375         QString const math =
2376                 fontModule->fontsMathCO->itemData(fontModule->fontsMathCO->currentIndex()).toString();
2377         int const i = fontModule->fontsMathCO->findData("default");
2378         if (providesNoMath(rm) && i == -1)
2379                 fontModule->fontsMathCO->insertItem(1, qt_("Class Default"), QString("default"));
2380         else if (!providesNoMath(rm) && i != -1) {
2381                 int const c = fontModule->fontsMathCO->currentIndex();
2382                 fontModule->fontsMathCO->removeItem(i);
2383                 if (c == i)
2384                         fontModule->fontsMathCO->setCurrentIndex(0);
2385         }
2386 }
2387
2388
2389 void GuiDocument::romanChanged(int item)
2390 {
2391         if (fontModule->osFontsCB->isChecked())
2392                 return;
2393         QString const font =
2394                 fontModule->fontsRomanCO->itemData(item).toString();
2395         fontModule->fontScCB->setEnabled(providesSC(font));
2396         fontModule->fontOsfCB->setEnabled(providesOSF(font));
2397         updateMathFonts(font);
2398 }
2399
2400
2401 void GuiDocument::sansChanged(int item)
2402 {
2403         if (fontModule->osFontsCB->isChecked())
2404                 return;
2405         QString const font =
2406                 fontModule->fontsSansCO->itemData(item).toString();
2407         bool scaleable = providesScale(font);
2408         fontModule->scaleSansSB->setEnabled(scaleable);
2409         fontModule->scaleSansLA->setEnabled(scaleable);
2410 }
2411
2412
2413 void GuiDocument::ttChanged(int item)
2414 {
2415         if (fontModule->osFontsCB->isChecked())
2416                 return;
2417         QString const font =
2418                 fontModule->fontsTypewriterCO->itemData(item).toString();
2419         bool scaleable = providesScale(font);
2420         fontModule->scaleTypewriterSB->setEnabled(scaleable);
2421         fontModule->scaleTypewriterLA->setEnabled(scaleable);
2422 }
2423
2424
2425 void GuiDocument::updatePagestyle(string const & items, string const & sel)
2426 {
2427         pagestyles.clear();
2428         pageLayoutModule->pagestyleCO->clear();
2429         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
2430
2431         for (int n = 0; !token(items, '|', n).empty(); ++n) {
2432                 string style = token(items, '|', n);
2433                 QString style_gui = qt_(style);
2434                 pagestyles.push_back(pair<string, QString>(style, style_gui));
2435                 pageLayoutModule->pagestyleCO->addItem(style_gui);
2436         }
2437
2438         if (sel == "default") {
2439                 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
2440                 return;
2441         }
2442
2443         int nn = 0;
2444
2445         for (size_t i = 0; i < pagestyles.size(); ++i)
2446                 if (pagestyles[i].first == sel)
2447                         nn = pageLayoutModule->pagestyleCO->findText(pagestyles[i].second);
2448
2449         if (nn > 0)
2450                 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
2451 }
2452
2453
2454 void GuiDocument::browseLayout()
2455 {
2456         QString const label1 = qt_("Lay&outs");
2457         QString const dir1 = toqstr(lyxrc.document_path);
2458         QStringList const filter(qt_("LyX Layout (*.layout)"));
2459         QString file = browseRelToParent(QString(), bufferFilePath(),
2460                 qt_("Local layout file"), filter, false,
2461                 label1, dir1);
2462
2463         if (!file.endsWith(".layout"))
2464                 return;
2465
2466         FileName layoutFile = support::makeAbsPath(fromqstr(file),
2467                 fromqstr(bufferFilePath()));
2468
2469         int const ret = Alert::prompt(_("Local layout file"),
2470                 _("The layout file you have selected is a local layout\n"
2471                   "file, not one in the system or user directory.\n"
2472                   "Your document will not work with this layout if you\n"
2473                   "move the layout file to a different directory."),
2474                   1, 1, _("&Set Layout"), _("&Cancel"));
2475         if (ret == 1)
2476                 return;
2477
2478         // load the layout file
2479         LayoutFileList & bcl = LayoutFileList::get();
2480         string classname = layoutFile.onlyFileName();
2481         // this will update an existing layout if that layout has been loaded before.
2482         LayoutFileIndex name = support::onlyFileName(bcl.addLocalLayout(
2483                 classname.substr(0, classname.size() - 7),
2484                 layoutFile.onlyPath().absFileName()));
2485
2486         if (name.empty()) {
2487                 Alert::error(_("Error"),
2488                         _("Unable to read local layout file."));
2489                 return;
2490         }
2491
2492         const_cast<Buffer &>(buffer()).setLayoutPos(layoutFile.onlyPath().absFileName());
2493
2494         // do not trigger classChanged if there is no change.
2495         if (latexModule->classCO->currentText() == toqstr(name))
2496                 return;
2497
2498         // add to combo box
2499         bool const avail = latexModule->classCO->set(toqstr(name));
2500         if (!avail) {
2501                 LayoutFile const & tc = bcl[name];
2502                 docstring const guiname = translateIfPossible(from_utf8(tc.description()));
2503                 // tooltip sensu "KOMA-Script Article [Class 'scrartcl']"
2504                 QString tooltip = toqstr(bformat(_("%1$s [Class '%2$s']"), guiname, from_utf8(tc.latexname())));
2505                 tooltip += '\n' + qt_("This is a local layout file.");
2506                 latexModule->classCO->addItemSort(toqstr(tc.name()), toqstr(guiname),
2507                                                   toqstr(translateIfPossible(from_utf8(tc.category()))),
2508                                                   tooltip,
2509                                                   true, true, true, true);
2510                 latexModule->classCO->set(toqstr(name));
2511         }
2512
2513         classChanged();
2514 }
2515
2516
2517 void GuiDocument::browseMaster()
2518 {
2519         QString const title = qt_("Select master document");
2520         QString const dir1 = toqstr(lyxrc.document_path);
2521         QString const old = latexModule->childDocLE->text();
2522         QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
2523         QStringList const filter(qt_("LyX Files (*.lyx)"));
2524         QString file = browseRelToSub(old, docpath, title, filter, false,
2525                 qt_("D&ocuments"), toqstr(lyxrc.document_path));
2526
2527         if (!file.isEmpty())
2528                 latexModule->childDocLE->setText(file);
2529 }
2530
2531
2532 void GuiDocument::classChanged_adaptor()
2533 {
2534         const_cast<Buffer &>(buffer()).setLayoutPos(string());
2535         classChanged();
2536 }
2537
2538
2539 void GuiDocument::classChanged()
2540 {
2541         int idx = latexModule->classCO->currentIndex();
2542         if (idx < 0)
2543                 return;
2544         string const classname = fromqstr(latexModule->classCO->getData(idx));
2545
2546         if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
2547                 int const ret = Alert::prompt(_("Unapplied changes"),
2548                                 _("Some changes in the dialog were not yet applied.\n"
2549                                 "If you do not apply now, they will be lost after this action."),
2550                                 1, 1, _("&Apply"), _("&Dismiss"));
2551                 if (ret == 0)
2552                         applyView();
2553         }
2554
2555         // We load the TextClass as soon as it is selected. This is
2556         // necessary so that other options in the dialog can be updated
2557         // according to the new class. Note, however, that, if you use
2558         // the scroll wheel when sitting on the combo box, we'll load a
2559         // lot of TextClass objects very quickly....
2560         if (!bp_.setBaseClass(classname, buffer().layoutPos())) {
2561                 Alert::error(_("Error"), _("Unable to set document class."));
2562                 return;
2563         }
2564         if (lyxrc.auto_reset_options)
2565                 bp_.useClassDefaults();
2566
2567         // With the introduction of modules came a distinction between the base
2568         // class and the document class. The former corresponds to the main layout
2569         // file; the latter is that plus the modules (or the document-specific layout,
2570         // or  whatever else there could be). Our parameters come from the document
2571         // class. So when we set the base class, we also need to recreate the document
2572         // class. Otherwise, we still have the old one.
2573         bp_.makeDocumentClass();
2574         paramsToDialog();
2575 }
2576
2577
2578 void GuiDocument::languagePackageChanged(int i)
2579 {
2580          langModule->languagePackageLE->setEnabled(
2581                 langModule->languagePackageCO->itemData(i).toString() == "custom");
2582 }
2583
2584
2585 void GuiDocument::biblioChanged()
2586 {
2587         biblioChanged_ = true;
2588         change_adaptor();
2589 }
2590
2591
2592 void GuiDocument::checkPossibleCiteEngines()
2593 {
2594         // Check if the class provides a specific engine,
2595         // and if so, enforce this.
2596         string force_engine;
2597         if (documentClass().provides("natbib")
2598             || documentClass().provides("natbib-internal"))
2599                 force_engine = "natbib";
2600         else if (documentClass().provides("jurabib"))
2601                 force_engine = "jurabib";
2602         else if (documentClass().provides("biblatex"))
2603                 force_engine = "biblatex";
2604         else if (documentClass().provides("biblatex-natbib"))
2605                 force_engine = "biblatex-natbib";
2606
2607         if (!force_engine.empty())
2608                 biblioModule->citeEngineCO->setCurrentIndex(
2609                         biblioModule->citeEngineCO->findData(toqstr(force_engine)));
2610         biblioModule->citeEngineCO->setEnabled(force_engine.empty());
2611 }
2612
2613
2614 void GuiDocument::rescanBibFiles()
2615 {
2616         if (isBiblatex())
2617                 rescanTexStyles("bbx cbx");
2618         else
2619                 rescanTexStyles("bst");
2620 }
2621
2622
2623 void GuiDocument::resetDefaultBibfile(string const & which)
2624 {
2625         QString const engine =
2626                 biblioModule->citeEngineCO->itemData(
2627                                 biblioModule->citeEngineCO->currentIndex()).toString();
2628
2629         CiteEngineType const cet =
2630                 CiteEngineType(biblioModule->citeStyleCO->itemData(
2631                                                           biblioModule->citeStyleCO->currentIndex()).toInt());
2632
2633         updateDefaultBiblio(theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet), which);
2634 }
2635
2636
2637 void GuiDocument::resetDefaultBbxBibfile()
2638 {
2639         resetDefaultBibfile("bbx");
2640 }
2641
2642
2643 void GuiDocument::resetDefaultCbxBibfile()
2644 {
2645         resetDefaultBibfile("cbx");
2646 }
2647
2648
2649 void GuiDocument::citeEngineChanged(int n)
2650 {
2651         QString const engine =
2652                 biblioModule->citeEngineCO->itemData(n).toString();
2653
2654         vector<string> const engs =
2655                 theCiteEnginesList[fromqstr(engine)]->getEngineType();
2656
2657         updateCiteStyles(engs);
2658         updateEngineDependends();
2659         resetDefaultBibfile();
2660         biblioChanged();
2661 }
2662
2663
2664 void GuiDocument::updateEngineDependends()
2665 {
2666         bool const biblatex = isBiblatex();
2667
2668         // These are only useful with BibTeX
2669         biblioModule->defaultBiblioCO->setEnabled(!biblatex);
2670         biblioModule->bibtexStyleLA->setEnabled(!biblatex);
2671         biblioModule->resetDefaultBiblioPB->setEnabled(!biblatex);
2672         biblioModule->bibtopicCB->setEnabled(!biblatex);
2673
2674         // These are only useful with Biblatex
2675         biblioModule->biblatexBbxCO->setEnabled(biblatex);
2676         biblioModule->biblatexBbxLA->setEnabled(biblatex);
2677         biblioModule->biblatexCbxCO->setEnabled(biblatex);
2678         biblioModule->biblatexCbxLA->setEnabled(biblatex);
2679         biblioModule->resetBbxPB->setEnabled(biblatex);
2680         biblioModule->resetCbxPB->setEnabled(biblatex);
2681         biblioModule->matchBbxPB->setEnabled(biblatex);
2682
2683         // These are useful with biblatex, jurabib and natbib
2684         QString const engine =
2685                 biblioModule->citeEngineCO->itemData(
2686                                 biblioModule->citeEngineCO->currentIndex()).toString();
2687         LyXCiteEngine const * ce = theCiteEnginesList[fromqstr(engine)];
2688
2689         bool const citepack = ce->requires("biblatex.sty") || ce->requires("jurabib.sty")
2690                         || ce->requires("natbib.sty");
2691         biblioModule->citePackageOptionsLE->setEnabled(citepack);
2692         biblioModule->citePackageOptionsL->setEnabled(citepack);
2693 }
2694
2695
2696 void GuiDocument::citeStyleChanged()
2697 {
2698         QString const engine =
2699                 biblioModule->citeEngineCO->itemData(
2700                                 biblioModule->citeEngineCO->currentIndex()).toString();
2701         QString const currentDef = isBiblatex() ?
2702                 biblioModule->biblatexBbxCO->currentText()
2703                 : biblioModule->defaultBiblioCO->currentText();
2704         if (theCiteEnginesList[fromqstr(engine)]->isDefaultBiblio(fromqstr(currentDef)))
2705                 resetDefaultBibfile();
2706
2707         biblioChanged();
2708 }
2709
2710
2711 void GuiDocument::bibtexChanged(int n)
2712 {
2713         biblioModule->bibtexOptionsLE->setEnabled(
2714                 biblioModule->bibtexCO->itemData(n).toString() != "default");
2715         biblioChanged();
2716 }
2717
2718
2719 void GuiDocument::updateCiteStyles(vector<string> const & engs, CiteEngineType const & sel)
2720 {
2721         biblioModule->citeStyleCO->clear();
2722
2723         vector<string>::const_iterator it  = engs.begin();
2724         vector<string>::const_iterator end = engs.end();
2725         for (; it != end; ++it) {
2726                 if (*it == "default")
2727                         biblioModule->citeStyleCO->addItem(qt_("Basic numerical"),
2728                                                            ENGINE_TYPE_DEFAULT);
2729                 else if (*it == "authoryear")
2730                         biblioModule->citeStyleCO->addItem(qt_("Author-year"),
2731                                                            ENGINE_TYPE_AUTHORYEAR);
2732                 else if (*it == "numerical")
2733                         biblioModule->citeStyleCO->addItem(qt_("Author-number"),
2734                                                            ENGINE_TYPE_NUMERICAL);
2735         }
2736         int i = biblioModule->citeStyleCO->findData(sel);
2737         if (biblioModule->citeStyleCO->findData(sel) == -1)
2738                 i = 0;
2739         biblioModule->citeStyleCO->setCurrentIndex(i);
2740
2741         biblioModule->citationStyleL->setEnabled(engs.size() > 1);
2742         biblioModule->citeStyleCO->setEnabled(engs.size() > 1);
2743 }
2744
2745
2746 void GuiDocument::updateEngineType(string const & items, CiteEngineType const & sel)
2747 {
2748         engine_types_.clear();
2749
2750         int nn = 0;
2751
2752         for (int n = 0; !token(items, '|', n).empty(); ++n) {
2753                 nn += 1;
2754                 string style = token(items, '|', n);
2755                 engine_types_.push_back(style);
2756         }
2757
2758         updateCiteStyles(engine_types_, sel);
2759 }
2760
2761
2762 namespace {
2763         // FIXME unicode
2764         // both of these should take a vector<docstring>
2765
2766         // This is an insanely complicated attempt to make this sort of thing
2767         // work with RTL languages.
2768         docstring formatStrVec(vector<string> const & v, docstring const & s)
2769         {
2770                 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
2771                 if (v.empty())
2772                         return docstring();
2773                 if (v.size() == 1)
2774                         return translateIfPossible(from_utf8(v[0]));
2775                 if (v.size() == 2) {
2776                         docstring retval = _("%1$s and %2$s");
2777                         retval = subst(retval, _("and"), s);
2778                         return bformat(retval, translateIfPossible(from_utf8(v[0])),
2779                                        translateIfPossible(from_utf8(v[1])));
2780                 }
2781                 // The idea here is to format all but the last two items...
2782                 int const vSize = v.size();
2783                 docstring t2 = _("%1$s, %2$s");
2784                 docstring retval = translateIfPossible(from_utf8(v[0]));
2785                 for (int i = 1; i < vSize - 2; ++i)
2786                         retval = bformat(t2, retval, translateIfPossible(from_utf8(v[i])));
2787                 //...and then to  plug them, and the last two, into this schema
2788                 docstring t = _("%1$s, %2$s, and %3$s");
2789                 t = subst(t, _("and"), s);
2790                 return bformat(t, retval, translateIfPossible(from_utf8(v[vSize - 2])),
2791                                translateIfPossible(from_utf8(v[vSize - 1])));
2792         }
2793
2794         vector<string> idsToNames(vector<string> const & idList)
2795         {
2796                 vector<string> retval;
2797                 vector<string>::const_iterator it  = idList.begin();
2798                 vector<string>::const_iterator end = idList.end();
2799                 for (; it != end; ++it) {
2800                         LyXModule const * const mod = theModuleList[*it];
2801                         if (!mod)
2802                                 retval.push_back(to_utf8(bformat(_("%1$s (unavailable)"),
2803                                                 translateIfPossible(from_utf8(*it)))));
2804                         else
2805                                 retval.push_back(mod->getName());
2806                 }
2807                 return retval;
2808         }
2809 } // end anonymous namespace
2810
2811
2812 void GuiDocument::modulesToParams(BufferParams & bp)
2813 {
2814         // update list of loaded modules
2815         bp.clearLayoutModules();
2816         int const srows = modules_sel_model_.rowCount();
2817         for (int i = 0; i < srows; ++i)
2818                 bp.addLayoutModule(modules_sel_model_.getIDString(i));
2819
2820         // update the list of removed modules
2821         bp.clearRemovedModules();
2822         LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
2823         list<string>::const_iterator rit = reqmods.begin();
2824         list<string>::const_iterator ren = reqmods.end();
2825
2826         // check each of the default modules
2827         for (; rit != ren; ++rit) {
2828                 list<string>::const_iterator mit = bp.getModules().begin();
2829                 list<string>::const_iterator men = bp.getModules().end();
2830                 bool found = false;
2831                 for (; mit != men; ++mit) {
2832                         if (*rit == *mit) {
2833                                 found = true;
2834                                 break;
2835                         }
2836                 }
2837                 if (!found) {
2838                         // the module isn't present so must have been removed by the user
2839                         bp.addRemovedModule(*rit);
2840                 }
2841         }
2842 }
2843
2844 void GuiDocument::modulesChanged()
2845 {
2846         modulesToParams(bp_);
2847
2848         if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()
2849             && (nonModuleChanged_ || shellescapeChanged_)) {
2850                 int const ret = Alert::prompt(_("Unapplied changes"),
2851                                 _("Some changes in the dialog were not yet applied.\n"
2852                                 "If you do not apply now, they will be lost after this action."),
2853                                 1, 1, _("&Apply"), _("&Dismiss"));
2854                 if (ret == 0)
2855                         applyView();
2856         }
2857
2858         modulesChanged_ = true;
2859         bp_.makeDocumentClass();
2860         paramsToDialog();
2861         changed();
2862 }
2863
2864
2865 void GuiDocument::updateModuleInfo()
2866 {
2867         selectionManager->update();
2868
2869         //Module description
2870         bool const focus_on_selected = selectionManager->selectedFocused();
2871         QAbstractItemView * lv;
2872         if (focus_on_selected)
2873                 lv = modulesModule->selectedLV;
2874         else
2875                 lv = modulesModule->availableLV;
2876         if (lv->selectionModel()->selectedIndexes().isEmpty()) {
2877                 modulesModule->infoML->document()->clear();
2878                 return;
2879         }
2880         QModelIndex const & idx = lv->selectionModel()->currentIndex();
2881         GuiIdListModel const & id_model =
2882                         focus_on_selected  ? modules_sel_model_ : modules_av_model_;
2883         string const modName = id_model.getIDString(idx.row());
2884         docstring desc = getModuleDescription(modName);
2885
2886         LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
2887         if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
2888                 if (!desc.empty())
2889                         desc += "\n";
2890                 desc += _("Module provided by document class.");
2891         }
2892
2893         docstring cat = getModuleCategory(modName);
2894         if (!cat.empty()) {
2895                 if (!desc.empty())
2896                         desc += "\n";
2897                 desc += bformat(_("Category: %1$s."), cat);
2898         }
2899
2900         vector<string> pkglist = getPackageList(modName);
2901         docstring pkgdesc = formatStrVec(pkglist, _("and"));
2902         if (!pkgdesc.empty()) {
2903                 if (!desc.empty())
2904                         desc += "\n";
2905                 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
2906         }
2907
2908         pkglist = getRequiredList(modName);
2909         if (!pkglist.empty()) {
2910                 vector<string> const reqdescs = idsToNames(pkglist);
2911                 pkgdesc = formatStrVec(reqdescs, _("or"));
2912                 if (!desc.empty())
2913                         desc += "\n";
2914                 desc += bformat(_("Modules required: %1$s."), pkgdesc);
2915         }
2916
2917         pkglist = getExcludedList(modName);
2918         if (!pkglist.empty()) {
2919                 vector<string> const reqdescs = idsToNames(pkglist);
2920                 pkgdesc = formatStrVec(reqdescs, _( "and"));
2921                 if (!desc.empty())
2922                         desc += "\n";
2923                 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
2924         }
2925
2926         if (!desc.empty())
2927                 desc += "\n";
2928         desc += bformat(_("Filename: %1$s.module."), from_utf8(modName));
2929
2930         if (!isModuleAvailable(modName)) {
2931                 if (!desc.empty())
2932                         desc += "\n";
2933                 desc += _("WARNING: Some required packages are unavailable!");
2934         }
2935
2936         modulesModule->infoML->document()->setPlainText(toqstr(desc));
2937 }
2938
2939
2940 void GuiDocument::updateNumbering()
2941 {
2942         DocumentClass const & tclass = documentClass();
2943
2944         numberingModule->tocTW->setUpdatesEnabled(false);
2945         numberingModule->tocTW->clear();
2946
2947         int const depth = numberingModule->depthSL->value();
2948         int const toc = numberingModule->tocSL->value();
2949         QString const no = qt_("No");
2950         QString const yes = qt_("Yes");
2951         QTreeWidgetItem * item = 0;
2952
2953         DocumentClass::const_iterator lit = tclass.begin();
2954         DocumentClass::const_iterator len = tclass.end();
2955         for (; lit != len; ++lit) {
2956                 int const toclevel = lit->toclevel;
2957                 if (toclevel != Layout::NOT_IN_TOC && !lit->counter.empty()) {
2958                         item = new QTreeWidgetItem(numberingModule->tocTW);
2959                         item->setText(0, toqstr(translateIfPossible(lit->name())));
2960                         item->setText(1, (toclevel <= depth) ? yes : no);
2961                         item->setText(2, (toclevel <= toc) ? yes : no);
2962                 }
2963         }
2964
2965         numberingModule->tocTW->setUpdatesEnabled(true);
2966         numberingModule->tocTW->update();
2967 }
2968
2969
2970 void GuiDocument::updateDefaultFormat()
2971 {
2972         if (!bufferview())
2973                 return;
2974         // make a copy in order to consider unapplied changes
2975         BufferParams param_copy = buffer().params();
2976         param_copy.useNonTeXFonts = fontModule->osFontsCB->isChecked();
2977         int const idx = latexModule->classCO->currentIndex();
2978         if (idx >= 0) {
2979                 string const classname = fromqstr(latexModule->classCO->getData(idx));
2980                 param_copy.setBaseClass(classname, buffer().layoutPos());
2981                 param_copy.makeDocumentClass(true);
2982         }
2983         outputModule->defaultFormatCO->blockSignals(true);
2984         outputModule->defaultFormatCO->clear();
2985         outputModule->defaultFormatCO->addItem(qt_("Default"),
2986                                 QVariant(QString("default")));
2987         FormatList const & formats =
2988                                 param_copy.exportableFormats(true);
2989         for (Format const * f : formats)
2990                 outputModule->defaultFormatCO->addItem
2991                         (toqstr(translateIfPossible(f->prettyname())),
2992                          QVariant(toqstr(f->name())));
2993         outputModule->defaultFormatCO->blockSignals(false);
2994 }
2995
2996
2997 bool GuiDocument::isChildIncluded(string const & child)
2998 {
2999         if (includeonlys_.empty())
3000                 return false;
3001         return (std::find(includeonlys_.begin(),
3002                           includeonlys_.end(), child) != includeonlys_.end());
3003 }
3004
3005
3006 void GuiDocument::applyView()
3007 {
3008         // preamble
3009         preambleModule->apply(bp_);
3010         localLayout->apply(bp_);
3011
3012         // date
3013         bp_.suppress_date = latexModule->suppressDateCB->isChecked();
3014         bp_.use_refstyle  = latexModule->refstyleCB->isChecked();
3015
3016         // biblio
3017         string const engine =
3018                 fromqstr(biblioModule->citeEngineCO->itemData(
3019                                 biblioModule->citeEngineCO->currentIndex()).toString());
3020         bp_.setCiteEngine(engine);
3021
3022         CiteEngineType const style = CiteEngineType(biblioModule->citeStyleCO->itemData(
3023                 biblioModule->citeStyleCO->currentIndex()).toInt());
3024         if (theCiteEnginesList[engine]->hasEngineType(style))
3025                 bp_.setCiteEngineType(style);
3026         else
3027                 bp_.setCiteEngineType(ENGINE_TYPE_DEFAULT);
3028
3029         bp_.splitbib(biblioModule->bibtopicCB->isChecked());
3030
3031         bp_.multibib = fromqstr(biblioModule->bibunitsCO->itemData(
3032                                 biblioModule->bibunitsCO->currentIndex()).toString());
3033
3034         bp_.setDefaultBiblioStyle(fromqstr(biblioModule->defaultBiblioCO->currentText()));
3035
3036         bp_.biblatex_bibstyle = fromqstr(biblioModule->biblatexBbxCO->currentText());
3037         bp_.biblatex_citestyle = fromqstr(biblioModule->biblatexCbxCO->currentText());
3038         bp_.biblio_opts = fromqstr(biblioModule->citePackageOptionsLE->text());
3039
3040         string const bibtex_command =
3041                 fromqstr(biblioModule->bibtexCO->itemData(
3042                         biblioModule->bibtexCO->currentIndex()).toString());
3043         string const bibtex_options =
3044                 fromqstr(biblioModule->bibtexOptionsLE->text());
3045         if (bibtex_command == "default" || bibtex_options.empty())
3046                 bp_.bibtex_command = bibtex_command;
3047         else
3048                 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
3049
3050         if (biblioChanged_) {
3051                 buffer().invalidateBibinfoCache();
3052                 buffer().removeBiblioTempFiles();
3053         }
3054
3055         // Indices
3056         indicesModule->apply(bp_);
3057
3058         // language & quotes
3059         if (langModule->defaultencodingRB->isChecked()) {
3060                 bp_.inputenc = "auto";
3061         } else {
3062                 int i = langModule->encodingCO->currentIndex();
3063                 if (i == 0)
3064                         bp_.inputenc = "default";
3065                 else {
3066                         QString const enc_gui =
3067                                 langModule->encodingCO->currentText();
3068                         Encodings::const_iterator it = encodings.begin();
3069                         Encodings::const_iterator const end = encodings.end();
3070                         bool found = false;
3071                         for (; it != end; ++it) {
3072                                 if (qt_(it->guiName()) == enc_gui &&
3073                                     !it->unsafe()) {
3074                                         bp_.inputenc = it->name();
3075                                         found = true;
3076                                         break;
3077                                 }
3078                         }
3079                         if (!found) {
3080                                 // should not happen
3081                                 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
3082                                 bp_.inputenc = "default";
3083                         }
3084                 }
3085         }
3086
3087         bp_.quotes_style = (InsetQuotesParams::QuoteStyle) langModule->quoteStyleCO->itemData(
3088                 langModule->quoteStyleCO->currentIndex()).toInt();
3089         bp_.dynamic_quotes = langModule->dynamicQuotesCB->isChecked();
3090
3091         QString const langname = langModule->languageCO->itemData(
3092                 langModule->languageCO->currentIndex()).toString();
3093         Language const * newlang = lyx::languages.getLanguage(fromqstr(langname));
3094         Cursor & cur = const_cast<BufferView *>(bufferview())->cursor();
3095         // If current cursor language was the document language, then update it too.
3096         if (cur.current_font.language() == bp_.language) {
3097                 cur.current_font.setLanguage(newlang);
3098                 cur.real_current_font.setLanguage(newlang);
3099         }
3100         bp_.language = newlang;
3101
3102         QString const pack = langModule->languagePackageCO->itemData(
3103                 langModule->languagePackageCO->currentIndex()).toString();
3104         if (pack == "custom")
3105                 bp_.lang_package =
3106                         fromqstr(langModule->languagePackageLE->text());
3107         else
3108                 bp_.lang_package = fromqstr(pack);
3109
3110         //color
3111         bp_.backgroundcolor = set_backgroundcolor;
3112         bp_.isbackgroundcolor = is_backgroundcolor;
3113         bp_.fontcolor = set_fontcolor;
3114         bp_.isfontcolor = is_fontcolor;
3115         bp_.notefontcolor = set_notefontcolor;
3116         bp_.boxbgcolor = set_boxbgcolor;
3117
3118         // numbering
3119         if (bp_.documentClass().hasTocLevels()) {
3120                 bp_.tocdepth = numberingModule->tocSL->value();
3121                 bp_.secnumdepth = numberingModule->depthSL->value();
3122         }
3123
3124         // bullets
3125         bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
3126         bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
3127         bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
3128         bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
3129
3130         // packages
3131         bp_.graphics_driver =
3132                 tex_graphics[latexModule->psdriverCO->currentIndex()];
3133
3134         // text layout
3135         int idx = latexModule->classCO->currentIndex();
3136         if (idx >= 0) {
3137                 string const classname = fromqstr(latexModule->classCO->getData(idx));
3138                 bp_.setBaseClass(classname, buffer().layoutPos());
3139         }
3140
3141         // Modules
3142         modulesToParams(bp_);
3143
3144         // Math
3145         map<string, string> const & packages = BufferParams::auto_packages();
3146         for (map<string, string>::const_iterator it = packages.begin();
3147              it != packages.end(); ++it) {
3148                 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
3149                 if (!item)
3150                         continue;
3151                 int row = mathsModule->packagesTW->row(item);
3152
3153                 QRadioButton * rb =
3154                         (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1)->layout()->itemAt(0)->widget();
3155                 if (rb->isChecked()) {
3156                         bp_.use_package(it->first, BufferParams::package_auto);
3157                         continue;
3158                 }
3159                 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2)->layout()->itemAt(0)->widget();
3160                 if (rb->isChecked()) {
3161                         bp_.use_package(it->first, BufferParams::package_on);
3162                         continue;
3163                 }
3164                 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3)->layout()->itemAt(0)->widget();
3165                 if (rb->isChecked())
3166                         bp_.use_package(it->first, BufferParams::package_off);
3167         }
3168         // if math is indented
3169         bp_.is_math_indent = mathsModule->MathIndentCB->isChecked();
3170         if (bp_.is_math_indent) {
3171                 // if formulas are indented
3172                 switch (mathsModule->MathIndentCO->currentIndex()) {
3173                 case 0:
3174                         bp_.setMathIndent(Length());
3175                         break;
3176                 case 1: {
3177                         Length mathindent(widgetsToLength(mathsModule->MathIndentLE,
3178                                                           mathsModule->MathIndentLengthCO));
3179                         bp_.setMathIndent(mathindent);
3180                         break;
3181                 }
3182                 default:
3183                         // this should never happen
3184                         bp_.setMathIndent(Length());
3185                         break;
3186                 }
3187         }
3188         switch (mathsModule->MathNumberingPosCO->currentIndex()) {
3189                 case 0:
3190                         bp_.math_numbering_side = BufferParams::LEFT;
3191                         break;
3192                 case 1:
3193                         bp_.math_numbering_side = BufferParams::DEFAULT;
3194                         break;
3195                 case 2:
3196                         bp_.math_numbering_side = BufferParams::RIGHT;
3197                         break;
3198                 default:
3199                         // this should never happen
3200                         bp_.math_numbering_side = BufferParams::DEFAULT;
3201                         break;
3202         }
3203
3204         // Page Layout
3205         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
3206                 bp_.pagestyle = "default";
3207         else {
3208                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
3209                 for (size_t i = 0; i != pagestyles.size(); ++i)
3210                         if (pagestyles[i].second == style_gui)
3211                                 bp_.pagestyle = pagestyles[i].first;
3212         }
3213
3214         // Text Layout
3215         switch (textLayoutModule->lspacingCO->currentIndex()) {
3216         case 0:
3217                 bp_.spacing().set(Spacing::Single);
3218                 break;
3219         case 1:
3220                 bp_.spacing().set(Spacing::Onehalf);
3221                 break;
3222         case 2:
3223                 bp_.spacing().set(Spacing::Double);
3224                 break;
3225         case 3: {
3226                 string s = widgetToDoubleStr(textLayoutModule->lspacingLE);
3227                 if (s.empty())
3228                         bp_.spacing().set(Spacing::Single);
3229                 else
3230                         bp_.spacing().set(Spacing::Other, s);
3231                 break;
3232                 }
3233         }
3234
3235         if (textLayoutModule->twoColumnCB->isChecked())
3236                 bp_.columns = 2;
3237         else
3238                 bp_.columns = 1;
3239
3240         bp_.justification = textLayoutModule->justCB->isChecked();
3241
3242         if (textLayoutModule->indentRB->isChecked()) {
3243                 // if paragraphs are separated by an indentation
3244                 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
3245                 switch (textLayoutModule->indentCO->currentIndex()) {
3246                 case 0:
3247                         bp_.setParIndent(Length());
3248                         break;
3249                 case 1: {
3250                         Length parindent(widgetsToLength(textLayoutModule->indentLE,
3251                                                          textLayoutModule->indentLengthCO));
3252                         bp_.setParIndent(parindent);
3253                         break;
3254                 }
3255                 default:
3256                         // this should never happen
3257                         bp_.setParIndent(Length());
3258                         break;
3259                 }
3260         } else {
3261                 // if paragraphs are separated by a skip
3262                 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
3263                 switch (textLayoutModule->skipCO->currentIndex()) {
3264                 case 0:
3265                         bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
3266                         break;
3267                 case 1:
3268                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
3269                         break;
3270                 case 2:
3271                         bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
3272                         break;
3273                 case 3:
3274                         {
3275                         VSpace vs = VSpace(
3276                                 widgetsToLength(textLayoutModule->skipLE,
3277                                 textLayoutModule->skipLengthCO)
3278                                 );
3279                         bp_.setDefSkip(vs);
3280                         break;
3281                         }
3282                 default:
3283                         // this should never happen
3284                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
3285                         break;
3286                 }
3287         }
3288
3289         bp_.options =
3290                 fromqstr(latexModule->optionsLE->text());
3291
3292         bp_.use_default_options =
3293                 latexModule->defaultOptionsCB->isChecked();
3294
3295         if (latexModule->childDocGB->isChecked())
3296                 bp_.master =
3297                         fromqstr(latexModule->childDocLE->text());
3298         else
3299                 bp_.master = string();
3300
3301         // Master/Child
3302         bp_.clearIncludedChildren();
3303         if (masterChildModule->includeonlyRB->isChecked()) {
3304                 list<string>::const_iterator it = includeonlys_.begin();
3305                 for (; it != includeonlys_.end() ; ++it) {
3306                         bp_.addIncludedChildren(*it);
3307                 }
3308         }
3309         bp_.maintain_unincluded_children =
3310                 masterChildModule->maintainAuxCB->isChecked();
3311
3312         // Float Settings
3313         bp_.float_placement = floatModule->getPlacement();
3314         bp_.float_alignment = floatModule->getAlignment();
3315
3316         // Listings
3317         // text should have passed validation
3318         idx = listingsModule->packageCO->currentIndex();
3319         bp_.use_minted = string(lst_packages[idx]) == "Minted";
3320         bp_.listings_params =
3321                 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
3322
3323         // Formats
3324         bp_.default_output_format = fromqstr(outputModule->defaultFormatCO->itemData(
3325                 outputModule->defaultFormatCO->currentIndex()).toString());
3326
3327         bool const nontexfonts = fontModule->osFontsCB->isChecked();
3328         bp_.useNonTeXFonts = nontexfonts;
3329
3330         bp_.shell_escape = outputModule->shellescapeCB->isChecked();
3331         if (!bp_.shell_escape)
3332             theSession().shellescapeFiles().remove(buffer().absFileName());
3333         else if (!theSession().shellescapeFiles().find(buffer().absFileName()))
3334             theSession().shellescapeFiles().insert(buffer().absFileName());
3335         Buffer & buf = const_cast<Buffer &>(buffer());
3336         buf.params().shell_escape = bp_.shell_escape;
3337
3338         bp_.output_sync = outputModule->outputsyncCB->isChecked();
3339
3340         bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
3341
3342         int mathfmt = outputModule->mathoutCB->currentIndex();
3343         if (mathfmt == -1)
3344                 mathfmt = 0;
3345         BufferParams::MathOutput const mo =
3346                 static_cast<BufferParams::MathOutput>(mathfmt);
3347         bp_.html_math_output = mo;
3348         bp_.html_be_strict = outputModule->strictCB->isChecked();
3349         bp_.html_css_as_file = outputModule->cssCB->isChecked();
3350         bp_.html_math_img_scale = outputModule->mathimgSB->value();
3351         bp_.display_pixel_ratio = theGuiApp()->pixelRatio();
3352
3353         bp_.save_transient_properties =
3354                 outputModule->saveTransientPropertiesCB->isChecked();
3355
3356         // fonts
3357         bp_.fonts_roman[nontexfonts] =
3358                 fromqstr(fontModule->fontsRomanCO->
3359                         itemData(fontModule->fontsRomanCO->currentIndex()).toString());
3360         bp_.fonts_roman[!nontexfonts] = fromqstr(fontModule->font_roman);
3361
3362         bp_.fonts_sans[nontexfonts] =
3363                 fromqstr(fontModule->fontsSansCO->
3364                         itemData(fontModule->fontsSansCO->currentIndex()).toString());
3365         bp_.fonts_sans[!nontexfonts] = fromqstr(fontModule->font_sans);
3366
3367         bp_.fonts_typewriter[nontexfonts] =
3368                 fromqstr(fontModule->fontsTypewriterCO->
3369                         itemData(fontModule->fontsTypewriterCO->currentIndex()).toString());
3370         bp_.fonts_typewriter[!nontexfonts] = fromqstr(fontModule->font_typewriter);
3371
3372         bp_.fonts_math[nontexfonts] =
3373                 fromqstr(fontModule->fontsMathCO->
3374                         itemData(fontModule->fontsMathCO->currentIndex()).toString());
3375         bp_.fonts_math[!nontexfonts] = fromqstr(fontModule->font_math);
3376
3377         QString const fontenc =
3378                 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
3379         if (fontenc == "custom")
3380                 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
3381         else
3382                 bp_.fontenc = fromqstr(fontenc);
3383
3384         bp_.fonts_cjk =
3385                 fromqstr(fontModule->cjkFontLE->text());
3386
3387         bp_.use_microtype = fontModule->microtypeCB->isChecked();
3388         bp_.use_dash_ligatures = !fontModule->dashesCB->isChecked();
3389
3390         bp_.fonts_sans_scale[nontexfonts] = fontModule->scaleSansSB->value();
3391         bp_.fonts_sans_scale[!nontexfonts] = fontModule->font_sf_scale;
3392
3393         bp_.fonts_typewriter_scale[nontexfonts] = fontModule->scaleTypewriterSB->value();
3394         bp_.fonts_typewriter_scale[!nontexfonts] = fontModule->font_tt_scale;
3395
3396         bp_.fonts_expert_sc = fontModule->fontScCB->isChecked();
3397
3398         bp_.fonts_old_figures = fontModule->fontOsfCB->isChecked();
3399
3400         if (nontexfonts)
3401                 bp_.fonts_default_family = "default";
3402         else
3403                 bp_.fonts_default_family = GuiDocument::fontfamilies[
3404                         fontModule->fontsDefaultCO->currentIndex()];
3405
3406         if (fontModule->fontsizeCO->currentIndex() == 0)
3407                 bp_.fontsize = "default";
3408         else
3409                 bp_.fontsize =
3410                         fromqstr(fontModule->fontsizeCO->currentText());
3411
3412         // paper
3413         bp_.papersize = PAPER_SIZE(
3414                 pageLayoutModule->papersizeCO->currentIndex());
3415
3416         bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
3417                 pageLayoutModule->paperwidthUnitCO);
3418
3419         bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
3420                 pageLayoutModule->paperheightUnitCO);
3421
3422         if (pageLayoutModule->facingPagesCB->isChecked())
3423                 bp_.sides = TwoSides;
3424         else
3425                 bp_.sides = OneSide;
3426
3427         if (pageLayoutModule->landscapeRB->isChecked())
3428                 bp_.orientation = ORIENTATION_LANDSCAPE;
3429         else
3430                 bp_.orientation = ORIENTATION_PORTRAIT;
3431
3432         // margins
3433         bp_.use_geometry = !marginsModule->marginCB->isChecked();
3434
3435         Ui::MarginsUi const * m = marginsModule;
3436
3437         bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
3438         bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
3439         bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
3440         bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
3441         bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
3442         bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
3443         bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
3444         bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
3445
3446         // branches
3447         branchesModule->apply(bp_);
3448
3449         // PDF support
3450         PDFOptions & pdf = bp_.pdfoptions();
3451         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
3452         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
3453         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
3454         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
3455         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
3456
3457         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
3458         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
3459         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
3460         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
3461
3462         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
3463         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
3464         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
3465         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
3466         pdf.backref =
3467                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
3468         if (pdfSupportModule->fullscreenCB->isChecked())
3469                 pdf.pagemode = pdf.pagemode_fullscreen;
3470         else
3471                 pdf.pagemode.clear();
3472         pdf.quoted_options = pdf.quoted_options_check(
3473                                 fromqstr(pdfSupportModule->optionsLE->text()));
3474
3475         // reset trackers
3476         nonModuleChanged_ = false;
3477         shellescapeChanged_ = false;
3478 }
3479
3480
3481 void GuiDocument::paramsToDialog()
3482 {
3483         // set the default unit
3484         Length::UNIT const default_unit = Length::defaultUnit();
3485
3486         // preamble
3487         preambleModule->update(bp_, id());
3488         localLayout->update(bp_, id());
3489
3490         // date
3491         latexModule->suppressDateCB->setChecked(bp_.suppress_date);
3492         latexModule->refstyleCB->setChecked(bp_.use_refstyle);
3493
3494         // biblio
3495         string const cite_engine = bp_.citeEngine();
3496
3497         biblioModule->citeEngineCO->setCurrentIndex(
3498                 biblioModule->citeEngineCO->findData(toqstr(cite_engine)));
3499
3500         updateEngineType(documentClass().opt_enginetype(),
3501                 bp_.citeEngineType());
3502
3503         checkPossibleCiteEngines();
3504
3505         biblioModule->citeStyleCO->setCurrentIndex(
3506                 biblioModule->citeStyleCO->findData(bp_.citeEngineType()));
3507
3508         biblioModule->bibtopicCB->setChecked(bp_.splitbib());
3509
3510         biblioModule->bibunitsCO->clear();
3511         biblioModule->bibunitsCO->addItem(qt_("No"), QString());
3512         if (documentClass().hasLaTeXLayout("part"))
3513                 biblioModule->bibunitsCO->addItem(qt_("per part"), toqstr("part"));
3514         if (documentClass().hasLaTeXLayout("chapter"))
3515                 biblioModule->bibunitsCO->addItem(qt_("per chapter"), toqstr("chapter"));
3516         if (documentClass().hasLaTeXLayout("section"))
3517                 biblioModule->bibunitsCO->addItem(qt_("per section"), toqstr("section"));
3518         if (documentClass().hasLaTeXLayout("subsection"))
3519                 biblioModule->bibunitsCO->addItem(qt_("per subsection"), toqstr("subsection"));
3520         biblioModule->bibunitsCO->addItem(qt_("per child document"), toqstr("child"));
3521
3522         int const mbpos = biblioModule->bibunitsCO->findData(toqstr(bp_.multibib));
3523         if (mbpos != -1)
3524                 biblioModule->bibunitsCO->setCurrentIndex(mbpos);
3525         else
3526                 biblioModule->bibunitsCO->setCurrentIndex(0);
3527
3528         updateEngineDependends();
3529
3530         if (isBiblatex()) {
3531                 updateDefaultBiblio(bp_.biblatex_bibstyle, "bbx");
3532                 updateDefaultBiblio(bp_.biblatex_citestyle, "cbx");
3533         } else
3534                 updateDefaultBiblio(bp_.defaultBiblioStyle());
3535
3536         biblioModule->citePackageOptionsLE->setText(toqstr(bp_.biblio_opts));
3537
3538         string command;
3539         string options =
3540                 split(bp_.bibtex_command, command, ' ');
3541
3542         int const bpos = biblioModule->bibtexCO->findData(toqstr(command));
3543         if (bpos != -1) {
3544                 biblioModule->bibtexCO->setCurrentIndex(bpos);
3545                 biblioModule->bibtexOptionsLE->setText(toqstr(options).trimmed());
3546         } else {
3547                 // We reset to default if we do not know the specified compiler
3548                 // This is for security reasons
3549                 biblioModule->bibtexCO->setCurrentIndex(
3550                         biblioModule->bibtexCO->findData(toqstr("default")));
3551                 biblioModule->bibtexOptionsLE->clear();
3552         }
3553         biblioModule->bibtexOptionsLE->setEnabled(
3554                 biblioModule->bibtexCO->currentIndex() != 0);
3555
3556         biblioChanged_ = false;
3557
3558         // indices
3559         // We may be called when there is no Buffer, e.g., when
3560         // the last view has just been closed.
3561         bool const isReadOnly = isBufferAvailable() ? buffer().isReadonly() : false;
3562         indicesModule->update(bp_, isReadOnly);
3563
3564         // language & quotes
3565         int const pos = langModule->languageCO->findData(toqstr(
3566                 bp_.language->lang()));
3567         langModule->languageCO->setCurrentIndex(pos);
3568
3569         updateQuoteStyles();
3570
3571         langModule->quoteStyleCO->setCurrentIndex(
3572                 langModule->quoteStyleCO->findData(bp_.quotes_style));
3573         langModule->dynamicQuotesCB->setChecked(bp_.dynamic_quotes);
3574
3575         bool default_enc = true;
3576         if (bp_.inputenc != "auto") {
3577                 default_enc = false;
3578                 if (bp_.inputenc == "default") {
3579                         langModule->encodingCO->setCurrentIndex(0);
3580                 } else {
3581                         string enc_gui;
3582                         Encodings::const_iterator it = encodings.begin();
3583                         Encodings::const_iterator const end = encodings.end();
3584                         for (; it != end; ++it) {
3585                                 if (it->name() == bp_.inputenc &&
3586                                     !it->unsafe()) {
3587                                         enc_gui = it->guiName();
3588                                         break;
3589                                 }
3590                         }
3591                         int const i = langModule->encodingCO->findText(
3592                                         qt_(enc_gui));
3593                         if (i >= 0)
3594                                 langModule->encodingCO->setCurrentIndex(i);
3595                         else
3596                                 // unknown encoding. Set to default.
3597                                 default_enc = true;
3598                 }
3599         }
3600         langModule->defaultencodingRB->setChecked(default_enc);
3601         langModule->otherencodingRB->setChecked(!default_enc);
3602
3603         int const p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
3604         if (p == -1) {
3605                 langModule->languagePackageCO->setCurrentIndex(
3606                           langModule->languagePackageCO->findData("custom"));
3607                 langModule->languagePackageLE->setText(toqstr(bp_.lang_package));
3608         } else {
3609                 langModule->languagePackageCO->setCurrentIndex(p);
3610                 langModule->languagePackageLE->clear();
3611         }
3612
3613         //color
3614         if (bp_.isfontcolor) {
3615                 colorModule->fontColorPB->setStyleSheet(
3616                         colorButtonStyleSheet(rgb2qcolor(bp_.fontcolor)));
3617         }
3618         set_fontcolor = bp_.fontcolor;
3619         is_fontcolor = bp_.isfontcolor;
3620
3621         colorModule->noteFontColorPB->setStyleSheet(
3622                 colorButtonStyleSheet(rgb2qcolor(bp_.notefontcolor)));
3623         set_notefontcolor = bp_.notefontcolor;
3624
3625         if (bp_.isbackgroundcolor) {
3626                 colorModule->backgroundPB->setStyleSheet(
3627                         colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
3628         }
3629         set_backgroundcolor = bp_.backgroundcolor;
3630         is_backgroundcolor = bp_.isbackgroundcolor;
3631
3632         colorModule->boxBackgroundPB->setStyleSheet(
3633                 colorButtonStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
3634         set_boxbgcolor = bp_.boxbgcolor;
3635
3636         // numbering
3637         int const min_toclevel = documentClass().min_toclevel();
3638         int const max_toclevel = documentClass().max_toclevel();
3639         if (documentClass().hasTocLevels()) {
3640                 numberingModule->setEnabled(true);
3641                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
3642                 numberingModule->depthSL->setMaximum(max_toclevel);
3643                 numberingModule->depthSL->setValue(bp_.secnumdepth);
3644                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
3645                 numberingModule->tocSL->setMaximum(max_toclevel);
3646                 numberingModule->tocSL->setValue(bp_.tocdepth);
3647                 updateNumbering();
3648         } else {
3649                 numberingModule->setEnabled(false);
3650                 numberingModule->tocTW->clear();
3651         }
3652
3653         // bullets
3654         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
3655         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
3656         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
3657         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
3658         bulletsModule->init();
3659
3660         // packages
3661         int nitem = findToken(tex_graphics, bp_.graphics_driver);
3662         if (nitem >= 0)
3663                 latexModule->psdriverCO->setCurrentIndex(nitem);
3664         updateModuleInfo();
3665
3666         // math
3667         mathsModule->MathIndentCB->setChecked(bp_.is_math_indent);
3668         if (bp_.is_math_indent) {
3669                 Length const mathindent = bp_.getMathIndent();
3670                 int indent = 0;
3671                 if (!mathindent.empty()) {
3672                         lengthToWidgets(mathsModule->MathIndentLE,
3673                                         mathsModule->MathIndentLengthCO,
3674                                         mathindent, default_unit);
3675                         indent = 1;
3676                 }
3677                 mathsModule->MathIndentCO->setCurrentIndex(indent);
3678                 enableMathIndent(indent);
3679         }
3680         switch(bp_.math_numbering_side) {
3681         case BufferParams::LEFT:
3682                 mathsModule->MathNumberingPosCO->setCurrentIndex(0);
3683                 break;
3684         case BufferParams::DEFAULT:
3685                 mathsModule->MathNumberingPosCO->setCurrentIndex(1);
3686                 break;
3687         case BufferParams::RIGHT:
3688                 mathsModule->MathNumberingPosCO->setCurrentIndex(2);
3689         }
3690
3691         map<string, string> const & packages = BufferParams::auto_packages();
3692         for (map<string, string>::const_iterator it = packages.begin();
3693              it != packages.end(); ++it) {
3694                 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
3695                 if (!item)
3696                         continue;
3697                 int row = mathsModule->packagesTW->row(item);
3698                 switch (bp_.use_package(it->first)) {
3699                         case BufferParams::package_off: {
3700                                 QRadioButton * rb =
3701                                         (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3)->layout()->itemAt(0)->widget();
3702                                 rb->setChecked(true);
3703                                 break;
3704                         }
3705                         case BufferParams::package_on: {
3706                                 QRadioButton * rb =
3707                                         (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2)->layout()->itemAt(0)->widget();
3708                                 rb->setChecked(true);
3709                                 break;
3710                         }
3711                         case BufferParams::package_auto: {
3712                                 QRadioButton * rb =
3713                                         (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1)->layout()->itemAt(0)->widget();
3714                                 rb->setChecked(true);
3715                                 break;
3716                         }
3717                 }
3718         }
3719
3720         switch (bp_.spacing().getSpace()) {
3721                 case Spacing::Other: nitem = 3; break;
3722                 case Spacing::Double: nitem = 2; break;
3723                 case Spacing::Onehalf: nitem = 1; break;
3724                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
3725         }
3726
3727         // text layout
3728         string const & layoutID = bp_.baseClassID();
3729         setLayoutComboByIDString(layoutID);
3730
3731         updatePagestyle(documentClass().opt_pagestyle(),
3732                                  bp_.pagestyle);
3733
3734         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
3735         if (bp_.spacing().getSpace() == Spacing::Other) {
3736                 doubleToWidget(textLayoutModule->lspacingLE,
3737                         bp_.spacing().getValueAsString());
3738         }
3739         setLSpacing(nitem);
3740
3741         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
3742                 textLayoutModule->indentRB->setChecked(true);
3743                 string parindent = bp_.getParIndent().asString();
3744                 int indent = 0;
3745                 if (!parindent.empty()) {
3746                         lengthToWidgets(textLayoutModule->indentLE,
3747                                         textLayoutModule->indentLengthCO,
3748                                         parindent, default_unit);
3749                         indent = 1;
3750                 }
3751                 textLayoutModule->indentCO->setCurrentIndex(indent);
3752                 setIndent(indent);
3753         } else {
3754                 textLayoutModule->skipRB->setChecked(true);
3755                 int skip = 0;
3756                 switch (bp_.getDefSkip().kind()) {
3757                 case VSpace::SMALLSKIP:
3758                         skip = 0;
3759                         break;
3760                 case VSpace::MEDSKIP:
3761                         skip = 1;
3762                         break;
3763                 case VSpace::BIGSKIP:
3764                         skip = 2;
3765                         break;
3766                 case VSpace::LENGTH:
3767                         {
3768                         skip = 3;
3769                         string const length = bp_.getDefSkip().asLyXCommand();
3770                         lengthToWidgets(textLayoutModule->skipLE,
3771                                 textLayoutModule->skipLengthCO,
3772                                 length, default_unit);
3773                         break;
3774                         }
3775                 default:
3776                         skip = 0;
3777                         break;
3778                 }
3779                 textLayoutModule->skipCO->setCurrentIndex(skip);
3780                 setSkip(skip);
3781         }
3782
3783         textLayoutModule->twoColumnCB->setChecked(
3784                 bp_.columns == 2);
3785         textLayoutModule->justCB->setChecked(bp_.justification);
3786
3787         if (!bp_.options.empty()) {
3788                 latexModule->optionsLE->setText(
3789                         toqstr(bp_.options));
3790         } else {
3791                 latexModule->optionsLE->setText(QString());
3792         }
3793
3794         // latex
3795         latexModule->defaultOptionsCB->setChecked(
3796                         bp_.use_default_options);
3797         updateSelectedModules();
3798         selectionManager->updateProvidedModules(
3799                         bp_.baseClass()->providedModules());
3800         selectionManager->updateExcludedModules(
3801                         bp_.baseClass()->excludedModules());
3802
3803         if (!documentClass().options().empty()) {
3804                 latexModule->defaultOptionsLE->setText(
3805                         toqstr(documentClass().options()));
3806         } else {
3807                 latexModule->defaultOptionsLE->setText(
3808                         toqstr(_("[No options predefined]")));
3809         }
3810
3811         latexModule->defaultOptionsLE->setEnabled(
3812                 bp_.use_default_options
3813                 && !documentClass().options().empty());
3814
3815         latexModule->defaultOptionsCB->setEnabled(
3816                 !documentClass().options().empty());
3817
3818         if (!bp_.master.empty()) {
3819                 latexModule->childDocGB->setChecked(true);
3820                 latexModule->childDocLE->setText(
3821                         toqstr(bp_.master));
3822         } else {
3823                 latexModule->childDocLE->setText(QString());
3824                 latexModule->childDocGB->setChecked(false);
3825         }
3826
3827         // Master/Child
3828         if (!bufferview() || !buffer().hasChildren()) {
3829                 masterChildModule->childrenTW->clear();
3830                 includeonlys_.clear();
3831                 docPS->showPanel("Child Documents", false);
3832                 if (docPS->isCurrentPanel("Child Documents"))
3833                         docPS->setCurrentPanel("Document Class");
3834         } else {
3835                 docPS->showPanel("Child Documents", true);
3836                 masterChildModule->setEnabled(true);
3837                 includeonlys_ = bp_.getIncludedChildren();
3838                 updateIncludeonlys();
3839         }
3840         masterChildModule->maintainAuxCB->setChecked(
3841                 bp_.maintain_unincluded_children);
3842
3843         // Float Settings
3844         floatModule->setPlacement(bp_.float_placement);
3845         floatModule->setAlignment(bp_.float_alignment);
3846
3847         // ListingsSettings
3848         // break listings_params to multiple lines
3849         string lstparams =
3850                 InsetListingsParams(bp_.listings_params).separatedParams();
3851         listingsModule->listingsED->setPlainText(toqstr(lstparams));
3852         int nn = findToken(lst_packages, bp_.use_minted ? "Minted" : "Listings");
3853         if (nn >= 0)
3854                 listingsModule->packageCO->setCurrentIndex(nn);
3855
3856         // Fonts
3857         // some languages only work with Polyglossia (which requires non-TeX fonts)
3858         Language const * lang = lyx::languages.getLanguage(
3859                 fromqstr(langModule->languageCO->itemData(
3860                         langModule->languageCO->currentIndex()).toString()));
3861         bool const need_fontspec =
3862                 lang->babel().empty() && !lang->polyglossia().empty();
3863         bool const os_fonts_available =
3864                 bp_.baseClass()->outputType() == lyx::LATEX
3865                 && LaTeXFeatures::isAvailable("fontspec");
3866         fontModule->osFontsCB->setEnabled(os_fonts_available && !need_fontspec);
3867         fontModule->osFontsCB->setChecked(
3868                 (os_fonts_available && bp_.useNonTeXFonts) || need_fontspec);
3869         updateFontsize(documentClass().opt_fontsize(),
3870                         bp_.fontsize);
3871
3872         QString font = toqstr(bp_.fontsRoman());
3873         int rpos = fontModule->fontsRomanCO->findData(font);
3874         if (rpos == -1) {
3875                 rpos = fontModule->fontsRomanCO->count();
3876                 fontModule->fontsRomanCO->addItem(font + qt_(" (not installed)"), font);
3877         }
3878         fontModule->fontsRomanCO->setCurrentIndex(rpos);
3879         fontModule->font_roman = toqstr(bp_.fonts_roman[!bp_.useNonTeXFonts]);
3880
3881         font = toqstr(bp_.fontsSans());
3882         int spos = fontModule->fontsSansCO->findData(font);
3883         if (spos == -1) {
3884                 spos = fontModule->fontsSansCO->count();
3885                 fontModule->fontsSansCO->addItem(font + qt_(" (not installed)"), font);
3886         }
3887         fontModule->fontsSansCO->setCurrentIndex(spos);
3888         fontModule->font_sans = toqstr(bp_.fonts_sans[!bp_.useNonTeXFonts]);
3889
3890         font = toqstr(bp_.fontsTypewriter());
3891         int tpos = fontModule->fontsTypewriterCO->findData(font);
3892         if (tpos == -1) {
3893                 tpos = fontModule->fontsTypewriterCO->count();
3894                 fontModule->fontsTypewriterCO->addItem(font + qt_(" (not installed)"), font);
3895         }
3896         fontModule->fontsTypewriterCO->setCurrentIndex(tpos);
3897         fontModule->font_typewriter = toqstr(bp_.fonts_typewriter[!bp_.useNonTeXFonts]);
3898
3899         font = toqstr(bp_.fontsMath());
3900         int mpos = fontModule->fontsMathCO->findData(font);
3901         if (mpos == -1) {
3902                 mpos = fontModule->fontsMathCO->count();
3903                 fontModule->fontsMathCO->addItem(font + qt_(" (not installed)"), font);
3904         }
3905         fontModule->fontsMathCO->setCurrentIndex(mpos);
3906         fontModule->font_math = toqstr(bp_.fonts_math[!bp_.useNonTeXFonts]);
3907
3908         if (bp_.useNonTeXFonts && os_fonts_available) {
3909                 fontModule->fontencLA->setEnabled(false);
3910                 fontModule->fontencCO->setEnabled(false);
3911                 fontModule->fontencLE->setEnabled(false);
3912         } else {
3913                 fontModule->fontencLA->setEnabled(true);
3914                 fontModule->fontencCO->setEnabled(true);
3915                 fontModule->fontencLE->setEnabled(true);
3916                 romanChanged(rpos);
3917                 sansChanged(spos);
3918                 ttChanged(tpos);
3919         }
3920
3921         if (!bp_.fonts_cjk.empty())
3922                 fontModule->cjkFontLE->setText(
3923                         toqstr(bp_.fonts_cjk));
3924         else
3925                 fontModule->cjkFontLE->setText(QString());
3926
3927         fontModule->microtypeCB->setChecked(bp_.use_microtype);
3928         fontModule->dashesCB->setChecked(!bp_.use_dash_ligatures);
3929
3930         fontModule->fontScCB->setChecked(bp_.fonts_expert_sc);
3931         fontModule->fontOsfCB->setChecked(bp_.fonts_old_figures);
3932         fontModule->scaleSansSB->setValue(bp_.fontsSansScale());
3933         fontModule->font_sf_scale = bp_.fonts_sans_scale[!bp_.useNonTeXFonts];
3934         fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale());
3935         fontModule->font_tt_scale = bp_.fonts_typewriter_scale[!bp_.useNonTeXFonts];
3936
3937         nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
3938         if (nn >= 0)
3939                 fontModule->fontsDefaultCO->setCurrentIndex(nn);
3940
3941         if (bp_.fontenc == "auto" || bp_.fontenc == "default") {
3942                 fontModule->fontencCO->setCurrentIndex(
3943                         fontModule->fontencCO->findData(toqstr(bp_.fontenc)));
3944                 fontModule->fontencLE->setEnabled(false);
3945         } else {
3946                 fontModule->fontencCO->setCurrentIndex(
3947                                         fontModule->fontencCO->findData("custom"));
3948                 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
3949         }
3950
3951         // Formats
3952         // This must be set _after_ fonts since updateDefaultFormat()
3953         // checks osFontsCB settings.
3954         // update combobox with formats
3955         updateDefaultFormat();
3956         int index = outputModule->defaultFormatCO->findData(toqstr(
3957                 bp_.default_output_format));
3958         // set to default if format is not found
3959         if (index == -1)
3960                 index = 0;
3961         outputModule->defaultFormatCO->setCurrentIndex(index);
3962
3963         outputModule->shellescapeCB->setChecked(bp_.shell_escape);
3964         outputModule->outputsyncCB->setChecked(bp_.output_sync);
3965         outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
3966
3967         outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
3968         outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
3969         outputModule->strictCB->setChecked(bp_.html_be_strict);
3970         outputModule->cssCB->setChecked(bp_.html_css_as_file);
3971
3972         outputModule->saveTransientPropertiesCB
3973                 ->setChecked(bp_.save_transient_properties);
3974
3975         // paper
3976         bool const extern_geometry =
3977                 documentClass().provides("geometry");
3978         int const psize = bp_.papersize;
3979         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
3980         setCustomPapersize(!extern_geometry && psize == 1);
3981         pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
3982
3983         bool const landscape =
3984                 bp_.orientation == ORIENTATION_LANDSCAPE;
3985         pageLayoutModule->landscapeRB->setChecked(landscape);
3986         pageLayoutModule->portraitRB->setChecked(!landscape);
3987         pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
3988         pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
3989
3990         pageLayoutModule->facingPagesCB->setChecked(
3991                 bp_.sides == TwoSides);
3992
3993         lengthToWidgets(pageLayoutModule->paperwidthLE,
3994                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, default_unit);
3995         lengthToWidgets(pageLayoutModule->paperheightLE,
3996                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, default_unit);
3997
3998         // margins
3999         Ui::MarginsUi * m = marginsModule;
4000
4001         setMargins();
4002
4003         lengthToWidgets(m->topLE, m->topUnit,
4004                 bp_.topmargin, default_unit);
4005
4006         lengthToWidgets(m->bottomLE, m->bottomUnit,
4007                 bp_.bottommargin, default_unit);
4008
4009         lengthToWidgets(m->innerLE, m->innerUnit,
4010                 bp_.leftmargin, default_unit);
4011
4012         lengthToWidgets(m->outerLE, m->outerUnit,
4013                 bp_.rightmargin, default_unit);
4014
4015         lengthToWidgets(m->headheightLE, m->headheightUnit,
4016                 bp_.headheight, default_unit);
4017
4018         lengthToWidgets(m->headsepLE, m->headsepUnit,
4019                 bp_.headsep, default_unit);
4020
4021         lengthToWidgets(m->footskipLE, m->footskipUnit,
4022                 bp_.footskip, default_unit);
4023
4024         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
4025                 bp_.columnsep, default_unit);
4026
4027         // branches
4028         updateUnknownBranches();
4029         branchesModule->update(bp_);
4030
4031         // PDF support
4032         PDFOptions const & pdf = bp_.pdfoptions();
4033         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
4034         if (bp_.documentClass().provides("hyperref"))
4035                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("C&ustomize Hyperref Options"));
4036         else
4037                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("&Use Hyperref Support"));
4038         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
4039         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
4040         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
4041         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
4042
4043         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
4044         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
4045         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
4046
4047         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
4048
4049         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
4050         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
4051         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
4052         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
4053
4054         nn = findToken(backref_opts, pdf.backref);
4055         if (nn >= 0)
4056                 pdfSupportModule->backrefCO->setCurrentIndex(nn);
4057
4058         pdfSupportModule->fullscreenCB->setChecked
4059                 (pdf.pagemode == pdf.pagemode_fullscreen);
4060
4061         pdfSupportModule->optionsLE->setText(
4062                 toqstr(pdf.quoted_options));
4063
4064         // Make sure that the bc is in the INITIAL state
4065         if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
4066                 bc().restore();
4067
4068         // clear changed branches cache
4069         changedBranches_.clear();
4070
4071         // reset trackers
4072         nonModuleChanged_ = false;
4073         shellescapeChanged_ = false;
4074 }
4075
4076
4077 void GuiDocument::saveDocDefault()
4078 {
4079         // we have to apply the params first
4080         applyView();
4081         saveAsDefault();
4082 }
4083
4084
4085 void GuiDocument::updateAvailableModules()
4086 {
4087         modules_av_model_.clear();
4088         list<modInfoStruct> modInfoList = getModuleInfo();
4089         // Sort names according to the locale
4090         modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
4091                         return 0 < b.name.localeAwareCompare(a.name);
4092                 });
4093         int i = 0;
4094         for (modInfoStruct const & m : modInfoList) {
4095                 modules_av_model_.insertRow(i, m.name, m.id, m.description);
4096                 ++i;
4097         }
4098 }
4099
4100
4101 void GuiDocument::updateSelectedModules()
4102 {
4103         modules_sel_model_.clear();
4104         list<modInfoStruct> const selModList = getSelectedModules();
4105         int i = 0;
4106         for (modInfoStruct const & m : selModList) {
4107                 modules_sel_model_.insertRow(i, m.name, m.id, m.description);
4108                 ++i;
4109         }
4110 }
4111
4112
4113 void GuiDocument::updateIncludeonlys()
4114 {
4115         masterChildModule->childrenTW->clear();
4116         QString const no = qt_("No");
4117         QString const yes = qt_("Yes");
4118
4119         if (includeonlys_.empty()) {
4120                 masterChildModule->includeallRB->setChecked(true);
4121                 masterChildModule->childrenTW->setEnabled(false);
4122                 masterChildModule->maintainAuxCB->setEnabled(false);
4123         } else {
4124                 masterChildModule->includeonlyRB->setChecked(true);
4125                 masterChildModule->childrenTW->setEnabled(true);
4126                 masterChildModule->maintainAuxCB->setEnabled(true);
4127         }
4128         ListOfBuffers children = buffer().getChildren();
4129         ListOfBuffers::const_iterator it  = children.begin();
4130         ListOfBuffers::const_iterator end = children.end();
4131         bool has_unincluded = false;
4132         bool all_unincluded = true;
4133         for (; it != end; ++it) {
4134                 QTreeWidgetItem * item = new QTreeWidgetItem(masterChildModule->childrenTW);
4135                 // FIXME Unicode
4136                 string const name =
4137                         to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
4138                                                         from_utf8(buffer().filePath())));
4139                 item->setText(0, toqstr(name));
4140                 item->setText(1, isChildIncluded(name) ? yes : no);
4141                 if (!isChildIncluded(name))
4142                         has_unincluded = true;
4143                 else
4144                         all_unincluded = false;
4145         }
4146         // Both if all childs are included and if none is included
4147         // is equal to "include all" (i.e., omit \includeonly).
4148         // Thus, reset the GUI.
4149         if (!has_unincluded || all_unincluded) {
4150                 masterChildModule->includeallRB->setChecked(true);
4151                 masterChildModule->childrenTW->setEnabled(false);
4152                 includeonlys_.clear();
4153         }
4154         // If all are included, we need to update again.
4155         if (!has_unincluded)
4156                 updateIncludeonlys();
4157 }
4158
4159
4160 bool GuiDocument::isBiblatex() const
4161 {
4162         QString const engine =
4163                 biblioModule->citeEngineCO->itemData(
4164                                 biblioModule->citeEngineCO->currentIndex()).toString();
4165
4166         // this can happen if the cite engine is unknown, which can happen
4167         // if one is using a file that came from someone else, etc. in that
4168         // case, we crash if we proceed.
4169         if (engine.isEmpty())
4170             return false;
4171
4172         return theCiteEnginesList[fromqstr(engine)]->getCiteFramework() == "biblatex";
4173 }
4174
4175
4176 void GuiDocument::updateDefaultBiblio(string const & style,
4177                                       string const & which)
4178 {
4179         QString const bibstyle = toqstr(style);
4180         biblioModule->defaultBiblioCO->clear();
4181
4182         int item_nr = -1;
4183
4184         if (isBiblatex()) {
4185                 if (which != "cbx") {
4186                         // First the bbx styles
4187                         biblioModule->biblatexBbxCO->clear();
4188                         QStringList str = texFileList("bbxFiles.lst");
4189                         // test whether we have a valid list, otherwise run rescan
4190                         if (str.isEmpty()) {
4191                                 rescanTexStyles("bbx");
4192                                 str = texFileList("bbxFiles.lst");
4193                         }
4194                         for (int i = 0; i != str.size(); ++i)
4195                                 str[i] = onlyFileName(str[i]);
4196                         // sort on filename only (no path)
4197                         str.sort();
4198
4199                         for (int i = 0; i != str.count(); ++i) {
4200                                 QString item = changeExtension(str[i], "");
4201                                 if (item == bibstyle)
4202                                         item_nr = i;
4203                                 biblioModule->biblatexBbxCO->addItem(item);
4204                         }
4205
4206                         if (item_nr == -1 && !bibstyle.isEmpty()) {
4207                                 biblioModule->biblatexBbxCO->addItem(bibstyle);
4208                                 item_nr = biblioModule->biblatexBbxCO->count() - 1;
4209                         }
4210
4211                         if (item_nr != -1)
4212                                 biblioModule->biblatexBbxCO->setCurrentIndex(item_nr);
4213                         else
4214                                 biblioModule->biblatexBbxCO->clearEditText();
4215                 }
4216
4217                 if (which != "bbx") {
4218                         // now the cbx styles
4219                         biblioModule->biblatexCbxCO->clear();
4220                         QStringList str = texFileList("cbxFiles.lst");
4221                         // test whether we have a valid list, otherwise run rescan
4222                         if (str.isEmpty()) {
4223                                 rescanTexStyles("cbx");
4224                                 str = texFileList("cbxFiles.lst");
4225                         }
4226                         for (int i = 0; i != str.size(); ++i)
4227                                 str[i] = onlyFileName(str[i]);
4228                         // sort on filename only (no path)
4229                         str.sort();
4230
4231                         for (int i = 0; i != str.count(); ++i) {
4232                                 QString item = changeExtension(str[i], "");
4233                                 if (item == bibstyle)
4234                                         item_nr = i;
4235                                 biblioModule->biblatexCbxCO->addItem(item);
4236                         }
4237
4238                         if (item_nr == -1 && !bibstyle.isEmpty()) {
4239                                 biblioModule->biblatexCbxCO->addItem(bibstyle);
4240                                 item_nr = biblioModule->biblatexCbxCO->count() - 1;
4241                         }
4242
4243                         if (item_nr != -1)
4244                                 biblioModule->biblatexCbxCO->setCurrentIndex(item_nr);
4245                         else
4246                                 biblioModule->biblatexCbxCO->clearEditText();
4247                 }
4248         } else {// BibTeX
4249                 biblioModule->biblatexBbxCO->clear();
4250                 biblioModule->biblatexCbxCO->clear();
4251                 QStringList str = texFileList("bstFiles.lst");
4252                 // test whether we have a valid list, otherwise run rescan
4253                 if (str.isEmpty()) {
4254                         rescanTexStyles("bst");
4255                         str = texFileList("bstFiles.lst");
4256                 }
4257                 for (int i = 0; i != str.size(); ++i)
4258                         str[i] = onlyFileName(str[i]);
4259                 // sort on filename only (no path)
4260                 str.sort();
4261
4262                 for (int i = 0; i != str.count(); ++i) {
4263                         QString item = changeExtension(str[i], "");
4264                         if (item == bibstyle)
4265                                 item_nr = i;
4266                         biblioModule->defaultBiblioCO->addItem(item);
4267                 }
4268
4269                 if (item_nr == -1 && !bibstyle.isEmpty()) {
4270                         biblioModule->defaultBiblioCO->addItem(bibstyle);
4271                         item_nr = biblioModule->defaultBiblioCO->count() - 1;
4272                 }
4273
4274                 if (item_nr != -1)
4275                         biblioModule->defaultBiblioCO->setCurrentIndex(item_nr);
4276                 else
4277                         biblioModule->defaultBiblioCO->clearEditText();
4278         }
4279
4280         updateResetDefaultBiblio();
4281 }
4282
4283
4284 void GuiDocument::updateResetDefaultBiblio()
4285 {
4286         QString const engine =
4287                 biblioModule->citeEngineCO->itemData(
4288                                 biblioModule->citeEngineCO->currentIndex()).toString();
4289         CiteEngineType const cet =
4290                 CiteEngineType(biblioModule->citeStyleCO->itemData(
4291                                                           biblioModule->citeStyleCO->currentIndex()).toInt());
4292
4293         string const defbib = theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet);
4294         if (isBiblatex()) {
4295                 QString const bbx = biblioModule->biblatexBbxCO->currentText();
4296                 QString const cbx = biblioModule->biblatexCbxCO->currentText();
4297                 biblioModule->resetCbxPB->setEnabled(defbib != fromqstr(cbx));
4298                 biblioModule->resetBbxPB->setEnabled(defbib != fromqstr(bbx));
4299                 biblioModule->matchBbxPB->setEnabled(bbx != cbx && !cbx.isEmpty()
4300                         && biblioModule->biblatexBbxCO->findText(cbx) != -1);
4301         } else
4302                 biblioModule->resetDefaultBiblioPB->setEnabled(
4303                         defbib != fromqstr(biblioModule->defaultBiblioCO->currentText()));
4304 }
4305
4306
4307 void GuiDocument::matchBiblatexStyles()
4308 {
4309         updateDefaultBiblio(fromqstr(biblioModule->biblatexCbxCO->currentText()), "bbx");
4310         biblioChanged();
4311 }
4312
4313
4314 void GuiDocument::updateContents()
4315 {
4316         // Nothing to do here as the document settings is not cursor dependant.
4317         return;
4318 }
4319
4320
4321 void GuiDocument::useClassDefaults()
4322 {
4323         if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
4324                 int const ret = Alert::prompt(_("Unapplied changes"),
4325                                 _("Some changes in the dialog were not yet applied.\n"
4326                                   "If you do not apply now, they will be lost after this action."),
4327                                 1, 1, _("&Apply"), _("&Dismiss"));
4328                 if (ret == 0)
4329                         applyView();
4330         }
4331
4332         int idx = latexModule->classCO->currentIndex();
4333         string const classname = fromqstr(latexModule->classCO->getData(idx));
4334         if (!bp_.setBaseClass(classname, buffer().layoutPos())) {
4335                 Alert::error(_("Error"), _("Unable to set document class."));
4336                 return;
4337         }
4338         bp_.useClassDefaults();
4339         paramsToDialog();
4340         changed();
4341 }
4342
4343
4344 void GuiDocument::setLayoutComboByIDString(string const & idString)
4345 {
4346         if (!latexModule->classCO->set(toqstr(idString)))
4347                 Alert::warning(_("Can't set layout!"),
4348                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
4349 }
4350
4351
4352 bool GuiDocument::isValid()
4353 {
4354         return
4355                 validateListingsParameters().isEmpty() &&
4356                 localLayout->isValid() &&
4357                 !localLayout->editing() &&
4358                 !preambleModule->editing() &&
4359                 (
4360                         // if we're asking for skips between paragraphs
4361                         !textLayoutModule->skipRB->isChecked() ||
4362                         // then either we haven't chosen custom
4363                         textLayoutModule->skipCO->currentIndex() != 3 ||
4364                         // or else a length has been given
4365                         !textLayoutModule->skipLE->text().isEmpty()
4366                 ) &&
4367                 (
4368                         // if we're asking for indentation
4369                         !textLayoutModule->indentRB->isChecked() ||
4370                         // then either we haven't chosen custom
4371                         textLayoutModule->indentCO->currentIndex() != 1 ||
4372                         // or else a length has been given
4373                         !textLayoutModule->indentLE->text().isEmpty()
4374                 ) &&
4375                 (
4376                         // if we're asking for math indentation
4377                         !mathsModule->MathIndentCB->isChecked() ||
4378                         // then either we haven't chosen custom
4379                         mathsModule->MathIndentCO->currentIndex() != 1 ||
4380                         // or else a length has been given
4381                         !mathsModule->MathIndentLE->text().isEmpty()
4382                 );
4383 }
4384
4385
4386 char const * const GuiDocument::fontfamilies[5] = {
4387         "default", "rmdefault", "sfdefault", "ttdefault", ""
4388 };
4389
4390
4391 char const * GuiDocument::fontfamilies_gui[5] = {
4392         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
4393 };
4394
4395
4396 bool GuiDocument::initialiseParams(string const &)
4397 {
4398         BufferView const * view = bufferview();
4399         if (!view) {
4400                 bp_ = BufferParams();
4401                 paramsToDialog();
4402                 return true;
4403         }
4404         bp_ = view->buffer().params();
4405         loadModuleInfo();
4406         updateAvailableModules();
4407         //FIXME It'd be nice to make sure here that the selected
4408         //modules are consistent: That required modules are actually
4409         //selected, and that we don't have conflicts. If so, we could
4410         //at least pop up a warning.
4411         paramsToDialog();
4412         return true;
4413 }
4414
4415
4416 void GuiDocument::clearParams()
4417 {
4418         bp_ = BufferParams();
4419 }
4420
4421
4422 BufferId GuiDocument::id() const
4423 {
4424         BufferView const * const view = bufferview();
4425         return view? &view->buffer() : 0;
4426 }
4427
4428
4429 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
4430 {
4431         return moduleNames_;
4432 }
4433
4434
4435 list<GuiDocument::modInfoStruct> const
4436 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
4437 {
4438         list<modInfoStruct> mInfo;
4439         for (string const & name : mods) {
4440                 modInfoStruct m;
4441                 LyXModule const * const mod = theModuleList[name];
4442                 if (mod)
4443                         m = modInfo(*mod);
4444                 else {
4445                         m.id = name;
4446                         m.name = toqstr(name + " (") + qt_("Not Found") + toqstr(")");
4447                 }
4448                 mInfo.push_back(m);
4449         }
4450         return mInfo;
4451 }
4452
4453
4454 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
4455 {
4456         return makeModuleInfo(params().getModules());
4457 }
4458
4459
4460 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
4461 {
4462         return makeModuleInfo(params().baseClass()->providedModules());
4463 }
4464
4465
4466 DocumentClass const & GuiDocument::documentClass() const
4467 {
4468         return bp_.documentClass();
4469 }
4470
4471
4472 static void dispatch_bufferparams(Dialog const & dialog,
4473         BufferParams const & bp, FuncCode lfun, Buffer const * buf)
4474 {
4475         ostringstream ss;
4476         ss << "\\begin_header\n";
4477         bp.writeFile(ss, buf);
4478         ss << "\\end_header\n";
4479         dialog.dispatch(FuncRequest(lfun, ss.str()));
4480 }
4481
4482
4483 void GuiDocument::dispatchParams()
4484 {
4485         // We need a non-const buffer object.
4486         Buffer & buf = const_cast<BufferView *>(bufferview())->buffer();
4487         // There may be several undo records; group them (bug #8998)
4488         // This handles undo groups automagically
4489         UndoGroupHelper ugh(&buf);
4490
4491         // This must come first so that a language change is correctly noticed
4492         setLanguage();
4493
4494         // We need to load the master before we formally update the params,
4495         // since otherwise we run updateBuffer, etc, before the child's master
4496         // has been set.
4497         if (!params().master.empty()) {
4498                 FileName const master_file = support::makeAbsPath(params().master,
4499                            support::onlyPath(buffer().absFileName()));
4500                 if (isLyXFileName(master_file.absFileName())) {
4501                         Buffer * master = checkAndLoadLyXFile(master_file);
4502                         if (master) {
4503                                 if (master->isChild(const_cast<Buffer *>(&buffer())))
4504                                         const_cast<Buffer &>(buffer()).setParent(master);
4505                                 else
4506                                         Alert::warning(_("Assigned master does not include this file"),
4507                                                 bformat(_("You must include this file in the document\n"
4508                                                           "'%1$s' in order to use the master document\n"
4509                                                           "feature."), from_utf8(params().master)));
4510                         } else
4511                                 Alert::warning(_("Could not load master"),
4512                                                 bformat(_("The master document '%1$s'\n"
4513                                                            "could not be loaded."),
4514                                                            from_utf8(params().master)));
4515                 }
4516         }
4517
4518         // Apply the BufferParams. Note that this will set the base class
4519         // and then update the buffer's layout.
4520         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY, &buffer());
4521
4522         // Generate the colours requested by each new branch.
4523         BranchList & branchlist = params().branchlist();
4524         if (!branchlist.empty()) {
4525                 BranchList::const_iterator it = branchlist.begin();
4526                 BranchList::const_iterator const end = branchlist.end();
4527                 for (; it != end; ++it) {
4528                         docstring const & current_branch = it->branch();
4529                         Branch const * branch = branchlist.find(current_branch);
4530                         string const x11hexname = X11hexname(branch->color());
4531                         // display the new color
4532                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
4533                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
4534                 }
4535         }
4536         // rename branches in the document
4537         executeBranchRenaming();
4538         // and clear changed branches cache
4539         changedBranches_.clear();
4540
4541         // Generate the colours requested by indices.
4542         IndicesList & indiceslist = params().indiceslist();
4543         if (!indiceslist.empty()) {
4544                 IndicesList::const_iterator it = indiceslist.begin();
4545                 IndicesList::const_iterator const end = indiceslist.end();
4546                 for (; it != end; ++it) {
4547                         docstring const & current_index = it->shortcut();
4548                         Index const * index = indiceslist.findShortcut(current_index);
4549                         string const x11hexname = X11hexname(index->color());
4550                         // display the new color
4551                         docstring const str = current_index + ' ' + from_ascii(x11hexname);
4552                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
4553                 }
4554         }
4555         // FIXME LFUN
4556         // If we used an LFUN, we would not need these two lines:
4557         BufferView * bv = const_cast<BufferView *>(bufferview());
4558         bv->processUpdateFlags(Update::Force | Update::FitCursor);
4559 }
4560
4561
4562 void GuiDocument::setLanguage() const
4563 {
4564         Language const * const newL = bp_.language;
4565         if (buffer().params().language == newL)
4566                 return;
4567
4568         string const & lang_name = newL->lang();
4569         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
4570 }
4571
4572
4573 void GuiDocument::saveAsDefault() const
4574 {
4575         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT, &buffer());
4576 }
4577
4578
4579 bool GuiDocument::providesOSF(QString const & font) const
4580 {
4581         if (fontModule->osFontsCB->isChecked())
4582                 // FIXME: we should check if the fonts really
4583                 // have OSF support. But how?
4584                 return true;
4585         return theLaTeXFonts().getLaTeXFont(
4586                                 qstring_to_ucs4(font)).providesOSF(ot1(),
4587                                                                    completeFontset(),
4588                                                                    noMathFont());
4589 }
4590
4591
4592 bool GuiDocument::providesSC(QString const & font) const
4593 {
4594         if (fontModule->osFontsCB->isChecked())
4595                 return false;
4596         return theLaTeXFonts().getLaTeXFont(
4597                                 qstring_to_ucs4(font)).providesSC(ot1(),
4598                                                                   completeFontset(),
4599                                                                   noMathFont());
4600 }
4601
4602
4603 bool GuiDocument::providesScale(QString const & font) const
4604 {
4605         if (fontModule->osFontsCB->isChecked())
4606                 return true;
4607         return theLaTeXFonts().getLaTeXFont(
4608                                 qstring_to_ucs4(font)).providesScale(ot1(),
4609                                                                      completeFontset(),
4610                                                                      noMathFont());
4611 }
4612
4613
4614 bool GuiDocument::providesNoMath(QString const & font) const
4615 {
4616         if (fontModule->osFontsCB->isChecked())
4617                 return false;
4618         return theLaTeXFonts().getLaTeXFont(
4619                                 qstring_to_ucs4(font)).providesNoMath(ot1(),
4620                                                                       completeFontset());
4621 }
4622
4623
4624 bool GuiDocument::hasMonolithicExpertSet(QString const & font) const
4625 {
4626         if (fontModule->osFontsCB->isChecked())
4627                 return false;
4628         return theLaTeXFonts().getLaTeXFont(
4629                                 qstring_to_ucs4(font)).hasMonolithicExpertSet(ot1(),
4630                                                                               completeFontset(),
4631                                                                               noMathFont());
4632 }
4633
4634
4635 //static
4636 GuiDocument::modInfoStruct GuiDocument::modInfo(LyXModule const & mod)
4637 {
4638         // FIXME Unicode: docstrings would be better for these parameters but this
4639         // change requires a lot of others
4640         modInfoStruct m;
4641         m.id = mod.getID();
4642         m.name = toqstr(translateIfPossible(from_utf8(mod.getName())));
4643         QString desc = toqstr(translateIfPossible(from_utf8(mod.getDescription())));
4644         // Find the first sentence of the description
4645         QTextBoundaryFinder bf(QTextBoundaryFinder::Sentence, desc);
4646         int pos = bf.toNextBoundary();
4647         if (pos > 0)
4648                 desc.truncate(pos);
4649         QString modulename = QString(qt_("(Module name: %1)")).arg(toqstr(m.id));
4650         // Tooltip is the desc followed by the module name
4651         m.description = QString("%1<i>%2</i>")
4652                 .arg(desc.isEmpty() ? QString() : QString("<p>%1</p>").arg(desc),
4653                      modulename);
4654         return m;
4655 }
4656
4657
4658 void GuiDocument::loadModuleInfo()
4659 {
4660         moduleNames_.clear();
4661         for (LyXModule const & mod : theModuleList)
4662                 if (mod.category().substr(0, 8) != "Citation")
4663                         moduleNames_.push_back(modInfo(mod));
4664 }
4665
4666
4667 void GuiDocument::updateUnknownBranches()
4668 {
4669         if (!bufferview())
4670                 return;
4671         list<docstring> used_branches;
4672         buffer().getUsedBranches(used_branches);
4673         list<docstring>::const_iterator it = used_branches.begin();
4674         QStringList unknown_branches;
4675         for (; it != used_branches.end() ; ++it) {
4676                 if (!buffer().params().branchlist().find(*it))
4677                         unknown_branches.append(toqstr(*it));
4678         }
4679         branchesModule->setUnknownBranches(unknown_branches);
4680 }
4681
4682
4683 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
4684 {
4685         map<docstring, docstring>::iterator it = changedBranches_.begin();
4686         for (; it != changedBranches_.end() ; ++it) {
4687                 if (it->second == oldname) {
4688                         // branch has already been renamed
4689                         it->second = newname;
4690                         return;
4691                 }
4692         }
4693         // store new name
4694         changedBranches_[oldname] = newname;
4695 }
4696
4697
4698 void GuiDocument::executeBranchRenaming() const
4699 {
4700         map<docstring, docstring>::const_iterator it = changedBranches_.begin();
4701         for (; it != changedBranches_.end() ; ++it) {
4702                 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
4703                 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
4704         }
4705 }
4706
4707
4708 void GuiDocument::allPackagesAuto()
4709 {
4710         allPackages(1);
4711 }
4712
4713
4714 void GuiDocument::allPackagesAlways()
4715 {
4716         allPackages(2);
4717 }
4718
4719
4720 void GuiDocument::allPackagesNot()
4721 {
4722         allPackages(3);
4723 }
4724
4725
4726 void GuiDocument::allPackages(int col)
4727 {
4728         for (int row = 0; row < mathsModule->packagesTW->rowCount(); ++row) {
4729                 QRadioButton * rb =
4730                         (QRadioButton*)mathsModule->packagesTW->cellWidget(row, col)->layout()->itemAt(0)->widget();
4731                 rb->setChecked(true);
4732         }
4733 }
4734
4735
4736 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
4737
4738
4739 } // namespace frontend
4740 } // namespace lyx
4741
4742 #include "moc_GuiDocument.cpp"