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