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