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