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