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