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