]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiDocument.cpp
Fix output of en- and em-dashes with TeX fonts
[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         updateMathFonts(font);
1961 }
1962
1963
1964 void GuiDocument::updateFontsize(string const & items, string const & sel)
1965 {
1966         fontModule->fontsizeCO->clear();
1967         fontModule->fontsizeCO->addItem(qt_("Default"));
1968
1969         for (int n = 0; !token(items,'|',n).empty(); ++n)
1970                 fontModule->fontsizeCO->
1971                         addItem(toqstr(token(items,'|',n)));
1972
1973         for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
1974                 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
1975                         fontModule->fontsizeCO->setCurrentIndex(n);
1976                         break;
1977                 }
1978         }
1979 }
1980
1981
1982 bool GuiDocument::ot1() const
1983 {
1984         QString const fontenc =
1985                 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
1986         return (fontenc == "default"
1987                 || (fontenc == "global" && (lyxrc.fontenc == "default" || lyxrc.fontenc == "OT1"))
1988                 || (fontenc == "custom" && fontModule->fontencLE->text() == "OT1"));
1989 }
1990
1991
1992 bool GuiDocument::completeFontset() const
1993 {
1994         return (fontModule->fontsSansCO->itemData(
1995                         fontModule->fontsSansCO->currentIndex()).toString() == "default"
1996                 && fontModule->fontsSansCO->itemData(
1997                         fontModule->fontsTypewriterCO->currentIndex()).toString() == "default");
1998 }
1999
2000
2001 bool GuiDocument::noMathFont() const
2002 {
2003         return (fontModule->fontsMathCO->itemData(
2004                 fontModule->fontsMathCO->currentIndex()).toString() == "default");
2005 }
2006
2007
2008 void GuiDocument::updateTexFonts()
2009 {
2010         LaTeXFonts::TexFontMap texfontmap = theLaTeXFonts().getLaTeXFonts();
2011
2012         LaTeXFonts::TexFontMap::const_iterator it = texfontmap.begin();
2013         LaTeXFonts::TexFontMap::const_iterator end = texfontmap.end();
2014         for (; it != end; ++it) {
2015                 LaTeXFont lf = it->second;
2016                 if (lf.name().empty()) {
2017                         LYXERR0("Error: Unnamed font: " << it->first);
2018                         continue;
2019                 }
2020                 docstring const family = lf.family();
2021                 docstring guiname = translateIfPossible(lf.guiname());
2022                 if (!lf.available(ot1(), noMathFont()))
2023                         guiname += _(" (not installed)");
2024                 if (family == "rm")
2025                         rmfonts_.insert(toqstr(guiname), toqstr(it->first));
2026                 else if (family == "sf")
2027                         sffonts_.insert(toqstr(guiname), toqstr(it->first));
2028                 else if (family == "tt")
2029                         ttfonts_.insert(toqstr(guiname), toqstr(it->first));
2030                 else if (family == "math")
2031                         mathfonts_.insert(toqstr(guiname), toqstr(it->first));
2032         }
2033 }
2034
2035
2036 void GuiDocument::updateFontlist()
2037 {
2038         fontModule->fontsRomanCO->clear();
2039         fontModule->fontsSansCO->clear();
2040         fontModule->fontsTypewriterCO->clear();
2041         fontModule->fontsMathCO->clear();
2042
2043         // With fontspec (XeTeX, LuaTeX), we have access to all system fonts, but not the LaTeX fonts
2044         if (fontModule->osFontsCB->isChecked()) {
2045                 fontModule->fontsRomanCO->addItem(qt_("Default"), QString("default"));
2046                 fontModule->fontsSansCO->addItem(qt_("Default"), QString("default"));
2047                 fontModule->fontsTypewriterCO->addItem(qt_("Default"), QString("default"));
2048                 QString unimath = qt_("Non-TeX Fonts Default");
2049                 if (!LaTeXFeatures::isAvailable("unicode-math"))
2050                         unimath += qt_(" (not available)");
2051                 fontModule->fontsMathCO->addItem(qt_("Class Default (TeX Fonts)"), QString("auto"));
2052                 fontModule->fontsMathCO->addItem(unimath, QString("default"));
2053
2054                 QFontDatabase fontdb;
2055                 QStringList families(fontdb.families());
2056                 for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
2057                         fontModule->fontsRomanCO->addItem(*it, *it);
2058                         fontModule->fontsSansCO->addItem(*it, *it);
2059                         fontModule->fontsTypewriterCO->addItem(*it, *it);
2060                 }
2061                 return;
2062         }
2063
2064         if (rmfonts_.empty())
2065                 updateTexFonts();
2066
2067         fontModule->fontsRomanCO->addItem(qt_("Default"), QString("default"));
2068         QMap<QString, QString>::const_iterator rmi = rmfonts_.constBegin();
2069         while (rmi != rmfonts_.constEnd()) {
2070                 fontModule->fontsRomanCO->addItem(rmi.key(), rmi.value());
2071                 ++rmi;
2072         }
2073
2074         fontModule->fontsSansCO->addItem(qt_("Default"), QString("default"));
2075         QMap<QString, QString>::const_iterator sfi = sffonts_.constBegin();
2076         while (sfi != sffonts_.constEnd()) {
2077                 fontModule->fontsSansCO->addItem(sfi.key(), sfi.value());
2078                 ++sfi;
2079         }
2080
2081         fontModule->fontsTypewriterCO->addItem(qt_("Default"), QString("default"));
2082         QMap<QString, QString>::const_iterator tti = ttfonts_.constBegin();
2083         while (tti != ttfonts_.constEnd()) {
2084                 fontModule->fontsTypewriterCO->addItem(tti.key(), tti.value());
2085                 ++tti;
2086         }
2087
2088         fontModule->fontsMathCO->addItem(qt_("Automatic"), QString("auto"));
2089         fontModule->fontsMathCO->addItem(qt_("Class Default"), QString("default"));
2090         QMap<QString, QString>::const_iterator mmi = mathfonts_.constBegin();
2091         while (mmi != mathfonts_.constEnd()) {
2092                 fontModule->fontsMathCO->addItem(mmi.key(), mmi.value());
2093                 ++mmi;
2094         }
2095 }
2096
2097
2098 void GuiDocument::fontencChanged(int item)
2099 {
2100         fontModule->fontencLE->setEnabled(
2101                 fontModule->fontencCO->itemData(item).toString() == "custom");
2102         // The availability of TeX fonts depends on the font encoding
2103         updateTexFonts();
2104         updateFontOptions();
2105 }
2106
2107
2108 void GuiDocument::updateMathFonts(QString const & rm)
2109 {
2110         if (fontModule->osFontsCB->isChecked())
2111                 return;
2112         QString const math =
2113                 fontModule->fontsMathCO->itemData(fontModule->fontsMathCO->currentIndex()).toString();
2114         int const i = fontModule->fontsMathCO->findData("default");
2115         if (providesNoMath(rm) && i == -1)
2116                 fontModule->fontsMathCO->insertItem(1, qt_("Class Default"), QString("default"));
2117         else if (!providesNoMath(rm) && i != -1) {
2118                 int const c = fontModule->fontsMathCO->currentIndex();
2119                 fontModule->fontsMathCO->removeItem(i);
2120                 if (c == i)
2121                         fontModule->fontsMathCO->setCurrentIndex(0);
2122         }
2123 }
2124
2125
2126 void GuiDocument::romanChanged(int item)
2127 {
2128         if (fontModule->osFontsCB->isChecked())
2129                 return;
2130         QString const font =
2131                 fontModule->fontsRomanCO->itemData(item).toString();
2132         fontModule->fontScCB->setEnabled(providesSC(font));
2133         fontModule->fontOsfCB->setEnabled(providesOSF(font));
2134         updateMathFonts(font);
2135 }
2136
2137
2138 void GuiDocument::sansChanged(int item)
2139 {
2140         if (fontModule->osFontsCB->isChecked())
2141                 return;
2142         QString const font =
2143                 fontModule->fontsSansCO->itemData(item).toString();
2144         bool scaleable = providesScale(font);
2145         fontModule->scaleSansSB->setEnabled(scaleable);
2146         fontModule->scaleSansLA->setEnabled(scaleable);
2147 }
2148
2149
2150 void GuiDocument::ttChanged(int item)
2151 {
2152         if (fontModule->osFontsCB->isChecked())
2153                 return;
2154         QString const font =
2155                 fontModule->fontsTypewriterCO->itemData(item).toString();
2156         bool scaleable = providesScale(font);
2157         fontModule->scaleTypewriterSB->setEnabled(scaleable);
2158         fontModule->scaleTypewriterLA->setEnabled(scaleable);
2159 }
2160
2161
2162 void GuiDocument::updatePagestyle(string const & items, string const & sel)
2163 {
2164         pagestyles.clear();
2165         pageLayoutModule->pagestyleCO->clear();
2166         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
2167
2168         for (int n = 0; !token(items, '|', n).empty(); ++n) {
2169                 string style = token(items, '|', n);
2170                 QString style_gui = qt_(style);
2171                 pagestyles.push_back(pair<string, QString>(style, style_gui));
2172                 pageLayoutModule->pagestyleCO->addItem(style_gui);
2173         }
2174
2175         if (sel == "default") {
2176                 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
2177                 return;
2178         }
2179
2180         int nn = 0;
2181
2182         for (size_t i = 0; i < pagestyles.size(); ++i)
2183                 if (pagestyles[i].first == sel)
2184                         nn = pageLayoutModule->pagestyleCO->findText(pagestyles[i].second);
2185
2186         if (nn > 0)
2187                 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
2188 }
2189
2190
2191 void GuiDocument::browseLayout()
2192 {
2193         QString const label1 = qt_("Layouts|#o#O");
2194         QString const dir1 = toqstr(lyxrc.document_path);
2195         QStringList const filter(qt_("LyX Layout (*.layout)"));
2196         QString file = browseRelToParent(QString(), bufferFilePath(),
2197                 qt_("Local layout file"), filter, false,
2198                 label1, dir1);
2199
2200         if (!file.endsWith(".layout"))
2201                 return;
2202
2203         FileName layoutFile = support::makeAbsPath(fromqstr(file),
2204                 fromqstr(bufferFilePath()));
2205
2206         int const ret = Alert::prompt(_("Local layout file"),
2207                 _("The layout file you have selected is a local layout\n"
2208                   "file, not one in the system or user directory.\n"
2209                   "Your document will not work with this layout if you\n"
2210                   "move the layout file to a different directory."),
2211                   1, 1, _("&Set Layout"), _("&Cancel"));
2212         if (ret == 1)
2213                 return;
2214
2215         // load the layout file
2216         LayoutFileList & bcl = LayoutFileList::get();
2217         string classname = layoutFile.onlyFileName();
2218         // this will update an existing layout if that layout has been loaded before.
2219         LayoutFileIndex name = support::onlyFileName(bcl.addLocalLayout(
2220                 classname.substr(0, classname.size() - 7),
2221                 layoutFile.onlyPath().absFileName()));
2222
2223         if (name.empty()) {
2224                 Alert::error(_("Error"),
2225                         _("Unable to read local layout file."));
2226                 return;
2227         }
2228
2229         const_cast<Buffer &>(buffer()).setLayoutPos(layoutFile.onlyPath().absFileName());
2230
2231         // do not trigger classChanged if there is no change.
2232         if (latexModule->classCO->currentText() == toqstr(name))
2233                 return;
2234
2235         // add to combo box
2236         bool const avail = latexModule->classCO->set(toqstr(name));
2237         if (!avail) {
2238                 LayoutFile const & tc = bcl[name];
2239                 docstring const guiname = translateIfPossible(from_utf8(tc.description()));
2240                 // tooltip sensu "KOMA-Script Article [Class 'scrartcl']"
2241                 QString tooltip = toqstr(bformat(_("%1$s [Class '%2$s']"), guiname, from_utf8(tc.latexname())));
2242                 tooltip += '\n' + qt_("This is a local layout file.");
2243                 latexModule->classCO->addItemSort(toqstr(tc.name()), toqstr(guiname),
2244                                                   toqstr(translateIfPossible(from_utf8(tc.category()))),
2245                                                   tooltip,
2246                                                   true, true, true, true);
2247                 latexModule->classCO->set(toqstr(name));
2248         }
2249
2250         classChanged();
2251 }
2252
2253
2254 void GuiDocument::browseMaster()
2255 {
2256         QString const title = qt_("Select master document");
2257         QString const dir1 = toqstr(lyxrc.document_path);
2258         QString const old = latexModule->childDocLE->text();
2259         QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
2260         QStringList const filter(qt_("LyX Files (*.lyx)"));
2261         QString file = browseRelToSub(old, docpath, title, filter, false,
2262                 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
2263
2264         if (!file.isEmpty())
2265                 latexModule->childDocLE->setText(file);
2266 }
2267
2268
2269 void GuiDocument::classChanged_adaptor()
2270 {
2271         const_cast<Buffer &>(buffer()).setLayoutPos(string());
2272         classChanged();
2273 }
2274
2275
2276 void GuiDocument::classChanged()
2277 {
2278         int idx = latexModule->classCO->currentIndex();
2279         if (idx < 0)
2280                 return;
2281         string const classname = fromqstr(latexModule->classCO->getData(idx));
2282
2283         if (applyPB->isEnabled()) {
2284                 int const ret = Alert::prompt(_("Unapplied changes"),
2285                                 _("Some changes in the dialog were not yet applied.\n"
2286                                 "If you do not apply now, they will be lost after this action."),
2287                                 1, 1, _("&Apply"), _("&Dismiss"));
2288                 if (ret == 0)
2289                         applyView();
2290         }
2291
2292         // We load the TextClass as soon as it is selected. This is
2293         // necessary so that other options in the dialog can be updated
2294         // according to the new class. Note, however, that, if you use
2295         // the scroll wheel when sitting on the combo box, we'll load a
2296         // lot of TextClass objects very quickly....
2297         if (!bp_.setBaseClass(classname)) {
2298                 Alert::error(_("Error"), _("Unable to set document class."));
2299                 return;
2300         }
2301         if (lyxrc.auto_reset_options)
2302                 bp_.useClassDefaults();
2303
2304         // With the introduction of modules came a distinction between the base
2305         // class and the document class. The former corresponds to the main layout
2306         // file; the latter is that plus the modules (or the document-specific layout,
2307         // or  whatever else there could be). Our parameters come from the document
2308         // class. So when we set the base class, we also need to recreate the document
2309         // class. Otherwise, we still have the old one.
2310         bp_.makeDocumentClass();
2311         paramsToDialog();
2312 }
2313
2314
2315 void GuiDocument::languagePackageChanged(int i)
2316 {
2317          langModule->languagePackageLE->setEnabled(
2318                 langModule->languagePackageCO->itemData(i).toString() == "custom");
2319 }
2320
2321
2322 void GuiDocument::biblioChanged()
2323 {
2324         biblioChanged_ = true;
2325         change_adaptor();
2326 }
2327
2328
2329 void GuiDocument::rescanBibFiles()
2330 {
2331         if (isBiblatex())
2332                 rescanTexStyles("bbx cbx");
2333         else
2334                 rescanTexStyles("bst");
2335 }
2336
2337
2338 void GuiDocument::resetDefaultBibfile(string const & which)
2339 {
2340         QString const engine =
2341                 biblioModule->citeEngineCO->itemData(
2342                                 biblioModule->citeEngineCO->currentIndex()).toString();
2343
2344         CiteEngineType const cet =
2345                 CiteEngineType(biblioModule->citeStyleCO->itemData(
2346                                                           biblioModule->citeStyleCO->currentIndex()).toInt());
2347
2348         updateDefaultBiblio(theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet), which);
2349 }
2350
2351
2352 void GuiDocument::resetDefaultBbxBibfile()
2353 {
2354         resetDefaultBibfile("bbx");
2355 }
2356
2357
2358 void GuiDocument::resetDefaultCbxBibfile()
2359 {
2360         resetDefaultBibfile("cbx");
2361 }
2362
2363
2364 void GuiDocument::citeEngineChanged(int n)
2365 {
2366         QString const engine =
2367                 biblioModule->citeEngineCO->itemData(n).toString();
2368
2369         vector<string> const engs =
2370                 theCiteEnginesList[fromqstr(engine)]->getEngineType();
2371
2372         updateCiteStyles(engs);
2373         updateEngineDependends();
2374         resetDefaultBibfile();
2375         biblioChanged();
2376 }
2377
2378
2379 void GuiDocument::updateEngineDependends()
2380 {
2381         bool const biblatex = isBiblatex();
2382
2383         // These are only useful with BibTeX
2384         biblioModule->defaultBiblioCO->setEnabled(!biblatex);
2385         biblioModule->bibtexStyleLA->setEnabled(!biblatex);
2386         biblioModule->resetDefaultBiblioPB->setEnabled(!biblatex);
2387         biblioModule->bibtopicCB->setEnabled(!biblatex);
2388
2389         // These are only useful with Biblatex
2390         biblioModule->biblatexBbxCO->setEnabled(biblatex);
2391         biblioModule->biblatexBbxLA->setEnabled(biblatex);
2392         biblioModule->biblatexCbxCO->setEnabled(biblatex);
2393         biblioModule->biblatexCbxLA->setEnabled(biblatex);
2394         biblioModule->resetBbxPB->setEnabled(biblatex);
2395         biblioModule->resetCbxPB->setEnabled(biblatex);
2396         biblioModule->matchBbxPB->setEnabled(biblatex);
2397
2398         // These are useful with biblatex, jurabib and natbib
2399         QString const engine =
2400                 biblioModule->citeEngineCO->itemData(
2401                                 biblioModule->citeEngineCO->currentIndex()).toString();
2402         LyXCiteEngine const * ce = theCiteEnginesList[fromqstr(engine)];
2403
2404         bool const citepack = ce->requires("biblatex.sty") || ce->requires("jurabib.sty")
2405                         || ce->requires("natbib.sty");
2406         biblioModule->citePackageOptionsLE->setEnabled(citepack);
2407         biblioModule->citePackageOptionsL->setEnabled(citepack);
2408 }
2409
2410
2411 void GuiDocument::citeStyleChanged()
2412 {
2413         QString const engine =
2414                 biblioModule->citeEngineCO->itemData(
2415                                 biblioModule->citeEngineCO->currentIndex()).toString();
2416         QString const currentDef = isBiblatex() ?
2417                 biblioModule->biblatexBbxCO->currentText()
2418                 : biblioModule->defaultBiblioCO->currentText();
2419         if (theCiteEnginesList[fromqstr(engine)]->isDefaultBiblio(fromqstr(currentDef)))
2420                 resetDefaultBibfile();
2421
2422         biblioChanged();
2423 }
2424
2425
2426 void GuiDocument::bibtexChanged(int n)
2427 {
2428         biblioModule->bibtexOptionsLE->setEnabled(
2429                 biblioModule->bibtexCO->itemData(n).toString() != "default");
2430         biblioChanged();
2431 }
2432
2433
2434 void GuiDocument::updateCiteStyles(vector<string> const & engs, CiteEngineType const & sel)
2435 {
2436         biblioModule->citeStyleCO->clear();
2437
2438         vector<string>::const_iterator it  = engs.begin();
2439         vector<string>::const_iterator end = engs.end();
2440         for (; it != end; ++it) {
2441                 if (*it == "default")
2442                         biblioModule->citeStyleCO->addItem(qt_("Basic numerical"),
2443                                                            ENGINE_TYPE_DEFAULT);
2444                 else if (*it == "authoryear")
2445                         biblioModule->citeStyleCO->addItem(qt_("Author-year"),
2446                                                            ENGINE_TYPE_AUTHORYEAR);
2447                 else if (*it == "numerical")
2448                         biblioModule->citeStyleCO->addItem(qt_("Author-number"),
2449                                                            ENGINE_TYPE_NUMERICAL);
2450         }
2451         int i = biblioModule->citeStyleCO->findData(sel);
2452         if (biblioModule->citeStyleCO->findData(sel) == -1)
2453                 i = 0;
2454         biblioModule->citeStyleCO->setCurrentIndex(i);
2455
2456         biblioModule->citationStyleL->setEnabled(engs.size() > 1);
2457         biblioModule->citeStyleCO->setEnabled(engs.size() > 1);
2458 }
2459
2460
2461 void GuiDocument::updateEngineType(string const & items, CiteEngineType const & sel)
2462 {
2463         engine_types_.clear();
2464
2465         int nn = 0;
2466
2467         for (int n = 0; !token(items, '|', n).empty(); ++n) {
2468                 nn += 1;
2469                 string style = token(items, '|', n);
2470                 engine_types_.push_back(style);
2471         }
2472
2473         updateCiteStyles(engine_types_, sel);
2474 }
2475
2476
2477 namespace {
2478         // FIXME unicode
2479         // both of these should take a vector<docstring>
2480
2481         // This is an insanely complicated attempt to make this sort of thing
2482         // work with RTL languages.
2483         docstring formatStrVec(vector<string> const & v, docstring const & s)
2484         {
2485                 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
2486                 if (v.empty())
2487                         return docstring();
2488                 if (v.size() == 1)
2489                         return translateIfPossible(from_utf8(v[0]));
2490                 if (v.size() == 2) {
2491                         docstring retval = _("%1$s and %2$s");
2492                         retval = subst(retval, _("and"), s);
2493                         return bformat(retval, translateIfPossible(from_utf8(v[0])),
2494                                        translateIfPossible(from_utf8(v[1])));
2495                 }
2496                 // The idea here is to format all but the last two items...
2497                 int const vSize = v.size();
2498                 docstring t2 = _("%1$s, %2$s");
2499                 docstring retval = translateIfPossible(from_utf8(v[0]));
2500                 for (int i = 1; i < vSize - 2; ++i)
2501                         retval = bformat(t2, retval, translateIfPossible(from_utf8(v[i])));
2502                 //...and then to  plug them, and the last two, into this schema
2503                 docstring t = _("%1$s, %2$s, and %3$s");
2504                 t = subst(t, _("and"), s);
2505                 return bformat(t, retval, translateIfPossible(from_utf8(v[vSize - 2])),
2506                                translateIfPossible(from_utf8(v[vSize - 1])));
2507         }
2508
2509         vector<string> idsToNames(vector<string> const & idList)
2510         {
2511                 vector<string> retval;
2512                 vector<string>::const_iterator it  = idList.begin();
2513                 vector<string>::const_iterator end = idList.end();
2514                 for (; it != end; ++it) {
2515                         LyXModule const * const mod = theModuleList[*it];
2516                         if (!mod)
2517                                 retval.push_back(to_utf8(bformat(_("%1$s (unavailable)"),
2518                                                 translateIfPossible(from_utf8(*it)))));
2519                         else
2520                                 retval.push_back(mod->getName());
2521                 }
2522                 return retval;
2523         }
2524 } // end anonymous namespace
2525
2526
2527 void GuiDocument::modulesToParams(BufferParams & bp)
2528 {
2529         // update list of loaded modules
2530         bp.clearLayoutModules();
2531         int const srows = modules_sel_model_.rowCount();
2532         for (int i = 0; i < srows; ++i)
2533                 bp.addLayoutModule(modules_sel_model_.getIDString(i));
2534
2535         // update the list of removed modules
2536         bp.clearRemovedModules();
2537         LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
2538         list<string>::const_iterator rit = reqmods.begin();
2539         list<string>::const_iterator ren = reqmods.end();
2540
2541         // check each of the default modules
2542         for (; rit != ren; ++rit) {
2543                 list<string>::const_iterator mit = bp.getModules().begin();
2544                 list<string>::const_iterator men = bp.getModules().end();
2545                 bool found = false;
2546                 for (; mit != men; ++mit) {
2547                         if (*rit == *mit) {
2548                                 found = true;
2549                                 break;
2550                         }
2551                 }
2552                 if (!found) {
2553                         // the module isn't present so must have been removed by the user
2554                         bp.addRemovedModule(*rit);
2555                 }
2556         }
2557 }
2558
2559 void GuiDocument::modulesChanged()
2560 {
2561         modulesToParams(bp_);
2562
2563         if (applyPB->isEnabled() && nonModuleChanged_) {
2564                 int const ret = Alert::prompt(_("Unapplied changes"),
2565                                 _("Some changes in the dialog were not yet applied.\n"
2566                                 "If you do not apply now, they will be lost after this action."),
2567                                 1, 1, _("&Apply"), _("&Dismiss"));
2568                 if (ret == 0)
2569                         applyView();
2570         }
2571
2572         bp_.makeDocumentClass();
2573         paramsToDialog();
2574         changed();
2575 }
2576
2577
2578 void GuiDocument::updateModuleInfo()
2579 {
2580         selectionManager->update();
2581
2582         //Module description
2583         bool const focus_on_selected = selectionManager->selectedFocused();
2584         QAbstractItemView * lv;
2585         if (focus_on_selected)
2586                 lv = modulesModule->selectedLV;
2587         else
2588                 lv = modulesModule->availableLV;
2589         if (lv->selectionModel()->selectedIndexes().isEmpty()) {
2590                 modulesModule->infoML->document()->clear();
2591                 return;
2592         }
2593         QModelIndex const & idx = lv->selectionModel()->currentIndex();
2594         GuiIdListModel const & id_model =
2595                         focus_on_selected  ? modules_sel_model_ : modules_av_model_;
2596         string const modName = id_model.getIDString(idx.row());
2597         docstring desc = getModuleDescription(modName);
2598
2599         LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
2600         if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
2601                 if (!desc.empty())
2602                         desc += "\n";
2603                 desc += _("Module provided by document class.");
2604         }
2605
2606         docstring cat = getModuleCategory(modName);
2607         if (!cat.empty()) {
2608                 if (!desc.empty())
2609                         desc += "\n";
2610                 desc += bformat(_("Category: %1$s."), cat);
2611         }
2612
2613         vector<string> pkglist = getPackageList(modName);
2614         docstring pkgdesc = formatStrVec(pkglist, _("and"));
2615         if (!pkgdesc.empty()) {
2616                 if (!desc.empty())
2617                         desc += "\n";
2618                 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
2619         }
2620
2621         pkglist = getRequiredList(modName);
2622         if (!pkglist.empty()) {
2623                 vector<string> const reqdescs = idsToNames(pkglist);
2624                 pkgdesc = formatStrVec(reqdescs, _("or"));
2625                 if (!desc.empty())
2626                         desc += "\n";
2627                 desc += bformat(_("Modules required: %1$s."), pkgdesc);
2628         }
2629
2630         pkglist = getExcludedList(modName);
2631         if (!pkglist.empty()) {
2632                 vector<string> const reqdescs = idsToNames(pkglist);
2633                 pkgdesc = formatStrVec(reqdescs, _( "and"));
2634                 if (!desc.empty())
2635                         desc += "\n";
2636                 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
2637         }
2638
2639         if (!isModuleAvailable(modName)) {
2640                 if (!desc.empty())
2641                         desc += "\n";
2642                 desc += _("WARNING: Some required packages are unavailable!");
2643         }
2644
2645         modulesModule->infoML->document()->setPlainText(toqstr(desc));
2646 }
2647
2648
2649 void GuiDocument::updateNumbering()
2650 {
2651         DocumentClass const & tclass = documentClass();
2652
2653         numberingModule->tocTW->setUpdatesEnabled(false);
2654         numberingModule->tocTW->clear();
2655
2656         int const depth = numberingModule->depthSL->value();
2657         int const toc = numberingModule->tocSL->value();
2658         QString const no = qt_("No");
2659         QString const yes = qt_("Yes");
2660         QTreeWidgetItem * item = 0;
2661
2662         DocumentClass::const_iterator lit = tclass.begin();
2663         DocumentClass::const_iterator len = tclass.end();
2664         for (; lit != len; ++lit) {
2665                 int const toclevel = lit->toclevel;
2666                 if (toclevel != Layout::NOT_IN_TOC && !lit->counter.empty()) {
2667                         item = new QTreeWidgetItem(numberingModule->tocTW);
2668                         item->setText(0, toqstr(translateIfPossible(lit->name())));
2669                         item->setText(1, (toclevel <= depth) ? yes : no);
2670                         item->setText(2, (toclevel <= toc) ? yes : no);
2671                 }
2672         }
2673
2674         numberingModule->tocTW->setUpdatesEnabled(true);
2675         numberingModule->tocTW->update();
2676 }
2677
2678
2679 void GuiDocument::updateDefaultFormat()
2680 {
2681         if (!bufferview())
2682                 return;
2683         // make a copy in order to consider unapplied changes
2684         BufferParams param_copy = buffer().params();
2685         param_copy.useNonTeXFonts = fontModule->osFontsCB->isChecked();
2686         int const idx = latexModule->classCO->currentIndex();
2687         if (idx >= 0) {
2688                 string const classname = fromqstr(latexModule->classCO->getData(idx));
2689                 param_copy.setBaseClass(classname);
2690                 param_copy.makeDocumentClass(true);
2691         }
2692         outputModule->defaultFormatCO->blockSignals(true);
2693         outputModule->defaultFormatCO->clear();
2694         outputModule->defaultFormatCO->addItem(qt_("Default"),
2695                                 QVariant(QString("default")));
2696         FormatList const & formats =
2697                                 param_copy.exportableFormats(true);
2698         for (Format const * f : formats)
2699                 outputModule->defaultFormatCO->addItem
2700                         (toqstr(translateIfPossible(f->prettyname())),
2701                          QVariant(toqstr(f->name())));
2702         outputModule->defaultFormatCO->blockSignals(false);
2703 }
2704
2705
2706 bool GuiDocument::isChildIncluded(string const & child)
2707 {
2708         if (includeonlys_.empty())
2709                 return false;
2710         return (std::find(includeonlys_.begin(),
2711                           includeonlys_.end(), child) != includeonlys_.end());
2712 }
2713
2714
2715 void GuiDocument::applyView()
2716 {
2717         // preamble
2718         preambleModule->apply(bp_);
2719         localLayout->apply(bp_);
2720
2721         // date
2722         bp_.suppress_date = latexModule->suppressDateCB->isChecked();
2723         bp_.use_refstyle  = latexModule->refstyleCB->isChecked();
2724
2725         // biblio
2726         string const engine =
2727                 fromqstr(biblioModule->citeEngineCO->itemData(
2728                                 biblioModule->citeEngineCO->currentIndex()).toString());
2729         bp_.setCiteEngine(engine);
2730
2731         CiteEngineType const style = CiteEngineType(biblioModule->citeStyleCO->itemData(
2732                 biblioModule->citeStyleCO->currentIndex()).toInt());
2733         if (theCiteEnginesList[engine]->hasEngineType(style))
2734                 bp_.setCiteEngineType(style);
2735         else
2736                 bp_.setCiteEngineType(ENGINE_TYPE_DEFAULT);
2737
2738         bp_.splitbib(biblioModule->bibtopicCB->isChecked());
2739
2740         bp_.multibib = fromqstr(biblioModule->bibunitsCO->itemData(
2741                                 biblioModule->bibunitsCO->currentIndex()).toString());
2742
2743         bp_.setDefaultBiblioStyle(fromqstr(biblioModule->defaultBiblioCO->currentText()));
2744
2745         bp_.biblatex_bibstyle = fromqstr(biblioModule->biblatexBbxCO->currentText());
2746         bp_.biblatex_citestyle = fromqstr(biblioModule->biblatexCbxCO->currentText());
2747         bp_.biblio_opts = fromqstr(biblioModule->citePackageOptionsLE->text());
2748
2749         string const bibtex_command =
2750                 fromqstr(biblioModule->bibtexCO->itemData(
2751                         biblioModule->bibtexCO->currentIndex()).toString());
2752         string const bibtex_options =
2753                 fromqstr(biblioModule->bibtexOptionsLE->text());
2754         if (bibtex_command == "default" || bibtex_options.empty())
2755                 bp_.bibtex_command = bibtex_command;
2756         else
2757                 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
2758
2759         if (biblioChanged_) {
2760                 buffer().invalidateBibinfoCache();
2761                 buffer().removeBiblioTempFiles();
2762         }
2763
2764         // Indices
2765         indicesModule->apply(bp_);
2766
2767         // language & quotes
2768         if (langModule->defaultencodingRB->isChecked()) {
2769                 bp_.inputenc = "auto";
2770         } else {
2771                 int i = langModule->encodingCO->currentIndex();
2772                 if (i == 0)
2773                         bp_.inputenc = "default";
2774                 else {
2775                         QString const enc_gui =
2776                                 langModule->encodingCO->currentText();
2777                         Encodings::const_iterator it = encodings.begin();
2778                         Encodings::const_iterator const end = encodings.end();
2779                         bool found = false;
2780                         for (; it != end; ++it) {
2781                                 if (qt_(it->guiName()) == enc_gui &&
2782                                     !it->unsafe()) {
2783                                         bp_.inputenc = it->name();
2784                                         found = true;
2785                                         break;
2786                                 }
2787                         }
2788                         if (!found) {
2789                                 // should not happen
2790                                 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
2791                                 bp_.inputenc = "default";
2792                         }
2793                 }
2794         }
2795
2796         bp_.quotes_style = (InsetQuotesParams::QuoteStyle) langModule->quoteStyleCO->itemData(
2797                 langModule->quoteStyleCO->currentIndex()).toInt();
2798         bp_.dynamic_quotes = langModule->dynamicQuotesCB->isChecked();
2799
2800         QString const langname = langModule->languageCO->itemData(
2801                 langModule->languageCO->currentIndex()).toString();
2802         Language const * newlang = lyx::languages.getLanguage(fromqstr(langname));
2803         Cursor & cur = const_cast<BufferView *>(bufferview())->cursor();
2804         // If current cursor language was the document language, then update it too.
2805         if (cur.current_font.language() == bp_.language) {
2806                 cur.current_font.setLanguage(newlang);
2807                 cur.real_current_font.setLanguage(newlang);
2808         }
2809         bp_.language = newlang;
2810
2811         QString const pack = langModule->languagePackageCO->itemData(
2812                 langModule->languagePackageCO->currentIndex()).toString();
2813         if (pack == "custom")
2814                 bp_.lang_package =
2815                         fromqstr(langModule->languagePackageLE->text());
2816         else
2817                 bp_.lang_package = fromqstr(pack);
2818
2819         //color
2820         bp_.backgroundcolor = set_backgroundcolor;
2821         bp_.isbackgroundcolor = is_backgroundcolor;
2822         bp_.fontcolor = set_fontcolor;
2823         bp_.isfontcolor = is_fontcolor;
2824         bp_.notefontcolor = set_notefontcolor;
2825         bp_.boxbgcolor = set_boxbgcolor;
2826
2827         // numbering
2828         if (bp_.documentClass().hasTocLevels()) {
2829                 bp_.tocdepth = numberingModule->tocSL->value();
2830                 bp_.secnumdepth = numberingModule->depthSL->value();
2831         }
2832
2833         // bullets
2834         bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
2835         bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
2836         bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
2837         bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
2838
2839         // packages
2840         bp_.graphics_driver =
2841                 tex_graphics[latexModule->psdriverCO->currentIndex()];
2842
2843         // text layout
2844         int idx = latexModule->classCO->currentIndex();
2845         if (idx >= 0) {
2846                 string const classname = fromqstr(latexModule->classCO->getData(idx));
2847                 bp_.setBaseClass(classname);
2848         }
2849
2850         // Modules
2851         modulesToParams(bp_);
2852
2853         // Math
2854         map<string, string> const & packages = BufferParams::auto_packages();
2855         for (map<string, string>::const_iterator it = packages.begin();
2856              it != packages.end(); ++it) {
2857                 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
2858                 if (!item)
2859                         continue;
2860                 int row = mathsModule->packagesTW->row(item);
2861                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1);
2862                 if (rb->isChecked()) {
2863                         bp_.use_package(it->first, BufferParams::package_auto);
2864                         continue;
2865                 }
2866                 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2);
2867                 if (rb->isChecked()) {
2868                         bp_.use_package(it->first, BufferParams::package_on);
2869                         continue;
2870                 }
2871                 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3);
2872                 if (rb->isChecked())
2873                         bp_.use_package(it->first, BufferParams::package_off);
2874         }
2875
2876         // Page Layout
2877         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
2878                 bp_.pagestyle = "default";
2879         else {
2880                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
2881                 for (size_t i = 0; i != pagestyles.size(); ++i)
2882                         if (pagestyles[i].second == style_gui)
2883                                 bp_.pagestyle = pagestyles[i].first;
2884         }
2885
2886         // Text Layout
2887         switch (textLayoutModule->lspacingCO->currentIndex()) {
2888         case 0:
2889                 bp_.spacing().set(Spacing::Single);
2890                 break;
2891         case 1:
2892                 bp_.spacing().set(Spacing::Onehalf);
2893                 break;
2894         case 2:
2895                 bp_.spacing().set(Spacing::Double);
2896                 break;
2897         case 3: {
2898                 string s = widgetToDoubleStr(textLayoutModule->lspacingLE);
2899                 if (s.empty())
2900                         bp_.spacing().set(Spacing::Single);
2901                 else
2902                         bp_.spacing().set(Spacing::Other, s);
2903                 break;
2904                 }
2905         }
2906
2907         if (textLayoutModule->twoColumnCB->isChecked())
2908                 bp_.columns = 2;
2909         else
2910                 bp_.columns = 1;
2911
2912         bp_.justification = textLayoutModule->justCB->isChecked();
2913
2914         if (textLayoutModule->indentRB->isChecked()) {
2915                 // if paragraphs are separated by an indentation
2916                 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
2917                 switch (textLayoutModule->indentCO->currentIndex()) {
2918                 case 0:
2919                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2920                         break;
2921                 case 1: {
2922                         HSpace indent = HSpace(
2923                                 widgetsToLength(textLayoutModule->indentLE,
2924                                 textLayoutModule->indentLengthCO)
2925                                 );
2926                         bp_.setIndentation(indent);
2927                         break;
2928                         }
2929                 default:
2930                         // this should never happen
2931                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2932                         break;
2933                 }
2934         } else {
2935                 // if paragraphs are separated by a skip
2936                 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
2937                 switch (textLayoutModule->skipCO->currentIndex()) {
2938                 case 0:
2939                         bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
2940                         break;
2941                 case 1:
2942                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2943                         break;
2944                 case 2:
2945                         bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
2946                         break;
2947                 case 3:
2948                         {
2949                         VSpace vs = VSpace(
2950                                 widgetsToLength(textLayoutModule->skipLE,
2951                                 textLayoutModule->skipLengthCO)
2952                                 );
2953                         bp_.setDefSkip(vs);
2954                         break;
2955                         }
2956                 default:
2957                         // this should never happen
2958                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2959                         break;
2960                 }
2961         }
2962
2963         bp_.options =
2964                 fromqstr(latexModule->optionsLE->text());
2965
2966         bp_.use_default_options =
2967                 latexModule->defaultOptionsCB->isChecked();
2968
2969         if (latexModule->childDocGB->isChecked())
2970                 bp_.master =
2971                         fromqstr(latexModule->childDocLE->text());
2972         else
2973                 bp_.master = string();
2974
2975         // Master/Child
2976         bp_.clearIncludedChildren();
2977         if (masterChildModule->includeonlyRB->isChecked()) {
2978                 list<string>::const_iterator it = includeonlys_.begin();
2979                 for (; it != includeonlys_.end() ; ++it) {
2980                         bp_.addIncludedChildren(*it);
2981                 }
2982         }
2983         bp_.maintain_unincluded_children =
2984                 masterChildModule->maintainAuxCB->isChecked();
2985
2986         // Float Placement
2987         bp_.float_placement = floatModule->get();
2988
2989         // Listings
2990         // text should have passed validation
2991         bp_.listings_params =
2992                 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
2993
2994         // Formats
2995         bp_.default_output_format = fromqstr(outputModule->defaultFormatCO->itemData(
2996                 outputModule->defaultFormatCO->currentIndex()).toString());
2997
2998         bool const nontexfonts = fontModule->osFontsCB->isChecked();
2999         bp_.useNonTeXFonts = nontexfonts;
3000
3001         bp_.output_sync = outputModule->outputsyncCB->isChecked();
3002
3003         bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
3004
3005         int mathfmt = outputModule->mathoutCB->currentIndex();
3006         if (mathfmt == -1)
3007                 mathfmt = 0;
3008         BufferParams::MathOutput const mo =
3009                 static_cast<BufferParams::MathOutput>(mathfmt);
3010         bp_.html_math_output = mo;
3011         bp_.html_be_strict = outputModule->strictCB->isChecked();
3012         bp_.html_css_as_file = outputModule->cssCB->isChecked();
3013         bp_.html_math_img_scale = outputModule->mathimgSB->value();
3014         bp_.display_pixel_ratio = theGuiApp()->pixelRatio();
3015
3016         bp_.save_transient_properties =
3017                 outputModule->saveTransientPropertiesCB->isChecked();
3018
3019         // fonts
3020         bp_.fonts_roman[nontexfonts] =
3021                 fromqstr(fontModule->fontsRomanCO->
3022                         itemData(fontModule->fontsRomanCO->currentIndex()).toString());
3023         bp_.fonts_roman[!nontexfonts] = fromqstr(fontModule->font_roman);
3024
3025         bp_.fonts_sans[nontexfonts] =
3026                 fromqstr(fontModule->fontsSansCO->
3027                         itemData(fontModule->fontsSansCO->currentIndex()).toString());
3028         bp_.fonts_sans[!nontexfonts] = fromqstr(fontModule->font_sans);
3029
3030         bp_.fonts_typewriter[nontexfonts] =
3031                 fromqstr(fontModule->fontsTypewriterCO->
3032                         itemData(fontModule->fontsTypewriterCO->currentIndex()).toString());
3033         bp_.fonts_typewriter[!nontexfonts] = fromqstr(fontModule->font_typewriter);
3034
3035         bp_.fonts_math[nontexfonts] =
3036                 fromqstr(fontModule->fontsMathCO->
3037                         itemData(fontModule->fontsMathCO->currentIndex()).toString());
3038         bp_.fonts_math[!nontexfonts] = fromqstr(fontModule->font_math);
3039
3040         QString const fontenc =
3041                 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
3042         if (fontenc == "custom")
3043                 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
3044         else
3045                 bp_.fontenc = fromqstr(fontenc);
3046
3047         bp_.fonts_cjk =
3048                 fromqstr(fontModule->cjkFontLE->text());
3049
3050         bp_.use_microtype = fontModule->microtypeCB->isChecked();
3051         bp_.use_dash_ligatures = !fontModule->dashesCB->isChecked();
3052
3053         bp_.fonts_sans_scale[nontexfonts] = fontModule->scaleSansSB->value();
3054         bp_.fonts_sans_scale[!nontexfonts] = fontModule->font_sf_scale;
3055
3056         bp_.fonts_typewriter_scale[nontexfonts] = fontModule->scaleTypewriterSB->value();
3057         bp_.fonts_typewriter_scale[!nontexfonts] = fontModule->font_tt_scale;
3058
3059         bp_.fonts_expert_sc = fontModule->fontScCB->isChecked();
3060
3061         bp_.fonts_old_figures = fontModule->fontOsfCB->isChecked();
3062
3063         if (nontexfonts)
3064                 bp_.fonts_default_family = "default";
3065         else
3066                 bp_.fonts_default_family = GuiDocument::fontfamilies[
3067                         fontModule->fontsDefaultCO->currentIndex()];
3068
3069         if (fontModule->fontsizeCO->currentIndex() == 0)
3070                 bp_.fontsize = "default";
3071         else
3072                 bp_.fontsize =
3073                         fromqstr(fontModule->fontsizeCO->currentText());
3074
3075         // paper
3076         bp_.papersize = PAPER_SIZE(
3077                 pageLayoutModule->papersizeCO->currentIndex());
3078
3079         bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
3080                 pageLayoutModule->paperwidthUnitCO);
3081
3082         bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
3083                 pageLayoutModule->paperheightUnitCO);
3084
3085         if (pageLayoutModule->facingPagesCB->isChecked())
3086                 bp_.sides = TwoSides;
3087         else
3088                 bp_.sides = OneSide;
3089
3090         if (pageLayoutModule->landscapeRB->isChecked())
3091                 bp_.orientation = ORIENTATION_LANDSCAPE;
3092         else
3093                 bp_.orientation = ORIENTATION_PORTRAIT;
3094
3095         // margins
3096         bp_.use_geometry = !marginsModule->marginCB->isChecked();
3097
3098         Ui::MarginsUi const * m = marginsModule;
3099
3100         bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
3101         bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
3102         bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
3103         bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
3104         bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
3105         bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
3106         bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
3107         bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
3108
3109         // branches
3110         branchesModule->apply(bp_);
3111
3112         // PDF support
3113         PDFOptions & pdf = bp_.pdfoptions();
3114         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
3115         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
3116         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
3117         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
3118         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
3119
3120         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
3121         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
3122         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
3123         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
3124
3125         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
3126         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
3127         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
3128         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
3129         pdf.backref =
3130                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
3131         if (pdfSupportModule->fullscreenCB->isChecked())
3132                 pdf.pagemode = pdf.pagemode_fullscreen;
3133         else
3134                 pdf.pagemode.clear();
3135         pdf.quoted_options = pdf.quoted_options_check(
3136                                 fromqstr(pdfSupportModule->optionsLE->text()));
3137
3138         // reset tracker
3139         nonModuleChanged_ = false;
3140 }
3141
3142
3143 void GuiDocument::paramsToDialog()
3144 {
3145         // set the default unit
3146         Length::UNIT const default_unit = Length::defaultUnit();
3147
3148         // preamble
3149         preambleModule->update(bp_, id());
3150         localLayout->update(bp_, id());
3151
3152         // date
3153         latexModule->suppressDateCB->setChecked(bp_.suppress_date);
3154         latexModule->refstyleCB->setChecked(bp_.use_refstyle);
3155
3156         // biblio
3157         string const cite_engine = bp_.citeEngine().list().front();
3158
3159         biblioModule->citeEngineCO->setCurrentIndex(
3160                 biblioModule->citeEngineCO->findData(toqstr(cite_engine)));
3161
3162         updateEngineType(documentClass().opt_enginetype(),
3163                 bp_.citeEngineType());
3164
3165         biblioModule->citeStyleCO->setCurrentIndex(
3166                 biblioModule->citeStyleCO->findData(bp_.citeEngineType()));
3167
3168         biblioModule->bibtopicCB->setChecked(bp_.splitbib());
3169
3170         biblioModule->bibunitsCO->clear();
3171         biblioModule->bibunitsCO->addItem(qt_("No"), QString());
3172         if (documentClass().hasLaTeXLayout("part"))
3173                 biblioModule->bibunitsCO->addItem(qt_("per part"), toqstr("part"));
3174         if (documentClass().hasLaTeXLayout("chapter"))
3175                 biblioModule->bibunitsCO->addItem(qt_("per chapter"), toqstr("chapter"));
3176         if (documentClass().hasLaTeXLayout("section"))
3177                 biblioModule->bibunitsCO->addItem(qt_("per section"), toqstr("section"));
3178         if (documentClass().hasLaTeXLayout("subsection"))
3179                 biblioModule->bibunitsCO->addItem(qt_("per subsection"), toqstr("subsection"));
3180         biblioModule->bibunitsCO->addItem(qt_("per child document"), toqstr("child"));
3181
3182         int const mbpos = biblioModule->bibunitsCO->findData(toqstr(bp_.multibib));
3183         if (mbpos != -1)
3184                 biblioModule->bibunitsCO->setCurrentIndex(mbpos);
3185         else
3186                 biblioModule->bibunitsCO->setCurrentIndex(0);
3187
3188         updateEngineDependends();
3189
3190         if (isBiblatex()) {
3191                 updateDefaultBiblio(bp_.biblatex_bibstyle, "bbx");
3192                 updateDefaultBiblio(bp_.biblatex_citestyle, "cbx");
3193         } else
3194                 updateDefaultBiblio(bp_.defaultBiblioStyle());
3195
3196         biblioModule->citePackageOptionsLE->setText(toqstr(bp_.biblio_opts));
3197
3198         string command;
3199         string options =
3200                 split(bp_.bibtex_command, command, ' ');
3201
3202         int const bpos = biblioModule->bibtexCO->findData(toqstr(command));
3203         if (bpos != -1) {
3204                 biblioModule->bibtexCO->setCurrentIndex(bpos);
3205                 biblioModule->bibtexOptionsLE->setText(toqstr(options).trimmed());
3206         } else {
3207                 // We reset to default if we do not know the specified compiler
3208                 // This is for security reasons
3209                 biblioModule->bibtexCO->setCurrentIndex(
3210                         biblioModule->bibtexCO->findData(toqstr("default")));
3211                 biblioModule->bibtexOptionsLE->clear();
3212         }
3213         biblioModule->bibtexOptionsLE->setEnabled(
3214                 biblioModule->bibtexCO->currentIndex() != 0);
3215
3216         biblioChanged_ = false;
3217
3218         // indices
3219         // We may be called when there is no Buffer, e.g., when 
3220         // the last view has just been closed.
3221         bool const isReadOnly = isBufferAvailable() ? buffer().isReadonly() : false;
3222         indicesModule->update(bp_, isReadOnly);
3223
3224         // language & quotes
3225         int const pos = langModule->languageCO->findData(toqstr(
3226                 bp_.language->lang()));
3227         langModule->languageCO->setCurrentIndex(pos);
3228
3229         updateQuoteStyles();
3230
3231         langModule->quoteStyleCO->setCurrentIndex(
3232                 langModule->quoteStyleCO->findData(bp_.quotes_style));
3233         langModule->dynamicQuotesCB->setChecked(bp_.dynamic_quotes);
3234
3235         bool default_enc = true;
3236         if (bp_.inputenc != "auto") {
3237                 default_enc = false;
3238                 if (bp_.inputenc == "default") {
3239                         langModule->encodingCO->setCurrentIndex(0);
3240                 } else {
3241                         string enc_gui;
3242                         Encodings::const_iterator it = encodings.begin();
3243                         Encodings::const_iterator const end = encodings.end();
3244                         for (; it != end; ++it) {
3245                                 if (it->name() == bp_.inputenc &&
3246                                     !it->unsafe()) {
3247                                         enc_gui = it->guiName();
3248                                         break;
3249                                 }
3250                         }
3251                         int const i = langModule->encodingCO->findText(
3252                                         qt_(enc_gui));
3253                         if (i >= 0)
3254                                 langModule->encodingCO->setCurrentIndex(i);
3255                         else
3256                                 // unknown encoding. Set to default.
3257                                 default_enc = true;
3258                 }
3259         }
3260         langModule->defaultencodingRB->setChecked(default_enc);
3261         langModule->otherencodingRB->setChecked(!default_enc);
3262
3263         int const p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
3264         if (p == -1) {
3265                 langModule->languagePackageCO->setCurrentIndex(
3266                           langModule->languagePackageCO->findData("custom"));
3267                 langModule->languagePackageLE->setText(toqstr(bp_.lang_package));
3268         } else {
3269                 langModule->languagePackageCO->setCurrentIndex(p);
3270                 langModule->languagePackageLE->clear();
3271         }
3272
3273         //color
3274         if (bp_.isfontcolor) {
3275                 colorModule->fontColorPB->setStyleSheet(
3276                         colorButtonStyleSheet(rgb2qcolor(bp_.fontcolor)));
3277         }
3278         set_fontcolor = bp_.fontcolor;
3279         is_fontcolor = bp_.isfontcolor;
3280
3281         colorModule->noteFontColorPB->setStyleSheet(
3282                 colorButtonStyleSheet(rgb2qcolor(bp_.notefontcolor)));
3283         set_notefontcolor = bp_.notefontcolor;
3284
3285         if (bp_.isbackgroundcolor) {
3286                 colorModule->backgroundPB->setStyleSheet(
3287                         colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
3288         }
3289         set_backgroundcolor = bp_.backgroundcolor;
3290         is_backgroundcolor = bp_.isbackgroundcolor;
3291
3292         colorModule->boxBackgroundPB->setStyleSheet(
3293                 colorButtonStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
3294         set_boxbgcolor = bp_.boxbgcolor;
3295
3296         // numbering
3297         int const min_toclevel = documentClass().min_toclevel();
3298         int const max_toclevel = documentClass().max_toclevel();
3299         if (documentClass().hasTocLevels()) {
3300                 numberingModule->setEnabled(true);
3301                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
3302                 numberingModule->depthSL->setMaximum(max_toclevel);
3303                 numberingModule->depthSL->setValue(bp_.secnumdepth);
3304                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
3305                 numberingModule->tocSL->setMaximum(max_toclevel);
3306                 numberingModule->tocSL->setValue(bp_.tocdepth);
3307                 updateNumbering();
3308         } else {
3309                 numberingModule->setEnabled(false);
3310                 numberingModule->tocTW->clear();
3311         }
3312
3313         // bullets
3314         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
3315         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
3316         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
3317         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
3318         bulletsModule->init();
3319
3320         // packages
3321         int nitem = findToken(tex_graphics, bp_.graphics_driver);
3322         if (nitem >= 0)
3323                 latexModule->psdriverCO->setCurrentIndex(nitem);
3324         updateModuleInfo();
3325
3326         map<string, string> const & packages = BufferParams::auto_packages();
3327         for (map<string, string>::const_iterator it = packages.begin();
3328              it != packages.end(); ++it) {
3329                 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
3330                 if (!item)
3331                         continue;
3332                 int row = mathsModule->packagesTW->row(item);
3333                 switch (bp_.use_package(it->first)) {
3334                         case BufferParams::package_off: {
3335                                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3);
3336                                 rb->setChecked(true);
3337                                 break;
3338                         }
3339                         case BufferParams::package_on: {
3340                                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2);
3341                                 rb->setChecked(true);
3342                                 break;
3343                         }
3344                         case BufferParams::package_auto: {
3345                                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1);
3346                                 rb->setChecked(true);
3347                                 break;
3348                         }
3349                 }
3350         }
3351
3352         switch (bp_.spacing().getSpace()) {
3353                 case Spacing::Other: nitem = 3; break;
3354                 case Spacing::Double: nitem = 2; break;
3355                 case Spacing::Onehalf: nitem = 1; break;
3356                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
3357         }
3358
3359         // text layout
3360         string const & layoutID = bp_.baseClassID();
3361         setLayoutComboByIDString(layoutID);
3362
3363         updatePagestyle(documentClass().opt_pagestyle(),
3364                                  bp_.pagestyle);
3365
3366         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
3367         if (bp_.spacing().getSpace() == Spacing::Other) {
3368                 doubleToWidget(textLayoutModule->lspacingLE,
3369                         bp_.spacing().getValueAsString());
3370         }
3371         setLSpacing(nitem);
3372
3373         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
3374                 textLayoutModule->indentRB->setChecked(true);
3375                 string indentation = bp_.getIndentation().asLyXCommand();
3376                 int indent = 0;
3377                 if (indentation != "default") {
3378                         lengthToWidgets(textLayoutModule->indentLE,
3379                         textLayoutModule->indentLengthCO,
3380                         indentation, default_unit);
3381                         indent = 1;
3382                 }
3383                 textLayoutModule->indentCO->setCurrentIndex(indent);
3384                 setIndent(indent);
3385         } else {
3386                 textLayoutModule->skipRB->setChecked(true);
3387                 int skip = 0;
3388                 switch (bp_.getDefSkip().kind()) {
3389                 case VSpace::SMALLSKIP:
3390                         skip = 0;
3391                         break;
3392                 case VSpace::MEDSKIP:
3393                         skip = 1;
3394                         break;
3395                 case VSpace::BIGSKIP:
3396                         skip = 2;
3397                         break;
3398                 case VSpace::LENGTH:
3399                         {
3400                         skip = 3;
3401                         string const length = bp_.getDefSkip().asLyXCommand();
3402                         lengthToWidgets(textLayoutModule->skipLE,
3403                                 textLayoutModule->skipLengthCO,
3404                                 length, default_unit);
3405                         break;
3406                         }
3407                 default:
3408                         skip = 0;
3409                         break;
3410                 }
3411                 textLayoutModule->skipCO->setCurrentIndex(skip);
3412                 setSkip(skip);
3413         }
3414
3415         textLayoutModule->twoColumnCB->setChecked(
3416                 bp_.columns == 2);
3417         textLayoutModule->justCB->setChecked(bp_.justification);
3418
3419         if (!bp_.options.empty()) {
3420                 latexModule->optionsLE->setText(
3421                         toqstr(bp_.options));
3422         } else {
3423                 latexModule->optionsLE->setText(QString());
3424         }
3425
3426         // latex
3427         latexModule->defaultOptionsCB->setChecked(
3428                         bp_.use_default_options);
3429         updateSelectedModules();
3430         selectionManager->updateProvidedModules(
3431                         bp_.baseClass()->providedModules());
3432         selectionManager->updateExcludedModules(
3433                         bp_.baseClass()->excludedModules());
3434
3435         if (!documentClass().options().empty()) {
3436                 latexModule->defaultOptionsLE->setText(
3437                         toqstr(documentClass().options()));
3438         } else {
3439                 latexModule->defaultOptionsLE->setText(
3440                         toqstr(_("[No options predefined]")));
3441         }
3442
3443         latexModule->defaultOptionsLE->setEnabled(
3444                 bp_.use_default_options
3445                 && !documentClass().options().empty());
3446
3447         latexModule->defaultOptionsCB->setEnabled(
3448                 !documentClass().options().empty());
3449
3450         if (!bp_.master.empty()) {
3451                 latexModule->childDocGB->setChecked(true);
3452                 latexModule->childDocLE->setText(
3453                         toqstr(bp_.master));
3454         } else {
3455                 latexModule->childDocLE->setText(QString());
3456                 latexModule->childDocGB->setChecked(false);
3457         }
3458
3459         // Master/Child
3460         if (!bufferview() || !buffer().hasChildren()) {
3461                 masterChildModule->childrenTW->clear();
3462                 includeonlys_.clear();
3463                 docPS->showPanel("Child Documents", false);
3464                 if (docPS->isCurrentPanel("Child Documents"))
3465                         docPS->setCurrentPanel("Document Class");
3466         } else {
3467                 docPS->showPanel("Child Documents", true);
3468                 masterChildModule->setEnabled(true);
3469                 includeonlys_ = bp_.getIncludedChildren();
3470                 updateIncludeonlys();
3471         }
3472         masterChildModule->maintainAuxCB->setChecked(
3473                 bp_.maintain_unincluded_children);
3474
3475         // Float Settings
3476         floatModule->set(bp_.float_placement);
3477
3478         // ListingsSettings
3479         // break listings_params to multiple lines
3480         string lstparams =
3481                 InsetListingsParams(bp_.listings_params).separatedParams();
3482         listingsModule->listingsED->setPlainText(toqstr(lstparams));
3483
3484         // Fonts
3485         // some languages only work with polyglossia/XeTeX
3486         Language const * lang = lyx::languages.getLanguage(
3487                 fromqstr(langModule->languageCO->itemData(
3488                         langModule->languageCO->currentIndex()).toString()));
3489         bool const need_fontspec =
3490                 lang->babel().empty() && !lang->polyglossia().empty();
3491         bool const os_fonts_available =
3492                 bp_.baseClass()->outputType() == lyx::LATEX
3493                 && LaTeXFeatures::isAvailable("fontspec");
3494         fontModule->osFontsCB->setEnabled(os_fonts_available && !need_fontspec);
3495         fontModule->osFontsCB->setChecked(
3496                 (os_fonts_available && bp_.useNonTeXFonts) || need_fontspec);
3497         updateFontsize(documentClass().opt_fontsize(),
3498                         bp_.fontsize);
3499
3500         QString font = toqstr(bp_.fontsRoman());
3501         int rpos = fontModule->fontsRomanCO->findData(font);
3502         if (rpos == -1) {
3503                 rpos = fontModule->fontsRomanCO->count();
3504                 fontModule->fontsRomanCO->addItem(font + qt_(" (not installed)"), font);
3505         }
3506         fontModule->fontsRomanCO->setCurrentIndex(rpos);
3507         fontModule->font_roman = toqstr(bp_.fonts_roman[!bp_.useNonTeXFonts]);
3508
3509         font = toqstr(bp_.fontsSans());
3510         int spos = fontModule->fontsSansCO->findData(font);
3511         if (spos == -1) {
3512                 spos = fontModule->fontsSansCO->count();
3513                 fontModule->fontsSansCO->addItem(font + qt_(" (not installed)"), font);
3514         }
3515         fontModule->fontsSansCO->setCurrentIndex(spos);
3516         fontModule->font_sans = toqstr(bp_.fonts_sans[!bp_.useNonTeXFonts]);
3517
3518         font = toqstr(bp_.fontsTypewriter());
3519         int tpos = fontModule->fontsTypewriterCO->findData(font);
3520         if (tpos == -1) {
3521                 tpos = fontModule->fontsTypewriterCO->count();
3522                 fontModule->fontsTypewriterCO->addItem(font + qt_(" (not installed)"), font);
3523         }
3524         fontModule->fontsTypewriterCO->setCurrentIndex(tpos);
3525         fontModule->font_typewriter = toqstr(bp_.fonts_typewriter[!bp_.useNonTeXFonts]);
3526
3527         font = toqstr(bp_.fontsMath());
3528         int mpos = fontModule->fontsMathCO->findData(font);
3529         if (mpos == -1) {
3530                 mpos = fontModule->fontsMathCO->count();
3531                 fontModule->fontsMathCO->addItem(font + qt_(" (not installed)"), font);
3532         }
3533         fontModule->fontsMathCO->setCurrentIndex(mpos);
3534         fontModule->font_math = toqstr(bp_.fonts_math[!bp_.useNonTeXFonts]);
3535
3536         if (bp_.useNonTeXFonts && os_fonts_available) {
3537                 fontModule->fontencLA->setEnabled(false);
3538                 fontModule->fontencCO->setEnabled(false);
3539                 fontModule->fontencLE->setEnabled(false);
3540         } else {
3541                 fontModule->fontencLA->setEnabled(true);
3542                 fontModule->fontencCO->setEnabled(true);
3543                 fontModule->fontencLE->setEnabled(true);
3544                 romanChanged(rpos);
3545                 sansChanged(spos);
3546                 ttChanged(tpos);
3547         }
3548
3549         if (!bp_.fonts_cjk.empty())
3550                 fontModule->cjkFontLE->setText(
3551                         toqstr(bp_.fonts_cjk));
3552         else
3553                 fontModule->cjkFontLE->setText(QString());
3554         
3555         fontModule->microtypeCB->setChecked(bp_.use_microtype);
3556         fontModule->dashesCB->setChecked(!bp_.use_dash_ligatures);
3557
3558         fontModule->fontScCB->setChecked(bp_.fonts_expert_sc);
3559         fontModule->fontOsfCB->setChecked(bp_.fonts_old_figures);
3560         fontModule->scaleSansSB->setValue(bp_.fontsSansScale());
3561         fontModule->font_sf_scale = bp_.fonts_sans_scale[!bp_.useNonTeXFonts];
3562         fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale());
3563         fontModule->font_tt_scale = bp_.fonts_typewriter_scale[!bp_.useNonTeXFonts];
3564
3565         int nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
3566         if (nn >= 0)
3567                 fontModule->fontsDefaultCO->setCurrentIndex(nn);
3568
3569         if (bp_.fontenc == "global" || bp_.fontenc == "default") {
3570                 fontModule->fontencCO->setCurrentIndex(
3571                         fontModule->fontencCO->findData(toqstr(bp_.fontenc)));
3572                 fontModule->fontencLE->setEnabled(false);
3573         } else {
3574                 fontModule->fontencCO->setCurrentIndex(1);
3575                 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
3576         }
3577
3578         // Formats
3579         // This must be set _after_ fonts since updateDefaultFormat()
3580         // checks osFontsCB settings.
3581         // update combobox with formats
3582         updateDefaultFormat();
3583         int index = outputModule->defaultFormatCO->findData(toqstr(
3584                 bp_.default_output_format));
3585         // set to default if format is not found
3586         if (index == -1)
3587                 index = 0;
3588         outputModule->defaultFormatCO->setCurrentIndex(index);
3589
3590         outputModule->outputsyncCB->setChecked(bp_.output_sync);
3591         outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
3592
3593         outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
3594         outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
3595         outputModule->strictCB->setChecked(bp_.html_be_strict);
3596         outputModule->cssCB->setChecked(bp_.html_css_as_file);
3597
3598         outputModule->saveTransientPropertiesCB
3599                 ->setChecked(bp_.save_transient_properties);
3600
3601         // paper
3602         bool const extern_geometry =
3603                 documentClass().provides("geometry");
3604         int const psize = bp_.papersize;
3605         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
3606         setCustomPapersize(!extern_geometry && psize == 1);
3607         pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
3608
3609         bool const landscape =
3610                 bp_.orientation == ORIENTATION_LANDSCAPE;
3611         pageLayoutModule->landscapeRB->setChecked(landscape);
3612         pageLayoutModule->portraitRB->setChecked(!landscape);
3613         pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
3614         pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
3615
3616         pageLayoutModule->facingPagesCB->setChecked(
3617                 bp_.sides == TwoSides);
3618
3619         lengthToWidgets(pageLayoutModule->paperwidthLE,
3620                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, default_unit);
3621         lengthToWidgets(pageLayoutModule->paperheightLE,
3622                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, default_unit);
3623
3624         // margins
3625         Ui::MarginsUi * m = marginsModule;
3626
3627         setMargins();
3628
3629         lengthToWidgets(m->topLE, m->topUnit,
3630                 bp_.topmargin, default_unit);
3631
3632         lengthToWidgets(m->bottomLE, m->bottomUnit,
3633                 bp_.bottommargin, default_unit);
3634
3635         lengthToWidgets(m->innerLE, m->innerUnit,
3636                 bp_.leftmargin, default_unit);
3637
3638         lengthToWidgets(m->outerLE, m->outerUnit,
3639                 bp_.rightmargin, default_unit);
3640
3641         lengthToWidgets(m->headheightLE, m->headheightUnit,
3642                 bp_.headheight, default_unit);
3643
3644         lengthToWidgets(m->headsepLE, m->headsepUnit,
3645                 bp_.headsep, default_unit);
3646
3647         lengthToWidgets(m->footskipLE, m->footskipUnit,
3648                 bp_.footskip, default_unit);
3649
3650         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
3651                 bp_.columnsep, default_unit);
3652
3653         // branches
3654         updateUnknownBranches();
3655         branchesModule->update(bp_);
3656
3657         // PDF support
3658         PDFOptions const & pdf = bp_.pdfoptions();
3659         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
3660         if (bp_.documentClass().provides("hyperref"))
3661                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("C&ustomize Hyperref Options"));
3662         else
3663                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("&Use Hyperref Support"));
3664         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
3665         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
3666         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
3667         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
3668
3669         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
3670         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
3671         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
3672
3673         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
3674
3675         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
3676         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
3677         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
3678         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
3679
3680         nn = findToken(backref_opts, pdf.backref);
3681         if (nn >= 0)
3682                 pdfSupportModule->backrefCO->setCurrentIndex(nn);
3683
3684         pdfSupportModule->fullscreenCB->setChecked
3685                 (pdf.pagemode == pdf.pagemode_fullscreen);
3686
3687         pdfSupportModule->optionsLE->setText(
3688                 toqstr(pdf.quoted_options));
3689
3690         // Make sure that the bc is in the INITIAL state
3691         if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
3692                 bc().restore();
3693
3694         // clear changed branches cache
3695         changedBranches_.clear();
3696
3697         // reset tracker
3698         nonModuleChanged_ = false;
3699 }
3700
3701
3702 void GuiDocument::saveDocDefault()
3703 {
3704         // we have to apply the params first
3705         applyView();
3706         saveAsDefault();
3707 }
3708
3709
3710 void GuiDocument::updateAvailableModules()
3711 {
3712         modules_av_model_.clear();
3713         list<modInfoStruct> modInfoList = getModuleInfo();
3714         // Sort names according to the locale
3715         modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
3716                         return 0 < b.name.localeAwareCompare(a.name);
3717                 });
3718         int i = 0;
3719         for (modInfoStruct const & m : modInfoList) {
3720                 modules_av_model_.insertRow(i, m.name, m.id, m.description);
3721                 ++i;
3722         }
3723 }
3724
3725
3726 void GuiDocument::updateSelectedModules()
3727 {
3728         modules_sel_model_.clear();
3729         list<modInfoStruct> const selModList = getSelectedModules();
3730         int i = 0;
3731         for (modInfoStruct const & m : selModList) {
3732                 modules_sel_model_.insertRow(i, m.name, m.id, m.description);
3733                 ++i;
3734         }
3735 }
3736
3737
3738 void GuiDocument::updateIncludeonlys()
3739 {
3740         masterChildModule->childrenTW->clear();
3741         QString const no = qt_("No");
3742         QString const yes = qt_("Yes");
3743
3744         if (includeonlys_.empty()) {
3745                 masterChildModule->includeallRB->setChecked(true);
3746                 masterChildModule->childrenTW->setEnabled(false);
3747                 masterChildModule->maintainAuxCB->setEnabled(false);
3748         } else {
3749                 masterChildModule->includeonlyRB->setChecked(true);
3750                 masterChildModule->childrenTW->setEnabled(true);
3751                 masterChildModule->maintainAuxCB->setEnabled(true);
3752         }
3753         ListOfBuffers children = buffer().getChildren();
3754         ListOfBuffers::const_iterator it  = children.begin();
3755         ListOfBuffers::const_iterator end = children.end();
3756         bool has_unincluded = false;
3757         bool all_unincluded = true;
3758         for (; it != end; ++it) {
3759                 QTreeWidgetItem * item = new QTreeWidgetItem(masterChildModule->childrenTW);
3760                 // FIXME Unicode
3761                 string const name =
3762                         to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
3763                                                         from_utf8(buffer().filePath())));
3764                 item->setText(0, toqstr(name));
3765                 item->setText(1, isChildIncluded(name) ? yes : no);
3766                 if (!isChildIncluded(name))
3767                         has_unincluded = true;
3768                 else
3769                         all_unincluded = false;
3770         }
3771         // Both if all childs are included and if none is included
3772         // is equal to "include all" (i.e., ommit \includeonly).
3773         // Thus, reset the GUI.
3774         if (!has_unincluded || all_unincluded) {
3775                 masterChildModule->includeallRB->setChecked(true);
3776                 masterChildModule->childrenTW->setEnabled(false);
3777                 includeonlys_.clear();
3778         }
3779         // If all are included, we need to update again.
3780         if (!has_unincluded)
3781                 updateIncludeonlys();
3782 }
3783
3784
3785 bool GuiDocument::isBiblatex() const
3786 {
3787         QString const engine =
3788                 biblioModule->citeEngineCO->itemData(
3789                                 biblioModule->citeEngineCO->currentIndex()).toString();
3790
3791         return theCiteEnginesList[fromqstr(engine)]->getCiteFramework() == "biblatex";
3792 }
3793
3794
3795 void GuiDocument::updateDefaultBiblio(string const & style,
3796                                       string const & which)
3797 {
3798         QString const bibstyle = toqstr(style);
3799         biblioModule->defaultBiblioCO->clear();
3800
3801         int item_nr = -1;
3802
3803         if (isBiblatex()) {
3804                 if (which != "cbx") {
3805                         // First the bbx styles
3806                         biblioModule->biblatexBbxCO->clear();
3807                         QStringList str = texFileList("bbxFiles.lst");
3808                         // test whether we have a valid list, otherwise run rescan
3809                         if (str.isEmpty()) {
3810                                 rescanTexStyles("bbx");
3811                                 str = texFileList("bbxFiles.lst");
3812                         }
3813                         for (int i = 0; i != str.size(); ++i)
3814                                 str[i] = onlyFileName(str[i]);
3815                         // sort on filename only (no path)
3816                         str.sort();
3817
3818                         for (int i = 0; i != str.count(); ++i) {
3819                                 QString item = changeExtension(str[i], "");
3820                                 if (item == bibstyle)
3821                                         item_nr = i;
3822                                 biblioModule->biblatexBbxCO->addItem(item);
3823                         }
3824
3825                         if (item_nr == -1 && !bibstyle.isEmpty()) {
3826                                 biblioModule->biblatexBbxCO->addItem(bibstyle);
3827                                 item_nr = biblioModule->biblatexBbxCO->count() - 1;
3828                         }
3829
3830                         if (item_nr != -1)
3831                                 biblioModule->biblatexBbxCO->setCurrentIndex(item_nr);
3832                         else
3833                                 biblioModule->biblatexBbxCO->clearEditText();
3834                 }
3835
3836                 if (which != "bbx") {
3837                         // now the cbx styles
3838                         biblioModule->biblatexCbxCO->clear();
3839                         QStringList str = texFileList("cbxFiles.lst");
3840                         // test whether we have a valid list, otherwise run rescan
3841                         if (str.isEmpty()) {
3842                                 rescanTexStyles("cbx");
3843                                 str = texFileList("cbxFiles.lst");
3844                         }
3845                         for (int i = 0; i != str.size(); ++i)
3846                                 str[i] = onlyFileName(str[i]);
3847                         // sort on filename only (no path)
3848                         str.sort();
3849
3850                         for (int i = 0; i != str.count(); ++i) {
3851                                 QString item = changeExtension(str[i], "");
3852                                 if (item == bibstyle)
3853                                         item_nr = i;
3854                                 biblioModule->biblatexCbxCO->addItem(item);
3855                         }
3856
3857                         if (item_nr == -1 && !bibstyle.isEmpty()) {
3858                                 biblioModule->biblatexCbxCO->addItem(bibstyle);
3859                                 item_nr = biblioModule->biblatexCbxCO->count() - 1;
3860                         }
3861
3862                         if (item_nr != -1)
3863                                 biblioModule->biblatexCbxCO->setCurrentIndex(item_nr);
3864                         else
3865                                 biblioModule->biblatexCbxCO->clearEditText();
3866                 }
3867         } else {// BibTeX
3868                 biblioModule->biblatexBbxCO->clear();
3869                 biblioModule->biblatexCbxCO->clear();
3870                 QStringList str = texFileList("bstFiles.lst");
3871                 // test whether we have a valid list, otherwise run rescan
3872                 if (str.isEmpty()) {
3873                         rescanTexStyles("bst");
3874                         str = texFileList("bstFiles.lst");
3875                 }
3876                 for (int i = 0; i != str.size(); ++i)
3877                         str[i] = onlyFileName(str[i]);
3878                 // sort on filename only (no path)
3879                 str.sort();
3880
3881                 for (int i = 0; i != str.count(); ++i) {
3882                         QString item = changeExtension(str[i], "");
3883                         if (item == bibstyle)
3884                                 item_nr = i;
3885                         biblioModule->defaultBiblioCO->addItem(item);
3886                 }
3887
3888                 if (item_nr == -1 && !bibstyle.isEmpty()) {
3889                         biblioModule->defaultBiblioCO->addItem(bibstyle);
3890                         item_nr = biblioModule->defaultBiblioCO->count() - 1;
3891                 }
3892
3893                 if (item_nr != -1)
3894                         biblioModule->defaultBiblioCO->setCurrentIndex(item_nr);
3895                 else
3896                         biblioModule->defaultBiblioCO->clearEditText();
3897         }
3898
3899         updateResetDefaultBiblio();
3900 }
3901
3902
3903 void GuiDocument::updateResetDefaultBiblio()
3904 {
3905         QString const engine =
3906                 biblioModule->citeEngineCO->itemData(
3907                                 biblioModule->citeEngineCO->currentIndex()).toString();
3908         CiteEngineType const cet =
3909                 CiteEngineType(biblioModule->citeStyleCO->itemData(
3910                                                           biblioModule->citeStyleCO->currentIndex()).toInt());
3911
3912         string const defbib = theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet);
3913         if (isBiblatex()) {
3914                 QString const bbx = biblioModule->biblatexBbxCO->currentText();
3915                 QString const cbx = biblioModule->biblatexCbxCO->currentText();
3916                 biblioModule->resetCbxPB->setEnabled(defbib != fromqstr(cbx));
3917                 biblioModule->resetBbxPB->setEnabled(defbib != fromqstr(bbx));
3918                 biblioModule->matchBbxPB->setEnabled(bbx != cbx && !cbx.isEmpty()
3919                         && biblioModule->biblatexBbxCO->findText(cbx) != -1);
3920         } else
3921                 biblioModule->resetDefaultBiblioPB->setEnabled(
3922                         defbib != fromqstr(biblioModule->defaultBiblioCO->currentText()));
3923 }
3924
3925
3926 void GuiDocument::matchBiblatexStyles()
3927 {
3928         updateDefaultBiblio(fromqstr(biblioModule->biblatexCbxCO->currentText()), "bbx");
3929         biblioChanged();
3930 }
3931
3932
3933 void GuiDocument::updateContents()
3934 {
3935         // Nothing to do here as the document settings is not cursor dependant.
3936         return;
3937 }
3938
3939
3940 void GuiDocument::useClassDefaults()
3941 {
3942         if (applyPB->isEnabled()) {
3943                 int const ret = Alert::prompt(_("Unapplied changes"),
3944                                 _("Some changes in the dialog were not yet applied.\n"
3945                                   "If you do not apply now, they will be lost after this action."),
3946                                 1, 1, _("&Apply"), _("&Dismiss"));
3947                 if (ret == 0)
3948                         applyView();
3949         }
3950
3951         int idx = latexModule->classCO->currentIndex();
3952         string const classname = fromqstr(latexModule->classCO->getData(idx));
3953         if (!bp_.setBaseClass(classname)) {
3954                 Alert::error(_("Error"), _("Unable to set document class."));
3955                 return;
3956         }
3957         bp_.useClassDefaults();
3958         paramsToDialog();
3959 }
3960
3961
3962 void GuiDocument::setLayoutComboByIDString(string const & idString)
3963 {
3964         if (!latexModule->classCO->set(toqstr(idString)))
3965                 Alert::warning(_("Can't set layout!"),
3966                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
3967 }
3968
3969
3970 bool GuiDocument::isValid()
3971 {
3972         return
3973                 validateListingsParameters().isEmpty() &&
3974                 localLayout->isValid() &&
3975                 (
3976                         // if we're asking for skips between paragraphs
3977                         !textLayoutModule->skipRB->isChecked() ||
3978                         // then either we haven't chosen custom
3979                         textLayoutModule->skipCO->currentIndex() != 3 ||
3980                         // or else a length has been given
3981                         !textLayoutModule->skipLE->text().isEmpty()
3982                 ) &&
3983                 (
3984                         // if we're asking for indentation
3985                         !textLayoutModule->indentRB->isChecked() ||
3986                         // then either we haven't chosen custom
3987                         textLayoutModule->indentCO->currentIndex() != 1 ||
3988                         // or else a length has been given
3989                         !textLayoutModule->indentLE->text().isEmpty()
3990                 );
3991 }
3992
3993
3994 char const * const GuiDocument::fontfamilies[5] = {
3995         "default", "rmdefault", "sfdefault", "ttdefault", ""
3996 };
3997
3998
3999 char const * GuiDocument::fontfamilies_gui[5] = {
4000         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
4001 };
4002
4003
4004 bool GuiDocument::initialiseParams(string const &)
4005 {
4006         BufferView const * view = bufferview();
4007         if (!view) {
4008                 bp_ = BufferParams();
4009                 paramsToDialog();
4010                 return true;
4011         }
4012         bp_ = view->buffer().params();
4013         loadModuleInfo();
4014         updateAvailableModules();
4015         //FIXME It'd be nice to make sure here that the selected
4016         //modules are consistent: That required modules are actually
4017         //selected, and that we don't have conflicts. If so, we could
4018         //at least pop up a warning.
4019         paramsToDialog();
4020         return true;
4021 }
4022
4023
4024 void GuiDocument::clearParams()
4025 {
4026         bp_ = BufferParams();
4027 }
4028
4029
4030 BufferId GuiDocument::id() const
4031 {
4032         BufferView const * const view = bufferview();
4033         return view? &view->buffer() : 0;
4034 }
4035
4036
4037 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
4038 {
4039         return moduleNames_;
4040 }
4041
4042
4043 list<GuiDocument::modInfoStruct> const
4044 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
4045 {
4046         list<modInfoStruct> mInfo;
4047         for (string const & name : mods) {
4048                 modInfoStruct m;
4049                 LyXModule const * const mod = theModuleList[name];
4050                 if (mod)
4051                         m = modInfo(*mod);
4052                 else {
4053                         m.id = name;
4054                         m.name = toqstr(name + " (") + qt_("Not Found") + toqstr(")");
4055                 }
4056                 mInfo.push_back(m);
4057         }
4058         return mInfo;
4059 }
4060
4061
4062 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
4063 {
4064         return makeModuleInfo(params().getModules());
4065 }
4066
4067
4068 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
4069 {
4070         return makeModuleInfo(params().baseClass()->providedModules());
4071 }
4072
4073
4074 DocumentClass const & GuiDocument::documentClass() const
4075 {
4076         return bp_.documentClass();
4077 }
4078
4079
4080 static void dispatch_bufferparams(Dialog const & dialog,
4081         BufferParams const & bp, FuncCode lfun, Buffer const * buf)
4082 {
4083         ostringstream ss;
4084         ss << "\\begin_header\n";
4085         bp.writeFile(ss, buf);
4086         ss << "\\end_header\n";
4087         dialog.dispatch(FuncRequest(lfun, ss.str()));
4088 }
4089
4090
4091 void GuiDocument::dispatchParams()
4092 {
4093         // We need a non-const buffer object.
4094         Buffer & buf = const_cast<BufferView *>(bufferview())->buffer();
4095         // There may be several undo records; group them (bug #8998)
4096         buf.undo().beginUndoGroup();
4097
4098         // This must come first so that a language change is correctly noticed
4099         setLanguage();
4100
4101         // Apply the BufferParams. Note that this will set the base class
4102         // and then update the buffer's layout.
4103         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY, &buffer());
4104
4105         if (!params().master.empty()) {
4106                 FileName const master_file = support::makeAbsPath(params().master,
4107                            support::onlyPath(buffer().absFileName()));
4108                 if (isLyXFileName(master_file.absFileName())) {
4109                         Buffer * master = checkAndLoadLyXFile(master_file);
4110                         if (master) {
4111                                 if (master->isChild(const_cast<Buffer *>(&buffer())))
4112                                         const_cast<Buffer &>(buffer()).setParent(master);
4113                                 else
4114                                         Alert::warning(_("Assigned master does not include this file"),
4115                                                 bformat(_("You must include this file in the document\n"
4116                                                           "'%1$s' in order to use the master document\n"
4117                                                           "feature."), from_utf8(params().master)));
4118                         } else
4119                                 Alert::warning(_("Could not load master"),
4120                                                 bformat(_("The master document '%1$s'\n"
4121                                                            "could not be loaded."),
4122                                                            from_utf8(params().master)));
4123                 }
4124         }
4125
4126         // Generate the colours requested by each new branch.
4127         BranchList & branchlist = params().branchlist();
4128         if (!branchlist.empty()) {
4129                 BranchList::const_iterator it = branchlist.begin();
4130                 BranchList::const_iterator const end = branchlist.end();
4131                 for (; it != end; ++it) {
4132                         docstring const & current_branch = it->branch();
4133                         Branch const * branch = branchlist.find(current_branch);
4134                         string const x11hexname = X11hexname(branch->color());
4135                         // display the new color
4136                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
4137                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
4138                 }
4139
4140                 // Open insets of selected branches, close deselected ones
4141                 dispatch(FuncRequest(LFUN_INSET_FORALL,
4142                         "Branch inset-toggle assign"));
4143         }
4144         // rename branches in the document
4145         executeBranchRenaming();
4146         // and clear changed branches cache
4147         changedBranches_.clear();
4148
4149         // Generate the colours requested by indices.
4150         IndicesList & indiceslist = params().indiceslist();
4151         if (!indiceslist.empty()) {
4152                 IndicesList::const_iterator it = indiceslist.begin();
4153                 IndicesList::const_iterator const end = indiceslist.end();
4154                 for (; it != end; ++it) {
4155                         docstring const & current_index = it->shortcut();
4156                         Index const * index = indiceslist.findShortcut(current_index);
4157                         string const x11hexname = X11hexname(index->color());
4158                         // display the new color
4159                         docstring const str = current_index + ' ' + from_ascii(x11hexname);
4160                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
4161                 }
4162         }
4163         // FIXME LFUN
4164         // If we used an LFUN, we would not need these two lines:
4165         BufferView * bv = const_cast<BufferView *>(bufferview());
4166         bv->processUpdateFlags(Update::Force | Update::FitCursor);
4167
4168         // Don't forget to close the group. Note that it is important
4169         // to check that there is no early return in the method.
4170         buf.undo().endUndoGroup();
4171 }
4172
4173
4174 void GuiDocument::setLanguage() const
4175 {
4176         Language const * const newL = bp_.language;
4177         if (buffer().params().language == newL)
4178                 return;
4179
4180         string const & lang_name = newL->lang();
4181         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
4182 }
4183
4184
4185 void GuiDocument::saveAsDefault() const
4186 {
4187         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT, &buffer());
4188 }
4189
4190
4191 bool GuiDocument::providesOSF(QString const & font) const
4192 {
4193         if (fontModule->osFontsCB->isChecked())
4194                 // FIXME: we should check if the fonts really
4195                 // have OSF support. But how?
4196                 return true;
4197         return theLaTeXFonts().getLaTeXFont(
4198                                 qstring_to_ucs4(font)).providesOSF(ot1(),
4199                                                                    completeFontset(),
4200                                                                    noMathFont());
4201 }
4202
4203
4204 bool GuiDocument::providesSC(QString const & font) const
4205 {
4206         if (fontModule->osFontsCB->isChecked())
4207                 return false;
4208         return theLaTeXFonts().getLaTeXFont(
4209                                 qstring_to_ucs4(font)).providesSC(ot1(),
4210                                                                   completeFontset(),
4211                                                                   noMathFont());
4212 }
4213
4214
4215 bool GuiDocument::providesScale(QString const & font) const
4216 {
4217         if (fontModule->osFontsCB->isChecked())
4218                 return true;
4219         return theLaTeXFonts().getLaTeXFont(
4220                                 qstring_to_ucs4(font)).providesScale(ot1(),
4221                                                                      completeFontset(),
4222                                                                      noMathFont());
4223 }
4224
4225
4226 bool GuiDocument::providesNoMath(QString const & font) const
4227 {
4228         if (fontModule->osFontsCB->isChecked())
4229                 return false;
4230         return theLaTeXFonts().getLaTeXFont(
4231                                 qstring_to_ucs4(font)).providesNoMath(ot1(),
4232                                                                       completeFontset());
4233 }
4234
4235
4236 bool GuiDocument::hasMonolithicExpertSet(QString const & font) const
4237 {
4238         if (fontModule->osFontsCB->isChecked())
4239                 return false;
4240         return theLaTeXFonts().getLaTeXFont(
4241                                 qstring_to_ucs4(font)).hasMonolithicExpertSet(ot1(),
4242                                                                               completeFontset(),
4243                                                                               noMathFont());
4244 }
4245
4246
4247 //static
4248 GuiDocument::modInfoStruct GuiDocument::modInfo(LyXModule const & mod)
4249 {
4250         // FIXME Unicode: docstrings would be better for these parameters but this
4251         // change requires a lot of others
4252         modInfoStruct m;
4253         m.id = mod.getID();
4254         m.name = toqstr(translateIfPossible(from_utf8(mod.getName())));
4255         QString desc = toqstr(translateIfPossible(from_utf8(mod.getDescription())));
4256         // Find the first sentence of the description
4257         QTextBoundaryFinder bf(QTextBoundaryFinder::Sentence, desc);
4258         int pos = bf.toNextBoundary();
4259         if (pos > 0)
4260                 desc.truncate(pos);
4261         QString modulename = QString(qt_("(Module name: %1)")).arg(toqstr(m.id));
4262         // Tooltip is the desc followed by the module name
4263         m.description = QString("%1<i>%2</i>")
4264                 .arg(desc.isEmpty() ? QString() : QString("<p>%1</p>").arg(desc),
4265                      modulename);
4266         return m;
4267 }
4268
4269
4270 void GuiDocument::loadModuleInfo()
4271 {
4272         moduleNames_.clear();
4273         for (LyXModule const & mod : theModuleList)
4274                 if (mod.category().substr(0, 8) != "Citation")
4275                         moduleNames_.push_back(modInfo(mod));
4276 }
4277
4278
4279 void GuiDocument::updateUnknownBranches()
4280 {
4281         if (!bufferview())
4282                 return;
4283         list<docstring> used_branches;
4284         buffer().getUsedBranches(used_branches);
4285         list<docstring>::const_iterator it = used_branches.begin();
4286         QStringList unknown_branches;
4287         for (; it != used_branches.end() ; ++it) {
4288                 if (!buffer().params().branchlist().find(*it))
4289                         unknown_branches.append(toqstr(*it));
4290         }
4291         branchesModule->setUnknownBranches(unknown_branches);
4292 }
4293
4294
4295 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
4296 {
4297         map<docstring, docstring>::iterator it = changedBranches_.begin();
4298         for (; it != changedBranches_.end() ; ++it) {
4299                 if (it->second == oldname) {
4300                         // branch has already been renamed
4301                         it->second = newname;
4302                         return;
4303                 }
4304         }
4305         // store new name
4306         changedBranches_[oldname] = newname;
4307 }
4308
4309
4310 void GuiDocument::executeBranchRenaming() const
4311 {
4312         map<docstring, docstring>::const_iterator it = changedBranches_.begin();
4313         for (; it != changedBranches_.end() ; ++it) {
4314                 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
4315                 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
4316         }
4317 }
4318
4319
4320 void GuiDocument::allPackagesAuto()
4321 {
4322         allPackages(1);
4323 }
4324
4325
4326 void GuiDocument::allPackagesAlways()
4327 {
4328         allPackages(2);
4329 }
4330
4331
4332 void GuiDocument::allPackagesNot()
4333 {
4334         allPackages(3);
4335 }
4336
4337
4338 void GuiDocument::allPackages(int col)
4339 {
4340         for (int row = 0; row < mathsModule->packagesTW->rowCount(); ++row) {
4341                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, col);
4342                 rb->setChecked(true);
4343         }
4344 }
4345
4346
4347 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
4348
4349
4350 } // namespace frontend
4351 } // namespace lyx
4352
4353 #include "moc_GuiDocument.cpp"