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