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