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