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