]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiDocument.cpp
Merge branch 'master' into biblatex2
[lyx.git] / src / frontends / qt4 / GuiDocument.cpp
1 /**
2  * \file GuiDocument.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Edwin Leuven
7  * \author Richard Heck (modules)
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "GuiDocument.h"
15
16 #include "CategorizedCombo.h"
17 #include "GuiApplication.h"
18 #include "GuiBranches.h"
19 #include "GuiIndices.h"
20 #include "GuiSelectionManager.h"
21 #include "LaTeXHighlighter.h"
22 #include "LengthCombo.h"
23 #include "PanelStack.h"
24 #include "Validator.h"
25
26 #include "LayoutFile.h"
27 #include "BranchList.h"
28 #include "buffer_funcs.h"
29 #include "Buffer.h"
30 #include "BufferParams.h"
31 #include "BufferView.h"
32 #include "CiteEnginesList.h"
33 #include "Color.h"
34 #include "ColorCache.h"
35 #include "Converter.h"
36 #include "Cursor.h"
37 #include "Encoding.h"
38 #include "FloatPlacement.h"
39 #include "Format.h"
40 #include "FuncRequest.h"
41 #include "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->citePackageOptionsLE->setEnabled(biblatex);
2382         biblioModule->citePackageOptionsL->setEnabled(biblatex);
2383         biblioModule->biblatexBbxCO->setEnabled(biblatex);
2384         biblioModule->biblatexBbxLA->setEnabled(biblatex);
2385         biblioModule->biblatexCbxCO->setEnabled(biblatex);
2386         biblioModule->biblatexCbxLA->setEnabled(biblatex);
2387         biblioModule->resetBbxPB->setEnabled(biblatex);
2388         biblioModule->resetCbxPB->setEnabled(biblatex);
2389         biblioModule->matchBbxPB->setEnabled(biblatex);
2390 }
2391
2392
2393 void GuiDocument::citeStyleChanged()
2394 {
2395         QString const engine =
2396                 biblioModule->citeEngineCO->itemData(
2397                                 biblioModule->citeEngineCO->currentIndex()).toString();
2398         QString const currentDef = isBiblatex() ?
2399                 biblioModule->biblatexBbxCO->currentText()
2400                 : biblioModule->defaultBiblioCO->currentText();
2401         if (theCiteEnginesList[fromqstr(engine)]->isDefaultBiblio(fromqstr(currentDef)))
2402                 resetDefaultBibfile();
2403
2404         biblioChanged();
2405 }
2406
2407
2408 void GuiDocument::bibtexChanged(int n)
2409 {
2410         biblioModule->bibtexOptionsLE->setEnabled(
2411                 biblioModule->bibtexCO->itemData(n).toString() != "default");
2412         biblioChanged();
2413 }
2414
2415
2416 void GuiDocument::updateCiteStyles(vector<string> const & engs, CiteEngineType const & sel)
2417 {
2418         biblioModule->citeStyleCO->clear();
2419
2420         vector<string>::const_iterator it  = engs.begin();
2421         vector<string>::const_iterator end = engs.end();
2422         for (; it != end; ++it) {
2423                 if (*it == "default")
2424                         biblioModule->citeStyleCO->addItem(qt_("Basic numerical"),
2425                                                            ENGINE_TYPE_DEFAULT);
2426                 else if (*it == "authoryear")
2427                         biblioModule->citeStyleCO->addItem(qt_("Author-year"),
2428                                                            ENGINE_TYPE_AUTHORYEAR);
2429                 else if (*it == "numerical")
2430                         biblioModule->citeStyleCO->addItem(qt_("Author-number"),
2431                                                            ENGINE_TYPE_NUMERICAL);
2432         }
2433         int i = biblioModule->citeStyleCO->findData(sel);
2434         if (biblioModule->citeStyleCO->findData(sel) == -1)
2435                 i = 0;
2436         biblioModule->citeStyleCO->setCurrentIndex(i);
2437
2438         biblioModule->citationStyleL->setEnabled(engs.size() > 1);
2439         biblioModule->citeStyleCO->setEnabled(engs.size() > 1);
2440 }
2441
2442
2443 void GuiDocument::updateEngineType(string const & items, CiteEngineType const & sel)
2444 {
2445         engine_types_.clear();
2446
2447         int nn = 0;
2448
2449         for (int n = 0; !token(items, '|', n).empty(); ++n) {
2450                 nn += 1;
2451                 string style = token(items, '|', n);
2452                 engine_types_.push_back(style);
2453         }
2454
2455         updateCiteStyles(engine_types_, sel);
2456 }
2457
2458
2459 namespace {
2460         // FIXME unicode
2461         // both of these should take a vector<docstring>
2462
2463         // This is an insanely complicated attempt to make this sort of thing
2464         // work with RTL languages.
2465         docstring formatStrVec(vector<string> const & v, docstring const & s)
2466         {
2467                 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
2468                 if (v.empty())
2469                         return docstring();
2470                 if (v.size() == 1)
2471                         return translateIfPossible(from_utf8(v[0]));
2472                 if (v.size() == 2) {
2473                         docstring retval = _("%1$s and %2$s");
2474                         retval = subst(retval, _("and"), s);
2475                         return bformat(retval, translateIfPossible(from_utf8(v[0])),
2476                                        translateIfPossible(from_utf8(v[1])));
2477                 }
2478                 // The idea here is to format all but the last two items...
2479                 int const vSize = v.size();
2480                 docstring t2 = _("%1$s, %2$s");
2481                 docstring retval = translateIfPossible(from_utf8(v[0]));
2482                 for (int i = 1; i < vSize - 2; ++i)
2483                         retval = bformat(t2, retval, translateIfPossible(from_utf8(v[i])));
2484                 //...and then to  plug them, and the last two, into this schema
2485                 docstring t = _("%1$s, %2$s, and %3$s");
2486                 t = subst(t, _("and"), s);
2487                 return bformat(t, retval, translateIfPossible(from_utf8(v[vSize - 2])),
2488                                translateIfPossible(from_utf8(v[vSize - 1])));
2489         }
2490
2491         vector<string> idsToNames(vector<string> const & idList)
2492         {
2493                 vector<string> retval;
2494                 vector<string>::const_iterator it  = idList.begin();
2495                 vector<string>::const_iterator end = idList.end();
2496                 for (; it != end; ++it) {
2497                         LyXModule const * const mod = theModuleList[*it];
2498                         if (!mod)
2499                                 retval.push_back(to_utf8(bformat(_("%1$s (unavailable)"),
2500                                                 translateIfPossible(from_utf8(*it)))));
2501                         else
2502                                 retval.push_back(mod->getName());
2503                 }
2504                 return retval;
2505         }
2506 } // end anonymous namespace
2507
2508
2509 void GuiDocument::modulesToParams(BufferParams & bp)
2510 {
2511         // update list of loaded modules
2512         bp.clearLayoutModules();
2513         int const srows = modules_sel_model_.rowCount();
2514         for (int i = 0; i < srows; ++i)
2515                 bp.addLayoutModule(modules_sel_model_.getIDString(i));
2516
2517         // update the list of removed modules
2518         bp.clearRemovedModules();
2519         LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
2520         list<string>::const_iterator rit = reqmods.begin();
2521         list<string>::const_iterator ren = reqmods.end();
2522
2523         // check each of the default modules
2524         for (; rit != ren; ++rit) {
2525                 list<string>::const_iterator mit = bp.getModules().begin();
2526                 list<string>::const_iterator men = bp.getModules().end();
2527                 bool found = false;
2528                 for (; mit != men; ++mit) {
2529                         if (*rit == *mit) {
2530                                 found = true;
2531                                 break;
2532                         }
2533                 }
2534                 if (!found) {
2535                         // the module isn't present so must have been removed by the user
2536                         bp.addRemovedModule(*rit);
2537                 }
2538         }
2539 }
2540
2541 void GuiDocument::modulesChanged()
2542 {
2543         modulesToParams(bp_);
2544
2545         if (applyPB->isEnabled() && nonModuleChanged_) {
2546                 int const ret = Alert::prompt(_("Unapplied changes"),
2547                                 _("Some changes in the dialog were not yet applied.\n"
2548                                 "If you do not apply now, they will be lost after this action."),
2549                                 1, 1, _("&Apply"), _("&Dismiss"));
2550                 if (ret == 0)
2551                         applyView();
2552         }
2553
2554         bp_.makeDocumentClass();
2555         paramsToDialog();
2556         changed();
2557 }
2558
2559
2560 void GuiDocument::updateModuleInfo()
2561 {
2562         selectionManager->update();
2563
2564         //Module description
2565         bool const focus_on_selected = selectionManager->selectedFocused();
2566         QAbstractItemView * lv;
2567         if (focus_on_selected)
2568                 lv = modulesModule->selectedLV;
2569         else
2570                 lv = modulesModule->availableLV;
2571         if (lv->selectionModel()->selectedIndexes().isEmpty()) {
2572                 modulesModule->infoML->document()->clear();
2573                 return;
2574         }
2575         QModelIndex const & idx = lv->selectionModel()->currentIndex();
2576         GuiIdListModel const & id_model =
2577                         focus_on_selected  ? modules_sel_model_ : modules_av_model_;
2578         string const modName = id_model.getIDString(idx.row());
2579         docstring desc = getModuleDescription(modName);
2580
2581         LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
2582         if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
2583                 if (!desc.empty())
2584                         desc += "\n";
2585                 desc += _("Module provided by document class.");
2586         }
2587
2588         docstring cat = getModuleCategory(modName);
2589         if (!cat.empty()) {
2590                 if (!desc.empty())
2591                         desc += "\n";
2592                 desc += bformat(_("Category: %1$s."), cat);
2593         }
2594
2595         vector<string> pkglist = getPackageList(modName);
2596         docstring pkgdesc = formatStrVec(pkglist, _("and"));
2597         if (!pkgdesc.empty()) {
2598                 if (!desc.empty())
2599                         desc += "\n";
2600                 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
2601         }
2602
2603         pkglist = getRequiredList(modName);
2604         if (!pkglist.empty()) {
2605                 vector<string> const reqdescs = idsToNames(pkglist);
2606                 pkgdesc = formatStrVec(reqdescs, _("or"));
2607                 if (!desc.empty())
2608                         desc += "\n";
2609                 desc += bformat(_("Modules required: %1$s."), pkgdesc);
2610         }
2611
2612         pkglist = getExcludedList(modName);
2613         if (!pkglist.empty()) {
2614                 vector<string> const reqdescs = idsToNames(pkglist);
2615                 pkgdesc = formatStrVec(reqdescs, _( "and"));
2616                 if (!desc.empty())
2617                         desc += "\n";
2618                 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
2619         }
2620
2621         if (!isModuleAvailable(modName)) {
2622                 if (!desc.empty())
2623                         desc += "\n";
2624                 desc += _("WARNING: Some required packages are unavailable!");
2625         }
2626
2627         modulesModule->infoML->document()->setPlainText(toqstr(desc));
2628 }
2629
2630
2631 void GuiDocument::updateNumbering()
2632 {
2633         DocumentClass const & tclass = documentClass();
2634
2635         numberingModule->tocTW->setUpdatesEnabled(false);
2636         numberingModule->tocTW->clear();
2637
2638         int const depth = numberingModule->depthSL->value();
2639         int const toc = numberingModule->tocSL->value();
2640         QString const no = qt_("No");
2641         QString const yes = qt_("Yes");
2642         QTreeWidgetItem * item = 0;
2643
2644         DocumentClass::const_iterator lit = tclass.begin();
2645         DocumentClass::const_iterator len = tclass.end();
2646         for (; lit != len; ++lit) {
2647                 int const toclevel = lit->toclevel;
2648                 if (toclevel != Layout::NOT_IN_TOC && !lit->counter.empty()) {
2649                         item = new QTreeWidgetItem(numberingModule->tocTW);
2650                         item->setText(0, toqstr(translateIfPossible(lit->name())));
2651                         item->setText(1, (toclevel <= depth) ? yes : no);
2652                         item->setText(2, (toclevel <= toc) ? yes : no);
2653                 }
2654         }
2655
2656         numberingModule->tocTW->setUpdatesEnabled(true);
2657         numberingModule->tocTW->update();
2658 }
2659
2660
2661 void GuiDocument::updateDefaultFormat()
2662 {
2663         if (!bufferview())
2664                 return;
2665         // make a copy in order to consider unapplied changes
2666         BufferParams param_copy = buffer().params();
2667         param_copy.useNonTeXFonts = fontModule->osFontsCB->isChecked();
2668         int const idx = latexModule->classCO->currentIndex();
2669         if (idx >= 0) {
2670                 string const classname = fromqstr(latexModule->classCO->getData(idx));
2671                 param_copy.setBaseClass(classname);
2672                 param_copy.makeDocumentClass(true);
2673         }
2674         outputModule->defaultFormatCO->blockSignals(true);
2675         outputModule->defaultFormatCO->clear();
2676         outputModule->defaultFormatCO->addItem(qt_("Default"),
2677                                 QVariant(QString("default")));
2678         FormatList const & formats =
2679                                 param_copy.exportableFormats(true);
2680         for (Format const * f : formats)
2681                 outputModule->defaultFormatCO->addItem
2682                         (toqstr(translateIfPossible(f->prettyname())),
2683                          QVariant(toqstr(f->name())));
2684         outputModule->defaultFormatCO->blockSignals(false);
2685 }
2686
2687
2688 bool GuiDocument::isChildIncluded(string const & child)
2689 {
2690         if (includeonlys_.empty())
2691                 return false;
2692         return (std::find(includeonlys_.begin(),
2693                           includeonlys_.end(), child) != includeonlys_.end());
2694 }
2695
2696
2697 void GuiDocument::applyView()
2698 {
2699         // preamble
2700         preambleModule->apply(bp_);
2701         localLayout->apply(bp_);
2702
2703         // date
2704         bp_.suppress_date = latexModule->suppressDateCB->isChecked();
2705         bp_.use_refstyle  = latexModule->refstyleCB->isChecked();
2706
2707         // biblio
2708         string const engine =
2709                 fromqstr(biblioModule->citeEngineCO->itemData(
2710                                 biblioModule->citeEngineCO->currentIndex()).toString());
2711         bp_.setCiteEngine(engine);
2712
2713         CiteEngineType const style = CiteEngineType(biblioModule->citeStyleCO->itemData(
2714                 biblioModule->citeStyleCO->currentIndex()).toInt());
2715         if (theCiteEnginesList[engine]->hasEngineType(style))
2716                 bp_.setCiteEngineType(style);
2717         else
2718                 bp_.setCiteEngineType(ENGINE_TYPE_DEFAULT);
2719
2720         bp_.use_bibtopic =
2721                 biblioModule->bibtopicCB->isChecked();
2722
2723         bp_.setDefaultBiblioStyle(fromqstr(biblioModule->defaultBiblioCO->currentText()));
2724
2725         bp_.biblatex_bibstyle = fromqstr(biblioModule->biblatexBbxCO->currentText());
2726         bp_.biblatex_citestyle = fromqstr(biblioModule->biblatexCbxCO->currentText());
2727         bp_.biblio_opts = fromqstr(biblioModule->citePackageOptionsLE->text());
2728
2729         string const bibtex_command =
2730                 fromqstr(biblioModule->bibtexCO->itemData(
2731                         biblioModule->bibtexCO->currentIndex()).toString());
2732         string const bibtex_options =
2733                 fromqstr(biblioModule->bibtexOptionsLE->text());
2734         if (bibtex_command == "default" || bibtex_options.empty())
2735                 bp_.bibtex_command = bibtex_command;
2736         else
2737                 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
2738
2739         if (biblioChanged_) {
2740                 buffer().invalidateBibinfoCache();
2741                 buffer().removeBiblioTempFiles();
2742         }
2743
2744         // Indices
2745         indicesModule->apply(bp_);
2746
2747         // language & quotes
2748         if (langModule->defaultencodingRB->isChecked()) {
2749                 bp_.inputenc = "auto";
2750         } else {
2751                 int i = langModule->encodingCO->currentIndex();
2752                 if (i == 0)
2753                         bp_.inputenc = "default";
2754                 else {
2755                         QString const enc_gui =
2756                                 langModule->encodingCO->currentText();
2757                         Encodings::const_iterator it = encodings.begin();
2758                         Encodings::const_iterator const end = encodings.end();
2759                         bool found = false;
2760                         for (; it != end; ++it) {
2761                                 if (qt_(it->guiName()) == enc_gui &&
2762                                     !it->unsafe()) {
2763                                         bp_.inputenc = it->name();
2764                                         found = true;
2765                                         break;
2766                                 }
2767                         }
2768                         if (!found) {
2769                                 // should not happen
2770                                 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
2771                                 bp_.inputenc = "default";
2772                         }
2773                 }
2774         }
2775
2776         bp_.quotes_style = (InsetQuotesParams::QuoteStyle) langModule->quoteStyleCO->itemData(
2777                 langModule->quoteStyleCO->currentIndex()).toInt();
2778         bp_.dynamic_quotes = langModule->dynamicQuotesCB->isChecked();
2779
2780         QString const langname = langModule->languageCO->itemData(
2781                 langModule->languageCO->currentIndex()).toString();
2782         Language const * newlang = lyx::languages.getLanguage(fromqstr(langname));
2783         Cursor & cur = const_cast<BufferView *>(bufferview())->cursor();
2784         // If current cursor language was the document language, then update it too.
2785         if (cur.current_font.language() == bp_.language) {
2786                 cur.current_font.setLanguage(newlang);
2787                 cur.real_current_font.setLanguage(newlang);
2788         }
2789         bp_.language = newlang;
2790
2791         QString const pack = langModule->languagePackageCO->itemData(
2792                 langModule->languagePackageCO->currentIndex()).toString();
2793         if (pack == "custom")
2794                 bp_.lang_package =
2795                         fromqstr(langModule->languagePackageLE->text());
2796         else
2797                 bp_.lang_package = fromqstr(pack);
2798
2799         //color
2800         bp_.backgroundcolor = set_backgroundcolor;
2801         bp_.isbackgroundcolor = is_backgroundcolor;
2802         bp_.fontcolor = set_fontcolor;
2803         bp_.isfontcolor = is_fontcolor;
2804         bp_.notefontcolor = set_notefontcolor;
2805         bp_.boxbgcolor = set_boxbgcolor;
2806
2807         // numbering
2808         if (bp_.documentClass().hasTocLevels()) {
2809                 bp_.tocdepth = numberingModule->tocSL->value();
2810                 bp_.secnumdepth = numberingModule->depthSL->value();
2811         }
2812
2813         // bullets
2814         bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
2815         bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
2816         bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
2817         bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
2818
2819         // packages
2820         bp_.graphics_driver =
2821                 tex_graphics[latexModule->psdriverCO->currentIndex()];
2822
2823         // text layout
2824         int idx = latexModule->classCO->currentIndex();
2825         if (idx >= 0) {
2826                 string const classname = fromqstr(latexModule->classCO->getData(idx));
2827                 bp_.setBaseClass(classname);
2828         }
2829
2830         // Modules
2831         modulesToParams(bp_);
2832
2833         // Math
2834         map<string, string> const & packages = BufferParams::auto_packages();
2835         for (map<string, string>::const_iterator it = packages.begin();
2836              it != packages.end(); ++it) {
2837                 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
2838                 if (!item)
2839                         continue;
2840                 int row = mathsModule->packagesTW->row(item);
2841                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1);
2842                 if (rb->isChecked()) {
2843                         bp_.use_package(it->first, BufferParams::package_auto);
2844                         continue;
2845                 }
2846                 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2);
2847                 if (rb->isChecked()) {
2848                         bp_.use_package(it->first, BufferParams::package_on);
2849                         continue;
2850                 }
2851                 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3);
2852                 if (rb->isChecked())
2853                         bp_.use_package(it->first, BufferParams::package_off);
2854         }
2855
2856         // Page Layout
2857         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
2858                 bp_.pagestyle = "default";
2859         else {
2860                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
2861                 for (size_t i = 0; i != pagestyles.size(); ++i)
2862                         if (pagestyles[i].second == style_gui)
2863                                 bp_.pagestyle = pagestyles[i].first;
2864         }
2865
2866         // Text Layout
2867         switch (textLayoutModule->lspacingCO->currentIndex()) {
2868         case 0:
2869                 bp_.spacing().set(Spacing::Single);
2870                 break;
2871         case 1:
2872                 bp_.spacing().set(Spacing::Onehalf);
2873                 break;
2874         case 2:
2875                 bp_.spacing().set(Spacing::Double);
2876                 break;
2877         case 3: {
2878                 string s = widgetToDoubleStr(textLayoutModule->lspacingLE);
2879                 if (s.empty())
2880                         bp_.spacing().set(Spacing::Single);
2881                 else
2882                         bp_.spacing().set(Spacing::Other, s);
2883                 break;
2884                 }
2885         }
2886
2887         if (textLayoutModule->twoColumnCB->isChecked())
2888                 bp_.columns = 2;
2889         else
2890                 bp_.columns = 1;
2891
2892         bp_.justification = textLayoutModule->justCB->isChecked();
2893
2894         if (textLayoutModule->indentRB->isChecked()) {
2895                 // if paragraphs are separated by an indentation
2896                 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
2897                 switch (textLayoutModule->indentCO->currentIndex()) {
2898                 case 0:
2899                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2900                         break;
2901                 case 1: {
2902                         HSpace indent = HSpace(
2903                                 widgetsToLength(textLayoutModule->indentLE,
2904                                 textLayoutModule->indentLengthCO)
2905                                 );
2906                         bp_.setIndentation(indent);
2907                         break;
2908                         }
2909                 default:
2910                         // this should never happen
2911                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2912                         break;
2913                 }
2914         } else {
2915                 // if paragraphs are separated by a skip
2916                 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
2917                 switch (textLayoutModule->skipCO->currentIndex()) {
2918                 case 0:
2919                         bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
2920                         break;
2921                 case 1:
2922                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2923                         break;
2924                 case 2:
2925                         bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
2926                         break;
2927                 case 3:
2928                         {
2929                         VSpace vs = VSpace(
2930                                 widgetsToLength(textLayoutModule->skipLE,
2931                                 textLayoutModule->skipLengthCO)
2932                                 );
2933                         bp_.setDefSkip(vs);
2934                         break;
2935                         }
2936                 default:
2937                         // this should never happen
2938                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2939                         break;
2940                 }
2941         }
2942
2943         bp_.options =
2944                 fromqstr(latexModule->optionsLE->text());
2945
2946         bp_.use_default_options =
2947                 latexModule->defaultOptionsCB->isChecked();
2948
2949         if (latexModule->childDocGB->isChecked())
2950                 bp_.master =
2951                         fromqstr(latexModule->childDocLE->text());
2952         else
2953                 bp_.master = string();
2954
2955         // Master/Child
2956         bp_.clearIncludedChildren();
2957         if (masterChildModule->includeonlyRB->isChecked()) {
2958                 list<string>::const_iterator it = includeonlys_.begin();
2959                 for (; it != includeonlys_.end() ; ++it) {
2960                         bp_.addIncludedChildren(*it);
2961                 }
2962         }
2963         bp_.maintain_unincluded_children =
2964                 masterChildModule->maintainAuxCB->isChecked();
2965
2966         // Float Placement
2967         bp_.float_placement = floatModule->get();
2968
2969         // Listings
2970         // text should have passed validation
2971         bp_.listings_params =
2972                 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
2973
2974         // Formats
2975         bp_.default_output_format = fromqstr(outputModule->defaultFormatCO->itemData(
2976                 outputModule->defaultFormatCO->currentIndex()).toString());
2977
2978         bool const nontexfonts = fontModule->osFontsCB->isChecked();
2979         bp_.useNonTeXFonts = nontexfonts;
2980
2981         bp_.output_sync = outputModule->outputsyncCB->isChecked();
2982
2983         bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
2984
2985         int mathfmt = outputModule->mathoutCB->currentIndex();
2986         if (mathfmt == -1)
2987                 mathfmt = 0;
2988         BufferParams::MathOutput const mo =
2989                 static_cast<BufferParams::MathOutput>(mathfmt);
2990         bp_.html_math_output = mo;
2991         bp_.html_be_strict = outputModule->strictCB->isChecked();
2992         bp_.html_css_as_file = outputModule->cssCB->isChecked();
2993         bp_.html_math_img_scale = outputModule->mathimgSB->value();
2994         bp_.display_pixel_ratio = theGuiApp()->pixelRatio();
2995
2996         bp_.save_transient_properties =
2997                 outputModule->saveTransientPropertiesCB->isChecked();
2998
2999         // fonts
3000         bp_.fonts_roman[nontexfonts] =
3001                 fromqstr(fontModule->fontsRomanCO->
3002                         itemData(fontModule->fontsRomanCO->currentIndex()).toString());
3003         bp_.fonts_roman[!nontexfonts] = fromqstr(fontModule->font_roman);
3004
3005         bp_.fonts_sans[nontexfonts] =
3006                 fromqstr(fontModule->fontsSansCO->
3007                         itemData(fontModule->fontsSansCO->currentIndex()).toString());
3008         bp_.fonts_sans[!nontexfonts] = fromqstr(fontModule->font_sans);
3009
3010         bp_.fonts_typewriter[nontexfonts] =
3011                 fromqstr(fontModule->fontsTypewriterCO->
3012                         itemData(fontModule->fontsTypewriterCO->currentIndex()).toString());
3013         bp_.fonts_typewriter[!nontexfonts] = fromqstr(fontModule->font_typewriter);
3014
3015         bp_.fonts_math[nontexfonts] =
3016                 fromqstr(fontModule->fontsMathCO->
3017                         itemData(fontModule->fontsMathCO->currentIndex()).toString());
3018         bp_.fonts_math[!nontexfonts] = fromqstr(fontModule->font_math);
3019
3020         QString const fontenc =
3021                 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
3022         if (fontenc == "custom")
3023                 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
3024         else
3025                 bp_.fontenc = fromqstr(fontenc);
3026
3027         bp_.fonts_cjk =
3028                 fromqstr(fontModule->cjkFontLE->text());
3029
3030         bp_.use_microtype = fontModule->microtypeCB->isChecked();
3031
3032         bp_.fonts_sans_scale[nontexfonts] = fontModule->scaleSansSB->value();
3033         bp_.fonts_sans_scale[!nontexfonts] = fontModule->font_sf_scale;
3034
3035         bp_.fonts_typewriter_scale[nontexfonts] = fontModule->scaleTypewriterSB->value();
3036         bp_.fonts_typewriter_scale[!nontexfonts] = fontModule->font_tt_scale;
3037
3038         bp_.fonts_expert_sc = fontModule->fontScCB->isChecked();
3039
3040         bp_.fonts_old_figures = fontModule->fontOsfCB->isChecked();
3041
3042         if (nontexfonts)
3043                 bp_.fonts_default_family = "default";
3044         else
3045                 bp_.fonts_default_family = GuiDocument::fontfamilies[
3046                         fontModule->fontsDefaultCO->currentIndex()];
3047
3048         if (fontModule->fontsizeCO->currentIndex() == 0)
3049                 bp_.fontsize = "default";
3050         else
3051                 bp_.fontsize =
3052                         fromqstr(fontModule->fontsizeCO->currentText());
3053
3054         // paper
3055         bp_.papersize = PAPER_SIZE(
3056                 pageLayoutModule->papersizeCO->currentIndex());
3057
3058         bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
3059                 pageLayoutModule->paperwidthUnitCO);
3060
3061         bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
3062                 pageLayoutModule->paperheightUnitCO);
3063
3064         if (pageLayoutModule->facingPagesCB->isChecked())
3065                 bp_.sides = TwoSides;
3066         else
3067                 bp_.sides = OneSide;
3068
3069         if (pageLayoutModule->landscapeRB->isChecked())
3070                 bp_.orientation = ORIENTATION_LANDSCAPE;
3071         else
3072                 bp_.orientation = ORIENTATION_PORTRAIT;
3073
3074         // margins
3075         bp_.use_geometry = !marginsModule->marginCB->isChecked();
3076
3077         Ui::MarginsUi const * m = marginsModule;
3078
3079         bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
3080         bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
3081         bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
3082         bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
3083         bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
3084         bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
3085         bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
3086         bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
3087
3088         // branches
3089         branchesModule->apply(bp_);
3090
3091         // PDF support
3092         PDFOptions & pdf = bp_.pdfoptions();
3093         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
3094         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
3095         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
3096         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
3097         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
3098
3099         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
3100         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
3101         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
3102         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
3103
3104         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
3105         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
3106         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
3107         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
3108         pdf.backref =
3109                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
3110         if (pdfSupportModule->fullscreenCB->isChecked())
3111                 pdf.pagemode = pdf.pagemode_fullscreen;
3112         else
3113                 pdf.pagemode.clear();
3114         pdf.quoted_options = pdf.quoted_options_check(
3115                                 fromqstr(pdfSupportModule->optionsLE->text()));
3116
3117         // reset tracker
3118         nonModuleChanged_ = false;
3119 }
3120
3121
3122 void GuiDocument::paramsToDialog()
3123 {
3124         // set the default unit
3125         Length::UNIT const default_unit = Length::defaultUnit();
3126
3127         // preamble
3128         preambleModule->update(bp_, id());
3129         localLayout->update(bp_, id());
3130
3131         // date
3132         latexModule->suppressDateCB->setChecked(bp_.suppress_date);
3133         latexModule->refstyleCB->setChecked(bp_.use_refstyle);
3134
3135         // biblio
3136         string const cite_engine = bp_.citeEngine().list().front();
3137
3138         biblioModule->citeEngineCO->setCurrentIndex(
3139                 biblioModule->citeEngineCO->findData(toqstr(cite_engine)));
3140
3141         updateEngineType(documentClass().opt_enginetype(),
3142                 bp_.citeEngineType());
3143
3144         biblioModule->citeStyleCO->setCurrentIndex(
3145                 biblioModule->citeStyleCO->findData(bp_.citeEngineType()));
3146
3147         biblioModule->bibtopicCB->setChecked(
3148                 bp_.use_bibtopic);
3149
3150         updateEngineDependends();
3151
3152         if (isBiblatex()) {
3153                 updateDefaultBiblio(bp_.biblatex_bibstyle, "bbx");
3154                 updateDefaultBiblio(bp_.biblatex_citestyle, "cbx");
3155         } else
3156                 updateDefaultBiblio(bp_.defaultBiblioStyle());
3157
3158         biblioModule->citePackageOptionsLE->setText(toqstr(bp_.biblio_opts));
3159
3160         string command;
3161         string options =
3162                 split(bp_.bibtex_command, command, ' ');
3163
3164         int const bpos = biblioModule->bibtexCO->findData(toqstr(command));
3165         if (bpos != -1) {
3166                 biblioModule->bibtexCO->setCurrentIndex(bpos);
3167                 biblioModule->bibtexOptionsLE->setText(toqstr(options).trimmed());
3168         } else {
3169                 // We reset to default if we do not know the specified compiler
3170                 // This is for security reasons
3171                 biblioModule->bibtexCO->setCurrentIndex(
3172                         biblioModule->bibtexCO->findData(toqstr("default")));
3173                 biblioModule->bibtexOptionsLE->clear();
3174         }
3175         biblioModule->bibtexOptionsLE->setEnabled(
3176                 biblioModule->bibtexCO->currentIndex() != 0);
3177
3178         biblioChanged_ = false;
3179
3180         // indices
3181         // We may be called when there is no Buffer, e.g., when 
3182         // the last view has just been closed.
3183         bool const isReadOnly = isBufferAvailable() ? buffer().isReadonly() : false;
3184         indicesModule->update(bp_, isReadOnly);
3185
3186         // language & quotes
3187         int const pos = langModule->languageCO->findData(toqstr(
3188                 bp_.language->lang()));
3189         langModule->languageCO->setCurrentIndex(pos);
3190
3191         updateQuoteStyles();
3192
3193         langModule->quoteStyleCO->setCurrentIndex(
3194                 langModule->quoteStyleCO->findData(bp_.quotes_style));
3195         langModule->dynamicQuotesCB->setChecked(bp_.dynamic_quotes);
3196
3197         bool default_enc = true;
3198         if (bp_.inputenc != "auto") {
3199                 default_enc = false;
3200                 if (bp_.inputenc == "default") {
3201                         langModule->encodingCO->setCurrentIndex(0);
3202                 } else {
3203                         string enc_gui;
3204                         Encodings::const_iterator it = encodings.begin();
3205                         Encodings::const_iterator const end = encodings.end();
3206                         for (; it != end; ++it) {
3207                                 if (it->name() == bp_.inputenc &&
3208                                     !it->unsafe()) {
3209                                         enc_gui = it->guiName();
3210                                         break;
3211                                 }
3212                         }
3213                         int const i = langModule->encodingCO->findText(
3214                                         qt_(enc_gui));
3215                         if (i >= 0)
3216                                 langModule->encodingCO->setCurrentIndex(i);
3217                         else
3218                                 // unknown encoding. Set to default.
3219                                 default_enc = true;
3220                 }
3221         }
3222         langModule->defaultencodingRB->setChecked(default_enc);
3223         langModule->otherencodingRB->setChecked(!default_enc);
3224
3225         int const p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
3226         if (p == -1) {
3227                 langModule->languagePackageCO->setCurrentIndex(
3228                           langModule->languagePackageCO->findData("custom"));
3229                 langModule->languagePackageLE->setText(toqstr(bp_.lang_package));
3230         } else {
3231                 langModule->languagePackageCO->setCurrentIndex(p);
3232                 langModule->languagePackageLE->clear();
3233         }
3234
3235         //color
3236         if (bp_.isfontcolor) {
3237                 colorModule->fontColorPB->setStyleSheet(
3238                         colorButtonStyleSheet(rgb2qcolor(bp_.fontcolor)));
3239         }
3240         set_fontcolor = bp_.fontcolor;
3241         is_fontcolor = bp_.isfontcolor;
3242
3243         colorModule->noteFontColorPB->setStyleSheet(
3244                 colorButtonStyleSheet(rgb2qcolor(bp_.notefontcolor)));
3245         set_notefontcolor = bp_.notefontcolor;
3246
3247         if (bp_.isbackgroundcolor) {
3248                 colorModule->backgroundPB->setStyleSheet(
3249                         colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
3250         }
3251         set_backgroundcolor = bp_.backgroundcolor;
3252         is_backgroundcolor = bp_.isbackgroundcolor;
3253
3254         colorModule->boxBackgroundPB->setStyleSheet(
3255                 colorButtonStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
3256         set_boxbgcolor = bp_.boxbgcolor;
3257
3258         // numbering
3259         int const min_toclevel = documentClass().min_toclevel();
3260         int const max_toclevel = documentClass().max_toclevel();
3261         if (documentClass().hasTocLevels()) {
3262                 numberingModule->setEnabled(true);
3263                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
3264                 numberingModule->depthSL->setMaximum(max_toclevel);
3265                 numberingModule->depthSL->setValue(bp_.secnumdepth);
3266                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
3267                 numberingModule->tocSL->setMaximum(max_toclevel);
3268                 numberingModule->tocSL->setValue(bp_.tocdepth);
3269                 updateNumbering();
3270         } else {
3271                 numberingModule->setEnabled(false);
3272                 numberingModule->tocTW->clear();
3273         }
3274
3275         // bullets
3276         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
3277         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
3278         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
3279         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
3280         bulletsModule->init();
3281
3282         // packages
3283         int nitem = findToken(tex_graphics, bp_.graphics_driver);
3284         if (nitem >= 0)
3285                 latexModule->psdriverCO->setCurrentIndex(nitem);
3286         updateModuleInfo();
3287
3288         map<string, string> const & packages = BufferParams::auto_packages();
3289         for (map<string, string>::const_iterator it = packages.begin();
3290              it != packages.end(); ++it) {
3291                 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
3292                 if (!item)
3293                         continue;
3294                 int row = mathsModule->packagesTW->row(item);
3295                 switch (bp_.use_package(it->first)) {
3296                         case BufferParams::package_off: {
3297                                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3);
3298                                 rb->setChecked(true);
3299                                 break;
3300                         }
3301                         case BufferParams::package_on: {
3302                                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2);
3303                                 rb->setChecked(true);
3304                                 break;
3305                         }
3306                         case BufferParams::package_auto: {
3307                                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1);
3308                                 rb->setChecked(true);
3309                                 break;
3310                         }
3311                 }
3312         }
3313
3314         switch (bp_.spacing().getSpace()) {
3315                 case Spacing::Other: nitem = 3; break;
3316                 case Spacing::Double: nitem = 2; break;
3317                 case Spacing::Onehalf: nitem = 1; break;
3318                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
3319         }
3320
3321         // text layout
3322         string const & layoutID = bp_.baseClassID();
3323         setLayoutComboByIDString(layoutID);
3324
3325         updatePagestyle(documentClass().opt_pagestyle(),
3326                                  bp_.pagestyle);
3327
3328         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
3329         if (bp_.spacing().getSpace() == Spacing::Other) {
3330                 doubleToWidget(textLayoutModule->lspacingLE,
3331                         bp_.spacing().getValueAsString());
3332         }
3333         setLSpacing(nitem);
3334
3335         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
3336                 textLayoutModule->indentRB->setChecked(true);
3337                 string indentation = bp_.getIndentation().asLyXCommand();
3338                 int indent = 0;
3339                 if (indentation != "default") {
3340                         lengthToWidgets(textLayoutModule->indentLE,
3341                         textLayoutModule->indentLengthCO,
3342                         indentation, default_unit);
3343                         indent = 1;
3344                 }
3345                 textLayoutModule->indentCO->setCurrentIndex(indent);
3346                 setIndent(indent);
3347         } else {
3348                 textLayoutModule->skipRB->setChecked(true);
3349                 int skip = 0;
3350                 switch (bp_.getDefSkip().kind()) {
3351                 case VSpace::SMALLSKIP:
3352                         skip = 0;
3353                         break;
3354                 case VSpace::MEDSKIP:
3355                         skip = 1;
3356                         break;
3357                 case VSpace::BIGSKIP:
3358                         skip = 2;
3359                         break;
3360                 case VSpace::LENGTH:
3361                         {
3362                         skip = 3;
3363                         string const length = bp_.getDefSkip().asLyXCommand();
3364                         lengthToWidgets(textLayoutModule->skipLE,
3365                                 textLayoutModule->skipLengthCO,
3366                                 length, default_unit);
3367                         break;
3368                         }
3369                 default:
3370                         skip = 0;
3371                         break;
3372                 }
3373                 textLayoutModule->skipCO->setCurrentIndex(skip);
3374                 setSkip(skip);
3375         }
3376
3377         textLayoutModule->twoColumnCB->setChecked(
3378                 bp_.columns == 2);
3379         textLayoutModule->justCB->setChecked(bp_.justification);
3380
3381         if (!bp_.options.empty()) {
3382                 latexModule->optionsLE->setText(
3383                         toqstr(bp_.options));
3384         } else {
3385                 latexModule->optionsLE->setText(QString());
3386         }
3387
3388         // latex
3389         latexModule->defaultOptionsCB->setChecked(
3390                         bp_.use_default_options);
3391         updateSelectedModules();
3392         selectionManager->updateProvidedModules(
3393                         bp_.baseClass()->providedModules());
3394         selectionManager->updateExcludedModules(
3395                         bp_.baseClass()->excludedModules());
3396
3397         if (!documentClass().options().empty()) {
3398                 latexModule->defaultOptionsLE->setText(
3399                         toqstr(documentClass().options()));
3400         } else {
3401                 latexModule->defaultOptionsLE->setText(
3402                         toqstr(_("[No options predefined]")));
3403         }
3404
3405         latexModule->defaultOptionsLE->setEnabled(
3406                 bp_.use_default_options
3407                 && !documentClass().options().empty());
3408
3409         latexModule->defaultOptionsCB->setEnabled(
3410                 !documentClass().options().empty());
3411
3412         if (!bp_.master.empty()) {
3413                 latexModule->childDocGB->setChecked(true);
3414                 latexModule->childDocLE->setText(
3415                         toqstr(bp_.master));
3416         } else {
3417                 latexModule->childDocLE->setText(QString());
3418                 latexModule->childDocGB->setChecked(false);
3419         }
3420
3421         // Master/Child
3422         if (!bufferview() || !buffer().hasChildren()) {
3423                 masterChildModule->childrenTW->clear();
3424                 includeonlys_.clear();
3425                 docPS->showPanel("Child Documents", false);
3426                 if (docPS->isCurrentPanel("Child Documents"))
3427                         docPS->setCurrentPanel("Document Class");
3428         } else {
3429                 docPS->showPanel("Child Documents", true);
3430                 masterChildModule->setEnabled(true);
3431                 includeonlys_ = bp_.getIncludedChildren();
3432                 updateIncludeonlys();
3433         }
3434         masterChildModule->maintainAuxCB->setChecked(
3435                 bp_.maintain_unincluded_children);
3436
3437         // Float Settings
3438         floatModule->set(bp_.float_placement);
3439
3440         // ListingsSettings
3441         // break listings_params to multiple lines
3442         string lstparams =
3443                 InsetListingsParams(bp_.listings_params).separatedParams();
3444         listingsModule->listingsED->setPlainText(toqstr(lstparams));
3445
3446         // Fonts
3447         // some languages only work with polyglossia/XeTeX
3448         Language const * lang = lyx::languages.getLanguage(
3449                 fromqstr(langModule->languageCO->itemData(
3450                         langModule->languageCO->currentIndex()).toString()));
3451         bool const need_fontspec =
3452                 lang->babel().empty() && !lang->polyglossia().empty();
3453         bool const os_fonts_available =
3454                 bp_.baseClass()->outputType() == lyx::LATEX
3455                 && LaTeXFeatures::isAvailable("fontspec");
3456         fontModule->osFontsCB->setEnabled(os_fonts_available && !need_fontspec);
3457         fontModule->osFontsCB->setChecked(
3458                 (os_fonts_available && bp_.useNonTeXFonts) || need_fontspec);
3459         updateFontsize(documentClass().opt_fontsize(),
3460                         bp_.fontsize);
3461
3462         QString font = toqstr(bp_.fontsRoman());
3463         int rpos = fontModule->fontsRomanCO->findData(font);
3464         if (rpos == -1) {
3465                 rpos = fontModule->fontsRomanCO->count();
3466                 fontModule->fontsRomanCO->addItem(font + qt_(" (not installed)"), font);
3467         }
3468         fontModule->fontsRomanCO->setCurrentIndex(rpos);
3469         fontModule->font_roman = toqstr(bp_.fonts_roman[!bp_.useNonTeXFonts]);
3470
3471         font = toqstr(bp_.fontsSans());
3472         int spos = fontModule->fontsSansCO->findData(font);
3473         if (spos == -1) {
3474                 spos = fontModule->fontsSansCO->count();
3475                 fontModule->fontsSansCO->addItem(font + qt_(" (not installed)"), font);
3476         }
3477         fontModule->fontsSansCO->setCurrentIndex(spos);
3478         fontModule->font_sans = toqstr(bp_.fonts_sans[!bp_.useNonTeXFonts]);
3479
3480         font = toqstr(bp_.fontsTypewriter());
3481         int tpos = fontModule->fontsTypewriterCO->findData(font);
3482         if (tpos == -1) {
3483                 tpos = fontModule->fontsTypewriterCO->count();
3484                 fontModule->fontsTypewriterCO->addItem(font + qt_(" (not installed)"), font);
3485         }
3486         fontModule->fontsTypewriterCO->setCurrentIndex(tpos);
3487         fontModule->font_typewriter = toqstr(bp_.fonts_typewriter[!bp_.useNonTeXFonts]);
3488
3489         font = toqstr(bp_.fontsMath());
3490         int mpos = fontModule->fontsMathCO->findData(font);
3491         if (mpos == -1) {
3492                 mpos = fontModule->fontsMathCO->count();
3493                 fontModule->fontsMathCO->addItem(font + qt_(" (not installed)"), font);
3494         }
3495         fontModule->fontsMathCO->setCurrentIndex(mpos);
3496         fontModule->font_math = toqstr(bp_.fonts_math[!bp_.useNonTeXFonts]);
3497
3498         if (bp_.useNonTeXFonts && os_fonts_available) {
3499                 fontModule->fontencLA->setEnabled(false);
3500                 fontModule->fontencCO->setEnabled(false);
3501                 fontModule->fontencLE->setEnabled(false);
3502         } else {
3503                 fontModule->fontencLA->setEnabled(true);
3504                 fontModule->fontencCO->setEnabled(true);
3505                 fontModule->fontencLE->setEnabled(true);
3506                 romanChanged(rpos);
3507                 sansChanged(spos);
3508                 ttChanged(tpos);
3509         }
3510
3511         if (!bp_.fonts_cjk.empty())
3512                 fontModule->cjkFontLE->setText(
3513                         toqstr(bp_.fonts_cjk));
3514         else
3515                 fontModule->cjkFontLE->setText(QString());
3516         
3517         fontModule->microtypeCB->setChecked(bp_.use_microtype);
3518
3519         fontModule->fontScCB->setChecked(bp_.fonts_expert_sc);
3520         fontModule->fontOsfCB->setChecked(bp_.fonts_old_figures);
3521         fontModule->scaleSansSB->setValue(bp_.fontsSansScale());
3522         fontModule->font_sf_scale = bp_.fonts_sans_scale[!bp_.useNonTeXFonts];
3523         fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale());
3524         fontModule->font_tt_scale = bp_.fonts_typewriter_scale[!bp_.useNonTeXFonts];
3525
3526         int nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
3527         if (nn >= 0)
3528                 fontModule->fontsDefaultCO->setCurrentIndex(nn);
3529
3530         if (bp_.fontenc == "global" || bp_.fontenc == "default") {
3531                 fontModule->fontencCO->setCurrentIndex(
3532                         fontModule->fontencCO->findData(toqstr(bp_.fontenc)));
3533                 fontModule->fontencLE->setEnabled(false);
3534         } else {
3535                 fontModule->fontencCO->setCurrentIndex(1);
3536                 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
3537         }
3538
3539         // Formats
3540         // This must be set _after_ fonts since updateDefaultFormat()
3541         // checks osFontsCB settings.
3542         // update combobox with formats
3543         updateDefaultFormat();
3544         int index = outputModule->defaultFormatCO->findData(toqstr(
3545                 bp_.default_output_format));
3546         // set to default if format is not found
3547         if (index == -1)
3548                 index = 0;
3549         outputModule->defaultFormatCO->setCurrentIndex(index);
3550
3551         outputModule->outputsyncCB->setChecked(bp_.output_sync);
3552         outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
3553
3554         outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
3555         outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
3556         outputModule->strictCB->setChecked(bp_.html_be_strict);
3557         outputModule->cssCB->setChecked(bp_.html_css_as_file);
3558
3559         outputModule->saveTransientPropertiesCB
3560                 ->setChecked(bp_.save_transient_properties);
3561
3562         // paper
3563         bool const extern_geometry =
3564                 documentClass().provides("geometry");
3565         int const psize = bp_.papersize;
3566         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
3567         setCustomPapersize(!extern_geometry && psize == 1);
3568         pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
3569
3570         bool const landscape =
3571                 bp_.orientation == ORIENTATION_LANDSCAPE;
3572         pageLayoutModule->landscapeRB->setChecked(landscape);
3573         pageLayoutModule->portraitRB->setChecked(!landscape);
3574         pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
3575         pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
3576
3577         pageLayoutModule->facingPagesCB->setChecked(
3578                 bp_.sides == TwoSides);
3579
3580         lengthToWidgets(pageLayoutModule->paperwidthLE,
3581                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, default_unit);
3582         lengthToWidgets(pageLayoutModule->paperheightLE,
3583                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, default_unit);
3584
3585         // margins
3586         Ui::MarginsUi * m = marginsModule;
3587
3588         setMargins();
3589
3590         lengthToWidgets(m->topLE, m->topUnit,
3591                 bp_.topmargin, default_unit);
3592
3593         lengthToWidgets(m->bottomLE, m->bottomUnit,
3594                 bp_.bottommargin, default_unit);
3595
3596         lengthToWidgets(m->innerLE, m->innerUnit,
3597                 bp_.leftmargin, default_unit);
3598
3599         lengthToWidgets(m->outerLE, m->outerUnit,
3600                 bp_.rightmargin, default_unit);
3601
3602         lengthToWidgets(m->headheightLE, m->headheightUnit,
3603                 bp_.headheight, default_unit);
3604
3605         lengthToWidgets(m->headsepLE, m->headsepUnit,
3606                 bp_.headsep, default_unit);
3607
3608         lengthToWidgets(m->footskipLE, m->footskipUnit,
3609                 bp_.footskip, default_unit);
3610
3611         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
3612                 bp_.columnsep, default_unit);
3613
3614         // branches
3615         updateUnknownBranches();
3616         branchesModule->update(bp_);
3617
3618         // PDF support
3619         PDFOptions const & pdf = bp_.pdfoptions();
3620         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
3621         if (bp_.documentClass().provides("hyperref"))
3622                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("C&ustomize Hyperref Options"));
3623         else
3624                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("&Use Hyperref Support"));
3625         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
3626         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
3627         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
3628         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
3629
3630         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
3631         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
3632         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
3633
3634         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
3635
3636         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
3637         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
3638         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
3639         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
3640
3641         nn = findToken(backref_opts, pdf.backref);
3642         if (nn >= 0)
3643                 pdfSupportModule->backrefCO->setCurrentIndex(nn);
3644
3645         pdfSupportModule->fullscreenCB->setChecked
3646                 (pdf.pagemode == pdf.pagemode_fullscreen);
3647
3648         pdfSupportModule->optionsLE->setText(
3649                 toqstr(pdf.quoted_options));
3650
3651         // Make sure that the bc is in the INITIAL state
3652         if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
3653                 bc().restore();
3654
3655         // clear changed branches cache
3656         changedBranches_.clear();
3657
3658         // reset tracker
3659         nonModuleChanged_ = false;
3660 }
3661
3662
3663 void GuiDocument::saveDocDefault()
3664 {
3665         // we have to apply the params first
3666         applyView();
3667         saveAsDefault();
3668 }
3669
3670
3671 void GuiDocument::updateAvailableModules()
3672 {
3673         modules_av_model_.clear();
3674         list<modInfoStruct> modInfoList = getModuleInfo();
3675         // Sort names according to the locale
3676         modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
3677                         return 0 < b.name.localeAwareCompare(a.name);
3678                 });
3679         int i = 0;
3680         for (modInfoStruct const & m : modInfoList) {
3681                 modules_av_model_.insertRow(i, m.name, m.id, m.description);
3682                 ++i;
3683         }
3684 }
3685
3686
3687 void GuiDocument::updateSelectedModules()
3688 {
3689         modules_sel_model_.clear();
3690         list<modInfoStruct> const selModList = getSelectedModules();
3691         int i = 0;
3692         for (modInfoStruct const & m : selModList) {
3693                 modules_sel_model_.insertRow(i, m.name, m.id, m.description);
3694                 ++i;
3695         }
3696 }
3697
3698
3699 void GuiDocument::updateIncludeonlys()
3700 {
3701         masterChildModule->childrenTW->clear();
3702         QString const no = qt_("No");
3703         QString const yes = qt_("Yes");
3704
3705         if (includeonlys_.empty()) {
3706                 masterChildModule->includeallRB->setChecked(true);
3707                 masterChildModule->childrenTW->setEnabled(false);
3708                 masterChildModule->maintainAuxCB->setEnabled(false);
3709         } else {
3710                 masterChildModule->includeonlyRB->setChecked(true);
3711                 masterChildModule->childrenTW->setEnabled(true);
3712                 masterChildModule->maintainAuxCB->setEnabled(true);
3713         }
3714         ListOfBuffers children = buffer().getChildren();
3715         ListOfBuffers::const_iterator it  = children.begin();
3716         ListOfBuffers::const_iterator end = children.end();
3717         bool has_unincluded = false;
3718         bool all_unincluded = true;
3719         for (; it != end; ++it) {
3720                 QTreeWidgetItem * item = new QTreeWidgetItem(masterChildModule->childrenTW);
3721                 // FIXME Unicode
3722                 string const name =
3723                         to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
3724                                                         from_utf8(buffer().filePath())));
3725                 item->setText(0, toqstr(name));
3726                 item->setText(1, isChildIncluded(name) ? yes : no);
3727                 if (!isChildIncluded(name))
3728                         has_unincluded = true;
3729                 else
3730                         all_unincluded = false;
3731         }
3732         // Both if all childs are included and if none is included
3733         // is equal to "include all" (i.e., ommit \includeonly).
3734         // Thus, reset the GUI.
3735         if (!has_unincluded || all_unincluded) {
3736                 masterChildModule->includeallRB->setChecked(true);
3737                 masterChildModule->childrenTW->setEnabled(false);
3738                 includeonlys_.clear();
3739         }
3740         // If all are included, we need to update again.
3741         if (!has_unincluded)
3742                 updateIncludeonlys();
3743 }
3744
3745
3746 bool GuiDocument::isBiblatex() const
3747 {
3748         QString const engine =
3749                 biblioModule->citeEngineCO->itemData(
3750                                 biblioModule->citeEngineCO->currentIndex()).toString();
3751
3752         return theCiteEnginesList[fromqstr(engine)]->getCiteFramework() == "biblatex";
3753 }
3754
3755
3756 void GuiDocument::updateDefaultBiblio(string const & style,
3757                                       string const & which)
3758 {
3759         QString const bibstyle = toqstr(style);
3760         biblioModule->defaultBiblioCO->clear();
3761         biblioModule->biblatexBbxCO->clear();
3762         biblioModule->biblatexCbxCO->clear();
3763
3764         int item_nr = -1;
3765
3766         if (isBiblatex()) {
3767                 if (which != "cbx") {
3768                         // First the bbx styles
3769                         QStringList str = texFileList("bbxFiles.lst");
3770                         // test whether we have a valid list, otherwise run rescan
3771                         if (str.isEmpty()) {
3772                                 rescanTexStyles("bbx");
3773                                 str = texFileList("bbxFiles.lst");
3774                         }
3775                         for (int i = 0; i != str.size(); ++i)
3776                                 str[i] = onlyFileName(str[i]);
3777                         // sort on filename only (no path)
3778                         str.sort();
3779
3780                         for (int i = 0; i != str.count(); ++i) {
3781                                 QString item = changeExtension(str[i], "");
3782                                 if (item == bibstyle)
3783                                         item_nr = i;
3784                                 biblioModule->biblatexBbxCO->addItem(item);
3785                         }
3786
3787                         if (item_nr == -1 && !bibstyle.isEmpty()) {
3788                                 biblioModule->biblatexBbxCO->addItem(bibstyle);
3789                                 item_nr = biblioModule->biblatexBbxCO->count() - 1;
3790                         }
3791
3792                         if (item_nr != -1)
3793                                 biblioModule->biblatexBbxCO->setCurrentIndex(item_nr);
3794                         else
3795                                 biblioModule->biblatexBbxCO->clearEditText();
3796                 }
3797
3798                 if (which != "bbx") {
3799                         // now the cbx styles
3800                         QStringList str = texFileList("cbxFiles.lst");
3801                         // test whether we have a valid list, otherwise run rescan
3802                         if (str.isEmpty()) {
3803                                 rescanTexStyles("cbx");
3804                                 str = texFileList("cbxFiles.lst");
3805                         }
3806                         for (int i = 0; i != str.size(); ++i)
3807                                 str[i] = onlyFileName(str[i]);
3808                         // sort on filename only (no path)
3809                         str.sort();
3810
3811                         for (int i = 0; i != str.count(); ++i) {
3812                                 QString item = changeExtension(str[i], "");
3813                                 if (item == bibstyle)
3814                                         item_nr = i;
3815                                 biblioModule->biblatexCbxCO->addItem(item);
3816                         }
3817
3818                         if (item_nr == -1 && !bibstyle.isEmpty()) {
3819                                 biblioModule->biblatexCbxCO->addItem(bibstyle);
3820                                 item_nr = biblioModule->biblatexCbxCO->count() - 1;
3821                         }
3822
3823                         if (item_nr != -1)
3824                                 biblioModule->biblatexCbxCO->setCurrentIndex(item_nr);
3825                         else
3826                                 biblioModule->biblatexCbxCO->clearEditText();
3827                 }
3828         } else {// BibTeX
3829                 QStringList str = texFileList("bstFiles.lst");
3830                 // test whether we have a valid list, otherwise run rescan
3831                 if (str.isEmpty()) {
3832                         rescanTexStyles("bst");
3833                         str = texFileList("bstFiles.lst");
3834                 }
3835                 for (int i = 0; i != str.size(); ++i)
3836                         str[i] = onlyFileName(str[i]);
3837                 // sort on filename only (no path)
3838                 str.sort();
3839
3840                 for (int i = 0; i != str.count(); ++i) {
3841                         QString item = changeExtension(str[i], "");
3842                         if (item == bibstyle)
3843                                 item_nr = i;
3844                         biblioModule->defaultBiblioCO->addItem(item);
3845                 }
3846
3847                 if (item_nr == -1 && !bibstyle.isEmpty()) {
3848                         biblioModule->defaultBiblioCO->addItem(bibstyle);
3849                         item_nr = biblioModule->defaultBiblioCO->count() - 1;
3850                 }
3851
3852                 if (item_nr != -1)
3853                         biblioModule->defaultBiblioCO->setCurrentIndex(item_nr);
3854                 else
3855                         biblioModule->defaultBiblioCO->clearEditText();
3856         }
3857
3858         updateResetDefaultBiblio();
3859 }
3860
3861
3862 void GuiDocument::updateResetDefaultBiblio()
3863 {
3864         QString const engine =
3865                 biblioModule->citeEngineCO->itemData(
3866                                 biblioModule->citeEngineCO->currentIndex()).toString();
3867         CiteEngineType const cet =
3868                 CiteEngineType(biblioModule->citeStyleCO->itemData(
3869                                                           biblioModule->citeStyleCO->currentIndex()).toInt());
3870
3871         string const defbib = theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet);
3872         if (isBiblatex()) {
3873                 QString const bbx = biblioModule->biblatexBbxCO->currentText();
3874                 QString const cbx = biblioModule->biblatexCbxCO->currentText();
3875                 biblioModule->resetCbxPB->setEnabled(defbib != fromqstr(cbx));
3876                 biblioModule->resetBbxPB->setEnabled(defbib != fromqstr(bbx));
3877                 biblioModule->matchBbxPB->setEnabled(bbx != cbx && !cbx.isEmpty()
3878                         && biblioModule->biblatexBbxCO->findText(cbx) != -1);
3879         } else
3880                 biblioModule->resetDefaultBiblioPB->setEnabled(
3881                         defbib != fromqstr(biblioModule->defaultBiblioCO->currentText()));
3882 }
3883
3884
3885 void GuiDocument::matchBiblatexStyles()
3886 {
3887         updateDefaultBiblio(fromqstr(biblioModule->biblatexCbxCO->currentText()), "bbx");
3888         biblioChanged();
3889 }
3890
3891
3892 void GuiDocument::updateContents()
3893 {
3894         // Nothing to do here as the document settings is not cursor dependant.
3895         return;
3896 }
3897
3898
3899 void GuiDocument::useClassDefaults()
3900 {
3901         if (applyPB->isEnabled()) {
3902                 int const ret = Alert::prompt(_("Unapplied changes"),
3903                                 _("Some changes in the dialog were not yet applied.\n"
3904                                   "If you do not apply now, they will be lost after this action."),
3905                                 1, 1, _("&Apply"), _("&Dismiss"));
3906                 if (ret == 0)
3907                         applyView();
3908         }
3909
3910         int idx = latexModule->classCO->currentIndex();
3911         string const classname = fromqstr(latexModule->classCO->getData(idx));
3912         if (!bp_.setBaseClass(classname)) {
3913                 Alert::error(_("Error"), _("Unable to set document class."));
3914                 return;
3915         }
3916         bp_.useClassDefaults();
3917         paramsToDialog();
3918 }
3919
3920
3921 void GuiDocument::setLayoutComboByIDString(string const & idString)
3922 {
3923         if (!latexModule->classCO->set(toqstr(idString)))
3924                 Alert::warning(_("Can't set layout!"),
3925                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
3926 }
3927
3928
3929 bool GuiDocument::isValid()
3930 {
3931         return
3932                 validateListingsParameters().isEmpty() &&
3933                 localLayout->isValid() &&
3934                 (
3935                         // if we're asking for skips between paragraphs
3936                         !textLayoutModule->skipRB->isChecked() ||
3937                         // then either we haven't chosen custom
3938                         textLayoutModule->skipCO->currentIndex() != 3 ||
3939                         // or else a length has been given
3940                         !textLayoutModule->skipLE->text().isEmpty()
3941                 ) &&
3942                 (
3943                         // if we're asking for indentation
3944                         !textLayoutModule->indentRB->isChecked() ||
3945                         // then either we haven't chosen custom
3946                         textLayoutModule->indentCO->currentIndex() != 1 ||
3947                         // or else a length has been given
3948                         !textLayoutModule->indentLE->text().isEmpty()
3949                 );
3950 }
3951
3952
3953 char const * const GuiDocument::fontfamilies[5] = {
3954         "default", "rmdefault", "sfdefault", "ttdefault", ""
3955 };
3956
3957
3958 char const * GuiDocument::fontfamilies_gui[5] = {
3959         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
3960 };
3961
3962
3963 bool GuiDocument::initialiseParams(string const &)
3964 {
3965         BufferView const * view = bufferview();
3966         if (!view) {
3967                 bp_ = BufferParams();
3968                 paramsToDialog();
3969                 return true;
3970         }
3971         bp_ = view->buffer().params();
3972         loadModuleInfo();
3973         updateAvailableModules();
3974         //FIXME It'd be nice to make sure here that the selected
3975         //modules are consistent: That required modules are actually
3976         //selected, and that we don't have conflicts. If so, we could
3977         //at least pop up a warning.
3978         paramsToDialog();
3979         return true;
3980 }
3981
3982
3983 void GuiDocument::clearParams()
3984 {
3985         bp_ = BufferParams();
3986 }
3987
3988
3989 BufferId GuiDocument::id() const
3990 {
3991         BufferView const * const view = bufferview();
3992         return view? &view->buffer() : 0;
3993 }
3994
3995
3996 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
3997 {
3998         return moduleNames_;
3999 }
4000
4001
4002 list<GuiDocument::modInfoStruct> const
4003 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
4004 {
4005         list<modInfoStruct> mInfo;
4006         for (string const & name : mods) {
4007                 modInfoStruct m;
4008                 LyXModule const * const mod = theModuleList[name];
4009                 if (mod)
4010                         m = modInfo(*mod);
4011                 else {
4012                         m.id = name;
4013                         m.name = toqstr(name + " (") + qt_("Not Found") + toqstr(")");
4014                 }
4015                 mInfo.push_back(m);
4016         }
4017         return mInfo;
4018 }
4019
4020
4021 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
4022 {
4023         return makeModuleInfo(params().getModules());
4024 }
4025
4026
4027 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
4028 {
4029         return makeModuleInfo(params().baseClass()->providedModules());
4030 }
4031
4032
4033 DocumentClass const & GuiDocument::documentClass() const
4034 {
4035         return bp_.documentClass();
4036 }
4037
4038
4039 static void dispatch_bufferparams(Dialog const & dialog,
4040         BufferParams const & bp, FuncCode lfun, Buffer const * buf)
4041 {
4042         ostringstream ss;
4043         ss << "\\begin_header\n";
4044         bp.writeFile(ss, buf);
4045         ss << "\\end_header\n";
4046         dialog.dispatch(FuncRequest(lfun, ss.str()));
4047 }
4048
4049
4050 void GuiDocument::dispatchParams()
4051 {
4052         // We need a non-const buffer object.
4053         Buffer & buf = const_cast<BufferView *>(bufferview())->buffer();
4054         // There may be several undo records; group them (bug #8998)
4055         buf.undo().beginUndoGroup();
4056
4057         // This must come first so that a language change is correctly noticed
4058         setLanguage();
4059
4060         // Apply the BufferParams. Note that this will set the base class
4061         // and then update the buffer's layout.
4062         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY, &buffer());
4063
4064         if (!params().master.empty()) {
4065                 FileName const master_file = support::makeAbsPath(params().master,
4066                            support::onlyPath(buffer().absFileName()));
4067                 if (isLyXFileName(master_file.absFileName())) {
4068                         Buffer * master = checkAndLoadLyXFile(master_file);
4069                         if (master) {
4070                                 if (master->isChild(const_cast<Buffer *>(&buffer())))
4071                                         const_cast<Buffer &>(buffer()).setParent(master);
4072                                 else
4073                                         Alert::warning(_("Assigned master does not include this file"),
4074                                                 bformat(_("You must include this file in the document\n"
4075                                                           "'%1$s' in order to use the master document\n"
4076                                                           "feature."), from_utf8(params().master)));
4077                         } else
4078                                 Alert::warning(_("Could not load master"),
4079                                                 bformat(_("The master document '%1$s'\n"
4080                                                            "could not be loaded."),
4081                                                            from_utf8(params().master)));
4082                 }
4083         }
4084
4085         // Generate the colours requested by each new branch.
4086         BranchList & branchlist = params().branchlist();
4087         if (!branchlist.empty()) {
4088                 BranchList::const_iterator it = branchlist.begin();
4089                 BranchList::const_iterator const end = branchlist.end();
4090                 for (; it != end; ++it) {
4091                         docstring const & current_branch = it->branch();
4092                         Branch const * branch = branchlist.find(current_branch);
4093                         string const x11hexname = X11hexname(branch->color());
4094                         // display the new color
4095                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
4096                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
4097                 }
4098
4099                 // Open insets of selected branches, close deselected ones
4100                 dispatch(FuncRequest(LFUN_INSET_FORALL,
4101                         "Branch inset-toggle assign"));
4102         }
4103         // rename branches in the document
4104         executeBranchRenaming();
4105         // and clear changed branches cache
4106         changedBranches_.clear();
4107
4108         // Generate the colours requested by indices.
4109         IndicesList & indiceslist = params().indiceslist();
4110         if (!indiceslist.empty()) {
4111                 IndicesList::const_iterator it = indiceslist.begin();
4112                 IndicesList::const_iterator const end = indiceslist.end();
4113                 for (; it != end; ++it) {
4114                         docstring const & current_index = it->shortcut();
4115                         Index const * index = indiceslist.findShortcut(current_index);
4116                         string const x11hexname = X11hexname(index->color());
4117                         // display the new color
4118                         docstring const str = current_index + ' ' + from_ascii(x11hexname);
4119                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
4120                 }
4121         }
4122         // FIXME LFUN
4123         // If we used an LFUN, we would not need these two lines:
4124         BufferView * bv = const_cast<BufferView *>(bufferview());
4125         bv->processUpdateFlags(Update::Force | Update::FitCursor);
4126
4127         // Don't forget to close the group. Note that it is important
4128         // to check that there is no early return in the method.
4129         buf.undo().endUndoGroup();
4130 }
4131
4132
4133 void GuiDocument::setLanguage() const
4134 {
4135         Language const * const newL = bp_.language;
4136         if (buffer().params().language == newL)
4137                 return;
4138
4139         string const & lang_name = newL->lang();
4140         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
4141 }
4142
4143
4144 void GuiDocument::saveAsDefault() const
4145 {
4146         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT, &buffer());
4147 }
4148
4149
4150 bool GuiDocument::providesOSF(QString const & font) const
4151 {
4152         if (fontModule->osFontsCB->isChecked())
4153                 // FIXME: we should check if the fonts really
4154                 // have OSF support. But how?
4155                 return true;
4156         return theLaTeXFonts().getLaTeXFont(
4157                                 qstring_to_ucs4(font)).providesOSF(ot1(),
4158                                                                    completeFontset(),
4159                                                                    noMathFont());
4160 }
4161
4162
4163 bool GuiDocument::providesSC(QString const & font) const
4164 {
4165         if (fontModule->osFontsCB->isChecked())
4166                 return false;
4167         return theLaTeXFonts().getLaTeXFont(
4168                                 qstring_to_ucs4(font)).providesSC(ot1(),
4169                                                                   completeFontset(),
4170                                                                   noMathFont());
4171 }
4172
4173
4174 bool GuiDocument::providesScale(QString const & font) const
4175 {
4176         if (fontModule->osFontsCB->isChecked())
4177                 return true;
4178         return theLaTeXFonts().getLaTeXFont(
4179                                 qstring_to_ucs4(font)).providesScale(ot1(),
4180                                                                      completeFontset(),
4181                                                                      noMathFont());
4182 }
4183
4184
4185 bool GuiDocument::providesNoMath(QString const & font) const
4186 {
4187         if (fontModule->osFontsCB->isChecked())
4188                 return false;
4189         return theLaTeXFonts().getLaTeXFont(
4190                                 qstring_to_ucs4(font)).providesNoMath(ot1(),
4191                                                                       completeFontset());
4192 }
4193
4194
4195 bool GuiDocument::hasMonolithicExpertSet(QString const & font) const
4196 {
4197         if (fontModule->osFontsCB->isChecked())
4198                 return false;
4199         return theLaTeXFonts().getLaTeXFont(
4200                                 qstring_to_ucs4(font)).hasMonolithicExpertSet(ot1(),
4201                                                                               completeFontset(),
4202                                                                               noMathFont());
4203 }
4204
4205
4206 //static
4207 GuiDocument::modInfoStruct GuiDocument::modInfo(LyXModule const & mod)
4208 {
4209         // FIXME Unicode: docstrings would be better for these parameters but this
4210         // change requires a lot of others
4211         modInfoStruct m;
4212         m.id = mod.getID();
4213         m.name = toqstr(translateIfPossible(from_utf8(mod.getName())));
4214         QString desc = toqstr(translateIfPossible(from_utf8(mod.getDescription())));
4215         // Find the first sentence of the description
4216         QTextBoundaryFinder bf(QTextBoundaryFinder::Sentence, desc);
4217         int pos = bf.toNextBoundary();
4218         if (pos > 0)
4219                 desc.truncate(pos);
4220         QString modulename = QString(qt_("(Module name: %1)")).arg(toqstr(m.id));
4221         // Tooltip is the desc followed by the module name
4222         m.description = QString("%1<i>%2</i>")
4223                 .arg(desc.isEmpty() ? QString() : QString("<p>%1</p>").arg(desc),
4224                      modulename);
4225         return m;
4226 }
4227
4228
4229 void GuiDocument::loadModuleInfo()
4230 {
4231         moduleNames_.clear();
4232         for (LyXModule const & mod : theModuleList)
4233                 if (mod.category().substr(0, 8) != "Citation")
4234                         moduleNames_.push_back(modInfo(mod));
4235 }
4236
4237
4238 void GuiDocument::updateUnknownBranches()
4239 {
4240         if (!bufferview())
4241                 return;
4242         list<docstring> used_branches;
4243         buffer().getUsedBranches(used_branches);
4244         list<docstring>::const_iterator it = used_branches.begin();
4245         QStringList unknown_branches;
4246         for (; it != used_branches.end() ; ++it) {
4247                 if (!buffer().params().branchlist().find(*it))
4248                         unknown_branches.append(toqstr(*it));
4249         }
4250         branchesModule->setUnknownBranches(unknown_branches);
4251 }
4252
4253
4254 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
4255 {
4256         map<docstring, docstring>::iterator it = changedBranches_.begin();
4257         for (; it != changedBranches_.end() ; ++it) {
4258                 if (it->second == oldname) {
4259                         // branch has already been renamed
4260                         it->second = newname;
4261                         return;
4262                 }
4263         }
4264         // store new name
4265         changedBranches_[oldname] = newname;
4266 }
4267
4268
4269 void GuiDocument::executeBranchRenaming() const
4270 {
4271         map<docstring, docstring>::const_iterator it = changedBranches_.begin();
4272         for (; it != changedBranches_.end() ; ++it) {
4273                 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
4274                 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
4275         }
4276 }
4277
4278
4279 void GuiDocument::allPackagesAuto()
4280 {
4281         allPackages(1);
4282 }
4283
4284
4285 void GuiDocument::allPackagesAlways()
4286 {
4287         allPackages(2);
4288 }
4289
4290
4291 void GuiDocument::allPackagesNot()
4292 {
4293         allPackages(3);
4294 }
4295
4296
4297 void GuiDocument::allPackages(int col)
4298 {
4299         for (int row = 0; row < mathsModule->packagesTW->rowCount(); ++row) {
4300                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, col);
4301                 rb->setChecked(true);
4302         }
4303 }
4304
4305
4306 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
4307
4308
4309 } // namespace frontend
4310 } // namespace lyx
4311
4312 #include "moc_GuiDocument.cpp"