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