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