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