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