]> git.lyx.org Git - features.git/blob - src/frontends/qt4/GuiDocument.cpp
Fix indentation
[features.git] / src / frontends / qt4 / GuiDocument.cpp
1 /**
2  * \file GuiDocument.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Edwin Leuven
7  * \author Richard Heck (modules)
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "GuiDocument.h"
15
16 #include "CategorizedCombo.h"
17 #include "GuiApplication.h"
18 #include "GuiBranches.h"
19 #include "GuiIndices.h"
20 #include "GuiSelectionManager.h"
21 #include "LaTeXHighlighter.h"
22 #include "LengthCombo.h"
23 #include "PanelStack.h"
24 #include "Validator.h"
25
26 #include "LayoutFile.h"
27 #include "BranchList.h"
28 #include "buffer_funcs.h"
29 #include "Buffer.h"
30 #include "BufferParams.h"
31 #include "BufferView.h"
32 #include "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_adaptor()));
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.\n"
2106                   "Your document will not work with this layout if you\n"
2107                   "move the layout file to a different 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 = support::onlyFileName(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         const_cast<Buffer &>(buffer()).setLayoutPos(layoutFile.onlyPath().absFileName());
2127
2128         // do not trigger classChanged if there is no change.
2129         if (latexModule->classCO->currentText() == toqstr(name))
2130                 return;
2131
2132         // add to combo box
2133         bool const avail = latexModule->classCO->set(toqstr(name));
2134         if (!avail) {
2135                 LayoutFile const & tc = bcl[name];
2136                 docstring const guiname = translateIfPossible(from_utf8(tc.description()));
2137                 // tooltip sensu "KOMA-Script Article [Class 'scrartcl']"
2138                 QString tooltip = toqstr(bformat(_("%1$s [Class '%2$s']"), guiname, from_utf8(tc.latexname())));
2139                 tooltip += '\n' + qt_("This is a local layout file.");
2140                 latexModule->classCO->addItemSort(toqstr(tc.name()), toqstr(guiname),
2141                                                   toqstr(translateIfPossible(from_utf8(tc.category()))),
2142                                                   tooltip,
2143                                                   true, true, true, true);
2144                 latexModule->classCO->set(toqstr(name));
2145         }
2146
2147         classChanged();
2148 }
2149
2150
2151 void GuiDocument::browseMaster()
2152 {
2153         QString const title = qt_("Select master document");
2154         QString const dir1 = toqstr(lyxrc.document_path);
2155         QString const old = latexModule->childDocLE->text();
2156         QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
2157         QStringList const filter(qt_("LyX Files (*.lyx)"));
2158         QString file = browseRelToSub(old, docpath, title, filter, false,
2159                 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
2160
2161         if (!file.isEmpty())
2162                 latexModule->childDocLE->setText(file);
2163 }
2164
2165
2166 void GuiDocument::classChanged_adaptor()
2167 {
2168         const_cast<Buffer &>(buffer()).setLayoutPos(string());
2169         classChanged();
2170 }
2171
2172
2173 void GuiDocument::classChanged()
2174 {
2175         int idx = latexModule->classCO->currentIndex();
2176         if (idx < 0)
2177                 return;
2178         string const classname = fromqstr(latexModule->classCO->getData(idx));
2179
2180         if (applyPB->isEnabled()) {
2181                 int const ret = Alert::prompt(_("Unapplied changes"),
2182                                 _("Some changes in the dialog were not yet applied.\n"
2183                                 "If you do not apply now, they will be lost after this action."),
2184                                 1, 1, _("&Apply"), _("&Dismiss"));
2185                 if (ret == 0)
2186                         applyView();
2187         }
2188
2189         // We load the TextClass as soon as it is selected. This is
2190         // necessary so that other options in the dialog can be updated
2191         // according to the new class. Note, however, that, if you use
2192         // the scroll wheel when sitting on the combo box, we'll load a
2193         // lot of TextClass objects very quickly....
2194         if (!bp_.setBaseClass(classname)) {
2195                 Alert::error(_("Error"), _("Unable to set document class."));
2196                 return;
2197         }
2198         if (lyxrc.auto_reset_options)
2199                 bp_.useClassDefaults();
2200
2201         // With the introduction of modules came a distinction between the base
2202         // class and the document class. The former corresponds to the main layout
2203         // file; the latter is that plus the modules (or the document-specific layout,
2204         // or  whatever else there could be). Our parameters come from the document
2205         // class. So when we set the base class, we also need to recreate the document
2206         // class. Otherwise, we still have the old one.
2207         bp_.makeDocumentClass();
2208         paramsToDialog();
2209 }
2210
2211
2212 void GuiDocument::languagePackageChanged(int i)
2213 {
2214          langModule->languagePackageLE->setEnabled(
2215                 langModule->languagePackageCO->itemData(i).toString() == "custom");
2216 }
2217
2218
2219 void GuiDocument::biblioChanged()
2220 {
2221         biblioChanged_ = true;
2222         change_adaptor();
2223 }
2224
2225
2226 void GuiDocument::bibtexChanged(int n)
2227 {
2228         biblioModule->bibtexOptionsLE->setEnabled(
2229                 biblioModule->bibtexCO->itemData(n).toString() != "default");
2230         biblioChanged();
2231 }
2232
2233
2234 void GuiDocument::setAuthorYear(bool authoryear)
2235 {
2236         if (authoryear)
2237                 biblioModule->citeStyleCO->setCurrentIndex(0);
2238         biblioChanged();
2239 }
2240
2241
2242 void GuiDocument::setNumerical(bool numerical)
2243 {
2244         if (numerical)
2245                 biblioModule->citeStyleCO->setCurrentIndex(1);
2246         biblioChanged();
2247 }
2248
2249
2250 void GuiDocument::updateEngineType(string const & items, CiteEngineType const & sel)
2251 {
2252         engine_types_.clear();
2253
2254         int nn = 0;
2255
2256         for (int n = 0; !token(items, '|', n).empty(); ++n) {
2257                 nn += 1;
2258                 string style = token(items, '|', n);
2259                 engine_types_.push_back(style);
2260         }
2261
2262         switch (sel) {
2263                 case ENGINE_TYPE_AUTHORYEAR:
2264                         biblioModule->citeStyleCO->setCurrentIndex(0);
2265                         break;
2266                 case ENGINE_TYPE_NUMERICAL:
2267                 case ENGINE_TYPE_DEFAULT:
2268                         biblioModule->citeStyleCO->setCurrentIndex(1);
2269                         break;
2270         }
2271
2272         biblioModule->citationStyleL->setEnabled(nn > 1);
2273         biblioModule->citeStyleCO->setEnabled(nn > 1);
2274
2275         if (nn != 1)
2276                 return;
2277
2278         // If the textclass allows only one of authoryear or numerical,
2279         // we have no choice but to force that engine type.
2280         if (engine_types_[0] == "authoryear")
2281                 biblioModule->citeStyleCO->setCurrentIndex(0);
2282         else
2283                 biblioModule->citeStyleCO->setCurrentIndex(1);
2284 }
2285
2286
2287 namespace {
2288         // FIXME unicode
2289         // both of these should take a vector<docstring>
2290
2291         // This is an insanely complicated attempt to make this sort of thing
2292         // work with RTL languages.
2293         docstring formatStrVec(vector<string> const & v, docstring const & s)
2294         {
2295                 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
2296                 if (v.empty())
2297                         return docstring();
2298                 if (v.size() == 1)
2299                         return translateIfPossible(from_utf8(v[0]));
2300                 if (v.size() == 2) {
2301                         docstring retval = _("%1$s and %2$s");
2302                         retval = subst(retval, _("and"), s);
2303                         return bformat(retval, translateIfPossible(from_utf8(v[0])),
2304                                        translateIfPossible(from_utf8(v[1])));
2305                 }
2306                 // The idea here is to format all but the last two items...
2307                 int const vSize = v.size();
2308                 docstring t2 = _("%1$s, %2$s");
2309                 docstring retval = translateIfPossible(from_utf8(v[0]));
2310                 for (int i = 1; i < vSize - 2; ++i)
2311                         retval = bformat(t2, retval, translateIfPossible(from_utf8(v[i])));
2312                 //...and then to  plug them, and the last two, into this schema
2313                 docstring t = _("%1$s, %2$s, and %3$s");
2314                 t = subst(t, _("and"), s);
2315                 return bformat(t, retval, translateIfPossible(from_utf8(v[vSize - 2])),
2316                                translateIfPossible(from_utf8(v[vSize - 1])));
2317         }
2318
2319         vector<string> idsToNames(vector<string> const & idList)
2320         {
2321                 vector<string> retval;
2322                 vector<string>::const_iterator it  = idList.begin();
2323                 vector<string>::const_iterator end = idList.end();
2324                 for (; it != end; ++it) {
2325                         LyXModule const * const mod = theModuleList[*it];
2326                         if (!mod)
2327                                 retval.push_back(to_utf8(bformat(_("%1$s (unavailable)"),
2328                                                 translateIfPossible(from_utf8(*it)))));
2329                         else
2330                                 retval.push_back(mod->getName());
2331                 }
2332                 return retval;
2333         }
2334 } // end anonymous namespace
2335
2336
2337 void GuiDocument::modulesToParams(BufferParams & bp)
2338 {
2339         // update list of loaded modules
2340         bp.clearLayoutModules();
2341         int const srows = modules_sel_model_.rowCount();
2342         for (int i = 0; i < srows; ++i)
2343                 bp.addLayoutModule(modules_sel_model_.getIDString(i));
2344
2345         // update the list of removed modules
2346         bp.clearRemovedModules();
2347         LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
2348         list<string>::const_iterator rit = reqmods.begin();
2349         list<string>::const_iterator ren = reqmods.end();
2350
2351         // check each of the default modules
2352         for (; rit != ren; ++rit) {
2353                 list<string>::const_iterator mit = bp.getModules().begin();
2354                 list<string>::const_iterator men = bp.getModules().end();
2355                 bool found = false;
2356                 for (; mit != men; ++mit) {
2357                         if (*rit == *mit) {
2358                                 found = true;
2359                                 break;
2360                         }
2361                 }
2362                 if (!found) {
2363                         // the module isn't present so must have been removed by the user
2364                         bp.addRemovedModule(*rit);
2365                 }
2366         }
2367 }
2368
2369 void GuiDocument::modulesChanged()
2370 {
2371         modulesToParams(bp_);
2372
2373         if (applyPB->isEnabled() && nonModuleChanged_) {
2374                 int const ret = Alert::prompt(_("Unapplied changes"),
2375                                 _("Some changes in the dialog were not yet applied.\n"
2376                                 "If you do not apply now, they will be lost after this action."),
2377                                 1, 1, _("&Apply"), _("&Dismiss"));
2378                 if (ret == 0)
2379                         applyView();
2380         }
2381
2382         bp_.makeDocumentClass();
2383         paramsToDialog();
2384         changed();
2385 }
2386
2387
2388 void GuiDocument::updateModuleInfo()
2389 {
2390         selectionManager->update();
2391
2392         //Module description
2393         bool const focus_on_selected = selectionManager->selectedFocused();
2394         QAbstractItemView * lv;
2395         if (focus_on_selected)
2396                 lv = modulesModule->selectedLV;
2397         else
2398                 lv = modulesModule->availableLV;
2399         if (lv->selectionModel()->selectedIndexes().isEmpty()) {
2400                 modulesModule->infoML->document()->clear();
2401                 return;
2402         }
2403         QModelIndex const & idx = lv->selectionModel()->currentIndex();
2404         GuiIdListModel const & id_model =
2405                         focus_on_selected  ? modules_sel_model_ : modules_av_model_;
2406         string const modName = id_model.getIDString(idx.row());
2407         docstring desc = getModuleDescription(modName);
2408
2409         LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
2410         if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
2411                 if (!desc.empty())
2412                         desc += "\n";
2413                 desc += _("Module provided by document class.");
2414         }
2415
2416         docstring cat = getModuleCategory(modName);
2417         if (!cat.empty()) {
2418                 if (!desc.empty())
2419                         desc += "\n";
2420                 desc += bformat(_("Category: %1$s."), cat);
2421         }
2422
2423         vector<string> pkglist = getPackageList(modName);
2424         docstring pkgdesc = formatStrVec(pkglist, _("and"));
2425         if (!pkgdesc.empty()) {
2426                 if (!desc.empty())
2427                         desc += "\n";
2428                 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
2429         }
2430
2431         pkglist = getRequiredList(modName);
2432         if (!pkglist.empty()) {
2433                 vector<string> const reqdescs = idsToNames(pkglist);
2434                 pkgdesc = formatStrVec(reqdescs, _("or"));
2435                 if (!desc.empty())
2436                         desc += "\n";
2437                 desc += bformat(_("Modules required: %1$s."), pkgdesc);
2438         }
2439
2440         pkglist = getExcludedList(modName);
2441         if (!pkglist.empty()) {
2442                 vector<string> const reqdescs = idsToNames(pkglist);
2443                 pkgdesc = formatStrVec(reqdescs, _( "and"));
2444                 if (!desc.empty())
2445                         desc += "\n";
2446                 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
2447         }
2448
2449         if (!isModuleAvailable(modName)) {
2450                 if (!desc.empty())
2451                         desc += "\n";
2452                 desc += _("WARNING: Some required packages are unavailable!");
2453         }
2454
2455         modulesModule->infoML->document()->setPlainText(toqstr(desc));
2456 }
2457
2458
2459 void GuiDocument::updateNumbering()
2460 {
2461         DocumentClass const & tclass = documentClass();
2462
2463         numberingModule->tocTW->setUpdatesEnabled(false);
2464         numberingModule->tocTW->clear();
2465
2466         int const depth = numberingModule->depthSL->value();
2467         int const toc = numberingModule->tocSL->value();
2468         QString const no = qt_("No");
2469         QString const yes = qt_("Yes");
2470         QTreeWidgetItem * item = 0;
2471
2472         DocumentClass::const_iterator lit = tclass.begin();
2473         DocumentClass::const_iterator len = tclass.end();
2474         for (; lit != len; ++lit) {
2475                 int const toclevel = lit->toclevel;
2476                 if (toclevel != Layout::NOT_IN_TOC && !lit->counter.empty()) {
2477                         item = new QTreeWidgetItem(numberingModule->tocTW);
2478                         item->setText(0, toqstr(translateIfPossible(lit->name())));
2479                         item->setText(1, (toclevel <= depth) ? yes : no);
2480                         item->setText(2, (toclevel <= toc) ? yes : no);
2481                 }
2482         }
2483
2484         numberingModule->tocTW->setUpdatesEnabled(true);
2485         numberingModule->tocTW->update();
2486 }
2487
2488
2489 void GuiDocument::updateDefaultFormat()
2490 {
2491         if (!bufferview())
2492                 return;
2493         // make a copy in order to consider unapplied changes
2494         BufferParams param_copy = buffer().params();
2495         param_copy.useNonTeXFonts = fontModule->osFontsCB->isChecked();
2496         int const idx = latexModule->classCO->currentIndex();
2497         if (idx >= 0) {
2498                 string const classname = fromqstr(latexModule->classCO->getData(idx));
2499                 param_copy.setBaseClass(classname);
2500                 param_copy.makeDocumentClass(true);
2501         }
2502         outputModule->defaultFormatCO->blockSignals(true);
2503         outputModule->defaultFormatCO->clear();
2504         outputModule->defaultFormatCO->addItem(qt_("Default"),
2505                                 QVariant(QString("default")));
2506         typedef vector<Format const *> Formats;
2507         Formats formats = param_copy.exportableFormats(true);
2508         sort(formats.begin(), formats.end(), Format::formatSorter);
2509         Formats::const_iterator cit = formats.begin();
2510         Formats::const_iterator end = formats.end();
2511         for (; cit != end; ++cit)
2512                 outputModule->defaultFormatCO->addItem(qt_((*cit)->prettyname()),
2513                                 QVariant(toqstr((*cit)->name())));
2514         outputModule->defaultFormatCO->blockSignals(false);
2515 }
2516
2517
2518 bool GuiDocument::isChildIncluded(string const & child)
2519 {
2520         if (includeonlys_.empty())
2521                 return false;
2522         return (std::find(includeonlys_.begin(),
2523                           includeonlys_.end(), child) != includeonlys_.end());
2524 }
2525
2526
2527 void GuiDocument::applyView()
2528 {
2529         // preamble
2530         preambleModule->apply(bp_);
2531         localLayout->apply(bp_);
2532
2533         // date
2534         bp_.suppress_date = latexModule->suppressDateCB->isChecked();
2535         bp_.use_refstyle  = latexModule->refstyleCB->isChecked();
2536
2537         // biblio
2538         if (biblioModule->citeNatbibRB->isChecked())
2539                 bp_.setCiteEngine("natbib");
2540         else if (biblioModule->citeJurabibRB->isChecked())
2541                 bp_.setCiteEngine("jurabib");
2542         if (biblioModule->citeDefaultRB->isChecked()) {
2543                 bp_.setCiteEngine("basic");
2544                 bp_.setCiteEngineType(ENGINE_TYPE_DEFAULT);
2545         }
2546         else
2547         if (biblioModule->citeStyleCO->currentIndex())
2548                 bp_.setCiteEngineType(ENGINE_TYPE_NUMERICAL);
2549         else
2550                 bp_.setCiteEngineType(ENGINE_TYPE_AUTHORYEAR);
2551
2552         bp_.use_bibtopic =
2553                 biblioModule->bibtopicCB->isChecked();
2554
2555         bp_.biblio_style = fromqstr(biblioModule->bibtexStyleLE->text());
2556
2557         string const bibtex_command =
2558                 fromqstr(biblioModule->bibtexCO->itemData(
2559                         biblioModule->bibtexCO->currentIndex()).toString());
2560         string const bibtex_options =
2561                 fromqstr(biblioModule->bibtexOptionsLE->text());
2562         if (bibtex_command == "default" || bibtex_options.empty())
2563                 bp_.bibtex_command = bibtex_command;
2564         else
2565                 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
2566
2567         if (biblioChanged_) {
2568                 buffer().invalidateBibinfoCache();
2569                 buffer().removeBiblioTempFiles();
2570         }
2571
2572         // Indices
2573         indicesModule->apply(bp_);
2574
2575         // language & quotes
2576         if (langModule->defaultencodingRB->isChecked()) {
2577                 bp_.inputenc = "auto";
2578         } else {
2579                 int i = langModule->encodingCO->currentIndex();
2580                 if (i == 0)
2581                         bp_.inputenc = "default";
2582                 else {
2583                         QString const enc_gui =
2584                                 langModule->encodingCO->currentText();
2585                         Encodings::const_iterator it = encodings.begin();
2586                         Encodings::const_iterator const end = encodings.end();
2587                         bool found = false;
2588                         for (; it != end; ++it) {
2589                                 if (qt_(it->guiName()) == enc_gui &&
2590                                     !it->unsafe()) {
2591                                         bp_.inputenc = it->name();
2592                                         found = true;
2593                                         break;
2594                                 }
2595                         }
2596                         if (!found) {
2597                                 // should not happen
2598                                 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
2599                                 bp_.inputenc = "default";
2600                         }
2601                 }
2602         }
2603
2604         bp_.quotes_language = (InsetQuotes::QuoteLanguage) langModule->quoteStyleCO->itemData(
2605                 langModule->quoteStyleCO->currentIndex()).toInt();
2606
2607         QString const lang = langModule->languageCO->itemData(
2608                 langModule->languageCO->currentIndex()).toString();
2609         bp_.language = lyx::languages.getLanguage(fromqstr(lang));
2610
2611         QString const pack = langModule->languagePackageCO->itemData(
2612                 langModule->languagePackageCO->currentIndex()).toString();
2613         if (pack == "custom")
2614                 bp_.lang_package =
2615                         fromqstr(langModule->languagePackageLE->text());
2616         else
2617                 bp_.lang_package = fromqstr(pack);
2618
2619         //color
2620         bp_.backgroundcolor = set_backgroundcolor;
2621         bp_.isbackgroundcolor = is_backgroundcolor;
2622         bp_.fontcolor = set_fontcolor;
2623         bp_.isfontcolor = is_fontcolor;
2624         bp_.notefontcolor = set_notefontcolor;
2625         bp_.boxbgcolor = set_boxbgcolor;
2626
2627         // numbering
2628         if (bp_.documentClass().hasTocLevels()) {
2629                 bp_.tocdepth = numberingModule->tocSL->value();
2630                 bp_.secnumdepth = numberingModule->depthSL->value();
2631         }
2632
2633         // bullets
2634         bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
2635         bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
2636         bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
2637         bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
2638
2639         // packages
2640         bp_.graphics_driver =
2641                 tex_graphics[latexModule->psdriverCO->currentIndex()];
2642
2643         // text layout
2644         int idx = latexModule->classCO->currentIndex();
2645         if (idx >= 0) {
2646                 string const classname = fromqstr(latexModule->classCO->getData(idx));
2647                 bp_.setBaseClass(classname);
2648         }
2649
2650         // Modules
2651         modulesToParams(bp_);
2652
2653         // Math
2654         map<string, string> const & packages = BufferParams::auto_packages();
2655         for (map<string, string>::const_iterator it = packages.begin();
2656              it != packages.end(); ++it) {
2657                 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
2658                 if (!item)
2659                         continue;
2660                 int row = mathsModule->packagesTW->row(item);
2661                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1);
2662                 if (rb->isChecked()) {
2663                         bp_.use_package(it->first, BufferParams::package_auto);
2664                         continue;
2665                 }
2666                 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2);
2667                 if (rb->isChecked()) {
2668                         bp_.use_package(it->first, BufferParams::package_on);
2669                         continue;
2670                 }
2671                 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3);
2672                 if (rb->isChecked())
2673                         bp_.use_package(it->first, BufferParams::package_off);
2674         }
2675
2676         // Page Layout
2677         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
2678                 bp_.pagestyle = "default";
2679         else {
2680                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
2681                 for (size_t i = 0; i != pagestyles.size(); ++i)
2682                         if (pagestyles[i].second == style_gui)
2683                                 bp_.pagestyle = pagestyles[i].first;
2684         }
2685
2686         // Text Layout
2687         switch (textLayoutModule->lspacingCO->currentIndex()) {
2688         case 0:
2689                 bp_.spacing().set(Spacing::Single);
2690                 break;
2691         case 1:
2692                 bp_.spacing().set(Spacing::Onehalf);
2693                 break;
2694         case 2:
2695                 bp_.spacing().set(Spacing::Double);
2696                 break;
2697         case 3: {
2698                 string s = widgetToDoubleStr(textLayoutModule->lspacingLE);
2699                 if (s.empty())
2700                         bp_.spacing().set(Spacing::Single);
2701                 else
2702                         bp_.spacing().set(Spacing::Other, s);
2703                 break;
2704                 }
2705         }
2706
2707         if (textLayoutModule->twoColumnCB->isChecked())
2708                 bp_.columns = 2;
2709         else
2710                 bp_.columns = 1;
2711
2712         bp_.justification = textLayoutModule->justCB->isChecked();
2713
2714         if (textLayoutModule->indentRB->isChecked()) {
2715                 // if paragraphs are separated by an indentation
2716                 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
2717                 switch (textLayoutModule->indentCO->currentIndex()) {
2718                 case 0:
2719                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2720                         break;
2721                 case 1: {
2722                         HSpace indent = HSpace(
2723                                 widgetsToLength(textLayoutModule->indentLE,
2724                                 textLayoutModule->indentLengthCO)
2725                                 );
2726                         bp_.setIndentation(indent);
2727                         break;
2728                         }
2729                 default:
2730                         // this should never happen
2731                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2732                         break;
2733                 }
2734         } else {
2735                 // if paragraphs are separated by a skip
2736                 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
2737                 switch (textLayoutModule->skipCO->currentIndex()) {
2738                 case 0:
2739                         bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
2740                         break;
2741                 case 1:
2742                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2743                         break;
2744                 case 2:
2745                         bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
2746                         break;
2747                 case 3:
2748                         {
2749                         VSpace vs = VSpace(
2750                                 widgetsToLength(textLayoutModule->skipLE,
2751                                 textLayoutModule->skipLengthCO)
2752                                 );
2753                         bp_.setDefSkip(vs);
2754                         break;
2755                         }
2756                 default:
2757                         // this should never happen
2758                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2759                         break;
2760                 }
2761         }
2762
2763         bp_.options =
2764                 fromqstr(latexModule->optionsLE->text());
2765
2766         bp_.use_default_options =
2767                 latexModule->defaultOptionsCB->isChecked();
2768
2769         if (latexModule->childDocGB->isChecked())
2770                 bp_.master =
2771                         fromqstr(latexModule->childDocLE->text());
2772         else
2773                 bp_.master = string();
2774
2775         // Master/Child
2776         bp_.clearIncludedChildren();
2777         if (masterChildModule->includeonlyRB->isChecked()) {
2778                 list<string>::const_iterator it = includeonlys_.begin();
2779                 for (; it != includeonlys_.end() ; ++it) {
2780                         bp_.addIncludedChildren(*it);
2781                 }
2782         }
2783         bp_.maintain_unincluded_children =
2784                 masterChildModule->maintainAuxCB->isChecked();
2785
2786         // Float Placement
2787         bp_.float_placement = floatModule->get();
2788
2789         // Listings
2790         // text should have passed validation
2791         bp_.listings_params =
2792                 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
2793
2794         // output
2795         bp_.default_output_format = fromqstr(outputModule->defaultFormatCO->itemData(
2796                 outputModule->defaultFormatCO->currentIndex()).toString());
2797
2798         bool const nontexfonts = fontModule->osFontsCB->isChecked();
2799         bp_.useNonTeXFonts = nontexfonts;
2800
2801         bp_.output_sync = outputModule->outputsyncCB->isChecked();
2802
2803         bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
2804
2805         int mathfmt = outputModule->mathoutCB->currentIndex();
2806         if (mathfmt == -1)
2807                 mathfmt = 0;
2808         BufferParams::MathOutput const mo =
2809                 static_cast<BufferParams::MathOutput>(mathfmt);
2810         bp_.html_math_output = mo;
2811         bp_.html_be_strict = outputModule->strictCB->isChecked();
2812         bp_.html_css_as_file = outputModule->cssCB->isChecked();
2813         bp_.html_math_img_scale = outputModule->mathimgSB->value();
2814         bp_.display_pixel_ratio = theGuiApp()->pixelRatio();
2815
2816         // fonts
2817         bp_.fonts_roman =
2818                 fromqstr(fontModule->fontsRomanCO->
2819                         itemData(fontModule->fontsRomanCO->currentIndex()).toString());
2820
2821         bp_.fonts_sans =
2822                 fromqstr(fontModule->fontsSansCO->
2823                         itemData(fontModule->fontsSansCO->currentIndex()).toString());
2824
2825         bp_.fonts_typewriter =
2826                 fromqstr(fontModule->fontsTypewriterCO->
2827                         itemData(fontModule->fontsTypewriterCO->currentIndex()).toString());
2828
2829         bp_.fonts_math =
2830                 fromqstr(fontModule->fontsMathCO->
2831                         itemData(fontModule->fontsMathCO->currentIndex()).toString());
2832
2833         QString const fontenc =
2834                 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
2835         if (fontenc == "custom")
2836                 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
2837         else
2838                 bp_.fontenc = fromqstr(fontenc);
2839
2840         bp_.fonts_cjk =
2841                 fromqstr(fontModule->cjkFontLE->text());
2842
2843         bp_.fonts_sans_scale = fontModule->scaleSansSB->value();
2844
2845         bp_.fonts_typewriter_scale = fontModule->scaleTypewriterSB->value();
2846
2847         bp_.fonts_expert_sc = fontModule->fontScCB->isChecked();
2848
2849         bp_.fonts_old_figures = fontModule->fontOsfCB->isChecked();
2850
2851         if (nontexfonts)
2852                 bp_.fonts_default_family = "default";
2853         else
2854                 bp_.fonts_default_family = GuiDocument::fontfamilies[
2855                         fontModule->fontsDefaultCO->currentIndex()];
2856
2857         if (fontModule->fontsizeCO->currentIndex() == 0)
2858                 bp_.fontsize = "default";
2859         else
2860                 bp_.fontsize =
2861                         fromqstr(fontModule->fontsizeCO->currentText());
2862
2863         // paper
2864         bp_.papersize = PAPER_SIZE(
2865                 pageLayoutModule->papersizeCO->currentIndex());
2866
2867         bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
2868                 pageLayoutModule->paperwidthUnitCO);
2869
2870         bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
2871                 pageLayoutModule->paperheightUnitCO);
2872
2873         if (pageLayoutModule->facingPagesCB->isChecked())
2874                 bp_.sides = TwoSides;
2875         else
2876                 bp_.sides = OneSide;
2877
2878         if (pageLayoutModule->landscapeRB->isChecked())
2879                 bp_.orientation = ORIENTATION_LANDSCAPE;
2880         else
2881                 bp_.orientation = ORIENTATION_PORTRAIT;
2882
2883         // margins
2884         bp_.use_geometry = !marginsModule->marginCB->isChecked();
2885
2886         Ui::MarginsUi const * m = marginsModule;
2887
2888         bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
2889         bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
2890         bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
2891         bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
2892         bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
2893         bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
2894         bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
2895         bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
2896
2897         // branches
2898         branchesModule->apply(bp_);
2899
2900         // PDF support
2901         PDFOptions & pdf = bp_.pdfoptions();
2902         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
2903         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
2904         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
2905         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
2906         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
2907
2908         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
2909         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
2910         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
2911         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
2912
2913         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
2914         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
2915         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
2916         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
2917         pdf.backref =
2918                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
2919         if (pdfSupportModule->fullscreenCB->isChecked())
2920                 pdf.pagemode = pdf.pagemode_fullscreen;
2921         else
2922                 pdf.pagemode.clear();
2923         pdf.quoted_options = pdf.quoted_options_check(
2924                                 fromqstr(pdfSupportModule->optionsLE->text()));
2925
2926         // reset tracker
2927         nonModuleChanged_ = false;
2928 }
2929
2930
2931 void GuiDocument::paramsToDialog()
2932 {
2933         // set the default unit
2934         Length::UNIT const default_unit = Length::defaultUnit();
2935
2936         // preamble
2937         preambleModule->update(bp_, id());
2938         localLayout->update(bp_, id());
2939
2940         // date
2941         latexModule->suppressDateCB->setChecked(bp_.suppress_date);
2942         latexModule->refstyleCB->setChecked(bp_.use_refstyle);
2943
2944         // biblio
2945         string const cite_engine = bp_.citeEngine().list().front();
2946
2947         biblioModule->citeDefaultRB->setChecked(
2948                 cite_engine == "basic");
2949
2950         biblioModule->citeJurabibRB->setChecked(
2951                 cite_engine == "jurabib");
2952
2953         biblioModule->citeNatbibRB->setChecked(
2954                 cite_engine == "natbib");
2955
2956         biblioModule->citeStyleCO->setCurrentIndex(
2957                 bp_.citeEngineType() & ENGINE_TYPE_NUMERICAL);
2958
2959         updateEngineType(documentClass().opt_enginetype(),
2960                 bp_.citeEngineType());
2961
2962         biblioModule->bibtopicCB->setChecked(
2963                 bp_.use_bibtopic);
2964
2965         biblioModule->bibtexStyleLE->setText(toqstr(bp_.biblio_style));
2966
2967         string command;
2968         string options =
2969                 split(bp_.bibtex_command, command, ' ');
2970
2971         int const bpos = biblioModule->bibtexCO->findData(toqstr(command));
2972         if (bpos != -1) {
2973                 biblioModule->bibtexCO->setCurrentIndex(bpos);
2974                 biblioModule->bibtexOptionsLE->setText(toqstr(options).trimmed());
2975         } else {
2976                 // We reset to default if we do not know the specified compiler
2977                 // This is for security reasons
2978                 biblioModule->bibtexCO->setCurrentIndex(
2979                         biblioModule->bibtexCO->findData(toqstr("default")));
2980                 biblioModule->bibtexOptionsLE->clear();
2981         }
2982         biblioModule->bibtexOptionsLE->setEnabled(
2983                 biblioModule->bibtexCO->currentIndex() != 0);
2984
2985         biblioChanged_ = false;
2986
2987         // indices
2988         indicesModule->update(bp_);
2989
2990         // language & quotes
2991         int const pos = langModule->languageCO->findData(toqstr(
2992                 bp_.language->lang()));
2993         langModule->languageCO->setCurrentIndex(pos);
2994
2995         langModule->quoteStyleCO->setCurrentIndex(
2996                 bp_.quotes_language);
2997
2998         bool default_enc = true;
2999         if (bp_.inputenc != "auto") {
3000                 default_enc = false;
3001                 if (bp_.inputenc == "default") {
3002                         langModule->encodingCO->setCurrentIndex(0);
3003                 } else {
3004                         string enc_gui;
3005                         Encodings::const_iterator it = encodings.begin();
3006                         Encodings::const_iterator const end = encodings.end();
3007                         for (; it != end; ++it) {
3008                                 if (it->name() == bp_.inputenc &&
3009                                     !it->unsafe()) {
3010                                         enc_gui = it->guiName();
3011                                         break;
3012                                 }
3013                         }
3014                         int const i = langModule->encodingCO->findText(
3015                                         qt_(enc_gui));
3016                         if (i >= 0)
3017                                 langModule->encodingCO->setCurrentIndex(i);
3018                         else
3019                                 // unknown encoding. Set to default.
3020                                 default_enc = true;
3021                 }
3022         }
3023         langModule->defaultencodingRB->setChecked(default_enc);
3024         langModule->otherencodingRB->setChecked(!default_enc);
3025
3026         int const p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
3027         if (p == -1) {
3028                 langModule->languagePackageCO->setCurrentIndex(
3029                           langModule->languagePackageCO->findData("custom"));
3030                 langModule->languagePackageLE->setText(toqstr(bp_.lang_package));
3031         } else {
3032                 langModule->languagePackageCO->setCurrentIndex(p);
3033                 langModule->languagePackageLE->clear();
3034         }
3035
3036         //color
3037         if (bp_.isfontcolor) {
3038                 colorModule->fontColorPB->setStyleSheet(
3039                         colorButtonStyleSheet(rgb2qcolor(bp_.fontcolor)));
3040         }
3041         set_fontcolor = bp_.fontcolor;
3042         is_fontcolor = bp_.isfontcolor;
3043
3044         colorModule->noteFontColorPB->setStyleSheet(
3045                 colorButtonStyleSheet(rgb2qcolor(bp_.notefontcolor)));
3046         set_notefontcolor = bp_.notefontcolor;
3047
3048         if (bp_.isbackgroundcolor) {
3049                 colorModule->backgroundPB->setStyleSheet(
3050                         colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
3051         }
3052         set_backgroundcolor = bp_.backgroundcolor;
3053         is_backgroundcolor = bp_.isbackgroundcolor;
3054
3055         colorModule->boxBackgroundPB->setStyleSheet(
3056                 colorButtonStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
3057         set_boxbgcolor = bp_.boxbgcolor;
3058
3059         // numbering
3060         int const min_toclevel = documentClass().min_toclevel();
3061         int const max_toclevel = documentClass().max_toclevel();
3062         if (documentClass().hasTocLevels()) {
3063                 numberingModule->setEnabled(true);
3064                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
3065                 numberingModule->depthSL->setMaximum(max_toclevel);
3066                 numberingModule->depthSL->setValue(bp_.secnumdepth);
3067                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
3068                 numberingModule->tocSL->setMaximum(max_toclevel);
3069                 numberingModule->tocSL->setValue(bp_.tocdepth);
3070                 updateNumbering();
3071         } else {
3072                 numberingModule->setEnabled(false);
3073                 numberingModule->tocTW->clear();
3074         }
3075
3076         // bullets
3077         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
3078         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
3079         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
3080         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
3081         bulletsModule->init();
3082
3083         // packages
3084         int nitem = findToken(tex_graphics, bp_.graphics_driver);
3085         if (nitem >= 0)
3086                 latexModule->psdriverCO->setCurrentIndex(nitem);
3087         updateModuleInfo();
3088
3089         map<string, string> const & packages = BufferParams::auto_packages();
3090         for (map<string, string>::const_iterator it = packages.begin();
3091              it != packages.end(); ++it) {
3092                 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
3093                 if (!item)
3094                         continue;
3095                 int row = mathsModule->packagesTW->row(item);
3096                 switch (bp_.use_package(it->first)) {
3097                         case BufferParams::package_off: {
3098                                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3);
3099                                 rb->setChecked(true);
3100                                 break;
3101                         }
3102                         case BufferParams::package_on: {
3103                                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2);
3104                                 rb->setChecked(true);
3105                                 break;
3106                         }
3107                         case BufferParams::package_auto: {
3108                                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1);
3109                                 rb->setChecked(true);
3110                                 break;
3111                         }
3112                 }
3113         }
3114
3115         switch (bp_.spacing().getSpace()) {
3116                 case Spacing::Other: nitem = 3; break;
3117                 case Spacing::Double: nitem = 2; break;
3118                 case Spacing::Onehalf: nitem = 1; break;
3119                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
3120         }
3121
3122         // text layout
3123         string const & layoutID = bp_.baseClassID();
3124         setLayoutComboByIDString(layoutID);
3125
3126         updatePagestyle(documentClass().opt_pagestyle(),
3127                                  bp_.pagestyle);
3128
3129         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
3130         if (bp_.spacing().getSpace() == Spacing::Other) {
3131                 doubleToWidget(textLayoutModule->lspacingLE,
3132                         bp_.spacing().getValueAsString());
3133         }
3134         setLSpacing(nitem);
3135
3136         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
3137                 textLayoutModule->indentRB->setChecked(true);
3138                 string indentation = bp_.getIndentation().asLyXCommand();
3139                 int indent = 0;
3140                 if (indentation != "default") {
3141                         lengthToWidgets(textLayoutModule->indentLE,
3142                         textLayoutModule->indentLengthCO,
3143                         indentation, default_unit);
3144                         indent = 1;
3145                 }
3146                 textLayoutModule->indentCO->setCurrentIndex(indent);
3147                 setIndent(indent);
3148         } else {
3149                 textLayoutModule->skipRB->setChecked(true);
3150                 int skip = 0;
3151                 switch (bp_.getDefSkip().kind()) {
3152                 case VSpace::SMALLSKIP:
3153                         skip = 0;
3154                         break;
3155                 case VSpace::MEDSKIP:
3156                         skip = 1;
3157                         break;
3158                 case VSpace::BIGSKIP:
3159                         skip = 2;
3160                         break;
3161                 case VSpace::LENGTH:
3162                         {
3163                         skip = 3;
3164                         string const length = bp_.getDefSkip().asLyXCommand();
3165                         lengthToWidgets(textLayoutModule->skipLE,
3166                                 textLayoutModule->skipLengthCO,
3167                                 length, default_unit);
3168                         break;
3169                         }
3170                 default:
3171                         skip = 0;
3172                         break;
3173                 }
3174                 textLayoutModule->skipCO->setCurrentIndex(skip);
3175                 setSkip(skip);
3176         }
3177
3178         textLayoutModule->twoColumnCB->setChecked(
3179                 bp_.columns == 2);
3180         textLayoutModule->justCB->setChecked(bp_.justification);
3181
3182         if (!bp_.options.empty()) {
3183                 latexModule->optionsLE->setText(
3184                         toqstr(bp_.options));
3185         } else {
3186                 latexModule->optionsLE->setText(QString());
3187         }
3188
3189         // latex
3190         latexModule->defaultOptionsCB->setChecked(
3191                         bp_.use_default_options);
3192         updateSelectedModules();
3193         selectionManager->updateProvidedModules(
3194                         bp_.baseClass()->providedModules());
3195         selectionManager->updateExcludedModules(
3196                         bp_.baseClass()->excludedModules());
3197
3198         if (!documentClass().options().empty()) {
3199                 latexModule->defaultOptionsLE->setText(
3200                         toqstr(documentClass().options()));
3201         } else {
3202                 latexModule->defaultOptionsLE->setText(
3203                         toqstr(_("[No options predefined]")));
3204         }
3205
3206         latexModule->defaultOptionsLE->setEnabled(
3207                 bp_.use_default_options
3208                 && !documentClass().options().empty());
3209
3210         latexModule->defaultOptionsCB->setEnabled(
3211                 !documentClass().options().empty());
3212
3213         if (!bp_.master.empty()) {
3214                 latexModule->childDocGB->setChecked(true);
3215                 latexModule->childDocLE->setText(
3216                         toqstr(bp_.master));
3217         } else {
3218                 latexModule->childDocLE->setText(QString());
3219                 latexModule->childDocGB->setChecked(false);
3220         }
3221
3222         // Master/Child
3223         if (!bufferview() || !buffer().hasChildren()) {
3224                 masterChildModule->childrenTW->clear();
3225                 includeonlys_.clear();
3226                 docPS->showPanel("Child Documents", false);
3227                 if (docPS->isCurrentPanel("Child Documents"))
3228                         docPS->setCurrentPanel("Document Class");
3229         } else {
3230                 docPS->showPanel("Child Documents", true);
3231                 masterChildModule->setEnabled(true);
3232                 includeonlys_ = bp_.getIncludedChildren();
3233                 updateIncludeonlys();
3234         }
3235         masterChildModule->maintainAuxCB->setChecked(
3236                 bp_.maintain_unincluded_children);
3237
3238         // Float Settings
3239         floatModule->set(bp_.float_placement);
3240
3241         // ListingsSettings
3242         // break listings_params to multiple lines
3243         string lstparams =
3244                 InsetListingsParams(bp_.listings_params).separatedParams();
3245         listingsModule->listingsED->setPlainText(toqstr(lstparams));
3246
3247         // Fonts
3248         // some languages only work with polyglossia/XeTeX
3249         Language const * lang = lyx::languages.getLanguage(
3250                 fromqstr(langModule->languageCO->itemData(
3251                         langModule->languageCO->currentIndex()).toString()));
3252         bool const need_fontspec =
3253                 lang->babel().empty() && !lang->polyglossia().empty();
3254         bool const os_fonts_available =
3255                 bp_.baseClass()->outputType() == lyx::LATEX
3256                 && LaTeXFeatures::isAvailable("fontspec");
3257         fontModule->osFontsCB->setEnabled(os_fonts_available && !need_fontspec);
3258         fontModule->osFontsCB->setChecked(
3259                 (os_fonts_available && bp_.useNonTeXFonts) || need_fontspec);
3260         updateFontsize(documentClass().opt_fontsize(),
3261                         bp_.fontsize);
3262
3263         QString font = toqstr(bp_.fonts_roman);
3264         int rpos = fontModule->fontsRomanCO->findData(font);
3265         if (rpos == -1) {
3266                 rpos = fontModule->fontsRomanCO->count();
3267                 fontModule->fontsRomanCO->addItem(font + qt_(" (not installed)"), font);
3268         }
3269         fontModule->fontsRomanCO->setCurrentIndex(rpos);
3270
3271         font = toqstr(bp_.fonts_sans);
3272         int spos = fontModule->fontsSansCO->findData(font);
3273         if (spos == -1) {
3274                 spos = fontModule->fontsSansCO->count();
3275                 fontModule->fontsSansCO->addItem(font + qt_(" (not installed)"), font);
3276         }
3277         fontModule->fontsSansCO->setCurrentIndex(spos);
3278
3279         font = toqstr(bp_.fonts_typewriter);
3280         int tpos = fontModule->fontsTypewriterCO->findData(font);
3281         if (tpos == -1) {
3282                 tpos = fontModule->fontsTypewriterCO->count();
3283                 fontModule->fontsTypewriterCO->addItem(font + qt_(" (not installed)"), font);
3284         }
3285         fontModule->fontsTypewriterCO->setCurrentIndex(tpos);
3286
3287         font = toqstr(bp_.fonts_math);
3288         int mpos = fontModule->fontsMathCO->findData(font);
3289         if (mpos == -1) {
3290                 mpos = fontModule->fontsMathCO->count();
3291                 fontModule->fontsMathCO->addItem(font + qt_(" (not installed)"), font);
3292         }
3293         fontModule->fontsMathCO->setCurrentIndex(mpos);
3294
3295         if (bp_.useNonTeXFonts && os_fonts_available) {
3296                 fontModule->fontencLA->setEnabled(false);
3297                 fontModule->fontencCO->setEnabled(false);
3298                 fontModule->fontencLE->setEnabled(false);
3299         } else {
3300                 fontModule->fontencLA->setEnabled(true);
3301                 fontModule->fontencCO->setEnabled(true);
3302                 fontModule->fontencLE->setEnabled(true);
3303                 romanChanged(rpos);
3304                 sansChanged(spos);
3305                 ttChanged(tpos);
3306         }
3307
3308         if (!bp_.fonts_cjk.empty())
3309                 fontModule->cjkFontLE->setText(
3310                         toqstr(bp_.fonts_cjk));
3311         else
3312                 fontModule->cjkFontLE->setText(QString());
3313
3314         fontModule->fontScCB->setChecked(bp_.fonts_expert_sc);
3315         fontModule->fontOsfCB->setChecked(bp_.fonts_old_figures);
3316         fontModule->scaleSansSB->setValue(bp_.fonts_sans_scale);
3317         fontModule->scaleTypewriterSB->setValue(bp_.fonts_typewriter_scale);
3318
3319         int nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
3320         if (nn >= 0)
3321                 fontModule->fontsDefaultCO->setCurrentIndex(nn);
3322
3323         if (bp_.fontenc == "global" || bp_.fontenc == "default") {
3324                 fontModule->fontencCO->setCurrentIndex(
3325                         fontModule->fontencCO->findData(toqstr(bp_.fontenc)));
3326                 fontModule->fontencLE->setEnabled(false);
3327         } else {
3328                 fontModule->fontencCO->setCurrentIndex(1);
3329                 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
3330         }
3331
3332         // Output
3333         // This must be set _after_ fonts since updateDefaultFormat()
3334         // checks osFontsCB settings.
3335         // update combobox with formats
3336         updateDefaultFormat();
3337         int index = outputModule->defaultFormatCO->findData(toqstr(
3338                 bp_.default_output_format));
3339         // set to default if format is not found
3340         if (index == -1)
3341                 index = 0;
3342         outputModule->defaultFormatCO->setCurrentIndex(index);
3343
3344         outputModule->outputsyncCB->setChecked(bp_.output_sync);
3345         outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
3346
3347         outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
3348         outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
3349         outputModule->strictCB->setChecked(bp_.html_be_strict);
3350         outputModule->cssCB->setChecked(bp_.html_css_as_file);
3351
3352         // paper
3353         bool const extern_geometry =
3354                 documentClass().provides("geometry");
3355         int const psize = bp_.papersize;
3356         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
3357         setCustomPapersize(!extern_geometry && psize == 1);
3358         pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
3359
3360         bool const landscape =
3361                 bp_.orientation == ORIENTATION_LANDSCAPE;
3362         pageLayoutModule->landscapeRB->setChecked(landscape);
3363         pageLayoutModule->portraitRB->setChecked(!landscape);
3364         pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
3365         pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
3366
3367         pageLayoutModule->facingPagesCB->setChecked(
3368                 bp_.sides == TwoSides);
3369
3370         lengthToWidgets(pageLayoutModule->paperwidthLE,
3371                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, default_unit);
3372         lengthToWidgets(pageLayoutModule->paperheightLE,
3373                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, default_unit);
3374
3375         // margins
3376         Ui::MarginsUi * m = marginsModule;
3377
3378         setMargins();
3379
3380         lengthToWidgets(m->topLE, m->topUnit,
3381                 bp_.topmargin, default_unit);
3382
3383         lengthToWidgets(m->bottomLE, m->bottomUnit,
3384                 bp_.bottommargin, default_unit);
3385
3386         lengthToWidgets(m->innerLE, m->innerUnit,
3387                 bp_.leftmargin, default_unit);
3388
3389         lengthToWidgets(m->outerLE, m->outerUnit,
3390                 bp_.rightmargin, default_unit);
3391
3392         lengthToWidgets(m->headheightLE, m->headheightUnit,
3393                 bp_.headheight, default_unit);
3394
3395         lengthToWidgets(m->headsepLE, m->headsepUnit,
3396                 bp_.headsep, default_unit);
3397
3398         lengthToWidgets(m->footskipLE, m->footskipUnit,
3399                 bp_.footskip, default_unit);
3400
3401         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
3402                 bp_.columnsep, default_unit);
3403
3404         // branches
3405         updateUnknownBranches();
3406         branchesModule->update(bp_);
3407
3408         // PDF support
3409         PDFOptions const & pdf = bp_.pdfoptions();
3410         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
3411         if (bp_.documentClass().provides("hyperref"))
3412                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("C&ustomize Hyperref Options"));
3413         else
3414                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("&Use Hyperref Support"));
3415         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
3416         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
3417         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
3418         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
3419
3420         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
3421         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
3422         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
3423
3424         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
3425
3426         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
3427         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
3428         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
3429         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
3430
3431         nn = findToken(backref_opts, pdf.backref);
3432         if (nn >= 0)
3433                 pdfSupportModule->backrefCO->setCurrentIndex(nn);
3434
3435         pdfSupportModule->fullscreenCB->setChecked
3436                 (pdf.pagemode == pdf.pagemode_fullscreen);
3437
3438         pdfSupportModule->optionsLE->setText(
3439                 toqstr(pdf.quoted_options));
3440
3441         // Make sure that the bc is in the INITIAL state
3442         if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
3443                 bc().restore();
3444
3445         // clear changed branches cache
3446         changedBranches_.clear();
3447
3448         // reset tracker
3449         nonModuleChanged_ = false;
3450 }
3451
3452
3453 void GuiDocument::saveDocDefault()
3454 {
3455         // we have to apply the params first
3456         applyView();
3457         saveAsDefault();
3458 }
3459
3460
3461 void GuiDocument::updateAvailableModules()
3462 {
3463         modules_av_model_.clear();
3464         list<modInfoStruct> const & modInfoList = getModuleInfo();
3465         list<modInfoStruct>::const_iterator mit = modInfoList.begin();
3466         list<modInfoStruct>::const_iterator men = modInfoList.end();
3467         for (int i = 0; mit != men; ++mit, ++i)
3468                 modules_av_model_.insertRow(i, mit->name, mit->id,
3469                                 mit->description);
3470 }
3471
3472
3473 void GuiDocument::updateSelectedModules()
3474 {
3475         modules_sel_model_.clear();
3476         list<modInfoStruct> const selModList = getSelectedModules();
3477         list<modInfoStruct>::const_iterator mit = selModList.begin();
3478         list<modInfoStruct>::const_iterator men = selModList.end();
3479         for (int i = 0; mit != men; ++mit, ++i)
3480                 modules_sel_model_.insertRow(i, mit->name, mit->id,
3481                                 mit->description);
3482 }
3483
3484
3485 void GuiDocument::updateIncludeonlys()
3486 {
3487         masterChildModule->childrenTW->clear();
3488         QString const no = qt_("No");
3489         QString const yes = qt_("Yes");
3490
3491         if (includeonlys_.empty()) {
3492                 masterChildModule->includeallRB->setChecked(true);
3493                 masterChildModule->childrenTW->setEnabled(false);
3494                 masterChildModule->maintainAuxCB->setEnabled(false);
3495         } else {
3496                 masterChildModule->includeonlyRB->setChecked(true);
3497                 masterChildModule->childrenTW->setEnabled(true);
3498                 masterChildModule->maintainAuxCB->setEnabled(true);
3499         }
3500         QTreeWidgetItem * item = 0;
3501         ListOfBuffers children = buffer().getChildren();
3502         ListOfBuffers::const_iterator it  = children.begin();
3503         ListOfBuffers::const_iterator end = children.end();
3504         bool has_unincluded = false;
3505         bool all_unincluded = true;
3506         for (; it != end; ++it) {
3507                 item = new QTreeWidgetItem(masterChildModule->childrenTW);
3508                 // FIXME Unicode
3509                 string const name =
3510                         to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
3511                                                         from_utf8(buffer().filePath())));
3512                 item->setText(0, toqstr(name));
3513                 item->setText(1, isChildIncluded(name) ? yes : no);
3514                 if (!isChildIncluded(name))
3515                         has_unincluded = true;
3516                 else
3517                         all_unincluded = false;
3518         }
3519         // Both if all childs are included and if none is included
3520         // is equal to "include all" (i.e., ommit \includeonly).
3521         // Thus, reset the GUI.
3522         if (!has_unincluded || all_unincluded) {
3523                 masterChildModule->includeallRB->setChecked(true);
3524                 masterChildModule->childrenTW->setEnabled(false);
3525                 includeonlys_.clear();
3526         }
3527         // If all are included, we need to update again.
3528         if (!has_unincluded)
3529                 updateIncludeonlys();
3530 }
3531
3532
3533 void GuiDocument::updateContents()
3534 {
3535         // Nothing to do here as the document settings is not cursor dependant.
3536         return;
3537 }
3538
3539
3540 void GuiDocument::useClassDefaults()
3541 {
3542         if (applyPB->isEnabled()) {
3543                 int const ret = Alert::prompt(_("Unapplied changes"),
3544                                 _("Some changes in the dialog were not yet applied.\n"
3545                                   "If you do not apply now, they will be lost after this action."),
3546                                 1, 1, _("&Apply"), _("&Dismiss"));
3547                 if (ret == 0)
3548                         applyView();
3549         }
3550
3551         int idx = latexModule->classCO->currentIndex();
3552         string const classname = fromqstr(latexModule->classCO->getData(idx));
3553         if (!bp_.setBaseClass(classname)) {
3554                 Alert::error(_("Error"), _("Unable to set document class."));
3555                 return;
3556         }
3557         bp_.useClassDefaults();
3558         paramsToDialog();
3559 }
3560
3561
3562 void GuiDocument::setLayoutComboByIDString(string const & idString)
3563 {
3564         if (!latexModule->classCO->set(toqstr(idString)))
3565                 Alert::warning(_("Can't set layout!"),
3566                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
3567 }
3568
3569
3570 bool GuiDocument::isValid()
3571 {
3572         return
3573                 validateListingsParameters().isEmpty() &&
3574                 localLayout->isValid() &&
3575                 (
3576                         // if we're asking for skips between paragraphs
3577                         !textLayoutModule->skipRB->isChecked() ||
3578                         // then either we haven't chosen custom
3579                         textLayoutModule->skipCO->currentIndex() != 3 ||
3580                         // or else a length has been given
3581                         !textLayoutModule->skipLE->text().isEmpty()
3582                 ) &&
3583                 (
3584                         // if we're asking for indentation
3585                         !textLayoutModule->indentRB->isChecked() ||
3586                         // then either we haven't chosen custom
3587                         textLayoutModule->indentCO->currentIndex() != 1 ||
3588                         // or else a length has been given
3589                         !textLayoutModule->indentLE->text().isEmpty()
3590                 );
3591 }
3592
3593
3594 char const * const GuiDocument::fontfamilies[5] = {
3595         "default", "rmdefault", "sfdefault", "ttdefault", ""
3596 };
3597
3598
3599 char const * GuiDocument::fontfamilies_gui[5] = {
3600         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
3601 };
3602
3603
3604 bool GuiDocument::initialiseParams(string const &)
3605 {
3606         BufferView const * view = bufferview();
3607         if (!view) {
3608                 bp_ = BufferParams();
3609                 paramsToDialog();
3610                 return true;
3611         }
3612         bp_ = view->buffer().params();
3613         loadModuleInfo();
3614         updateAvailableModules();
3615         //FIXME It'd be nice to make sure here that the selected
3616         //modules are consistent: That required modules are actually
3617         //selected, and that we don't have conflicts. If so, we could
3618         //at least pop up a warning.
3619         paramsToDialog();
3620         return true;
3621 }
3622
3623
3624 void GuiDocument::clearParams()
3625 {
3626         bp_ = BufferParams();
3627 }
3628
3629
3630 BufferId GuiDocument::id() const
3631 {
3632         BufferView const * const view = bufferview();
3633         return view? &view->buffer() : 0;
3634 }
3635
3636
3637 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
3638 {
3639         return moduleNames_;
3640 }
3641
3642
3643 list<GuiDocument::modInfoStruct> const
3644                 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
3645 {
3646         LayoutModuleList::const_iterator it =  mods.begin();
3647         LayoutModuleList::const_iterator end = mods.end();
3648         list<modInfoStruct> mInfo;
3649         for (; it != end; ++it) {
3650                 modInfoStruct m;
3651                 m.id = *it;
3652                 LyXModule const * const mod = theModuleList[*it];
3653                 if (mod)
3654                         // FIXME Unicode
3655                         m.name = toqstr(translateIfPossible(from_utf8(mod->getName())));
3656                 else
3657                         m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
3658                 mInfo.push_back(m);
3659         }
3660         return mInfo;
3661 }
3662
3663
3664 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
3665 {
3666         return makeModuleInfo(params().getModules());
3667 }
3668
3669
3670 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
3671 {
3672         return makeModuleInfo(params().baseClass()->providedModules());
3673 }
3674
3675
3676 DocumentClass const & GuiDocument::documentClass() const
3677 {
3678         return bp_.documentClass();
3679 }
3680
3681
3682 static void dispatch_bufferparams(Dialog const & dialog,
3683         BufferParams const & bp, FuncCode lfun, Buffer const * buf)
3684 {
3685         ostringstream ss;
3686         ss << "\\begin_header\n";
3687         bp.writeFile(ss, buf);
3688         ss << "\\end_header\n";
3689         dialog.dispatch(FuncRequest(lfun, ss.str()));
3690 }
3691
3692
3693 void GuiDocument::dispatchParams()
3694 {
3695         // We need a non-const buffer object.
3696         Buffer & buf = const_cast<BufferView *>(bufferview())->buffer();
3697         // There may be several undo records; group them (bug #8998)
3698         buf.undo().beginUndoGroup();
3699
3700         // This must come first so that a language change is correctly noticed
3701         setLanguage();
3702
3703         // Apply the BufferParams. Note that this will set the base class
3704         // and then update the buffer's layout.
3705         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY, &buffer());
3706
3707         if (!params().master.empty()) {
3708                 FileName const master_file = support::makeAbsPath(params().master,
3709                            support::onlyPath(buffer().absFileName()));
3710                 if (isLyXFileName(master_file.absFileName())) {
3711                         Buffer * master = checkAndLoadLyXFile(master_file);
3712                         if (master) {
3713                                 if (master->isChild(const_cast<Buffer *>(&buffer())))
3714                                         const_cast<Buffer &>(buffer()).setParent(master);
3715                                 else
3716                                         Alert::warning(_("Assigned master does not include this file"),
3717                                                 bformat(_("You must include this file in the document\n"
3718                                                           "'%1$s' in order to use the master document\n"
3719                                                           "feature."), from_utf8(params().master)));
3720                         } else
3721                                 Alert::warning(_("Could not load master"),
3722                                                 bformat(_("The master document '%1$s'\n"
3723                                                            "could not be loaded."),
3724                                                            from_utf8(params().master)));
3725                 }
3726         }
3727
3728         // Generate the colours requested by each new branch.
3729         BranchList & branchlist = params().branchlist();
3730         if (!branchlist.empty()) {
3731                 BranchList::const_iterator it = branchlist.begin();
3732                 BranchList::const_iterator const end = branchlist.end();
3733                 for (; it != end; ++it) {
3734                         docstring const & current_branch = it->branch();
3735                         Branch const * branch = branchlist.find(current_branch);
3736                         string const x11hexname = X11hexname(branch->color());
3737                         // display the new color
3738                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
3739                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
3740                 }
3741
3742                 // Open insets of selected branches, close deselected ones
3743                 dispatch(FuncRequest(LFUN_INSET_FORALL,
3744                         "Branch inset-toggle assign"));
3745         }
3746         // rename branches in the document
3747         executeBranchRenaming();
3748         // and clear changed branches cache
3749         changedBranches_.clear();
3750
3751         // Generate the colours requested by indices.
3752         IndicesList & indiceslist = params().indiceslist();
3753         if (!indiceslist.empty()) {
3754                 IndicesList::const_iterator it = indiceslist.begin();
3755                 IndicesList::const_iterator const end = indiceslist.end();
3756                 for (; it != end; ++it) {
3757                         docstring const & current_index = it->shortcut();
3758                         Index const * index = indiceslist.findShortcut(current_index);
3759                         string const x11hexname = X11hexname(index->color());
3760                         // display the new color
3761                         docstring const str = current_index + ' ' + from_ascii(x11hexname);
3762                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
3763                 }
3764         }
3765         // FIXME LFUN
3766         // If we used an LFUN, we would not need these two lines:
3767         BufferView * bv = const_cast<BufferView *>(bufferview());
3768         bv->processUpdateFlags(Update::Force | Update::FitCursor);
3769
3770         // Don't forget to close the group. Note that it is important
3771         // to check that there is no early return in the method.
3772         buf.undo().endUndoGroup();
3773 }
3774
3775
3776 void GuiDocument::setLanguage() const
3777 {
3778         Language const * const newL = bp_.language;
3779         if (buffer().params().language == newL)
3780                 return;
3781
3782         string const & lang_name = newL->lang();
3783         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
3784 }
3785
3786
3787 void GuiDocument::saveAsDefault() const
3788 {
3789         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT, &buffer());
3790 }
3791
3792
3793 bool GuiDocument::providesOSF(QString const & font) const
3794 {
3795         if (fontModule->osFontsCB->isChecked())
3796                 // FIXME: we should check if the fonts really
3797                 // have OSF support. But how?
3798                 return true;
3799         return theLaTeXFonts().getLaTeXFont(
3800                                 qstring_to_ucs4(font)).providesOSF(ot1(),
3801                                                                    completeFontset(),
3802                                                                    noMathFont());
3803 }
3804
3805
3806 bool GuiDocument::providesSC(QString const & font) const
3807 {
3808         if (fontModule->osFontsCB->isChecked())
3809                 return false;
3810         return theLaTeXFonts().getLaTeXFont(
3811                                 qstring_to_ucs4(font)).providesSC(ot1(),
3812                                                                   completeFontset(),
3813                                                                   noMathFont());
3814 }
3815
3816
3817 bool GuiDocument::providesScale(QString const & font) const
3818 {
3819         if (fontModule->osFontsCB->isChecked())
3820                 return true;
3821         return theLaTeXFonts().getLaTeXFont(
3822                                 qstring_to_ucs4(font)).providesScale(ot1(),
3823                                                                      completeFontset(),
3824                                                                      noMathFont());
3825 }
3826
3827
3828 bool GuiDocument::providesNoMath(QString const & font) const
3829 {
3830         if (fontModule->osFontsCB->isChecked())
3831                 return false;
3832         return theLaTeXFonts().getLaTeXFont(
3833                                 qstring_to_ucs4(font)).providesNoMath(ot1(),
3834                                                                       completeFontset());
3835 }
3836
3837
3838 bool GuiDocument::hasMonolithicExpertSet(QString const & font) const
3839 {
3840         if (fontModule->osFontsCB->isChecked())
3841                 return false;
3842         return theLaTeXFonts().getLaTeXFont(
3843                                 qstring_to_ucs4(font)).hasMonolithicExpertSet(ot1(),
3844                                                                               completeFontset(),
3845                                                                               noMathFont());
3846 }
3847
3848
3849 void GuiDocument::loadModuleInfo()
3850 {
3851         moduleNames_.clear();
3852         LyXModuleList::const_iterator it  = theModuleList.begin();
3853         LyXModuleList::const_iterator end = theModuleList.end();
3854         for (; it != end; ++it) {
3855                 modInfoStruct m;
3856                 m.id = it->getID();
3857                 // FIXME Unicode
3858                 m.name = toqstr(translateIfPossible(from_utf8(it->getName())));
3859                 // this is supposed to give us the first sentence of the description
3860                 // FIXME Unicode
3861                 QString desc =
3862                         toqstr(translateIfPossible(from_utf8(it->getDescription())));
3863                 int const pos = desc.indexOf(".");
3864                 if (pos > 0)
3865                         desc.truncate(pos + 1);
3866                 m.description = desc;
3867                 if (it->category().substr(0, 8) != "Citation")
3868                         moduleNames_.push_back(m);
3869         }
3870 }
3871
3872
3873 void GuiDocument::updateUnknownBranches()
3874 {
3875         if (!bufferview())
3876                 return;
3877         list<docstring> used_branches;
3878         buffer().getUsedBranches(used_branches);
3879         list<docstring>::const_iterator it = used_branches.begin();
3880         QStringList unknown_branches;
3881         for (; it != used_branches.end() ; ++it) {
3882                 if (!buffer().params().branchlist().find(*it))
3883                         unknown_branches.append(toqstr(*it));
3884         }
3885         branchesModule->setUnknownBranches(unknown_branches);
3886 }
3887
3888
3889 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
3890 {
3891         map<docstring, docstring>::iterator it = changedBranches_.begin();
3892         for (; it != changedBranches_.end() ; ++it) {
3893                 if (it->second == oldname) {
3894                         // branch has already been renamed
3895                         it->second = newname;
3896                         return;
3897                 }
3898         }
3899         // store new name
3900         changedBranches_[oldname] = newname;
3901 }
3902
3903
3904 void GuiDocument::executeBranchRenaming() const
3905 {
3906         map<docstring, docstring>::const_iterator it = changedBranches_.begin();
3907         for (; it != changedBranches_.end() ; ++it) {
3908                 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
3909                 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
3910         }
3911 }
3912
3913
3914 void GuiDocument::allPackagesAuto()
3915 {
3916         allPackages(1);
3917 }
3918
3919
3920 void GuiDocument::allPackagesAlways()
3921 {
3922         allPackages(2);
3923 }
3924
3925
3926 void GuiDocument::allPackagesNot()
3927 {
3928         allPackages(3);
3929 }
3930
3931
3932 void GuiDocument::allPackages(int col)
3933 {
3934         for (int row = 0; row < mathsModule->packagesTW->rowCount(); ++row) {
3935                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, col);
3936                 rb->setChecked(true);
3937         }
3938 }
3939
3940
3941 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
3942
3943
3944 } // namespace frontend
3945 } // namespace lyx
3946
3947 #include "moc_GuiDocument.cpp"