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