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