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