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