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