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