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