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