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