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