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