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