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