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