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