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