]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiDocument.cpp
Fix copy-paste leftover
[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 UiWidget<Ui::FontUi>;
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         updateFontlist();
1779         // store default format
1780         QString const dformat = outputModule->defaultFormatCO->itemData(
1781                 outputModule->defaultFormatCO->currentIndex()).toString();
1782         updateDefaultFormat();
1783         // try to restore default format
1784         int index = outputModule->defaultFormatCO->findData(dformat);
1785         // set to default if format is not found
1786         if (index == -1)
1787                 index = 0;
1788         outputModule->defaultFormatCO->setCurrentIndex(index);
1789         langModule->encodingCO->setEnabled(tex_fonts &&
1790                 !langModule->defaultencodingRB->isChecked());
1791         langModule->defaultencodingRB->setEnabled(tex_fonts);
1792         langModule->otherencodingRB->setEnabled(tex_fonts);
1793
1794         fontModule->fontsDefaultCO->setEnabled(tex_fonts);
1795         fontModule->fontsDefaultLA->setEnabled(tex_fonts);
1796         fontModule->cjkFontLE->setEnabled(tex_fonts);
1797         fontModule->cjkFontLA->setEnabled(tex_fonts);
1798
1799         updateFontOptions();
1800
1801         fontModule->fontencLA->setEnabled(tex_fonts);
1802         fontModule->fontencCO->setEnabled(tex_fonts);
1803         if (!tex_fonts)
1804                 fontModule->fontencLE->setEnabled(false);
1805         else
1806                 fontencChanged(fontModule->fontencCO->currentIndex());
1807 }
1808
1809
1810 void GuiDocument::mathFontChanged(int)
1811 {
1812         updateFontOptions();
1813 }
1814
1815
1816 void GuiDocument::fontOsfToggled(bool state)
1817 {
1818         if (fontModule->osFontsCB->isChecked())
1819                 return;
1820         QString font = fontModule->fontsRomanCO->itemData(
1821                         fontModule->fontsRomanCO->currentIndex()).toString();
1822         if (hasMonolithicExpertSet(font))
1823                 fontModule->fontScCB->setChecked(state);
1824 }
1825
1826
1827 void GuiDocument::fontScToggled(bool state)
1828 {
1829         if (fontModule->osFontsCB->isChecked())
1830                 return;
1831         QString font = fontModule->fontsRomanCO->itemData(
1832                         fontModule->fontsRomanCO->currentIndex()).toString();
1833         if (hasMonolithicExpertSet(font))
1834                 fontModule->fontOsfCB->setChecked(state);
1835 }
1836
1837
1838 void GuiDocument::updateFontOptions()
1839 {
1840         bool const tex_fonts = !fontModule->osFontsCB->isChecked();
1841         QString font;
1842         if (tex_fonts)
1843                 font = fontModule->fontsSansCO->itemData(
1844                                 fontModule->fontsSansCO->currentIndex()).toString();
1845         bool scaleable = providesScale(font);
1846         fontModule->scaleSansSB->setEnabled(scaleable);
1847         fontModule->scaleSansLA->setEnabled(scaleable);
1848         if (tex_fonts)
1849                 font = fontModule->fontsTypewriterCO->itemData(
1850                                 fontModule->fontsTypewriterCO->currentIndex()).toString();
1851         scaleable = providesScale(font);
1852         fontModule->scaleTypewriterSB->setEnabled(scaleable);
1853         fontModule->scaleTypewriterLA->setEnabled(scaleable);
1854         if (tex_fonts)
1855                 font = fontModule->fontsRomanCO->itemData(
1856                                 fontModule->fontsRomanCO->currentIndex()).toString();
1857         fontModule->fontScCB->setEnabled(providesSC(font));
1858         fontModule->fontOsfCB->setEnabled(providesOSF(font));
1859         updateMathFonts(font);
1860 }
1861
1862
1863 void GuiDocument::updateFontsize(string const & items, string const & sel)
1864 {
1865         fontModule->fontsizeCO->clear();
1866         fontModule->fontsizeCO->addItem(qt_("Default"));
1867
1868         for (int n = 0; !token(items,'|',n).empty(); ++n)
1869                 fontModule->fontsizeCO->
1870                         addItem(toqstr(token(items,'|',n)));
1871
1872         for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
1873                 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
1874                         fontModule->fontsizeCO->setCurrentIndex(n);
1875                         break;
1876                 }
1877         }
1878 }
1879
1880
1881 bool GuiDocument::ot1() const
1882 {
1883         QString const fontenc =
1884                 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
1885         return (fontenc == "default"
1886                 || (fontenc == "global" && (lyxrc.fontenc == "default" || lyxrc.fontenc == "OT1"))
1887                 || (fontenc == "custom" && fontModule->fontencLE->text() == "OT1"));
1888 }
1889
1890
1891 bool GuiDocument::completeFontset() const
1892 {
1893         return (fontModule->fontsSansCO->itemData(
1894                         fontModule->fontsSansCO->currentIndex()).toString() == "default"
1895                 && fontModule->fontsSansCO->itemData(
1896                         fontModule->fontsTypewriterCO->currentIndex()).toString() == "default");
1897 }
1898
1899
1900 bool GuiDocument::noMathFont() const
1901 {
1902         return (fontModule->fontsMathCO->itemData(
1903                 fontModule->fontsMathCO->currentIndex()).toString() == "default");
1904 }
1905
1906
1907 void GuiDocument::updateTexFonts()
1908 {
1909         LaTeXFonts::TexFontMap texfontmap = theLaTeXFonts().getLaTeXFonts();
1910
1911         LaTeXFonts::TexFontMap::const_iterator it = texfontmap.begin();
1912         LaTeXFonts::TexFontMap::const_iterator end = texfontmap.end();
1913         for (; it != end; ++it) {
1914                 LaTeXFont lf = it->second;
1915                 if (lf.name().empty()) {
1916                         LYXERR0("Error: Unnamed font: " << it->first);
1917                         continue;
1918                 }
1919                 docstring const family = lf.family();
1920                 docstring guiname = translateIfPossible(lf.guiname());
1921                 if (!lf.available(ot1(), noMathFont()))
1922                         guiname += _(" (not installed)");
1923                 if (family == "rm")
1924                         rmfonts_.insert(toqstr(guiname), toqstr(it->first));
1925                 else if (family == "sf")
1926                         sffonts_.insert(toqstr(guiname), toqstr(it->first));
1927                 else if (family == "tt")
1928                         ttfonts_.insert(toqstr(guiname), toqstr(it->first));
1929                 else if (family == "math")
1930                         mathfonts_.insert(toqstr(guiname), toqstr(it->first));
1931         }
1932 }
1933
1934
1935 void GuiDocument::updateFontlist()
1936 {
1937         fontModule->fontsRomanCO->clear();
1938         fontModule->fontsSansCO->clear();
1939         fontModule->fontsTypewriterCO->clear();
1940         fontModule->fontsMathCO->clear();
1941
1942         // With fontspec (XeTeX, LuaTeX), we have access to all system fonts, but not the LaTeX fonts
1943         if (fontModule->osFontsCB->isChecked()) {
1944                 fontModule->fontsRomanCO->addItem(qt_("Default"), QString("default"));
1945                 fontModule->fontsSansCO->addItem(qt_("Default"), QString("default"));
1946                 fontModule->fontsTypewriterCO->addItem(qt_("Default"), QString("default"));
1947                 QString unimath = qt_("Non-TeX Fonts Default");
1948                 if (!LaTeXFeatures::isAvailable("unicode-math"))
1949                         unimath += qt_(" (not available)");
1950                 fontModule->fontsMathCO->addItem(qt_("Class Default (TeX Fonts)"), QString("auto"));
1951                 fontModule->fontsMathCO->addItem(unimath, QString("default"));
1952
1953                 QFontDatabase fontdb;
1954                 QStringList families(fontdb.families());
1955                 for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
1956                         fontModule->fontsRomanCO->addItem(*it, *it);
1957                         fontModule->fontsSansCO->addItem(*it, *it);
1958                         fontModule->fontsTypewriterCO->addItem(*it, *it);
1959                 }
1960                 return;
1961         }
1962
1963         if (rmfonts_.empty())
1964                 updateTexFonts();
1965
1966         fontModule->fontsRomanCO->addItem(qt_("Default"), QString("default"));
1967         QMap<QString, QString>::const_iterator rmi = rmfonts_.constBegin();
1968         while (rmi != rmfonts_.constEnd()) {
1969                 fontModule->fontsRomanCO->addItem(rmi.key(), rmi.value());
1970                 ++rmi;
1971         }
1972
1973         fontModule->fontsSansCO->addItem(qt_("Default"), QString("default"));
1974         QMap<QString, QString>::const_iterator sfi = sffonts_.constBegin();
1975         while (sfi != sffonts_.constEnd()) {
1976                 fontModule->fontsSansCO->addItem(sfi.key(), sfi.value());
1977                 ++sfi;
1978         }
1979
1980         fontModule->fontsTypewriterCO->addItem(qt_("Default"), QString("default"));
1981         QMap<QString, QString>::const_iterator tti = ttfonts_.constBegin();
1982         while (tti != ttfonts_.constEnd()) {
1983                 fontModule->fontsTypewriterCO->addItem(tti.key(), tti.value());
1984                 ++tti;
1985         }
1986
1987         fontModule->fontsMathCO->addItem(qt_("Automatic"), QString("auto"));
1988         fontModule->fontsMathCO->addItem(qt_("Class Default"), QString("default"));
1989         QMap<QString, QString>::const_iterator mmi = mathfonts_.constBegin();
1990         while (mmi != mathfonts_.constEnd()) {
1991                 fontModule->fontsMathCO->addItem(mmi.key(), mmi.value());
1992                 ++mmi;
1993         }
1994 }
1995
1996
1997 void GuiDocument::fontencChanged(int item)
1998 {
1999         fontModule->fontencLE->setEnabled(
2000                 fontModule->fontencCO->itemData(item).toString() == "custom");
2001         // The availability of TeX fonts depends on the font encoding
2002         updateTexFonts();
2003         updateFontOptions();
2004 }
2005
2006
2007 void GuiDocument::updateMathFonts(QString const & rm)
2008 {
2009         if (fontModule->osFontsCB->isChecked())
2010                 return;
2011         QString const math =
2012                 fontModule->fontsMathCO->itemData(fontModule->fontsMathCO->currentIndex()).toString();
2013         int const i = fontModule->fontsMathCO->findData("default");
2014         if (providesNoMath(rm) && i == -1)
2015                 fontModule->fontsMathCO->insertItem(1, qt_("Class Default"), QString("default"));
2016         else if (!providesNoMath(rm) && i != -1) {
2017                 int const c = fontModule->fontsMathCO->currentIndex();
2018                 fontModule->fontsMathCO->removeItem(i);
2019                 if (c == i)
2020                         fontModule->fontsMathCO->setCurrentIndex(0);
2021         }
2022 }
2023
2024
2025 void GuiDocument::romanChanged(int item)
2026 {
2027         if (fontModule->osFontsCB->isChecked())
2028                 return;
2029         QString const font =
2030                 fontModule->fontsRomanCO->itemData(item).toString();
2031         fontModule->fontScCB->setEnabled(providesSC(font));
2032         fontModule->fontOsfCB->setEnabled(providesOSF(font));
2033         updateMathFonts(font);
2034 }
2035
2036
2037 void GuiDocument::sansChanged(int item)
2038 {
2039         if (fontModule->osFontsCB->isChecked())
2040                 return;
2041         QString const font =
2042                 fontModule->fontsSansCO->itemData(item).toString();
2043         bool scaleable = providesScale(font);
2044         fontModule->scaleSansSB->setEnabled(scaleable);
2045         fontModule->scaleSansLA->setEnabled(scaleable);
2046 }
2047
2048
2049 void GuiDocument::ttChanged(int item)
2050 {
2051         if (fontModule->osFontsCB->isChecked())
2052                 return;
2053         QString const font =
2054                 fontModule->fontsTypewriterCO->itemData(item).toString();
2055         bool scaleable = providesScale(font);
2056         fontModule->scaleTypewriterSB->setEnabled(scaleable);
2057         fontModule->scaleTypewriterLA->setEnabled(scaleable);
2058 }
2059
2060
2061 void GuiDocument::updatePagestyle(string const & items, string const & sel)
2062 {
2063         pagestyles.clear();
2064         pageLayoutModule->pagestyleCO->clear();
2065         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
2066
2067         for (int n = 0; !token(items, '|', n).empty(); ++n) {
2068                 string style = token(items, '|', n);
2069                 QString style_gui = qt_(style);
2070                 pagestyles.push_back(pair<string, QString>(style, style_gui));
2071                 pageLayoutModule->pagestyleCO->addItem(style_gui);
2072         }
2073
2074         if (sel == "default") {
2075                 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
2076                 return;
2077         }
2078
2079         int nn = 0;
2080
2081         for (size_t i = 0; i < pagestyles.size(); ++i)
2082                 if (pagestyles[i].first == sel)
2083                         nn = pageLayoutModule->pagestyleCO->findText(pagestyles[i].second);
2084
2085         if (nn > 0)
2086                 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
2087 }
2088
2089
2090 void GuiDocument::browseLayout()
2091 {
2092         QString const label1 = qt_("Layouts|#o#O");
2093         QString const dir1 = toqstr(lyxrc.document_path);
2094         QStringList const filter(qt_("LyX Layout (*.layout)"));
2095         QString file = browseRelToParent(QString(), bufferFilePath(),
2096                 qt_("Local layout file"), filter, false,
2097                 label1, dir1);
2098
2099         if (!file.endsWith(".layout"))
2100                 return;
2101
2102         FileName layoutFile = support::makeAbsPath(fromqstr(file),
2103                 fromqstr(bufferFilePath()));
2104
2105         int const ret = Alert::prompt(_("Local layout file"),
2106                 _("The layout file you have selected is a local layout\n"
2107                   "file, not one in the system or user directory.\n"
2108                   "Your document will not work with this layout if you\n"
2109                   "move the layout file to a different directory."),
2110                   1, 1, _("&Set Layout"), _("&Cancel"));
2111         if (ret == 1)
2112                 return;
2113
2114         // load the layout file
2115         LayoutFileList & bcl = LayoutFileList::get();
2116         string classname = layoutFile.onlyFileName();
2117         // this will update an existing layout if that layout has been loaded before.
2118         LayoutFileIndex name = support::onlyFileName(bcl.addLocalLayout(
2119                 classname.substr(0, classname.size() - 7),
2120                 layoutFile.onlyPath().absFileName()));
2121
2122         if (name.empty()) {
2123                 Alert::error(_("Error"),
2124                         _("Unable to read local layout file."));
2125                 return;
2126         }
2127
2128         const_cast<Buffer &>(buffer()).setLayoutPos(layoutFile.onlyPath().absFileName());
2129
2130         // do not trigger classChanged if there is no change.
2131         if (latexModule->classCO->currentText() == toqstr(name))
2132                 return;
2133
2134         // add to combo box
2135         bool const avail = latexModule->classCO->set(toqstr(name));
2136         if (!avail) {
2137                 LayoutFile const & tc = bcl[name];
2138                 docstring const guiname = translateIfPossible(from_utf8(tc.description()));
2139                 // tooltip sensu "KOMA-Script Article [Class 'scrartcl']"
2140                 QString tooltip = toqstr(bformat(_("%1$s [Class '%2$s']"), guiname, from_utf8(tc.latexname())));
2141                 tooltip += '\n' + qt_("This is a local layout file.");
2142                 latexModule->classCO->addItemSort(toqstr(tc.name()), toqstr(guiname),
2143                                                   toqstr(translateIfPossible(from_utf8(tc.category()))),
2144                                                   tooltip,
2145                                                   true, true, true, true);
2146                 latexModule->classCO->set(toqstr(name));
2147         }
2148
2149         classChanged();
2150 }
2151
2152
2153 void GuiDocument::browseMaster()
2154 {
2155         QString const title = qt_("Select master document");
2156         QString const dir1 = toqstr(lyxrc.document_path);
2157         QString const old = latexModule->childDocLE->text();
2158         QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
2159         QStringList const filter(qt_("LyX Files (*.lyx)"));
2160         QString file = browseRelToSub(old, docpath, title, filter, false,
2161                 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
2162
2163         if (!file.isEmpty())
2164                 latexModule->childDocLE->setText(file);
2165 }
2166
2167
2168 void GuiDocument::classChanged_adaptor()
2169 {
2170         const_cast<Buffer &>(buffer()).setLayoutPos(string());
2171         classChanged();
2172 }
2173
2174
2175 void GuiDocument::classChanged()
2176 {
2177         int idx = latexModule->classCO->currentIndex();
2178         if (idx < 0)
2179                 return;
2180         string const classname = fromqstr(latexModule->classCO->getData(idx));
2181
2182         if (applyPB->isEnabled()) {
2183                 int const ret = Alert::prompt(_("Unapplied changes"),
2184                                 _("Some changes in the dialog were not yet applied.\n"
2185                                 "If you do not apply now, they will be lost after this action."),
2186                                 1, 1, _("&Apply"), _("&Dismiss"));
2187                 if (ret == 0)
2188                         applyView();
2189         }
2190
2191         // We load the TextClass as soon as it is selected. This is
2192         // necessary so that other options in the dialog can be updated
2193         // according to the new class. Note, however, that, if you use
2194         // the scroll wheel when sitting on the combo box, we'll load a
2195         // lot of TextClass objects very quickly....
2196         if (!bp_.setBaseClass(classname)) {
2197                 Alert::error(_("Error"), _("Unable to set document class."));
2198                 return;
2199         }
2200         if (lyxrc.auto_reset_options)
2201                 bp_.useClassDefaults();
2202
2203         // With the introduction of modules came a distinction between the base
2204         // class and the document class. The former corresponds to the main layout
2205         // file; the latter is that plus the modules (or the document-specific layout,
2206         // or  whatever else there could be). Our parameters come from the document
2207         // class. So when we set the base class, we also need to recreate the document
2208         // class. Otherwise, we still have the old one.
2209         bp_.makeDocumentClass();
2210         paramsToDialog();
2211 }
2212
2213
2214 void GuiDocument::languagePackageChanged(int i)
2215 {
2216          langModule->languagePackageLE->setEnabled(
2217                 langModule->languagePackageCO->itemData(i).toString() == "custom");
2218 }
2219
2220
2221 void GuiDocument::biblioChanged()
2222 {
2223         biblioChanged_ = true;
2224         change_adaptor();
2225 }
2226
2227
2228 void GuiDocument::bibtexChanged(int n)
2229 {
2230         biblioModule->bibtexOptionsLE->setEnabled(
2231                 biblioModule->bibtexCO->itemData(n).toString() != "default");
2232         biblioChanged();
2233 }
2234
2235
2236 void GuiDocument::setAuthorYear(bool authoryear)
2237 {
2238         if (authoryear)
2239                 biblioModule->citeStyleCO->setCurrentIndex(0);
2240         biblioChanged();
2241 }
2242
2243
2244 void GuiDocument::setNumerical(bool numerical)
2245 {
2246         if (numerical)
2247                 biblioModule->citeStyleCO->setCurrentIndex(1);
2248         biblioChanged();
2249 }
2250
2251
2252 void GuiDocument::updateEngineType(string const & items, CiteEngineType const & sel)
2253 {
2254         engine_types_.clear();
2255
2256         int nn = 0;
2257
2258         for (int n = 0; !token(items, '|', n).empty(); ++n) {
2259                 nn += 1;
2260                 string style = token(items, '|', n);
2261                 engine_types_.push_back(style);
2262         }
2263
2264         switch (sel) {
2265                 case ENGINE_TYPE_AUTHORYEAR:
2266                         biblioModule->citeStyleCO->setCurrentIndex(0);
2267                         break;
2268                 case ENGINE_TYPE_NUMERICAL:
2269                 case ENGINE_TYPE_DEFAULT:
2270                         biblioModule->citeStyleCO->setCurrentIndex(1);
2271                         break;
2272         }
2273
2274         biblioModule->citationStyleL->setEnabled(nn > 1);
2275         biblioModule->citeStyleCO->setEnabled(nn > 1);
2276
2277         if (nn != 1)
2278                 return;
2279
2280         // If the textclass allows only one of authoryear or numerical,
2281         // we have no choice but to force that engine type.
2282         if (engine_types_[0] == "authoryear")
2283                 biblioModule->citeStyleCO->setCurrentIndex(0);
2284         else
2285                 biblioModule->citeStyleCO->setCurrentIndex(1);
2286 }
2287
2288
2289 namespace {
2290         // FIXME unicode
2291         // both of these should take a vector<docstring>
2292
2293         // This is an insanely complicated attempt to make this sort of thing
2294         // work with RTL languages.
2295         docstring formatStrVec(vector<string> const & v, docstring const & s)
2296         {
2297                 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
2298                 if (v.empty())
2299                         return docstring();
2300                 if (v.size() == 1)
2301                         return translateIfPossible(from_utf8(v[0]));
2302                 if (v.size() == 2) {
2303                         docstring retval = _("%1$s and %2$s");
2304                         retval = subst(retval, _("and"), s);
2305                         return bformat(retval, translateIfPossible(from_utf8(v[0])),
2306                                        translateIfPossible(from_utf8(v[1])));
2307                 }
2308                 // The idea here is to format all but the last two items...
2309                 int const vSize = v.size();
2310                 docstring t2 = _("%1$s, %2$s");
2311                 docstring retval = translateIfPossible(from_utf8(v[0]));
2312                 for (int i = 1; i < vSize - 2; ++i)
2313                         retval = bformat(t2, retval, translateIfPossible(from_utf8(v[i])));
2314                 //...and then to  plug them, and the last two, into this schema
2315                 docstring t = _("%1$s, %2$s, and %3$s");
2316                 t = subst(t, _("and"), s);
2317                 return bformat(t, retval, translateIfPossible(from_utf8(v[vSize - 2])),
2318                                translateIfPossible(from_utf8(v[vSize - 1])));
2319         }
2320
2321         vector<string> idsToNames(vector<string> const & idList)
2322         {
2323                 vector<string> retval;
2324                 vector<string>::const_iterator it  = idList.begin();
2325                 vector<string>::const_iterator end = idList.end();
2326                 for (; it != end; ++it) {
2327                         LyXModule const * const mod = theModuleList[*it];
2328                         if (!mod)
2329                                 retval.push_back(to_utf8(bformat(_("%1$s (unavailable)"),
2330                                                 translateIfPossible(from_utf8(*it)))));
2331                         else
2332                                 retval.push_back(mod->getName());
2333                 }
2334                 return retval;
2335         }
2336 } // end anonymous namespace
2337
2338
2339 void GuiDocument::modulesToParams(BufferParams & bp)
2340 {
2341         // update list of loaded modules
2342         bp.clearLayoutModules();
2343         int const srows = modules_sel_model_.rowCount();
2344         for (int i = 0; i < srows; ++i)
2345                 bp.addLayoutModule(modules_sel_model_.getIDString(i));
2346
2347         // update the list of removed modules
2348         bp.clearRemovedModules();
2349         LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
2350         list<string>::const_iterator rit = reqmods.begin();
2351         list<string>::const_iterator ren = reqmods.end();
2352
2353         // check each of the default modules
2354         for (; rit != ren; ++rit) {
2355                 list<string>::const_iterator mit = bp.getModules().begin();
2356                 list<string>::const_iterator men = bp.getModules().end();
2357                 bool found = false;
2358                 for (; mit != men; ++mit) {
2359                         if (*rit == *mit) {
2360                                 found = true;
2361                                 break;
2362                         }
2363                 }
2364                 if (!found) {
2365                         // the module isn't present so must have been removed by the user
2366                         bp.addRemovedModule(*rit);
2367                 }
2368         }
2369 }
2370
2371 void GuiDocument::modulesChanged()
2372 {
2373         modulesToParams(bp_);
2374
2375         if (applyPB->isEnabled() && nonModuleChanged_) {
2376                 int const ret = Alert::prompt(_("Unapplied changes"),
2377                                 _("Some changes in the dialog were not yet applied.\n"
2378                                 "If you do not apply now, they will be lost after this action."),
2379                                 1, 1, _("&Apply"), _("&Dismiss"));
2380                 if (ret == 0)
2381                         applyView();
2382         }
2383
2384         bp_.makeDocumentClass();
2385         paramsToDialog();
2386         changed();
2387 }
2388
2389
2390 void GuiDocument::updateModuleInfo()
2391 {
2392         selectionManager->update();
2393
2394         //Module description
2395         bool const focus_on_selected = selectionManager->selectedFocused();
2396         QAbstractItemView * lv;
2397         if (focus_on_selected)
2398                 lv = modulesModule->selectedLV;
2399         else
2400                 lv = modulesModule->availableLV;
2401         if (lv->selectionModel()->selectedIndexes().isEmpty()) {
2402                 modulesModule->infoML->document()->clear();
2403                 return;
2404         }
2405         QModelIndex const & idx = lv->selectionModel()->currentIndex();
2406         GuiIdListModel const & id_model =
2407                         focus_on_selected  ? modules_sel_model_ : modules_av_model_;
2408         string const modName = id_model.getIDString(idx.row());
2409         docstring desc = getModuleDescription(modName);
2410
2411         LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
2412         if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
2413                 if (!desc.empty())
2414                         desc += "\n";
2415                 desc += _("Module provided by document class.");
2416         }
2417
2418         docstring cat = getModuleCategory(modName);
2419         if (!cat.empty()) {
2420                 if (!desc.empty())
2421                         desc += "\n";
2422                 desc += bformat(_("Category: %1$s."), cat);
2423         }
2424
2425         vector<string> pkglist = getPackageList(modName);
2426         docstring pkgdesc = formatStrVec(pkglist, _("and"));
2427         if (!pkgdesc.empty()) {
2428                 if (!desc.empty())
2429                         desc += "\n";
2430                 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
2431         }
2432
2433         pkglist = getRequiredList(modName);
2434         if (!pkglist.empty()) {
2435                 vector<string> const reqdescs = idsToNames(pkglist);
2436                 pkgdesc = formatStrVec(reqdescs, _("or"));
2437                 if (!desc.empty())
2438                         desc += "\n";
2439                 desc += bformat(_("Modules required: %1$s."), pkgdesc);
2440         }
2441
2442         pkglist = getExcludedList(modName);
2443         if (!pkglist.empty()) {
2444                 vector<string> const reqdescs = idsToNames(pkglist);
2445                 pkgdesc = formatStrVec(reqdescs, _( "and"));
2446                 if (!desc.empty())
2447                         desc += "\n";
2448                 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
2449         }
2450
2451         if (!isModuleAvailable(modName)) {
2452                 if (!desc.empty())
2453                         desc += "\n";
2454                 desc += _("WARNING: Some required packages are unavailable!");
2455         }
2456
2457         modulesModule->infoML->document()->setPlainText(toqstr(desc));
2458 }
2459
2460
2461 void GuiDocument::updateNumbering()
2462 {
2463         DocumentClass const & tclass = documentClass();
2464
2465         numberingModule->tocTW->setUpdatesEnabled(false);
2466         numberingModule->tocTW->clear();
2467
2468         int const depth = numberingModule->depthSL->value();
2469         int const toc = numberingModule->tocSL->value();
2470         QString const no = qt_("No");
2471         QString const yes = qt_("Yes");
2472         QTreeWidgetItem * item = 0;
2473
2474         DocumentClass::const_iterator lit = tclass.begin();
2475         DocumentClass::const_iterator len = tclass.end();
2476         for (; lit != len; ++lit) {
2477                 int const toclevel = lit->toclevel;
2478                 if (toclevel != Layout::NOT_IN_TOC && !lit->counter.empty()) {
2479                         item = new QTreeWidgetItem(numberingModule->tocTW);
2480                         item->setText(0, toqstr(translateIfPossible(lit->name())));
2481                         item->setText(1, (toclevel <= depth) ? yes : no);
2482                         item->setText(2, (toclevel <= toc) ? yes : no);
2483                 }
2484         }
2485
2486         numberingModule->tocTW->setUpdatesEnabled(true);
2487         numberingModule->tocTW->update();
2488 }
2489
2490
2491 void GuiDocument::updateDefaultFormat()
2492 {
2493         if (!bufferview())
2494                 return;
2495         // make a copy in order to consider unapplied changes
2496         BufferParams param_copy = buffer().params();
2497         param_copy.useNonTeXFonts = fontModule->osFontsCB->isChecked();
2498         int const idx = latexModule->classCO->currentIndex();
2499         if (idx >= 0) {
2500                 string const classname = fromqstr(latexModule->classCO->getData(idx));
2501                 param_copy.setBaseClass(classname);
2502                 param_copy.makeDocumentClass(true);
2503         }
2504         outputModule->defaultFormatCO->blockSignals(true);
2505         outputModule->defaultFormatCO->clear();
2506         outputModule->defaultFormatCO->addItem(qt_("Default"),
2507                                 QVariant(QString("default")));
2508         typedef vector<Format const *> Formats;
2509         Formats formats = param_copy.exportableFormats(true);
2510         sort(formats.begin(), formats.end(), Format::formatSorter);
2511         Formats::const_iterator cit = formats.begin();
2512         Formats::const_iterator end = formats.end();
2513         for (; cit != end; ++cit)
2514                 outputModule->defaultFormatCO->addItem(qt_((*cit)->prettyname()),
2515                                 QVariant(toqstr((*cit)->name())));
2516         outputModule->defaultFormatCO->blockSignals(false);
2517 }
2518
2519
2520 bool GuiDocument::isChildIncluded(string const & child)
2521 {
2522         if (includeonlys_.empty())
2523                 return false;
2524         return (std::find(includeonlys_.begin(),
2525                           includeonlys_.end(), child) != includeonlys_.end());
2526 }
2527
2528
2529 void GuiDocument::applyView()
2530 {
2531         // preamble
2532         preambleModule->apply(bp_);
2533         localLayout->apply(bp_);
2534
2535         // date
2536         bp_.suppress_date = latexModule->suppressDateCB->isChecked();
2537         bp_.use_refstyle  = latexModule->refstyleCB->isChecked();
2538
2539         // biblio
2540         if (biblioModule->citeNatbibRB->isChecked())
2541                 bp_.setCiteEngine("natbib");
2542         else if (biblioModule->citeJurabibRB->isChecked())
2543                 bp_.setCiteEngine("jurabib");
2544         if (biblioModule->citeDefaultRB->isChecked()) {
2545                 bp_.setCiteEngine("basic");
2546                 bp_.setCiteEngineType(ENGINE_TYPE_DEFAULT);
2547         }
2548         else
2549         if (biblioModule->citeStyleCO->currentIndex())
2550                 bp_.setCiteEngineType(ENGINE_TYPE_NUMERICAL);
2551         else
2552                 bp_.setCiteEngineType(ENGINE_TYPE_AUTHORYEAR);
2553
2554         bp_.use_bibtopic =
2555                 biblioModule->bibtopicCB->isChecked();
2556
2557         bp_.biblio_style = fromqstr(biblioModule->bibtexStyleLE->text());
2558
2559         string const bibtex_command =
2560                 fromqstr(biblioModule->bibtexCO->itemData(
2561                         biblioModule->bibtexCO->currentIndex()).toString());
2562         string const bibtex_options =
2563                 fromqstr(biblioModule->bibtexOptionsLE->text());
2564         if (bibtex_command == "default" || bibtex_options.empty())
2565                 bp_.bibtex_command = bibtex_command;
2566         else
2567                 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
2568
2569         if (biblioChanged_) {
2570                 buffer().invalidateBibinfoCache();
2571                 buffer().removeBiblioTempFiles();
2572         }
2573
2574         // Indices
2575         indicesModule->apply(bp_);
2576
2577         // language & quotes
2578         if (langModule->defaultencodingRB->isChecked()) {
2579                 bp_.inputenc = "auto";
2580         } else {
2581                 int i = langModule->encodingCO->currentIndex();
2582                 if (i == 0)
2583                         bp_.inputenc = "default";
2584                 else {
2585                         QString const enc_gui =
2586                                 langModule->encodingCO->currentText();
2587                         Encodings::const_iterator it = encodings.begin();
2588                         Encodings::const_iterator const end = encodings.end();
2589                         bool found = false;
2590                         for (; it != end; ++it) {
2591                                 if (qt_(it->guiName()) == enc_gui &&
2592                                     !it->unsafe()) {
2593                                         bp_.inputenc = it->name();
2594                                         found = true;
2595                                         break;
2596                                 }
2597                         }
2598                         if (!found) {
2599                                 // should not happen
2600                                 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
2601                                 bp_.inputenc = "default";
2602                         }
2603                 }
2604         }
2605
2606         bp_.quotes_language = (InsetQuotes::QuoteLanguage) langModule->quoteStyleCO->itemData(
2607                 langModule->quoteStyleCO->currentIndex()).toInt();
2608
2609         QString const langname = langModule->languageCO->itemData(
2610                 langModule->languageCO->currentIndex()).toString();
2611         Language const * newlang = lyx::languages.getLanguage(fromqstr(langname));
2612         Cursor & cur = const_cast<BufferView *>(bufferview())->cursor();
2613         // If current cursor language was the document language, then update it too.
2614         if (cur.current_font.language() == bp_.language) {
2615                 cur.current_font.setLanguage(newlang);
2616                 cur.real_current_font.setLanguage(newlang);
2617         }
2618         bp_.language = newlang;
2619
2620         QString const pack = langModule->languagePackageCO->itemData(
2621                 langModule->languagePackageCO->currentIndex()).toString();
2622         if (pack == "custom")
2623                 bp_.lang_package =
2624                         fromqstr(langModule->languagePackageLE->text());
2625         else
2626                 bp_.lang_package = fromqstr(pack);
2627
2628         //color
2629         bp_.backgroundcolor = set_backgroundcolor;
2630         bp_.isbackgroundcolor = is_backgroundcolor;
2631         bp_.fontcolor = set_fontcolor;
2632         bp_.isfontcolor = is_fontcolor;
2633         bp_.notefontcolor = set_notefontcolor;
2634         bp_.boxbgcolor = set_boxbgcolor;
2635
2636         // numbering
2637         if (bp_.documentClass().hasTocLevels()) {
2638                 bp_.tocdepth = numberingModule->tocSL->value();
2639                 bp_.secnumdepth = numberingModule->depthSL->value();
2640         }
2641
2642         // bullets
2643         bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
2644         bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
2645         bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
2646         bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
2647
2648         // packages
2649         bp_.graphics_driver =
2650                 tex_graphics[latexModule->psdriverCO->currentIndex()];
2651
2652         // text layout
2653         int idx = latexModule->classCO->currentIndex();
2654         if (idx >= 0) {
2655                 string const classname = fromqstr(latexModule->classCO->getData(idx));
2656                 bp_.setBaseClass(classname);
2657         }
2658
2659         // Modules
2660         modulesToParams(bp_);
2661
2662         // Math
2663         map<string, string> const & packages = BufferParams::auto_packages();
2664         for (map<string, string>::const_iterator it = packages.begin();
2665              it != packages.end(); ++it) {
2666                 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
2667                 if (!item)
2668                         continue;
2669                 int row = mathsModule->packagesTW->row(item);
2670                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1);
2671                 if (rb->isChecked()) {
2672                         bp_.use_package(it->first, BufferParams::package_auto);
2673                         continue;
2674                 }
2675                 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2);
2676                 if (rb->isChecked()) {
2677                         bp_.use_package(it->first, BufferParams::package_on);
2678                         continue;
2679                 }
2680                 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3);
2681                 if (rb->isChecked())
2682                         bp_.use_package(it->first, BufferParams::package_off);
2683         }
2684
2685         // Page Layout
2686         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
2687                 bp_.pagestyle = "default";
2688         else {
2689                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
2690                 for (size_t i = 0; i != pagestyles.size(); ++i)
2691                         if (pagestyles[i].second == style_gui)
2692                                 bp_.pagestyle = pagestyles[i].first;
2693         }
2694
2695         // Text Layout
2696         switch (textLayoutModule->lspacingCO->currentIndex()) {
2697         case 0:
2698                 bp_.spacing().set(Spacing::Single);
2699                 break;
2700         case 1:
2701                 bp_.spacing().set(Spacing::Onehalf);
2702                 break;
2703         case 2:
2704                 bp_.spacing().set(Spacing::Double);
2705                 break;
2706         case 3: {
2707                 string s = widgetToDoubleStr(textLayoutModule->lspacingLE);
2708                 if (s.empty())
2709                         bp_.spacing().set(Spacing::Single);
2710                 else
2711                         bp_.spacing().set(Spacing::Other, s);
2712                 break;
2713                 }
2714         }
2715
2716         if (textLayoutModule->twoColumnCB->isChecked())
2717                 bp_.columns = 2;
2718         else
2719                 bp_.columns = 1;
2720
2721         bp_.justification = textLayoutModule->justCB->isChecked();
2722
2723         if (textLayoutModule->indentRB->isChecked()) {
2724                 // if paragraphs are separated by an indentation
2725                 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
2726                 switch (textLayoutModule->indentCO->currentIndex()) {
2727                 case 0:
2728                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2729                         break;
2730                 case 1: {
2731                         HSpace indent = HSpace(
2732                                 widgetsToLength(textLayoutModule->indentLE,
2733                                 textLayoutModule->indentLengthCO)
2734                                 );
2735                         bp_.setIndentation(indent);
2736                         break;
2737                         }
2738                 default:
2739                         // this should never happen
2740                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2741                         break;
2742                 }
2743         } else {
2744                 // if paragraphs are separated by a skip
2745                 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
2746                 switch (textLayoutModule->skipCO->currentIndex()) {
2747                 case 0:
2748                         bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
2749                         break;
2750                 case 1:
2751                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2752                         break;
2753                 case 2:
2754                         bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
2755                         break;
2756                 case 3:
2757                         {
2758                         VSpace vs = VSpace(
2759                                 widgetsToLength(textLayoutModule->skipLE,
2760                                 textLayoutModule->skipLengthCO)
2761                                 );
2762                         bp_.setDefSkip(vs);
2763                         break;
2764                         }
2765                 default:
2766                         // this should never happen
2767                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2768                         break;
2769                 }
2770         }
2771
2772         bp_.options =
2773                 fromqstr(latexModule->optionsLE->text());
2774
2775         bp_.use_default_options =
2776                 latexModule->defaultOptionsCB->isChecked();
2777
2778         if (latexModule->childDocGB->isChecked())
2779                 bp_.master =
2780                         fromqstr(latexModule->childDocLE->text());
2781         else
2782                 bp_.master = string();
2783
2784         // Master/Child
2785         bp_.clearIncludedChildren();
2786         if (masterChildModule->includeonlyRB->isChecked()) {
2787                 list<string>::const_iterator it = includeonlys_.begin();
2788                 for (; it != includeonlys_.end() ; ++it) {
2789                         bp_.addIncludedChildren(*it);
2790                 }
2791         }
2792         bp_.maintain_unincluded_children =
2793                 masterChildModule->maintainAuxCB->isChecked();
2794
2795         // Float Placement
2796         bp_.float_placement = floatModule->get();
2797
2798         // Listings
2799         // text should have passed validation
2800         bp_.listings_params =
2801                 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
2802
2803         // output
2804         bp_.default_output_format = fromqstr(outputModule->defaultFormatCO->itemData(
2805                 outputModule->defaultFormatCO->currentIndex()).toString());
2806
2807         bool const nontexfonts = fontModule->osFontsCB->isChecked();
2808         bp_.useNonTeXFonts = nontexfonts;
2809
2810         bp_.output_sync = outputModule->outputsyncCB->isChecked();
2811
2812         bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
2813
2814         int mathfmt = outputModule->mathoutCB->currentIndex();
2815         if (mathfmt == -1)
2816                 mathfmt = 0;
2817         BufferParams::MathOutput const mo =
2818                 static_cast<BufferParams::MathOutput>(mathfmt);
2819         bp_.html_math_output = mo;
2820         bp_.html_be_strict = outputModule->strictCB->isChecked();
2821         bp_.html_css_as_file = outputModule->cssCB->isChecked();
2822         bp_.html_math_img_scale = outputModule->mathimgSB->value();
2823         bp_.display_pixel_ratio = theGuiApp()->pixelRatio();
2824
2825         // fonts
2826         bp_.fonts_roman =
2827                 fromqstr(fontModule->fontsRomanCO->
2828                         itemData(fontModule->fontsRomanCO->currentIndex()).toString());
2829
2830         bp_.fonts_sans =
2831                 fromqstr(fontModule->fontsSansCO->
2832                         itemData(fontModule->fontsSansCO->currentIndex()).toString());
2833
2834         bp_.fonts_typewriter =
2835                 fromqstr(fontModule->fontsTypewriterCO->
2836                         itemData(fontModule->fontsTypewriterCO->currentIndex()).toString());
2837
2838         bp_.fonts_math =
2839                 fromqstr(fontModule->fontsMathCO->
2840                         itemData(fontModule->fontsMathCO->currentIndex()).toString());
2841
2842         QString const fontenc =
2843                 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
2844         if (fontenc == "custom")
2845                 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
2846         else
2847                 bp_.fontenc = fromqstr(fontenc);
2848
2849         bp_.fonts_cjk =
2850                 fromqstr(fontModule->cjkFontLE->text());
2851
2852         bp_.fonts_sans_scale = fontModule->scaleSansSB->value();
2853
2854         bp_.fonts_typewriter_scale = fontModule->scaleTypewriterSB->value();
2855
2856         bp_.fonts_expert_sc = fontModule->fontScCB->isChecked();
2857
2858         bp_.fonts_old_figures = fontModule->fontOsfCB->isChecked();
2859
2860         if (nontexfonts)
2861                 bp_.fonts_default_family = "default";
2862         else
2863                 bp_.fonts_default_family = GuiDocument::fontfamilies[
2864                         fontModule->fontsDefaultCO->currentIndex()];
2865
2866         if (fontModule->fontsizeCO->currentIndex() == 0)
2867                 bp_.fontsize = "default";
2868         else
2869                 bp_.fontsize =
2870                         fromqstr(fontModule->fontsizeCO->currentText());
2871
2872         // paper
2873         bp_.papersize = PAPER_SIZE(
2874                 pageLayoutModule->papersizeCO->currentIndex());
2875
2876         bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
2877                 pageLayoutModule->paperwidthUnitCO);
2878
2879         bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
2880                 pageLayoutModule->paperheightUnitCO);
2881
2882         if (pageLayoutModule->facingPagesCB->isChecked())
2883                 bp_.sides = TwoSides;
2884         else
2885                 bp_.sides = OneSide;
2886
2887         if (pageLayoutModule->landscapeRB->isChecked())
2888                 bp_.orientation = ORIENTATION_LANDSCAPE;
2889         else
2890                 bp_.orientation = ORIENTATION_PORTRAIT;
2891
2892         // margins
2893         bp_.use_geometry = !marginsModule->marginCB->isChecked();
2894
2895         Ui::MarginsUi const * m = marginsModule;
2896
2897         bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
2898         bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
2899         bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
2900         bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
2901         bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
2902         bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
2903         bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
2904         bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
2905
2906         // branches
2907         branchesModule->apply(bp_);
2908
2909         // PDF support
2910         PDFOptions & pdf = bp_.pdfoptions();
2911         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
2912         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
2913         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
2914         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
2915         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
2916
2917         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
2918         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
2919         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
2920         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
2921
2922         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
2923         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
2924         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
2925         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
2926         pdf.backref =
2927                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
2928         if (pdfSupportModule->fullscreenCB->isChecked())
2929                 pdf.pagemode = pdf.pagemode_fullscreen;
2930         else
2931                 pdf.pagemode.clear();
2932         pdf.quoted_options = pdf.quoted_options_check(
2933                                 fromqstr(pdfSupportModule->optionsLE->text()));
2934
2935         // reset tracker
2936         nonModuleChanged_ = false;
2937 }
2938
2939
2940 void GuiDocument::paramsToDialog()
2941 {
2942         // set the default unit
2943         Length::UNIT const default_unit = Length::defaultUnit();
2944
2945         // preamble
2946         preambleModule->update(bp_, id());
2947         localLayout->update(bp_, id());
2948
2949         // date
2950         latexModule->suppressDateCB->setChecked(bp_.suppress_date);
2951         latexModule->refstyleCB->setChecked(bp_.use_refstyle);
2952
2953         // biblio
2954         string const cite_engine = bp_.citeEngine().list().front();
2955
2956         biblioModule->citeDefaultRB->setChecked(
2957                 cite_engine == "basic");
2958
2959         biblioModule->citeJurabibRB->setChecked(
2960                 cite_engine == "jurabib");
2961
2962         biblioModule->citeNatbibRB->setChecked(
2963                 cite_engine == "natbib");
2964
2965         biblioModule->citeStyleCO->setCurrentIndex(
2966                 bp_.citeEngineType() & ENGINE_TYPE_NUMERICAL);
2967
2968         updateEngineType(documentClass().opt_enginetype(),
2969                 bp_.citeEngineType());
2970
2971         biblioModule->bibtopicCB->setChecked(
2972                 bp_.use_bibtopic);
2973
2974         biblioModule->bibtexStyleLE->setText(toqstr(bp_.biblio_style));
2975
2976         string command;
2977         string options =
2978                 split(bp_.bibtex_command, command, ' ');
2979
2980         int const bpos = biblioModule->bibtexCO->findData(toqstr(command));
2981         if (bpos != -1) {
2982                 biblioModule->bibtexCO->setCurrentIndex(bpos);
2983                 biblioModule->bibtexOptionsLE->setText(toqstr(options).trimmed());
2984         } else {
2985                 // We reset to default if we do not know the specified compiler
2986                 // This is for security reasons
2987                 biblioModule->bibtexCO->setCurrentIndex(
2988                         biblioModule->bibtexCO->findData(toqstr("default")));
2989                 biblioModule->bibtexOptionsLE->clear();
2990         }
2991         biblioModule->bibtexOptionsLE->setEnabled(
2992                 biblioModule->bibtexCO->currentIndex() != 0);
2993
2994         biblioChanged_ = false;
2995
2996         // indices
2997         indicesModule->update(bp_, buffer().isReadonly());
2998
2999         // language & quotes
3000         int const pos = langModule->languageCO->findData(toqstr(
3001                 bp_.language->lang()));
3002         langModule->languageCO->setCurrentIndex(pos);
3003
3004         langModule->quoteStyleCO->setCurrentIndex(
3005                 bp_.quotes_language);
3006
3007         bool default_enc = true;
3008         if (bp_.inputenc != "auto") {
3009                 default_enc = false;
3010                 if (bp_.inputenc == "default") {
3011                         langModule->encodingCO->setCurrentIndex(0);
3012                 } else {
3013                         string enc_gui;
3014                         Encodings::const_iterator it = encodings.begin();
3015                         Encodings::const_iterator const end = encodings.end();
3016                         for (; it != end; ++it) {
3017                                 if (it->name() == bp_.inputenc &&
3018                                     !it->unsafe()) {
3019                                         enc_gui = it->guiName();
3020                                         break;
3021                                 }
3022                         }
3023                         int const i = langModule->encodingCO->findText(
3024                                         qt_(enc_gui));
3025                         if (i >= 0)
3026                                 langModule->encodingCO->setCurrentIndex(i);
3027                         else
3028                                 // unknown encoding. Set to default.
3029                                 default_enc = true;
3030                 }
3031         }
3032         langModule->defaultencodingRB->setChecked(default_enc);
3033         langModule->otherencodingRB->setChecked(!default_enc);
3034
3035         int const p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
3036         if (p == -1) {
3037                 langModule->languagePackageCO->setCurrentIndex(
3038                           langModule->languagePackageCO->findData("custom"));
3039                 langModule->languagePackageLE->setText(toqstr(bp_.lang_package));
3040         } else {
3041                 langModule->languagePackageCO->setCurrentIndex(p);
3042                 langModule->languagePackageLE->clear();
3043         }
3044
3045         //color
3046         if (bp_.isfontcolor) {
3047                 colorModule->fontColorPB->setStyleSheet(
3048                         colorButtonStyleSheet(rgb2qcolor(bp_.fontcolor)));
3049         }
3050         set_fontcolor = bp_.fontcolor;
3051         is_fontcolor = bp_.isfontcolor;
3052
3053         colorModule->noteFontColorPB->setStyleSheet(
3054                 colorButtonStyleSheet(rgb2qcolor(bp_.notefontcolor)));
3055         set_notefontcolor = bp_.notefontcolor;
3056
3057         if (bp_.isbackgroundcolor) {
3058                 colorModule->backgroundPB->setStyleSheet(
3059                         colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
3060         }
3061         set_backgroundcolor = bp_.backgroundcolor;
3062         is_backgroundcolor = bp_.isbackgroundcolor;
3063
3064         colorModule->boxBackgroundPB->setStyleSheet(
3065                 colorButtonStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
3066         set_boxbgcolor = bp_.boxbgcolor;
3067
3068         // numbering
3069         int const min_toclevel = documentClass().min_toclevel();
3070         int const max_toclevel = documentClass().max_toclevel();
3071         if (documentClass().hasTocLevels()) {
3072                 numberingModule->setEnabled(true);
3073                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
3074                 numberingModule->depthSL->setMaximum(max_toclevel);
3075                 numberingModule->depthSL->setValue(bp_.secnumdepth);
3076                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
3077                 numberingModule->tocSL->setMaximum(max_toclevel);
3078                 numberingModule->tocSL->setValue(bp_.tocdepth);
3079                 updateNumbering();
3080         } else {
3081                 numberingModule->setEnabled(false);
3082                 numberingModule->tocTW->clear();
3083         }
3084
3085         // bullets
3086         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
3087         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
3088         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
3089         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
3090         bulletsModule->init();
3091
3092         // packages
3093         int nitem = findToken(tex_graphics, bp_.graphics_driver);
3094         if (nitem >= 0)
3095                 latexModule->psdriverCO->setCurrentIndex(nitem);
3096         updateModuleInfo();
3097
3098         map<string, string> const & packages = BufferParams::auto_packages();
3099         for (map<string, string>::const_iterator it = packages.begin();
3100              it != packages.end(); ++it) {
3101                 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
3102                 if (!item)
3103                         continue;
3104                 int row = mathsModule->packagesTW->row(item);
3105                 switch (bp_.use_package(it->first)) {
3106                         case BufferParams::package_off: {
3107                                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3);
3108                                 rb->setChecked(true);
3109                                 break;
3110                         }
3111                         case BufferParams::package_on: {
3112                                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2);
3113                                 rb->setChecked(true);
3114                                 break;
3115                         }
3116                         case BufferParams::package_auto: {
3117                                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1);
3118                                 rb->setChecked(true);
3119                                 break;
3120                         }
3121                 }
3122         }
3123
3124         switch (bp_.spacing().getSpace()) {
3125                 case Spacing::Other: nitem = 3; break;
3126                 case Spacing::Double: nitem = 2; break;
3127                 case Spacing::Onehalf: nitem = 1; break;
3128                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
3129         }
3130
3131         // text layout
3132         string const & layoutID = bp_.baseClassID();
3133         setLayoutComboByIDString(layoutID);
3134
3135         updatePagestyle(documentClass().opt_pagestyle(),
3136                                  bp_.pagestyle);
3137
3138         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
3139         if (bp_.spacing().getSpace() == Spacing::Other) {
3140                 doubleToWidget(textLayoutModule->lspacingLE,
3141                         bp_.spacing().getValueAsString());
3142         }
3143         setLSpacing(nitem);
3144
3145         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
3146                 textLayoutModule->indentRB->setChecked(true);
3147                 string indentation = bp_.getIndentation().asLyXCommand();
3148                 int indent = 0;
3149                 if (indentation != "default") {
3150                         lengthToWidgets(textLayoutModule->indentLE,
3151                         textLayoutModule->indentLengthCO,
3152                         indentation, default_unit);
3153                         indent = 1;
3154                 }
3155                 textLayoutModule->indentCO->setCurrentIndex(indent);
3156                 setIndent(indent);
3157         } else {
3158                 textLayoutModule->skipRB->setChecked(true);
3159                 int skip = 0;
3160                 switch (bp_.getDefSkip().kind()) {
3161                 case VSpace::SMALLSKIP:
3162                         skip = 0;
3163                         break;
3164                 case VSpace::MEDSKIP:
3165                         skip = 1;
3166                         break;
3167                 case VSpace::BIGSKIP:
3168                         skip = 2;
3169                         break;
3170                 case VSpace::LENGTH:
3171                         {
3172                         skip = 3;
3173                         string const length = bp_.getDefSkip().asLyXCommand();
3174                         lengthToWidgets(textLayoutModule->skipLE,
3175                                 textLayoutModule->skipLengthCO,
3176                                 length, default_unit);
3177                         break;
3178                         }
3179                 default:
3180                         skip = 0;
3181                         break;
3182                 }
3183                 textLayoutModule->skipCO->setCurrentIndex(skip);
3184                 setSkip(skip);
3185         }
3186
3187         textLayoutModule->twoColumnCB->setChecked(
3188                 bp_.columns == 2);
3189         textLayoutModule->justCB->setChecked(bp_.justification);
3190
3191         if (!bp_.options.empty()) {
3192                 latexModule->optionsLE->setText(
3193                         toqstr(bp_.options));
3194         } else {
3195                 latexModule->optionsLE->setText(QString());
3196         }
3197
3198         // latex
3199         latexModule->defaultOptionsCB->setChecked(
3200                         bp_.use_default_options);
3201         updateSelectedModules();
3202         selectionManager->updateProvidedModules(
3203                         bp_.baseClass()->providedModules());
3204         selectionManager->updateExcludedModules(
3205                         bp_.baseClass()->excludedModules());
3206
3207         if (!documentClass().options().empty()) {
3208                 latexModule->defaultOptionsLE->setText(
3209                         toqstr(documentClass().options()));
3210         } else {
3211                 latexModule->defaultOptionsLE->setText(
3212                         toqstr(_("[No options predefined]")));
3213         }
3214
3215         latexModule->defaultOptionsLE->setEnabled(
3216                 bp_.use_default_options
3217                 && !documentClass().options().empty());
3218
3219         latexModule->defaultOptionsCB->setEnabled(
3220                 !documentClass().options().empty());
3221
3222         if (!bp_.master.empty()) {
3223                 latexModule->childDocGB->setChecked(true);
3224                 latexModule->childDocLE->setText(
3225                         toqstr(bp_.master));
3226         } else {
3227                 latexModule->childDocLE->setText(QString());
3228                 latexModule->childDocGB->setChecked(false);
3229         }
3230
3231         // Master/Child
3232         if (!bufferview() || !buffer().hasChildren()) {
3233                 masterChildModule->childrenTW->clear();
3234                 includeonlys_.clear();
3235                 docPS->showPanel("Child Documents", false);
3236                 if (docPS->isCurrentPanel("Child Documents"))
3237                         docPS->setCurrentPanel("Document Class");
3238         } else {
3239                 docPS->showPanel("Child Documents", true);
3240                 masterChildModule->setEnabled(true);
3241                 includeonlys_ = bp_.getIncludedChildren();
3242                 updateIncludeonlys();
3243         }
3244         masterChildModule->maintainAuxCB->setChecked(
3245                 bp_.maintain_unincluded_children);
3246
3247         // Float Settings
3248         floatModule->set(bp_.float_placement);
3249
3250         // ListingsSettings
3251         // break listings_params to multiple lines
3252         string lstparams =
3253                 InsetListingsParams(bp_.listings_params).separatedParams();
3254         listingsModule->listingsED->setPlainText(toqstr(lstparams));
3255
3256         // Fonts
3257         // some languages only work with polyglossia/XeTeX
3258         Language const * lang = lyx::languages.getLanguage(
3259                 fromqstr(langModule->languageCO->itemData(
3260                         langModule->languageCO->currentIndex()).toString()));
3261         bool const need_fontspec =
3262                 lang->babel().empty() && !lang->polyglossia().empty();
3263         bool const os_fonts_available =
3264                 bp_.baseClass()->outputType() == lyx::LATEX
3265                 && LaTeXFeatures::isAvailable("fontspec");
3266         fontModule->osFontsCB->setEnabled(os_fonts_available && !need_fontspec);
3267         fontModule->osFontsCB->setChecked(
3268                 (os_fonts_available && bp_.useNonTeXFonts) || need_fontspec);
3269         updateFontsize(documentClass().opt_fontsize(),
3270                         bp_.fontsize);
3271
3272         QString font = toqstr(bp_.fonts_roman);
3273         int rpos = fontModule->fontsRomanCO->findData(font);
3274         if (rpos == -1) {
3275                 rpos = fontModule->fontsRomanCO->count();
3276                 fontModule->fontsRomanCO->addItem(font + qt_(" (not installed)"), font);
3277         }
3278         fontModule->fontsRomanCO->setCurrentIndex(rpos);
3279
3280         font = toqstr(bp_.fonts_sans);
3281         int spos = fontModule->fontsSansCO->findData(font);
3282         if (spos == -1) {
3283                 spos = fontModule->fontsSansCO->count();
3284                 fontModule->fontsSansCO->addItem(font + qt_(" (not installed)"), font);
3285         }
3286         fontModule->fontsSansCO->setCurrentIndex(spos);
3287
3288         font = toqstr(bp_.fonts_typewriter);
3289         int tpos = fontModule->fontsTypewriterCO->findData(font);
3290         if (tpos == -1) {
3291                 tpos = fontModule->fontsTypewriterCO->count();
3292                 fontModule->fontsTypewriterCO->addItem(font + qt_(" (not installed)"), font);
3293         }
3294         fontModule->fontsTypewriterCO->setCurrentIndex(tpos);
3295
3296         font = toqstr(bp_.fonts_math);
3297         int mpos = fontModule->fontsMathCO->findData(font);
3298         if (mpos == -1) {
3299                 mpos = fontModule->fontsMathCO->count();
3300                 fontModule->fontsMathCO->addItem(font + qt_(" (not installed)"), font);
3301         }
3302         fontModule->fontsMathCO->setCurrentIndex(mpos);
3303
3304         if (bp_.useNonTeXFonts && os_fonts_available) {
3305                 fontModule->fontencLA->setEnabled(false);
3306                 fontModule->fontencCO->setEnabled(false);
3307                 fontModule->fontencLE->setEnabled(false);
3308         } else {
3309                 fontModule->fontencLA->setEnabled(true);
3310                 fontModule->fontencCO->setEnabled(true);
3311                 fontModule->fontencLE->setEnabled(true);
3312                 romanChanged(rpos);
3313                 sansChanged(spos);
3314                 ttChanged(tpos);
3315         }
3316
3317         if (!bp_.fonts_cjk.empty())
3318                 fontModule->cjkFontLE->setText(
3319                         toqstr(bp_.fonts_cjk));
3320         else
3321                 fontModule->cjkFontLE->setText(QString());
3322
3323         fontModule->fontScCB->setChecked(bp_.fonts_expert_sc);
3324         fontModule->fontOsfCB->setChecked(bp_.fonts_old_figures);
3325         fontModule->scaleSansSB->setValue(bp_.fonts_sans_scale);
3326         fontModule->scaleTypewriterSB->setValue(bp_.fonts_typewriter_scale);
3327
3328         int nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
3329         if (nn >= 0)
3330                 fontModule->fontsDefaultCO->setCurrentIndex(nn);
3331
3332         if (bp_.fontenc == "global" || bp_.fontenc == "default") {
3333                 fontModule->fontencCO->setCurrentIndex(
3334                         fontModule->fontencCO->findData(toqstr(bp_.fontenc)));
3335                 fontModule->fontencLE->setEnabled(false);
3336         } else {
3337                 fontModule->fontencCO->setCurrentIndex(1);
3338                 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
3339         }
3340
3341         // Output
3342         // This must be set _after_ fonts since updateDefaultFormat()
3343         // checks osFontsCB settings.
3344         // update combobox with formats
3345         updateDefaultFormat();
3346         int index = outputModule->defaultFormatCO->findData(toqstr(
3347                 bp_.default_output_format));
3348         // set to default if format is not found
3349         if (index == -1)
3350                 index = 0;
3351         outputModule->defaultFormatCO->setCurrentIndex(index);
3352
3353         outputModule->outputsyncCB->setChecked(bp_.output_sync);
3354         outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
3355
3356         outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
3357         outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
3358         outputModule->strictCB->setChecked(bp_.html_be_strict);
3359         outputModule->cssCB->setChecked(bp_.html_css_as_file);
3360
3361         // paper
3362         bool const extern_geometry =
3363                 documentClass().provides("geometry");
3364         int const psize = bp_.papersize;
3365         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
3366         setCustomPapersize(!extern_geometry && psize == 1);
3367         pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
3368
3369         bool const landscape =
3370                 bp_.orientation == ORIENTATION_LANDSCAPE;
3371         pageLayoutModule->landscapeRB->setChecked(landscape);
3372         pageLayoutModule->portraitRB->setChecked(!landscape);
3373         pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
3374         pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
3375
3376         pageLayoutModule->facingPagesCB->setChecked(
3377                 bp_.sides == TwoSides);
3378
3379         lengthToWidgets(pageLayoutModule->paperwidthLE,
3380                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, default_unit);
3381         lengthToWidgets(pageLayoutModule->paperheightLE,
3382                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, default_unit);
3383
3384         // margins
3385         Ui::MarginsUi * m = marginsModule;
3386
3387         setMargins();
3388
3389         lengthToWidgets(m->topLE, m->topUnit,
3390                 bp_.topmargin, default_unit);
3391
3392         lengthToWidgets(m->bottomLE, m->bottomUnit,
3393                 bp_.bottommargin, default_unit);
3394
3395         lengthToWidgets(m->innerLE, m->innerUnit,
3396                 bp_.leftmargin, default_unit);
3397
3398         lengthToWidgets(m->outerLE, m->outerUnit,
3399                 bp_.rightmargin, default_unit);
3400
3401         lengthToWidgets(m->headheightLE, m->headheightUnit,
3402                 bp_.headheight, default_unit);
3403
3404         lengthToWidgets(m->headsepLE, m->headsepUnit,
3405                 bp_.headsep, default_unit);
3406
3407         lengthToWidgets(m->footskipLE, m->footskipUnit,
3408                 bp_.footskip, default_unit);
3409
3410         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
3411                 bp_.columnsep, default_unit);
3412
3413         // branches
3414         updateUnknownBranches();
3415         branchesModule->update(bp_);
3416
3417         // PDF support
3418         PDFOptions const & pdf = bp_.pdfoptions();
3419         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
3420         if (bp_.documentClass().provides("hyperref"))
3421                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("C&ustomize Hyperref Options"));
3422         else
3423                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("&Use Hyperref Support"));
3424         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
3425         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
3426         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
3427         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
3428
3429         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
3430         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
3431         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
3432
3433         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
3434
3435         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
3436         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
3437         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
3438         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
3439
3440         nn = findToken(backref_opts, pdf.backref);
3441         if (nn >= 0)
3442                 pdfSupportModule->backrefCO->setCurrentIndex(nn);
3443
3444         pdfSupportModule->fullscreenCB->setChecked
3445                 (pdf.pagemode == pdf.pagemode_fullscreen);
3446
3447         pdfSupportModule->optionsLE->setText(
3448                 toqstr(pdf.quoted_options));
3449
3450         // Make sure that the bc is in the INITIAL state
3451         if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
3452                 bc().restore();
3453
3454         // clear changed branches cache
3455         changedBranches_.clear();
3456
3457         // reset tracker
3458         nonModuleChanged_ = false;
3459 }
3460
3461
3462 void GuiDocument::saveDocDefault()
3463 {
3464         // we have to apply the params first
3465         applyView();
3466         saveAsDefault();
3467 }
3468
3469
3470 void GuiDocument::updateAvailableModules()
3471 {
3472         modules_av_model_.clear();
3473         list<modInfoStruct> const & modInfoList = getModuleInfo();
3474         list<modInfoStruct>::const_iterator mit = modInfoList.begin();
3475         list<modInfoStruct>::const_iterator men = modInfoList.end();
3476         for (int i = 0; mit != men; ++mit, ++i)
3477                 modules_av_model_.insertRow(i, mit->name, mit->id,
3478                                 mit->description);
3479 }
3480
3481
3482 void GuiDocument::updateSelectedModules()
3483 {
3484         modules_sel_model_.clear();
3485         list<modInfoStruct> const selModList = getSelectedModules();
3486         list<modInfoStruct>::const_iterator mit = selModList.begin();
3487         list<modInfoStruct>::const_iterator men = selModList.end();
3488         for (int i = 0; mit != men; ++mit, ++i)
3489                 modules_sel_model_.insertRow(i, mit->name, mit->id,
3490                                 mit->description);
3491 }
3492
3493
3494 void GuiDocument::updateIncludeonlys()
3495 {
3496         masterChildModule->childrenTW->clear();
3497         QString const no = qt_("No");
3498         QString const yes = qt_("Yes");
3499
3500         if (includeonlys_.empty()) {
3501                 masterChildModule->includeallRB->setChecked(true);
3502                 masterChildModule->childrenTW->setEnabled(false);
3503                 masterChildModule->maintainAuxCB->setEnabled(false);
3504         } else {
3505                 masterChildModule->includeonlyRB->setChecked(true);
3506                 masterChildModule->childrenTW->setEnabled(true);
3507                 masterChildModule->maintainAuxCB->setEnabled(true);
3508         }
3509         ListOfBuffers children = buffer().getChildren();
3510         ListOfBuffers::const_iterator it  = children.begin();
3511         ListOfBuffers::const_iterator end = children.end();
3512         bool has_unincluded = false;
3513         bool all_unincluded = true;
3514         for (; it != end; ++it) {
3515                 QTreeWidgetItem * item = new QTreeWidgetItem(masterChildModule->childrenTW);
3516                 // FIXME Unicode
3517                 string const name =
3518                         to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
3519                                                         from_utf8(buffer().filePath())));
3520                 item->setText(0, toqstr(name));
3521                 item->setText(1, isChildIncluded(name) ? yes : no);
3522                 if (!isChildIncluded(name))
3523                         has_unincluded = true;
3524                 else
3525                         all_unincluded = false;
3526         }
3527         // Both if all childs are included and if none is included
3528         // is equal to "include all" (i.e., ommit \includeonly).
3529         // Thus, reset the GUI.
3530         if (!has_unincluded || all_unincluded) {
3531                 masterChildModule->includeallRB->setChecked(true);
3532                 masterChildModule->childrenTW->setEnabled(false);
3533                 includeonlys_.clear();
3534         }
3535         // If all are included, we need to update again.
3536         if (!has_unincluded)
3537                 updateIncludeonlys();
3538 }
3539
3540
3541 void GuiDocument::updateContents()
3542 {
3543         // Nothing to do here as the document settings is not cursor dependant.
3544         return;
3545 }
3546
3547
3548 void GuiDocument::useClassDefaults()
3549 {
3550         if (applyPB->isEnabled()) {
3551                 int const ret = Alert::prompt(_("Unapplied changes"),
3552                                 _("Some changes in the dialog were not yet applied.\n"
3553                                   "If you do not apply now, they will be lost after this action."),
3554                                 1, 1, _("&Apply"), _("&Dismiss"));
3555                 if (ret == 0)
3556                         applyView();
3557         }
3558
3559         int idx = latexModule->classCO->currentIndex();
3560         string const classname = fromqstr(latexModule->classCO->getData(idx));
3561         if (!bp_.setBaseClass(classname)) {
3562                 Alert::error(_("Error"), _("Unable to set document class."));
3563                 return;
3564         }
3565         bp_.useClassDefaults();
3566         paramsToDialog();
3567 }
3568
3569
3570 void GuiDocument::setLayoutComboByIDString(string const & idString)
3571 {
3572         if (!latexModule->classCO->set(toqstr(idString)))
3573                 Alert::warning(_("Can't set layout!"),
3574                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
3575 }
3576
3577
3578 bool GuiDocument::isValid()
3579 {
3580         return
3581                 validateListingsParameters().isEmpty() &&
3582                 localLayout->isValid() &&
3583                 (
3584                         // if we're asking for skips between paragraphs
3585                         !textLayoutModule->skipRB->isChecked() ||
3586                         // then either we haven't chosen custom
3587                         textLayoutModule->skipCO->currentIndex() != 3 ||
3588                         // or else a length has been given
3589                         !textLayoutModule->skipLE->text().isEmpty()
3590                 ) &&
3591                 (
3592                         // if we're asking for indentation
3593                         !textLayoutModule->indentRB->isChecked() ||
3594                         // then either we haven't chosen custom
3595                         textLayoutModule->indentCO->currentIndex() != 1 ||
3596                         // or else a length has been given
3597                         !textLayoutModule->indentLE->text().isEmpty()
3598                 );
3599 }
3600
3601
3602 char const * const GuiDocument::fontfamilies[5] = {
3603         "default", "rmdefault", "sfdefault", "ttdefault", ""
3604 };
3605
3606
3607 char const * GuiDocument::fontfamilies_gui[5] = {
3608         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
3609 };
3610
3611
3612 bool GuiDocument::initialiseParams(string const &)
3613 {
3614         BufferView const * view = bufferview();
3615         if (!view) {
3616                 bp_ = BufferParams();
3617                 paramsToDialog();
3618                 return true;
3619         }
3620         bp_ = view->buffer().params();
3621         loadModuleInfo();
3622         updateAvailableModules();
3623         //FIXME It'd be nice to make sure here that the selected
3624         //modules are consistent: That required modules are actually
3625         //selected, and that we don't have conflicts. If so, we could
3626         //at least pop up a warning.
3627         paramsToDialog();
3628         return true;
3629 }
3630
3631
3632 void GuiDocument::clearParams()
3633 {
3634         bp_ = BufferParams();
3635 }
3636
3637
3638 BufferId GuiDocument::id() const
3639 {
3640         BufferView const * const view = bufferview();
3641         return view? &view->buffer() : 0;
3642 }
3643
3644
3645 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
3646 {
3647         return moduleNames_;
3648 }
3649
3650
3651 list<GuiDocument::modInfoStruct> const
3652                 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
3653 {
3654         LayoutModuleList::const_iterator it =  mods.begin();
3655         LayoutModuleList::const_iterator end = mods.end();
3656         list<modInfoStruct> mInfo;
3657         for (; it != end; ++it) {
3658                 modInfoStruct m;
3659                 m.id = *it;
3660                 LyXModule const * const mod = theModuleList[*it];
3661                 if (mod)
3662                         // FIXME Unicode
3663                         m.name = toqstr(translateIfPossible(from_utf8(mod->getName())));
3664                 else
3665                         m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
3666                 mInfo.push_back(m);
3667         }
3668         return mInfo;
3669 }
3670
3671
3672 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
3673 {
3674         return makeModuleInfo(params().getModules());
3675 }
3676
3677
3678 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
3679 {
3680         return makeModuleInfo(params().baseClass()->providedModules());
3681 }
3682
3683
3684 DocumentClass const & GuiDocument::documentClass() const
3685 {
3686         return bp_.documentClass();
3687 }
3688
3689
3690 static void dispatch_bufferparams(Dialog const & dialog,
3691         BufferParams const & bp, FuncCode lfun, Buffer const * buf)
3692 {
3693         ostringstream ss;
3694         ss << "\\begin_header\n";
3695         bp.writeFile(ss, buf);
3696         ss << "\\end_header\n";
3697         dialog.dispatch(FuncRequest(lfun, ss.str()));
3698 }
3699
3700
3701 void GuiDocument::dispatchParams()
3702 {
3703         // We need a non-const buffer object.
3704         Buffer & buf = const_cast<BufferView *>(bufferview())->buffer();
3705         // There may be several undo records; group them (bug #8998)
3706         buf.undo().beginUndoGroup();
3707
3708         // This must come first so that a language change is correctly noticed
3709         setLanguage();
3710
3711         // Apply the BufferParams. Note that this will set the base class
3712         // and then update the buffer's layout.
3713         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY, &buffer());
3714
3715         if (!params().master.empty()) {
3716                 FileName const master_file = support::makeAbsPath(params().master,
3717                            support::onlyPath(buffer().absFileName()));
3718                 if (isLyXFileName(master_file.absFileName())) {
3719                         Buffer * master = checkAndLoadLyXFile(master_file);
3720                         if (master) {
3721                                 if (master->isChild(const_cast<Buffer *>(&buffer())))
3722                                         const_cast<Buffer &>(buffer()).setParent(master);
3723                                 else
3724                                         Alert::warning(_("Assigned master does not include this file"),
3725                                                 bformat(_("You must include this file in the document\n"
3726                                                           "'%1$s' in order to use the master document\n"
3727                                                           "feature."), from_utf8(params().master)));
3728                         } else
3729                                 Alert::warning(_("Could not load master"),
3730                                                 bformat(_("The master document '%1$s'\n"
3731                                                            "could not be loaded."),
3732                                                            from_utf8(params().master)));
3733                 }
3734         }
3735
3736         // Generate the colours requested by each new branch.
3737         BranchList & branchlist = params().branchlist();
3738         if (!branchlist.empty()) {
3739                 BranchList::const_iterator it = branchlist.begin();
3740                 BranchList::const_iterator const end = branchlist.end();
3741                 for (; it != end; ++it) {
3742                         docstring const & current_branch = it->branch();
3743                         Branch const * branch = branchlist.find(current_branch);
3744                         string const x11hexname = X11hexname(branch->color());
3745                         // display the new color
3746                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
3747                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
3748                 }
3749
3750                 // Open insets of selected branches, close deselected ones
3751                 dispatch(FuncRequest(LFUN_INSET_FORALL,
3752                         "Branch inset-toggle assign"));
3753         }
3754         // rename branches in the document
3755         executeBranchRenaming();
3756         // and clear changed branches cache
3757         changedBranches_.clear();
3758
3759         // Generate the colours requested by indices.
3760         IndicesList & indiceslist = params().indiceslist();
3761         if (!indiceslist.empty()) {
3762                 IndicesList::const_iterator it = indiceslist.begin();
3763                 IndicesList::const_iterator const end = indiceslist.end();
3764                 for (; it != end; ++it) {
3765                         docstring const & current_index = it->shortcut();
3766                         Index const * index = indiceslist.findShortcut(current_index);
3767                         string const x11hexname = X11hexname(index->color());
3768                         // display the new color
3769                         docstring const str = current_index + ' ' + from_ascii(x11hexname);
3770                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
3771                 }
3772         }
3773         // FIXME LFUN
3774         // If we used an LFUN, we would not need these two lines:
3775         BufferView * bv = const_cast<BufferView *>(bufferview());
3776         bv->processUpdateFlags(Update::Force | Update::FitCursor);
3777
3778         // Don't forget to close the group. Note that it is important
3779         // to check that there is no early return in the method.
3780         buf.undo().endUndoGroup();
3781 }
3782
3783
3784 void GuiDocument::setLanguage() const
3785 {
3786         Language const * const newL = bp_.language;
3787         if (buffer().params().language == newL)
3788                 return;
3789
3790         string const & lang_name = newL->lang();
3791         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
3792 }
3793
3794
3795 void GuiDocument::saveAsDefault() const
3796 {
3797         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT, &buffer());
3798 }
3799
3800
3801 bool GuiDocument::providesOSF(QString const & font) const
3802 {
3803         if (fontModule->osFontsCB->isChecked())
3804                 // FIXME: we should check if the fonts really
3805                 // have OSF support. But how?
3806                 return true;
3807         return theLaTeXFonts().getLaTeXFont(
3808                                 qstring_to_ucs4(font)).providesOSF(ot1(),
3809                                                                    completeFontset(),
3810                                                                    noMathFont());
3811 }
3812
3813
3814 bool GuiDocument::providesSC(QString const & font) const
3815 {
3816         if (fontModule->osFontsCB->isChecked())
3817                 return false;
3818         return theLaTeXFonts().getLaTeXFont(
3819                                 qstring_to_ucs4(font)).providesSC(ot1(),
3820                                                                   completeFontset(),
3821                                                                   noMathFont());
3822 }
3823
3824
3825 bool GuiDocument::providesScale(QString const & font) const
3826 {
3827         if (fontModule->osFontsCB->isChecked())
3828                 return true;
3829         return theLaTeXFonts().getLaTeXFont(
3830                                 qstring_to_ucs4(font)).providesScale(ot1(),
3831                                                                      completeFontset(),
3832                                                                      noMathFont());
3833 }
3834
3835
3836 bool GuiDocument::providesNoMath(QString const & font) const
3837 {
3838         if (fontModule->osFontsCB->isChecked())
3839                 return false;
3840         return theLaTeXFonts().getLaTeXFont(
3841                                 qstring_to_ucs4(font)).providesNoMath(ot1(),
3842                                                                       completeFontset());
3843 }
3844
3845
3846 bool GuiDocument::hasMonolithicExpertSet(QString const & font) const
3847 {
3848         if (fontModule->osFontsCB->isChecked())
3849                 return false;
3850         return theLaTeXFonts().getLaTeXFont(
3851                                 qstring_to_ucs4(font)).hasMonolithicExpertSet(ot1(),
3852                                                                               completeFontset(),
3853                                                                               noMathFont());
3854 }
3855
3856
3857 void GuiDocument::loadModuleInfo()
3858 {
3859         moduleNames_.clear();
3860         LyXModuleList::const_iterator it  = theModuleList.begin();
3861         LyXModuleList::const_iterator end = theModuleList.end();
3862         for (; it != end; ++it) {
3863                 modInfoStruct m;
3864                 m.id = it->getID();
3865                 // FIXME Unicode
3866                 m.name = toqstr(translateIfPossible(from_utf8(it->getName())));
3867                 // this is supposed to give us the first sentence of the description
3868                 // FIXME Unicode
3869                 QString desc =
3870                         toqstr(translateIfPossible(from_utf8(it->getDescription())));
3871                 int const pos = desc.indexOf(".");
3872                 if (pos > 0)
3873                         desc.truncate(pos + 1);
3874                 m.description = desc;
3875                 if (it->category().substr(0, 8) != "Citation")
3876                         moduleNames_.push_back(m);
3877         }
3878 }
3879
3880
3881 void GuiDocument::updateUnknownBranches()
3882 {
3883         if (!bufferview())
3884                 return;
3885         list<docstring> used_branches;
3886         buffer().getUsedBranches(used_branches);
3887         list<docstring>::const_iterator it = used_branches.begin();
3888         QStringList unknown_branches;
3889         for (; it != used_branches.end() ; ++it) {
3890                 if (!buffer().params().branchlist().find(*it))
3891                         unknown_branches.append(toqstr(*it));
3892         }
3893         branchesModule->setUnknownBranches(unknown_branches);
3894 }
3895
3896
3897 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
3898 {
3899         map<docstring, docstring>::iterator it = changedBranches_.begin();
3900         for (; it != changedBranches_.end() ; ++it) {
3901                 if (it->second == oldname) {
3902                         // branch has already been renamed
3903                         it->second = newname;
3904                         return;
3905                 }
3906         }
3907         // store new name
3908         changedBranches_[oldname] = newname;
3909 }
3910
3911
3912 void GuiDocument::executeBranchRenaming() const
3913 {
3914         map<docstring, docstring>::const_iterator it = changedBranches_.begin();
3915         for (; it != changedBranches_.end() ; ++it) {
3916                 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
3917                 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
3918         }
3919 }
3920
3921
3922 void GuiDocument::allPackagesAuto()
3923 {
3924         allPackages(1);
3925 }
3926
3927
3928 void GuiDocument::allPackagesAlways()
3929 {
3930         allPackages(2);
3931 }
3932
3933
3934 void GuiDocument::allPackagesNot()
3935 {
3936         allPackages(3);
3937 }
3938
3939
3940 void GuiDocument::allPackages(int col)
3941 {
3942         for (int row = 0; row < mathsModule->packagesTW->rowCount(); ++row) {
3943                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, col);
3944                 rb->setChecked(true);
3945         }
3946 }
3947
3948
3949 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
3950
3951
3952 } // namespace frontend
3953 } // namespace lyx
3954
3955 #include "moc_GuiDocument.cpp"