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