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