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