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