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