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