]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiDocument.cpp
Better handling for negative position in pos2x
[lyx.git] / src / frontends / qt4 / GuiDocument.cpp
1 /**
2  * \file GuiDocument.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Edwin Leuven
7  * \author Richard Heck (modules)
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "GuiDocument.h"
15
16 #include "CategorizedCombo.h"
17 #include "GuiApplication.h"
18 #include "GuiBranches.h"
19 #include "GuiIndices.h"
20 #include "GuiSelectionManager.h"
21 #include "LaTeXHighlighter.h"
22 #include "LengthCombo.h"
23 #include "PanelStack.h"
24 #include "Validator.h"
25
26 #include "LayoutFile.h"
27 #include "BranchList.h"
28 #include "buffer_funcs.h"
29 #include "Buffer.h"
30 #include "BufferParams.h"
31 #include "BufferView.h"
32 #include "CiteEnginesList.h"
33 #include "Color.h"
34 #include "ColorCache.h"
35 #include "Converter.h"
36 #include "Cursor.h"
37 #include "Encoding.h"
38 #include "FloatPlacement.h"
39 #include "Format.h"
40 #include "FuncRequest.h"
41 #include "HSpace.h"
42 #include "IndicesList.h"
43 #include "Language.h"
44 #include "LaTeXFeatures.h"
45 #include "LaTeXFonts.h"
46 #include "Layout.h"
47 #include "LayoutEnums.h"
48 #include "LayoutModuleList.h"
49 #include "LyXRC.h"
50 #include "ModuleList.h"
51 #include "OutputParams.h"
52 #include "PDFOptions.h"
53 #include "qt_helpers.h"
54 #include "Spacing.h"
55 #include "TextClass.h"
56 #include "Undo.h"
57 #include "VSpace.h"
58
59 #include "insets/InsetListingsParams.h"
60
61 #include "support/debug.h"
62 #include "support/FileName.h"
63 #include "support/filetools.h"
64 #include "support/gettext.h"
65 #include "support/lassert.h"
66 #include "support/lstrings.h"
67
68 #include "frontends/alert.h"
69
70 #include <QAbstractItemModel>
71 #include <QHeaderView>
72 #include <QColor>
73 #include <QColorDialog>
74 #include <QCloseEvent>
75 #include <QFontDatabase>
76 #include <QScrollBar>
77 #include <QTextBoundaryFinder>
78 #include <QTextCursor>
79
80 #include <sstream>
81 #include <vector>
82
83 #ifdef IN
84 #undef IN
85 #endif
86
87
88 // a style sheet for buttons
89 // this is for example used for the background color setting button
90 static inline QString colorButtonStyleSheet(QColor const & bgColor)
91 {
92         if (bgColor.isValid()) {
93                 QString rc = QLatin1String("background-color:");
94                 rc += bgColor.name();
95                 return rc;
96         }
97         return QString();
98 }
99
100
101 using namespace std;
102 using namespace lyx::support;
103
104
105 namespace {
106
107 char const * const tex_graphics[] =
108 {
109         "default", "dvialw", "dvilaser", "dvipdf", "dvipdfm", "dvipdfmx",
110         "dvips", "dvipsone", "dvitops", "dviwin", "dviwindo", "dvi2ps", "emtex",
111         "ln", "oztex", "pctexhp", "pctexps", "pctexwin", "pctex32", "pdftex",
112         "psprint", "pubps", "tcidvi", "textures", "truetex", "vtex", "xdvi",
113         "xetex", "none", ""
114 };
115
116
117 char const * const tex_graphics_gui[] =
118 {
119         N_("Default"), "dvialw", "DviLaser", "dvipdf", "DVIPDFM", "DVIPDFMx",
120         "Dvips", "DVIPSONE", "DVItoPS", "DVIWIN", "DVIWindo", "dvi2ps", "EmTeX",
121         "LN", "OzTeX", "pctexhp", "pctexps", "pctexwin", "PCTeX32", "pdfTeX",
122         "psprint", "pubps", "tcidvi", "Textures", "TrueTeX", "VTeX", "xdvi",
123         "XeTeX", N_("None"), ""
124 };
125
126
127 char const * backref_opts[] =
128 {
129         "false", "section", "slide", "page", ""
130 };
131
132
133 char const * backref_opts_gui[] =
134 {
135         N_("Off"), N_("Section"), N_("Slide"), N_("Page"), ""
136 };
137
138
139 vector<string> engine_types_;
140 vector<pair<string, QString> > pagestyles;
141
142 QMap<QString, QString> rmfonts_;
143 QMap<QString, QString> sffonts_;
144 QMap<QString, QString> ttfonts_;
145 QMap<QString, QString> mathfonts_;
146
147
148 } // anonymous namespace
149
150 namespace lyx {
151
152 RGBColor set_backgroundcolor;
153 bool is_backgroundcolor;
154 RGBColor set_fontcolor;
155 bool is_fontcolor;
156 RGBColor set_notefontcolor;
157 RGBColor set_boxbgcolor;
158 bool forced_fontspec_activation;
159
160 namespace {
161 // used when sorting the textclass list.
162 class less_textclass_avail_desc
163         : public binary_function<string, string, int>
164 {
165 public:
166         bool operator()(string const & lhs, string const & rhs) const
167         {
168                 // Ordering criteria:
169                 //   1. Availability of text class
170                 //   2. Description (lexicographic)
171                 LayoutFile const & tc1 = LayoutFileList::get()[lhs];
172                 LayoutFile const & tc2 = LayoutFileList::get()[rhs];
173                 int const order = compare_no_case(
174                         translateIfPossible(from_utf8(tc1.description())),
175                         translateIfPossible(from_utf8(tc2.description())));
176                 return (tc1.isTeXClassAvailable() && !tc2.isTeXClassAvailable()) ||
177                         (tc1.isTeXClassAvailable() == tc2.isTeXClassAvailable() && order < 0);
178         }
179 };
180
181 }
182
183 namespace frontend {
184 namespace {
185
186 vector<string> getRequiredList(string const & modName)
187 {
188         LyXModule const * const mod = theModuleList[modName];
189         if (!mod)
190                 return vector<string>(); //empty such thing
191         return mod->getRequiredModules();
192 }
193
194
195 vector<string> getExcludedList(string const & modName)
196 {
197         LyXModule const * const mod = theModuleList[modName];
198         if (!mod)
199                 return vector<string>(); //empty such thing
200         return mod->getExcludedModules();
201 }
202
203
204 docstring getModuleCategory(string const & modName)
205 {
206         LyXModule const * const mod = theModuleList[modName];
207         if (!mod)
208                 return docstring();
209         return from_utf8(mod->category());
210 }
211
212
213 docstring getModuleDescription(string const & modName)
214 {
215         LyXModule const * const mod = theModuleList[modName];
216         if (!mod)
217                 return _("Module not found!");
218         // FIXME Unicode
219         return translateIfPossible(from_utf8(mod->getDescription()));
220 }
221
222
223 vector<string> getPackageList(string const & modName)
224 {
225         LyXModule const * const mod = theModuleList[modName];
226         if (!mod)
227                 return vector<string>(); //empty such thing
228         return mod->getPackageList();
229 }
230
231
232 bool isModuleAvailable(string const & modName)
233 {
234         LyXModule const * const mod = theModuleList[modName];
235         if (!mod)
236                 return false;
237         return mod->isAvailable();
238 }
239
240 } // anonymous namespace
241
242
243 /////////////////////////////////////////////////////////////////////
244 //
245 // ModuleSelectionManager
246 //
247 /////////////////////////////////////////////////////////////////////
248
249 /// SelectionManager for use with modules
250 class ModuleSelectionManager : public GuiSelectionManager
251 {
252 public:
253         ///
254         ModuleSelectionManager(
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         biblioModule->bibunitsCO->addItem(qt_("per child document"), toqstr("child"));
3173
3174         int const mbpos = biblioModule->bibunitsCO->findData(toqstr(bp_.multibib));
3175         if (mbpos != -1)
3176                 biblioModule->bibunitsCO->setCurrentIndex(mbpos);
3177         else
3178                 biblioModule->bibunitsCO->setCurrentIndex(0);
3179
3180         updateEngineDependends();
3181
3182         if (isBiblatex()) {
3183                 updateDefaultBiblio(bp_.biblatex_bibstyle, "bbx");
3184                 updateDefaultBiblio(bp_.biblatex_citestyle, "cbx");
3185         } else
3186                 updateDefaultBiblio(bp_.defaultBiblioStyle());
3187
3188         biblioModule->citePackageOptionsLE->setText(toqstr(bp_.biblio_opts));
3189
3190         string command;
3191         string options =
3192                 split(bp_.bibtex_command, command, ' ');
3193
3194         int const bpos = biblioModule->bibtexCO->findData(toqstr(command));
3195         if (bpos != -1) {
3196                 biblioModule->bibtexCO->setCurrentIndex(bpos);
3197                 biblioModule->bibtexOptionsLE->setText(toqstr(options).trimmed());
3198         } else {
3199                 // We reset to default if we do not know the specified compiler
3200                 // This is for security reasons
3201                 biblioModule->bibtexCO->setCurrentIndex(
3202                         biblioModule->bibtexCO->findData(toqstr("default")));
3203                 biblioModule->bibtexOptionsLE->clear();
3204         }
3205         biblioModule->bibtexOptionsLE->setEnabled(
3206                 biblioModule->bibtexCO->currentIndex() != 0);
3207
3208         biblioChanged_ = false;
3209
3210         // indices
3211         // We may be called when there is no Buffer, e.g., when 
3212         // the last view has just been closed.
3213         bool const isReadOnly = isBufferAvailable() ? buffer().isReadonly() : false;
3214         indicesModule->update(bp_, isReadOnly);
3215
3216         // language & quotes
3217         int const pos = langModule->languageCO->findData(toqstr(
3218                 bp_.language->lang()));
3219         langModule->languageCO->setCurrentIndex(pos);
3220
3221         updateQuoteStyles();
3222
3223         langModule->quoteStyleCO->setCurrentIndex(
3224                 langModule->quoteStyleCO->findData(bp_.quotes_style));
3225         langModule->dynamicQuotesCB->setChecked(bp_.dynamic_quotes);
3226
3227         bool default_enc = true;
3228         if (bp_.inputenc != "auto") {
3229                 default_enc = false;
3230                 if (bp_.inputenc == "default") {
3231                         langModule->encodingCO->setCurrentIndex(0);
3232                 } else {
3233                         string enc_gui;
3234                         Encodings::const_iterator it = encodings.begin();
3235                         Encodings::const_iterator const end = encodings.end();
3236                         for (; it != end; ++it) {
3237                                 if (it->name() == bp_.inputenc &&
3238                                     !it->unsafe()) {
3239                                         enc_gui = it->guiName();
3240                                         break;
3241                                 }
3242                         }
3243                         int const i = langModule->encodingCO->findText(
3244                                         qt_(enc_gui));
3245                         if (i >= 0)
3246                                 langModule->encodingCO->setCurrentIndex(i);
3247                         else
3248                                 // unknown encoding. Set to default.
3249                                 default_enc = true;
3250                 }
3251         }
3252         langModule->defaultencodingRB->setChecked(default_enc);
3253         langModule->otherencodingRB->setChecked(!default_enc);
3254
3255         int const p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
3256         if (p == -1) {
3257                 langModule->languagePackageCO->setCurrentIndex(
3258                           langModule->languagePackageCO->findData("custom"));
3259                 langModule->languagePackageLE->setText(toqstr(bp_.lang_package));
3260         } else {
3261                 langModule->languagePackageCO->setCurrentIndex(p);
3262                 langModule->languagePackageLE->clear();
3263         }
3264
3265         //color
3266         if (bp_.isfontcolor) {
3267                 colorModule->fontColorPB->setStyleSheet(
3268                         colorButtonStyleSheet(rgb2qcolor(bp_.fontcolor)));
3269         }
3270         set_fontcolor = bp_.fontcolor;
3271         is_fontcolor = bp_.isfontcolor;
3272
3273         colorModule->noteFontColorPB->setStyleSheet(
3274                 colorButtonStyleSheet(rgb2qcolor(bp_.notefontcolor)));
3275         set_notefontcolor = bp_.notefontcolor;
3276
3277         if (bp_.isbackgroundcolor) {
3278                 colorModule->backgroundPB->setStyleSheet(
3279                         colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
3280         }
3281         set_backgroundcolor = bp_.backgroundcolor;
3282         is_backgroundcolor = bp_.isbackgroundcolor;
3283
3284         colorModule->boxBackgroundPB->setStyleSheet(
3285                 colorButtonStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
3286         set_boxbgcolor = bp_.boxbgcolor;
3287
3288         // numbering
3289         int const min_toclevel = documentClass().min_toclevel();
3290         int const max_toclevel = documentClass().max_toclevel();
3291         if (documentClass().hasTocLevels()) {
3292                 numberingModule->setEnabled(true);
3293                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
3294                 numberingModule->depthSL->setMaximum(max_toclevel);
3295                 numberingModule->depthSL->setValue(bp_.secnumdepth);
3296                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
3297                 numberingModule->tocSL->setMaximum(max_toclevel);
3298                 numberingModule->tocSL->setValue(bp_.tocdepth);
3299                 updateNumbering();
3300         } else {
3301                 numberingModule->setEnabled(false);
3302                 numberingModule->tocTW->clear();
3303         }
3304
3305         // bullets
3306         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
3307         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
3308         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
3309         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
3310         bulletsModule->init();
3311
3312         // packages
3313         int nitem = findToken(tex_graphics, bp_.graphics_driver);
3314         if (nitem >= 0)
3315                 latexModule->psdriverCO->setCurrentIndex(nitem);
3316         updateModuleInfo();
3317
3318         map<string, string> const & packages = BufferParams::auto_packages();
3319         for (map<string, string>::const_iterator it = packages.begin();
3320              it != packages.end(); ++it) {
3321                 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
3322                 if (!item)
3323                         continue;
3324                 int row = mathsModule->packagesTW->row(item);
3325                 switch (bp_.use_package(it->first)) {
3326                         case BufferParams::package_off: {
3327                                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3);
3328                                 rb->setChecked(true);
3329                                 break;
3330                         }
3331                         case BufferParams::package_on: {
3332                                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2);
3333                                 rb->setChecked(true);
3334                                 break;
3335                         }
3336                         case BufferParams::package_auto: {
3337                                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1);
3338                                 rb->setChecked(true);
3339                                 break;
3340                         }
3341                 }
3342         }
3343
3344         switch (bp_.spacing().getSpace()) {
3345                 case Spacing::Other: nitem = 3; break;
3346                 case Spacing::Double: nitem = 2; break;
3347                 case Spacing::Onehalf: nitem = 1; break;
3348                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
3349         }
3350
3351         // text layout
3352         string const & layoutID = bp_.baseClassID();
3353         setLayoutComboByIDString(layoutID);
3354
3355         updatePagestyle(documentClass().opt_pagestyle(),
3356                                  bp_.pagestyle);
3357
3358         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
3359         if (bp_.spacing().getSpace() == Spacing::Other) {
3360                 doubleToWidget(textLayoutModule->lspacingLE,
3361                         bp_.spacing().getValueAsString());
3362         }
3363         setLSpacing(nitem);
3364
3365         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
3366                 textLayoutModule->indentRB->setChecked(true);
3367                 string indentation = bp_.getIndentation().asLyXCommand();
3368                 int indent = 0;
3369                 if (indentation != "default") {
3370                         lengthToWidgets(textLayoutModule->indentLE,
3371                         textLayoutModule->indentLengthCO,
3372                         indentation, default_unit);
3373                         indent = 1;
3374                 }
3375                 textLayoutModule->indentCO->setCurrentIndex(indent);
3376                 setIndent(indent);
3377         } else {
3378                 textLayoutModule->skipRB->setChecked(true);
3379                 int skip = 0;
3380                 switch (bp_.getDefSkip().kind()) {
3381                 case VSpace::SMALLSKIP:
3382                         skip = 0;
3383                         break;
3384                 case VSpace::MEDSKIP:
3385                         skip = 1;
3386                         break;
3387                 case VSpace::BIGSKIP:
3388                         skip = 2;
3389                         break;
3390                 case VSpace::LENGTH:
3391                         {
3392                         skip = 3;
3393                         string const length = bp_.getDefSkip().asLyXCommand();
3394                         lengthToWidgets(textLayoutModule->skipLE,
3395                                 textLayoutModule->skipLengthCO,
3396                                 length, default_unit);
3397                         break;
3398                         }
3399                 default:
3400                         skip = 0;
3401                         break;
3402                 }
3403                 textLayoutModule->skipCO->setCurrentIndex(skip);
3404                 setSkip(skip);
3405         }
3406
3407         textLayoutModule->twoColumnCB->setChecked(
3408                 bp_.columns == 2);
3409         textLayoutModule->justCB->setChecked(bp_.justification);
3410
3411         if (!bp_.options.empty()) {
3412                 latexModule->optionsLE->setText(
3413                         toqstr(bp_.options));
3414         } else {
3415                 latexModule->optionsLE->setText(QString());
3416         }
3417
3418         // latex
3419         latexModule->defaultOptionsCB->setChecked(
3420                         bp_.use_default_options);
3421         updateSelectedModules();
3422         selectionManager->updateProvidedModules(
3423                         bp_.baseClass()->providedModules());
3424         selectionManager->updateExcludedModules(
3425                         bp_.baseClass()->excludedModules());
3426
3427         if (!documentClass().options().empty()) {
3428                 latexModule->defaultOptionsLE->setText(
3429                         toqstr(documentClass().options()));
3430         } else {
3431                 latexModule->defaultOptionsLE->setText(
3432                         toqstr(_("[No options predefined]")));
3433         }
3434
3435         latexModule->defaultOptionsLE->setEnabled(
3436                 bp_.use_default_options
3437                 && !documentClass().options().empty());
3438
3439         latexModule->defaultOptionsCB->setEnabled(
3440                 !documentClass().options().empty());
3441
3442         if (!bp_.master.empty()) {
3443                 latexModule->childDocGB->setChecked(true);
3444                 latexModule->childDocLE->setText(
3445                         toqstr(bp_.master));
3446         } else {
3447                 latexModule->childDocLE->setText(QString());
3448                 latexModule->childDocGB->setChecked(false);
3449         }
3450
3451         // Master/Child
3452         if (!bufferview() || !buffer().hasChildren()) {
3453                 masterChildModule->childrenTW->clear();
3454                 includeonlys_.clear();
3455                 docPS->showPanel("Child Documents", false);
3456                 if (docPS->isCurrentPanel("Child Documents"))
3457                         docPS->setCurrentPanel("Document Class");
3458         } else {
3459                 docPS->showPanel("Child Documents", true);
3460                 masterChildModule->setEnabled(true);
3461                 includeonlys_ = bp_.getIncludedChildren();
3462                 updateIncludeonlys();
3463         }
3464         masterChildModule->maintainAuxCB->setChecked(
3465                 bp_.maintain_unincluded_children);
3466
3467         // Float Settings
3468         floatModule->set(bp_.float_placement);
3469
3470         // ListingsSettings
3471         // break listings_params to multiple lines
3472         string lstparams =
3473                 InsetListingsParams(bp_.listings_params).separatedParams();
3474         listingsModule->listingsED->setPlainText(toqstr(lstparams));
3475
3476         // Fonts
3477         // some languages only work with polyglossia/XeTeX
3478         Language const * lang = lyx::languages.getLanguage(
3479                 fromqstr(langModule->languageCO->itemData(
3480                         langModule->languageCO->currentIndex()).toString()));
3481         bool const need_fontspec =
3482                 lang->babel().empty() && !lang->polyglossia().empty();
3483         bool const os_fonts_available =
3484                 bp_.baseClass()->outputType() == lyx::LATEX
3485                 && LaTeXFeatures::isAvailable("fontspec");
3486         fontModule->osFontsCB->setEnabled(os_fonts_available && !need_fontspec);
3487         fontModule->osFontsCB->setChecked(
3488                 (os_fonts_available && bp_.useNonTeXFonts) || need_fontspec);
3489         updateFontsize(documentClass().opt_fontsize(),
3490                         bp_.fontsize);
3491
3492         QString font = toqstr(bp_.fontsRoman());
3493         int rpos = fontModule->fontsRomanCO->findData(font);
3494         if (rpos == -1) {
3495                 rpos = fontModule->fontsRomanCO->count();
3496                 fontModule->fontsRomanCO->addItem(font + qt_(" (not installed)"), font);
3497         }
3498         fontModule->fontsRomanCO->setCurrentIndex(rpos);
3499         fontModule->font_roman = toqstr(bp_.fonts_roman[!bp_.useNonTeXFonts]);
3500
3501         font = toqstr(bp_.fontsSans());
3502         int spos = fontModule->fontsSansCO->findData(font);
3503         if (spos == -1) {
3504                 spos = fontModule->fontsSansCO->count();
3505                 fontModule->fontsSansCO->addItem(font + qt_(" (not installed)"), font);
3506         }
3507         fontModule->fontsSansCO->setCurrentIndex(spos);
3508         fontModule->font_sans = toqstr(bp_.fonts_sans[!bp_.useNonTeXFonts]);
3509
3510         font = toqstr(bp_.fontsTypewriter());
3511         int tpos = fontModule->fontsTypewriterCO->findData(font);
3512         if (tpos == -1) {
3513                 tpos = fontModule->fontsTypewriterCO->count();
3514                 fontModule->fontsTypewriterCO->addItem(font + qt_(" (not installed)"), font);
3515         }
3516         fontModule->fontsTypewriterCO->setCurrentIndex(tpos);
3517         fontModule->font_typewriter = toqstr(bp_.fonts_typewriter[!bp_.useNonTeXFonts]);
3518
3519         font = toqstr(bp_.fontsMath());
3520         int mpos = fontModule->fontsMathCO->findData(font);
3521         if (mpos == -1) {
3522                 mpos = fontModule->fontsMathCO->count();
3523                 fontModule->fontsMathCO->addItem(font + qt_(" (not installed)"), font);
3524         }
3525         fontModule->fontsMathCO->setCurrentIndex(mpos);
3526         fontModule->font_math = toqstr(bp_.fonts_math[!bp_.useNonTeXFonts]);
3527
3528         if (bp_.useNonTeXFonts && os_fonts_available) {
3529                 fontModule->fontencLA->setEnabled(false);
3530                 fontModule->fontencCO->setEnabled(false);
3531                 fontModule->fontencLE->setEnabled(false);
3532         } else {
3533                 fontModule->fontencLA->setEnabled(true);
3534                 fontModule->fontencCO->setEnabled(true);
3535                 fontModule->fontencLE->setEnabled(true);
3536                 romanChanged(rpos);
3537                 sansChanged(spos);
3538                 ttChanged(tpos);
3539         }
3540
3541         if (!bp_.fonts_cjk.empty())
3542                 fontModule->cjkFontLE->setText(
3543                         toqstr(bp_.fonts_cjk));
3544         else
3545                 fontModule->cjkFontLE->setText(QString());
3546         
3547         fontModule->microtypeCB->setChecked(bp_.use_microtype);
3548
3549         fontModule->fontScCB->setChecked(bp_.fonts_expert_sc);
3550         fontModule->fontOsfCB->setChecked(bp_.fonts_old_figures);
3551         fontModule->scaleSansSB->setValue(bp_.fontsSansScale());
3552         fontModule->font_sf_scale = bp_.fonts_sans_scale[!bp_.useNonTeXFonts];
3553         fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale());
3554         fontModule->font_tt_scale = bp_.fonts_typewriter_scale[!bp_.useNonTeXFonts];
3555
3556         int nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
3557         if (nn >= 0)
3558                 fontModule->fontsDefaultCO->setCurrentIndex(nn);
3559
3560         if (bp_.fontenc == "global" || bp_.fontenc == "default") {
3561                 fontModule->fontencCO->setCurrentIndex(
3562                         fontModule->fontencCO->findData(toqstr(bp_.fontenc)));
3563                 fontModule->fontencLE->setEnabled(false);
3564         } else {
3565                 fontModule->fontencCO->setCurrentIndex(1);
3566                 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
3567         }
3568
3569         // Formats
3570         // This must be set _after_ fonts since updateDefaultFormat()
3571         // checks osFontsCB settings.
3572         // update combobox with formats
3573         updateDefaultFormat();
3574         int index = outputModule->defaultFormatCO->findData(toqstr(
3575                 bp_.default_output_format));
3576         // set to default if format is not found
3577         if (index == -1)
3578                 index = 0;
3579         outputModule->defaultFormatCO->setCurrentIndex(index);
3580
3581         outputModule->outputsyncCB->setChecked(bp_.output_sync);
3582         outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
3583
3584         outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
3585         outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
3586         outputModule->strictCB->setChecked(bp_.html_be_strict);
3587         outputModule->cssCB->setChecked(bp_.html_css_as_file);
3588
3589         outputModule->saveTransientPropertiesCB
3590                 ->setChecked(bp_.save_transient_properties);
3591
3592         // paper
3593         bool const extern_geometry =
3594                 documentClass().provides("geometry");
3595         int const psize = bp_.papersize;
3596         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
3597         setCustomPapersize(!extern_geometry && psize == 1);
3598         pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
3599
3600         bool const landscape =
3601                 bp_.orientation == ORIENTATION_LANDSCAPE;
3602         pageLayoutModule->landscapeRB->setChecked(landscape);
3603         pageLayoutModule->portraitRB->setChecked(!landscape);
3604         pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
3605         pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
3606
3607         pageLayoutModule->facingPagesCB->setChecked(
3608                 bp_.sides == TwoSides);
3609
3610         lengthToWidgets(pageLayoutModule->paperwidthLE,
3611                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, default_unit);
3612         lengthToWidgets(pageLayoutModule->paperheightLE,
3613                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, default_unit);
3614
3615         // margins
3616         Ui::MarginsUi * m = marginsModule;
3617
3618         setMargins();
3619
3620         lengthToWidgets(m->topLE, m->topUnit,
3621                 bp_.topmargin, default_unit);
3622
3623         lengthToWidgets(m->bottomLE, m->bottomUnit,
3624                 bp_.bottommargin, default_unit);
3625
3626         lengthToWidgets(m->innerLE, m->innerUnit,
3627                 bp_.leftmargin, default_unit);
3628
3629         lengthToWidgets(m->outerLE, m->outerUnit,
3630                 bp_.rightmargin, default_unit);
3631
3632         lengthToWidgets(m->headheightLE, m->headheightUnit,
3633                 bp_.headheight, default_unit);
3634
3635         lengthToWidgets(m->headsepLE, m->headsepUnit,
3636                 bp_.headsep, default_unit);
3637
3638         lengthToWidgets(m->footskipLE, m->footskipUnit,
3639                 bp_.footskip, default_unit);
3640
3641         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
3642                 bp_.columnsep, default_unit);
3643
3644         // branches
3645         updateUnknownBranches();
3646         branchesModule->update(bp_);
3647
3648         // PDF support
3649         PDFOptions const & pdf = bp_.pdfoptions();
3650         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
3651         if (bp_.documentClass().provides("hyperref"))
3652                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("C&ustomize Hyperref Options"));
3653         else
3654                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("&Use Hyperref Support"));
3655         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
3656         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
3657         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
3658         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
3659
3660         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
3661         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
3662         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
3663
3664         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
3665
3666         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
3667         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
3668         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
3669         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
3670
3671         nn = findToken(backref_opts, pdf.backref);
3672         if (nn >= 0)
3673                 pdfSupportModule->backrefCO->setCurrentIndex(nn);
3674
3675         pdfSupportModule->fullscreenCB->setChecked
3676                 (pdf.pagemode == pdf.pagemode_fullscreen);
3677
3678         pdfSupportModule->optionsLE->setText(
3679                 toqstr(pdf.quoted_options));
3680
3681         // Make sure that the bc is in the INITIAL state
3682         if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
3683                 bc().restore();
3684
3685         // clear changed branches cache
3686         changedBranches_.clear();
3687
3688         // reset tracker
3689         nonModuleChanged_ = false;
3690 }
3691
3692
3693 void GuiDocument::saveDocDefault()
3694 {
3695         // we have to apply the params first
3696         applyView();
3697         saveAsDefault();
3698 }
3699
3700
3701 void GuiDocument::updateAvailableModules()
3702 {
3703         modules_av_model_.clear();
3704         list<modInfoStruct> modInfoList = getModuleInfo();
3705         // Sort names according to the locale
3706         modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
3707                         return 0 < b.name.localeAwareCompare(a.name);
3708                 });
3709         int i = 0;
3710         for (modInfoStruct const & m : modInfoList) {
3711                 modules_av_model_.insertRow(i, m.name, m.id, m.description);
3712                 ++i;
3713         }
3714 }
3715
3716
3717 void GuiDocument::updateSelectedModules()
3718 {
3719         modules_sel_model_.clear();
3720         list<modInfoStruct> const selModList = getSelectedModules();
3721         int i = 0;
3722         for (modInfoStruct const & m : selModList) {
3723                 modules_sel_model_.insertRow(i, m.name, m.id, m.description);
3724                 ++i;
3725         }
3726 }
3727
3728
3729 void GuiDocument::updateIncludeonlys()
3730 {
3731         masterChildModule->childrenTW->clear();
3732         QString const no = qt_("No");
3733         QString const yes = qt_("Yes");
3734
3735         if (includeonlys_.empty()) {
3736                 masterChildModule->includeallRB->setChecked(true);
3737                 masterChildModule->childrenTW->setEnabled(false);
3738                 masterChildModule->maintainAuxCB->setEnabled(false);
3739         } else {
3740                 masterChildModule->includeonlyRB->setChecked(true);
3741                 masterChildModule->childrenTW->setEnabled(true);
3742                 masterChildModule->maintainAuxCB->setEnabled(true);
3743         }
3744         ListOfBuffers children = buffer().getChildren();
3745         ListOfBuffers::const_iterator it  = children.begin();
3746         ListOfBuffers::const_iterator end = children.end();
3747         bool has_unincluded = false;
3748         bool all_unincluded = true;
3749         for (; it != end; ++it) {
3750                 QTreeWidgetItem * item = new QTreeWidgetItem(masterChildModule->childrenTW);
3751                 // FIXME Unicode
3752                 string const name =
3753                         to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
3754                                                         from_utf8(buffer().filePath())));
3755                 item->setText(0, toqstr(name));
3756                 item->setText(1, isChildIncluded(name) ? yes : no);
3757                 if (!isChildIncluded(name))
3758                         has_unincluded = true;
3759                 else
3760                         all_unincluded = false;
3761         }
3762         // Both if all childs are included and if none is included
3763         // is equal to "include all" (i.e., ommit \includeonly).
3764         // Thus, reset the GUI.
3765         if (!has_unincluded || all_unincluded) {
3766                 masterChildModule->includeallRB->setChecked(true);
3767                 masterChildModule->childrenTW->setEnabled(false);
3768                 includeonlys_.clear();
3769         }
3770         // If all are included, we need to update again.
3771         if (!has_unincluded)
3772                 updateIncludeonlys();
3773 }
3774
3775
3776 bool GuiDocument::isBiblatex() const
3777 {
3778         QString const engine =
3779                 biblioModule->citeEngineCO->itemData(
3780                                 biblioModule->citeEngineCO->currentIndex()).toString();
3781
3782         return theCiteEnginesList[fromqstr(engine)]->getCiteFramework() == "biblatex";
3783 }
3784
3785
3786 void GuiDocument::updateDefaultBiblio(string const & style,
3787                                       string const & which)
3788 {
3789         QString const bibstyle = toqstr(style);
3790         biblioModule->defaultBiblioCO->clear();
3791
3792         int item_nr = -1;
3793
3794         if (isBiblatex()) {
3795                 if (which != "cbx") {
3796                         // First the bbx styles
3797                         biblioModule->biblatexBbxCO->clear();
3798                         QStringList str = texFileList("bbxFiles.lst");
3799                         // test whether we have a valid list, otherwise run rescan
3800                         if (str.isEmpty()) {
3801                                 rescanTexStyles("bbx");
3802                                 str = texFileList("bbxFiles.lst");
3803                         }
3804                         for (int i = 0; i != str.size(); ++i)
3805                                 str[i] = onlyFileName(str[i]);
3806                         // sort on filename only (no path)
3807                         str.sort();
3808
3809                         for (int i = 0; i != str.count(); ++i) {
3810                                 QString item = changeExtension(str[i], "");
3811                                 if (item == bibstyle)
3812                                         item_nr = i;
3813                                 biblioModule->biblatexBbxCO->addItem(item);
3814                         }
3815
3816                         if (item_nr == -1 && !bibstyle.isEmpty()) {
3817                                 biblioModule->biblatexBbxCO->addItem(bibstyle);
3818                                 item_nr = biblioModule->biblatexBbxCO->count() - 1;
3819                         }
3820
3821                         if (item_nr != -1)
3822                                 biblioModule->biblatexBbxCO->setCurrentIndex(item_nr);
3823                         else
3824                                 biblioModule->biblatexBbxCO->clearEditText();
3825                 }
3826
3827                 if (which != "bbx") {
3828                         // now the cbx styles
3829                         biblioModule->biblatexCbxCO->clear();
3830                         QStringList str = texFileList("cbxFiles.lst");
3831                         // test whether we have a valid list, otherwise run rescan
3832                         if (str.isEmpty()) {
3833                                 rescanTexStyles("cbx");
3834                                 str = texFileList("cbxFiles.lst");
3835                         }
3836                         for (int i = 0; i != str.size(); ++i)
3837                                 str[i] = onlyFileName(str[i]);
3838                         // sort on filename only (no path)
3839                         str.sort();
3840
3841                         for (int i = 0; i != str.count(); ++i) {
3842                                 QString item = changeExtension(str[i], "");
3843                                 if (item == bibstyle)
3844                                         item_nr = i;
3845                                 biblioModule->biblatexCbxCO->addItem(item);
3846                         }
3847
3848                         if (item_nr == -1 && !bibstyle.isEmpty()) {
3849                                 biblioModule->biblatexCbxCO->addItem(bibstyle);
3850                                 item_nr = biblioModule->biblatexCbxCO->count() - 1;
3851                         }
3852
3853                         if (item_nr != -1)
3854                                 biblioModule->biblatexCbxCO->setCurrentIndex(item_nr);
3855                         else
3856                                 biblioModule->biblatexCbxCO->clearEditText();
3857                 }
3858         } else {// BibTeX
3859                 biblioModule->biblatexBbxCO->clear();
3860                 biblioModule->biblatexCbxCO->clear();
3861                 QStringList str = texFileList("bstFiles.lst");
3862                 // test whether we have a valid list, otherwise run rescan
3863                 if (str.isEmpty()) {
3864                         rescanTexStyles("bst");
3865                         str = texFileList("bstFiles.lst");
3866                 }
3867                 for (int i = 0; i != str.size(); ++i)
3868                         str[i] = onlyFileName(str[i]);
3869                 // sort on filename only (no path)
3870                 str.sort();
3871
3872                 for (int i = 0; i != str.count(); ++i) {
3873                         QString item = changeExtension(str[i], "");
3874                         if (item == bibstyle)
3875                                 item_nr = i;
3876                         biblioModule->defaultBiblioCO->addItem(item);
3877                 }
3878
3879                 if (item_nr == -1 && !bibstyle.isEmpty()) {
3880                         biblioModule->defaultBiblioCO->addItem(bibstyle);
3881                         item_nr = biblioModule->defaultBiblioCO->count() - 1;
3882                 }
3883
3884                 if (item_nr != -1)
3885                         biblioModule->defaultBiblioCO->setCurrentIndex(item_nr);
3886                 else
3887                         biblioModule->defaultBiblioCO->clearEditText();
3888         }
3889
3890         updateResetDefaultBiblio();
3891 }
3892
3893
3894 void GuiDocument::updateResetDefaultBiblio()
3895 {
3896         QString const engine =
3897                 biblioModule->citeEngineCO->itemData(
3898                                 biblioModule->citeEngineCO->currentIndex()).toString();
3899         CiteEngineType const cet =
3900                 CiteEngineType(biblioModule->citeStyleCO->itemData(
3901                                                           biblioModule->citeStyleCO->currentIndex()).toInt());
3902
3903         string const defbib = theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet);
3904         if (isBiblatex()) {
3905                 QString const bbx = biblioModule->biblatexBbxCO->currentText();
3906                 QString const cbx = biblioModule->biblatexCbxCO->currentText();
3907                 biblioModule->resetCbxPB->setEnabled(defbib != fromqstr(cbx));
3908                 biblioModule->resetBbxPB->setEnabled(defbib != fromqstr(bbx));
3909                 biblioModule->matchBbxPB->setEnabled(bbx != cbx && !cbx.isEmpty()
3910                         && biblioModule->biblatexBbxCO->findText(cbx) != -1);
3911         } else
3912                 biblioModule->resetDefaultBiblioPB->setEnabled(
3913                         defbib != fromqstr(biblioModule->defaultBiblioCO->currentText()));
3914 }
3915
3916
3917 void GuiDocument::matchBiblatexStyles()
3918 {
3919         updateDefaultBiblio(fromqstr(biblioModule->biblatexCbxCO->currentText()), "bbx");
3920         biblioChanged();
3921 }
3922
3923
3924 void GuiDocument::updateContents()
3925 {
3926         // Nothing to do here as the document settings is not cursor dependant.
3927         return;
3928 }
3929
3930
3931 void GuiDocument::useClassDefaults()
3932 {
3933         if (applyPB->isEnabled()) {
3934                 int const ret = Alert::prompt(_("Unapplied changes"),
3935                                 _("Some changes in the dialog were not yet applied.\n"
3936                                   "If you do not apply now, they will be lost after this action."),
3937                                 1, 1, _("&Apply"), _("&Dismiss"));
3938                 if (ret == 0)
3939                         applyView();
3940         }
3941
3942         int idx = latexModule->classCO->currentIndex();
3943         string const classname = fromqstr(latexModule->classCO->getData(idx));
3944         if (!bp_.setBaseClass(classname)) {
3945                 Alert::error(_("Error"), _("Unable to set document class."));
3946                 return;
3947         }
3948         bp_.useClassDefaults();
3949         paramsToDialog();
3950 }
3951
3952
3953 void GuiDocument::setLayoutComboByIDString(string const & idString)
3954 {
3955         if (!latexModule->classCO->set(toqstr(idString)))
3956                 Alert::warning(_("Can't set layout!"),
3957                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
3958 }
3959
3960
3961 bool GuiDocument::isValid()
3962 {
3963         return
3964                 validateListingsParameters().isEmpty() &&
3965                 localLayout->isValid() &&
3966                 (
3967                         // if we're asking for skips between paragraphs
3968                         !textLayoutModule->skipRB->isChecked() ||
3969                         // then either we haven't chosen custom
3970                         textLayoutModule->skipCO->currentIndex() != 3 ||
3971                         // or else a length has been given
3972                         !textLayoutModule->skipLE->text().isEmpty()
3973                 ) &&
3974                 (
3975                         // if we're asking for indentation
3976                         !textLayoutModule->indentRB->isChecked() ||
3977                         // then either we haven't chosen custom
3978                         textLayoutModule->indentCO->currentIndex() != 1 ||
3979                         // or else a length has been given
3980                         !textLayoutModule->indentLE->text().isEmpty()
3981                 );
3982 }
3983
3984
3985 char const * const GuiDocument::fontfamilies[5] = {
3986         "default", "rmdefault", "sfdefault", "ttdefault", ""
3987 };
3988
3989
3990 char const * GuiDocument::fontfamilies_gui[5] = {
3991         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
3992 };
3993
3994
3995 bool GuiDocument::initialiseParams(string const &)
3996 {
3997         BufferView const * view = bufferview();
3998         if (!view) {
3999                 bp_ = BufferParams();
4000                 paramsToDialog();
4001                 return true;
4002         }
4003         bp_ = view->buffer().params();
4004         loadModuleInfo();
4005         updateAvailableModules();
4006         //FIXME It'd be nice to make sure here that the selected
4007         //modules are consistent: That required modules are actually
4008         //selected, and that we don't have conflicts. If so, we could
4009         //at least pop up a warning.
4010         paramsToDialog();
4011         return true;
4012 }
4013
4014
4015 void GuiDocument::clearParams()
4016 {
4017         bp_ = BufferParams();
4018 }
4019
4020
4021 BufferId GuiDocument::id() const
4022 {
4023         BufferView const * const view = bufferview();
4024         return view? &view->buffer() : 0;
4025 }
4026
4027
4028 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
4029 {
4030         return moduleNames_;
4031 }
4032
4033
4034 list<GuiDocument::modInfoStruct> const
4035 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
4036 {
4037         list<modInfoStruct> mInfo;
4038         for (string const & name : mods) {
4039                 modInfoStruct m;
4040                 LyXModule const * const mod = theModuleList[name];
4041                 if (mod)
4042                         m = modInfo(*mod);
4043                 else {
4044                         m.id = name;
4045                         m.name = toqstr(name + " (") + qt_("Not Found") + toqstr(")");
4046                 }
4047                 mInfo.push_back(m);
4048         }
4049         return mInfo;
4050 }
4051
4052
4053 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
4054 {
4055         return makeModuleInfo(params().getModules());
4056 }
4057
4058
4059 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
4060 {
4061         return makeModuleInfo(params().baseClass()->providedModules());
4062 }
4063
4064
4065 DocumentClass const & GuiDocument::documentClass() const
4066 {
4067         return bp_.documentClass();
4068 }
4069
4070
4071 static void dispatch_bufferparams(Dialog const & dialog,
4072         BufferParams const & bp, FuncCode lfun, Buffer const * buf)
4073 {
4074         ostringstream ss;
4075         ss << "\\begin_header\n";
4076         bp.writeFile(ss, buf);
4077         ss << "\\end_header\n";
4078         dialog.dispatch(FuncRequest(lfun, ss.str()));
4079 }
4080
4081
4082 void GuiDocument::dispatchParams()
4083 {
4084         // We need a non-const buffer object.
4085         Buffer & buf = const_cast<BufferView *>(bufferview())->buffer();
4086         // There may be several undo records; group them (bug #8998)
4087         buf.undo().beginUndoGroup();
4088
4089         // This must come first so that a language change is correctly noticed
4090         setLanguage();
4091
4092         // Apply the BufferParams. Note that this will set the base class
4093         // and then update the buffer's layout.
4094         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY, &buffer());
4095
4096         if (!params().master.empty()) {
4097                 FileName const master_file = support::makeAbsPath(params().master,
4098                            support::onlyPath(buffer().absFileName()));
4099                 if (isLyXFileName(master_file.absFileName())) {
4100                         Buffer * master = checkAndLoadLyXFile(master_file);
4101                         if (master) {
4102                                 if (master->isChild(const_cast<Buffer *>(&buffer())))
4103                                         const_cast<Buffer &>(buffer()).setParent(master);
4104                                 else
4105                                         Alert::warning(_("Assigned master does not include this file"),
4106                                                 bformat(_("You must include this file in the document\n"
4107                                                           "'%1$s' in order to use the master document\n"
4108                                                           "feature."), from_utf8(params().master)));
4109                         } else
4110                                 Alert::warning(_("Could not load master"),
4111                                                 bformat(_("The master document '%1$s'\n"
4112                                                            "could not be loaded."),
4113                                                            from_utf8(params().master)));
4114                 }
4115         }
4116
4117         // Generate the colours requested by each new branch.
4118         BranchList & branchlist = params().branchlist();
4119         if (!branchlist.empty()) {
4120                 BranchList::const_iterator it = branchlist.begin();
4121                 BranchList::const_iterator const end = branchlist.end();
4122                 for (; it != end; ++it) {
4123                         docstring const & current_branch = it->branch();
4124                         Branch const * branch = branchlist.find(current_branch);
4125                         string const x11hexname = X11hexname(branch->color());
4126                         // display the new color
4127                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
4128                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
4129                 }
4130
4131                 // Open insets of selected branches, close deselected ones
4132                 dispatch(FuncRequest(LFUN_INSET_FORALL,
4133                         "Branch inset-toggle assign"));
4134         }
4135         // rename branches in the document
4136         executeBranchRenaming();
4137         // and clear changed branches cache
4138         changedBranches_.clear();
4139
4140         // Generate the colours requested by indices.
4141         IndicesList & indiceslist = params().indiceslist();
4142         if (!indiceslist.empty()) {
4143                 IndicesList::const_iterator it = indiceslist.begin();
4144                 IndicesList::const_iterator const end = indiceslist.end();
4145                 for (; it != end; ++it) {
4146                         docstring const & current_index = it->shortcut();
4147                         Index const * index = indiceslist.findShortcut(current_index);
4148                         string const x11hexname = X11hexname(index->color());
4149                         // display the new color
4150                         docstring const str = current_index + ' ' + from_ascii(x11hexname);
4151                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
4152                 }
4153         }
4154         // FIXME LFUN
4155         // If we used an LFUN, we would not need these two lines:
4156         BufferView * bv = const_cast<BufferView *>(bufferview());
4157         bv->processUpdateFlags(Update::Force | Update::FitCursor);
4158
4159         // Don't forget to close the group. Note that it is important
4160         // to check that there is no early return in the method.
4161         buf.undo().endUndoGroup();
4162 }
4163
4164
4165 void GuiDocument::setLanguage() const
4166 {
4167         Language const * const newL = bp_.language;
4168         if (buffer().params().language == newL)
4169                 return;
4170
4171         string const & lang_name = newL->lang();
4172         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
4173 }
4174
4175
4176 void GuiDocument::saveAsDefault() const
4177 {
4178         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT, &buffer());
4179 }
4180
4181
4182 bool GuiDocument::providesOSF(QString const & font) const
4183 {
4184         if (fontModule->osFontsCB->isChecked())
4185                 // FIXME: we should check if the fonts really
4186                 // have OSF support. But how?
4187                 return true;
4188         return theLaTeXFonts().getLaTeXFont(
4189                                 qstring_to_ucs4(font)).providesOSF(ot1(),
4190                                                                    completeFontset(),
4191                                                                    noMathFont());
4192 }
4193
4194
4195 bool GuiDocument::providesSC(QString const & font) const
4196 {
4197         if (fontModule->osFontsCB->isChecked())
4198                 return false;
4199         return theLaTeXFonts().getLaTeXFont(
4200                                 qstring_to_ucs4(font)).providesSC(ot1(),
4201                                                                   completeFontset(),
4202                                                                   noMathFont());
4203 }
4204
4205
4206 bool GuiDocument::providesScale(QString const & font) const
4207 {
4208         if (fontModule->osFontsCB->isChecked())
4209                 return true;
4210         return theLaTeXFonts().getLaTeXFont(
4211                                 qstring_to_ucs4(font)).providesScale(ot1(),
4212                                                                      completeFontset(),
4213                                                                      noMathFont());
4214 }
4215
4216
4217 bool GuiDocument::providesNoMath(QString const & font) const
4218 {
4219         if (fontModule->osFontsCB->isChecked())
4220                 return false;
4221         return theLaTeXFonts().getLaTeXFont(
4222                                 qstring_to_ucs4(font)).providesNoMath(ot1(),
4223                                                                       completeFontset());
4224 }
4225
4226
4227 bool GuiDocument::hasMonolithicExpertSet(QString const & font) const
4228 {
4229         if (fontModule->osFontsCB->isChecked())
4230                 return false;
4231         return theLaTeXFonts().getLaTeXFont(
4232                                 qstring_to_ucs4(font)).hasMonolithicExpertSet(ot1(),
4233                                                                               completeFontset(),
4234                                                                               noMathFont());
4235 }
4236
4237
4238 //static
4239 GuiDocument::modInfoStruct GuiDocument::modInfo(LyXModule const & mod)
4240 {
4241         // FIXME Unicode: docstrings would be better for these parameters but this
4242         // change requires a lot of others
4243         modInfoStruct m;
4244         m.id = mod.getID();
4245         m.name = toqstr(translateIfPossible(from_utf8(mod.getName())));
4246         QString desc = toqstr(translateIfPossible(from_utf8(mod.getDescription())));
4247         // Find the first sentence of the description
4248         QTextBoundaryFinder bf(QTextBoundaryFinder::Sentence, desc);
4249         int pos = bf.toNextBoundary();
4250         if (pos > 0)
4251                 desc.truncate(pos);
4252         QString modulename = QString(qt_("(Module name: %1)")).arg(toqstr(m.id));
4253         // Tooltip is the desc followed by the module name
4254         m.description = QString("%1<i>%2</i>")
4255                 .arg(desc.isEmpty() ? QString() : QString("<p>%1</p>").arg(desc),
4256                      modulename);
4257         return m;
4258 }
4259
4260
4261 void GuiDocument::loadModuleInfo()
4262 {
4263         moduleNames_.clear();
4264         for (LyXModule const & mod : theModuleList)
4265                 if (mod.category().substr(0, 8) != "Citation")
4266                         moduleNames_.push_back(modInfo(mod));
4267 }
4268
4269
4270 void GuiDocument::updateUnknownBranches()
4271 {
4272         if (!bufferview())
4273                 return;
4274         list<docstring> used_branches;
4275         buffer().getUsedBranches(used_branches);
4276         list<docstring>::const_iterator it = used_branches.begin();
4277         QStringList unknown_branches;
4278         for (; it != used_branches.end() ; ++it) {
4279                 if (!buffer().params().branchlist().find(*it))
4280                         unknown_branches.append(toqstr(*it));
4281         }
4282         branchesModule->setUnknownBranches(unknown_branches);
4283 }
4284
4285
4286 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
4287 {
4288         map<docstring, docstring>::iterator it = changedBranches_.begin();
4289         for (; it != changedBranches_.end() ; ++it) {
4290                 if (it->second == oldname) {
4291                         // branch has already been renamed
4292                         it->second = newname;
4293                         return;
4294                 }
4295         }
4296         // store new name
4297         changedBranches_[oldname] = newname;
4298 }
4299
4300
4301 void GuiDocument::executeBranchRenaming() const
4302 {
4303         map<docstring, docstring>::const_iterator it = changedBranches_.begin();
4304         for (; it != changedBranches_.end() ; ++it) {
4305                 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
4306                 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
4307         }
4308 }
4309
4310
4311 void GuiDocument::allPackagesAuto()
4312 {
4313         allPackages(1);
4314 }
4315
4316
4317 void GuiDocument::allPackagesAlways()
4318 {
4319         allPackages(2);
4320 }
4321
4322
4323 void GuiDocument::allPackagesNot()
4324 {
4325         allPackages(3);
4326 }
4327
4328
4329 void GuiDocument::allPackages(int col)
4330 {
4331         for (int row = 0; row < mathsModule->packagesTW->rowCount(); ++row) {
4332                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, col);
4333                 rb->setChecked(true);
4334         }
4335 }
4336
4337
4338 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
4339
4340
4341 } // namespace frontend
4342 } // namespace lyx
4343
4344 #include "moc_GuiDocument.cpp"