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