]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiDocument.cpp
* Add native support for \includeonly (bug 5360).
[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 "GuiApplication.h"
17 #include "GuiBranches.h"
18 #include "GuiIndices.h"
19 #include "GuiSelectionManager.h"
20 #include "LaTeXHighlighter.h"
21 #include "LengthCombo.h"
22 #include "PanelStack.h"
23 #include "Validator.h"
24
25 #include "LayoutFile.h"
26 #include "BranchList.h"
27 #include "buffer_funcs.h"
28 #include "Buffer.h"
29 #include "BufferParams.h"
30 #include "BufferView.h"
31 #include "Color.h"
32 #include "ColorCache.h"
33 #include "Encoding.h"
34 #include "FloatPlacement.h"
35 #include "Format.h"
36 #include "FuncRequest.h"
37 #include "HSpace.h"
38 #include "IndicesList.h"
39 #include "Language.h"
40 #include "LaTeXFeatures.h"
41 #include "Layout.h"
42 #include "LayoutModuleList.h"
43 #include "LyXRC.h"
44 #include "ModuleList.h"
45 #include "OutputParams.h"
46 #include "PDFOptions.h"
47 #include "qt_helpers.h"
48 #include "Spacing.h"
49
50 #include "insets/InsetListingsParams.h"
51
52 #include "support/debug.h"
53 #include "support/FileName.h"
54 #include "support/filetools.h"
55 #include "support/gettext.h"
56 #include "support/lstrings.h"
57
58 #include "frontends/alert.h"
59
60 #include <QAbstractItemModel>
61 #include <QHeaderView>
62 #include <QColor>
63 #include <QColorDialog>
64 #include <QCloseEvent>
65 #include <QFontDatabase>
66 #include <QScrollBar>
67 #include <QTextCursor>
68
69 #include <sstream>
70 #include <vector>
71
72 #ifdef IN
73 #undef IN
74 #endif
75
76
77 // a style sheet for buttons
78 // this is for example used for the background color setting button
79 static inline QString colorButtonStyleSheet(QColor const & bgColor)
80 {
81         if (bgColor.isValid()) {
82                 QString rc = QLatin1String("background:");
83                 rc += bgColor.name();
84                 return rc;
85         }
86         return QString();
87 }
88
89
90 using namespace std;
91 using namespace lyx::support;
92
93
94 namespace {
95
96 char const * const tex_graphics[] =
97 {
98         "default", "dvialw", "dvilaser", "dvipdf", "dvipdfm", "dvipdfmx",
99         "dvips", "dvipsone", "dvitops", "dviwin", "dviwindo", "dvi2ps", "emtex",
100         "ln", "oztex", "pctexhp", "pctexps", "pctexwin", "pctex32", "pdftex",
101         "psprint", "pubps", "tcidvi", "textures", "truetex", "vtex", "xdvi",
102         "xetex", "none", ""
103 };
104
105
106 char const * const tex_graphics_gui[] =
107 {
108         N_("Default"), "dvialw", "DviLaser", "dvipdf", "DVIPDFM", "DVIPDFMx",
109         "Dvips", "DVIPSONE", "DVItoPS", "DVIWIN", "DVIWindo", "dvi2ps", "EmTeX",
110         "LN", "OzTeX", "pctexhp", "pctexps", "pctexwin", "PCTeX32", "pdfTeX",
111         "psprint", "pubps", "tcidvi", "Textures", "TrueTeX", "VTeX", "xdvi",
112         "XeTeX", N_("None"), ""
113 };
114
115
116 char const * const tex_fonts_roman[] =
117 {
118         "default", "cmr", "lmodern", "ae", "times", "palatino",
119         "charter", "newcent", "bookman", "utopia", "beraserif",
120         "ccfonts", "chancery", ""
121 };
122
123
124 char const * tex_fonts_roman_gui[] =
125 {
126         N_("Default"), N_("Computer Modern Roman"), N_("Latin Modern Roman"),
127         N_("AE (Almost European)"), N_("Times Roman"), N_("Palatino"),
128         N_("Bitstream Charter"), N_("New Century Schoolbook"), N_("Bookman"),
129         N_("Utopia"),  N_("Bera Serif"), N_("Concrete Roman"), N_("Zapf Chancery"),
130         ""
131 };
132
133
134 char const * const tex_fonts_sans[] =
135 {
136         "default", "cmss", "lmss", "helvet", "avant", "berasans", "cmbr", ""
137 };
138
139
140 char const * tex_fonts_sans_gui[] =
141 {
142         N_("Default"), N_("Computer Modern Sans"), N_("Latin Modern Sans"),
143         N_("Helvetica"), N_("Avant Garde"), N_("Bera Sans"), N_("CM Bright"), ""
144 };
145
146
147 char const * const tex_fonts_monospaced[] =
148 {
149         "default", "cmtt", "lmtt", "courier", "beramono", "luximono", "cmtl", ""
150 };
151
152
153 char const * tex_fonts_monospaced_gui[] =
154 {
155         N_("Default"), N_("Computer Modern Typewriter"),
156         N_("Latin Modern Typewriter"), N_("Courier"), N_("Bera Mono"),
157         N_("LuxiMono"), N_("CM Typewriter Light"), ""
158 };
159
160
161 char const * backref_opts[] =
162 {
163         "false", "section", "slide", "page", ""
164 };
165
166
167 char const * backref_opts_gui[] =
168 {
169         N_("Off"), N_("Section"), N_("Slide"), N_("Page"), ""
170 };
171
172
173 vector<pair<string, QString> > pagestyles;
174
175
176 } // anonymous namespace
177
178 namespace lyx {
179
180 RGBColor set_backgroundcolor;
181
182 namespace {
183 // used when sorting the textclass list.
184 class less_textclass_avail_desc
185         : public binary_function<string, string, int>
186 {
187 public:
188         bool operator()(string const & lhs, string const & rhs) const
189         {
190                 // Ordering criteria:
191                 //   1. Availability of text class
192                 //   2. Description (lexicographic)
193                 LayoutFile const & tc1 = LayoutFileList::get()[lhs];
194                 LayoutFile const & tc2 = LayoutFileList::get()[rhs];
195                 int const order = compare_no_case(
196                         translateIfPossible(from_utf8(tc1.description())),
197                         translateIfPossible(from_utf8(tc2.description())));
198                 return (tc1.isTeXClassAvailable() && !tc2.isTeXClassAvailable()) ||
199                         (tc1.isTeXClassAvailable() == tc2.isTeXClassAvailable() && order < 0);
200         }
201 };
202
203 }
204
205 namespace frontend {
206 namespace {
207
208 vector<string> getRequiredList(string const & modName) 
209 {
210         LyXModule const * const mod = theModuleList[modName];
211         if (!mod)
212                 return vector<string>(); //empty such thing
213         return mod->getRequiredModules();
214 }
215
216
217 vector<string> getExcludedList(string const & modName)
218 {
219         LyXModule const * const mod = theModuleList[modName];
220         if (!mod)
221                 return vector<string>(); //empty such thing
222         return mod->getExcludedModules();
223 }
224
225
226 docstring getModuleDescription(string const & modName)
227 {
228         LyXModule const * const mod = theModuleList[modName];
229         if (!mod)
230                 return _("Module not found!");
231         // FIXME Unicode
232         return translateIfPossible(from_utf8(mod->getDescription()));
233 }
234
235
236 vector<string> getPackageList(string const & modName)
237 {
238         LyXModule const * const mod = theModuleList[modName];
239         if (!mod)
240                 return vector<string>(); //empty such thing
241         return mod->getPackageList();
242 }
243
244
245 bool isModuleAvailable(string const & modName)
246 {
247         LyXModule const * const mod = theModuleList[modName];
248         if (!mod)
249                 return false;
250         return mod->isAvailable();
251 }
252
253 } // anonymous namespace
254
255
256 /////////////////////////////////////////////////////////////////////
257 //
258 // ModuleSelectionManager
259 //
260 /////////////////////////////////////////////////////////////////////
261
262 /// SelectionManager for use with modules
263 class ModuleSelectionManager : public GuiSelectionManager 
264 {
265 public:
266         ///
267         ModuleSelectionManager(
268                 QTreeView * availableLV,
269                 QListView * selectedLV,
270                 QPushButton * addPB, 
271                 QPushButton * delPB, 
272                 QPushButton * upPB, 
273                 QPushButton * downPB,
274                 GuiIdListModel * availableModel,
275                 GuiIdListModel * selectedModel,
276                 GuiDocument const * container)
277         : GuiSelectionManager(availableLV, selectedLV, addPB, delPB,
278                                 upPB, downPB, availableModel, selectedModel), container_(container)
279                 {}
280         ///
281         void updateProvidedModules(LayoutModuleList const & pm) 
282                         { provided_modules_ = pm.list(); }
283         ///
284         void updateExcludedModules(LayoutModuleList const & em) 
285                         { excluded_modules_ = em.list(); }
286 private:
287         ///
288         virtual void updateAddPB();
289         ///
290         virtual void updateUpPB();
291         ///
292         virtual void updateDownPB();
293         ///
294         virtual void updateDelPB();
295         /// returns availableModel as a GuiIdListModel
296         GuiIdListModel * getAvailableModel() 
297         {
298                 return dynamic_cast<GuiIdListModel *>(availableModel);
299         }
300         /// returns selectedModel as a GuiIdListModel
301         GuiIdListModel * getSelectedModel() 
302         {
303                 return dynamic_cast<GuiIdListModel *>(selectedModel);
304         }
305         /// keeps a list of the modules the text class provides
306         list<string> provided_modules_;
307         /// similarly...
308         list<string> excluded_modules_;
309         /// 
310         GuiDocument const * container_;
311 };
312
313 void ModuleSelectionManager::updateAddPB() 
314 {
315         int const arows = availableModel->rowCount();
316         QModelIndexList const avail_sels = 
317                         availableLV->selectionModel()->selectedIndexes();
318
319         // disable if there aren't any modules (?), if none of them is chosen
320         // in the dialog, or if the chosen one is already selected for use.
321         if (arows == 0 || avail_sels.isEmpty() || isSelected(avail_sels.first())) {
322                 addPB->setEnabled(false);
323                 return;
324         }
325
326         QModelIndex const & idx = availableLV->selectionModel()->currentIndex();
327         string const modname = getAvailableModel()->getIDString(idx.row());
328
329         bool const enable = 
330                 container_->params().moduleCanBeAdded(modname);
331         addPB->setEnabled(enable);
332 }
333
334
335 void ModuleSelectionManager::updateDownPB()
336 {
337         int const srows = selectedModel->rowCount();
338         if (srows == 0) {
339                 downPB->setEnabled(false);
340                 return;
341         }
342         QModelIndex const & curidx = selectedLV->selectionModel()->currentIndex();
343         int const curRow = curidx.row();
344         if (curRow < 0 || curRow >= srows - 1) { // invalid or last item
345                 downPB->setEnabled(false);
346                 return;
347         }
348
349         // determine whether immediately succeding element requires this one
350         string const curmodname = getSelectedModel()->getIDString(curRow);
351         string const nextmodname = getSelectedModel()->getIDString(curRow + 1);
352
353         vector<string> reqs = getRequiredList(nextmodname);
354
355         // if it doesn't require anything....
356         if (reqs.empty()) {
357                 downPB->setEnabled(true);
358                 return;
359         }
360
361         // Enable it if this module isn't required.
362         // FIXME This should perhaps be more flexible and check whether, even 
363         // if the next one is required, there is also an earlier one that will do.
364         downPB->setEnabled(
365                         find(reqs.begin(), reqs.end(), curmodname) == reqs.end());
366 }
367
368 void ModuleSelectionManager::updateUpPB() 
369 {
370         int const srows = selectedModel->rowCount();
371         if (srows == 0) {
372                 upPB->setEnabled(false);
373                 return;
374         }
375
376         QModelIndex const & curIdx = selectedLV->selectionModel()->currentIndex();
377         int curRow = curIdx.row();
378         if (curRow <= 0 || curRow > srows - 1) { // first item or invalid
379                 upPB->setEnabled(false);
380                 return;
381         }
382         string const curmodname = getSelectedModel()->getIDString(curRow);
383
384         // determine whether immediately preceding element is required by this one
385         vector<string> reqs = getRequiredList(curmodname);
386
387         // if this one doesn't require anything....
388         if (reqs.empty()) {
389                 upPB->setEnabled(true);
390                 return;
391         }
392
393
394         // Enable it if the preceding module isn't required.
395         // NOTE This is less flexible than it might be. We could check whether, even 
396         // if the previous one is required, there is an earlier one that would do.
397         string const premod = getSelectedModel()->getIDString(curRow - 1);
398         upPB->setEnabled(find(reqs.begin(), reqs.end(), premod) == reqs.end());
399 }
400
401 void ModuleSelectionManager::updateDelPB() 
402 {
403         int const srows = selectedModel->rowCount();
404         if (srows == 0) {
405                 deletePB->setEnabled(false);
406                 return;
407         }
408
409         QModelIndex const & curidx = 
410                 selectedLV->selectionModel()->currentIndex();
411         int const curRow = curidx.row();
412         if (curRow < 0 || curRow >= srows) { // invalid index?
413                 deletePB->setEnabled(false);
414                 return;
415         }
416
417         string const curmodname = getSelectedModel()->getIDString(curRow);
418
419         // We're looking here for a reason NOT to enable the button. If we
420         // find one, we disable it and return. If we don't, we'll end up at
421         // the end of the function, and then we enable it.
422         for (int i = curRow + 1; i < srows; ++i) {
423                 string const thisMod = getSelectedModel()->getIDString(i);
424                 vector<string> reqs = getRequiredList(thisMod);
425                 //does this one require us?
426                 if (find(reqs.begin(), reqs.end(), curmodname) == reqs.end())
427                         //no...
428                         continue;
429
430                 // OK, so this module requires us
431                 // is there an EARLIER module that also satisfies the require?
432                 // NOTE We demand that it be earlier to keep the list of modules
433                 // consistent with the rule that a module must be proceeded by a
434                 // required module. There would be more flexible ways to proceed,
435                 // but that would be a lot more complicated, and the logic here is
436                 // already complicated. (That's why I've left the debugging code.)
437                 // lyxerr << "Testing " << thisMod << endl;
438                 bool foundone = false;
439                 for (int j = 0; j < curRow; ++j) {
440                         string const mod = getSelectedModel()->getIDString(j);
441                         // lyxerr << "In loop: Testing " << mod << endl;
442                         // do we satisfy the require? 
443                         if (find(reqs.begin(), reqs.end(), mod) != reqs.end()) {
444                                 // lyxerr << mod << " does the trick." << endl;
445                                 foundone = true;
446                                 break;
447                         }
448                 }
449                 // did we find a module to satisfy the require?
450                 if (!foundone) {
451                         // lyxerr << "No matching module found." << endl;
452                         deletePB->setEnabled(false);
453                         return;
454                 }
455         }
456         // lyxerr << "All's well that ends well." << endl;
457         deletePB->setEnabled(true);
458 }
459
460
461 /////////////////////////////////////////////////////////////////////
462 //
463 // PreambleModule
464 //
465 /////////////////////////////////////////////////////////////////////
466
467 PreambleModule::PreambleModule() : current_id_(0)
468 {
469         // This is not a memory leak. The object will be destroyed
470         // with this.
471         (void) new LaTeXHighlighter(preambleTE->document());
472         setFocusProxy(preambleTE);
473         connect(preambleTE, SIGNAL(textChanged()), this, SIGNAL(changed()));
474 }
475
476
477 void PreambleModule::update(BufferParams const & params, BufferId id)
478 {
479         QString preamble = toqstr(params.preamble);
480         // Nothing to do if the params and preamble are unchanged.
481         if (id == current_id_
482                 && preamble == preambleTE->document()->toPlainText())
483                 return;
484
485         QTextCursor cur = preambleTE->textCursor();
486         // Save the coords before switching to the new one.
487         preamble_coords_[current_id_] =
488                 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
489
490         // Save the params address for further use.
491         current_id_ = id;
492         preambleTE->document()->setPlainText(preamble);
493         Coords::const_iterator it = preamble_coords_.find(current_id_);
494         if (it == preamble_coords_.end())
495                 // First time we open this one.
496                 preamble_coords_[current_id_] = make_pair(0, 0);
497         else {
498                 // Restore saved coords.
499                 QTextCursor cur = preambleTE->textCursor();
500                 cur.setPosition(it->second.first);
501                 preambleTE->setTextCursor(cur);
502                 preambleTE->verticalScrollBar()->setValue(it->second.second);
503         }
504 }
505
506
507 void PreambleModule::apply(BufferParams & params)
508 {
509         params.preamble = fromqstr(preambleTE->document()->toPlainText());
510 }
511
512
513 void PreambleModule::closeEvent(QCloseEvent * e)
514 {
515         // Save the coords before closing.
516         QTextCursor cur = preambleTE->textCursor();
517         preamble_coords_[current_id_] =
518                 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
519         e->accept();
520 }
521
522
523 /////////////////////////////////////////////////////////////////////
524 //
525 // DocumentDialog
526 //
527 /////////////////////////////////////////////////////////////////////
528
529
530 GuiDocument::GuiDocument(GuiView & lv)
531         : GuiDialog(lv, "document", qt_("Document Settings"))
532 {
533         setupUi(this);
534
535         connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
536         connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
537         connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
538         connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore()));
539
540         connect(savePB, SIGNAL(clicked()), this, SLOT(saveDefaultClicked()));
541         connect(defaultPB, SIGNAL(clicked()), this, SLOT(useDefaultsClicked()));
542
543         // Manage the restore, ok, apply, restore and cancel/close buttons
544         bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
545         bc().setOK(okPB);
546         bc().setApply(applyPB);
547         bc().setCancel(closePB);
548         bc().setRestore(restorePB);
549
550         textLayoutModule = new UiWidget<Ui::TextLayoutUi>;
551         // text layout
552         connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
553                 this, SLOT(change_adaptor()));
554         connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
555                 this, SLOT(setLSpacing(int)));
556         connect(textLayoutModule->lspacingLE, SIGNAL(textChanged(const QString &)),
557                 this, SLOT(change_adaptor()));
558
559         connect(textLayoutModule->indentRB, SIGNAL(clicked()),
560                 this, SLOT(change_adaptor()));
561         connect(textLayoutModule->indentRB, SIGNAL(toggled(bool)),
562                 textLayoutModule->indentCO, SLOT(setEnabled(bool)));
563         connect(textLayoutModule->indentCO, SIGNAL(activated(int)),
564                 this, SLOT(change_adaptor()));
565         connect(textLayoutModule->indentCO, SIGNAL(activated(int)),
566                 this, SLOT(setIndent(int)));
567         connect(textLayoutModule->indentLE, SIGNAL(textChanged(const QString &)),
568                 this, SLOT(change_adaptor()));
569         connect(textLayoutModule->indentLengthCO, SIGNAL(activated(int)),
570                 this, SLOT(change_adaptor()));
571
572         connect(textLayoutModule->skipRB, SIGNAL(clicked()),
573                 this, SLOT(change_adaptor()));
574         connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
575                 textLayoutModule->skipCO, SLOT(setEnabled(bool)));
576         connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
577                 this, SLOT(change_adaptor()));
578         connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
579                 this, SLOT(setSkip(int)));
580         connect(textLayoutModule->skipLE, SIGNAL(textChanged(const QString &)),
581                 this, SLOT(change_adaptor()));
582         connect(textLayoutModule->skipLengthCO, SIGNAL(activated(int)),
583                 this, SLOT(change_adaptor()));
584
585         connect(textLayoutModule->indentRB, SIGNAL(toggled(bool)),
586                 this, SLOT(enableIndent(bool)));
587         connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
588                 this, SLOT(enableSkip(bool)));
589
590         connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
591                 this, SLOT(change_adaptor()));
592         connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
593                 this, SLOT(setColSep()));
594
595         textLayoutModule->lspacingLE->setValidator(new QDoubleValidator(
596                 textLayoutModule->lspacingLE));
597         textLayoutModule->indentLE->setValidator(unsignedLengthValidator(
598                 textLayoutModule->indentLE));
599         textLayoutModule->skipLE->setValidator(unsignedGlueLengthValidator(
600                 textLayoutModule->skipLE));
601
602         textLayoutModule->indentCO->addItem(qt_("Default"));
603         textLayoutModule->indentCO->addItem(qt_("Custom"));
604         textLayoutModule->skipCO->addItem(qt_("SmallSkip"));
605         textLayoutModule->skipCO->addItem(qt_("MedSkip"));
606         textLayoutModule->skipCO->addItem(qt_("BigSkip"));
607         textLayoutModule->skipCO->addItem(qt_("Custom"));
608         textLayoutModule->lspacingCO->insertItem(
609                 Spacing::Single, qt_("Single"));
610         textLayoutModule->lspacingCO->insertItem(
611                 Spacing::Onehalf, qt_("OneHalf"));
612         textLayoutModule->lspacingCO->insertItem(
613                 Spacing::Double, qt_("Double"));
614         textLayoutModule->lspacingCO->insertItem(
615                 Spacing::Other, qt_("Custom"));
616         // initialize the length validator
617         bc().addCheckedLineEdit(textLayoutModule->indentLE);
618         bc().addCheckedLineEdit(textLayoutModule->skipLE);
619
620         // master/child handling
621         masterChildModule = new UiWidget<Ui::MasterChildUi>;
622
623         connect(masterChildModule->childrenTW, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),
624                 this, SLOT(includeonlyClicked(QTreeWidgetItem *, int)));
625         connect(masterChildModule->includeonlyRB, SIGNAL(toggled(bool)),
626                 masterChildModule->childrenTW, SLOT(setEnabled(bool)));
627         connect(masterChildModule->includeallRB, SIGNAL(clicked()),
628                 this, SLOT(change_adaptor()));
629         connect(masterChildModule->includeonlyRB, SIGNAL(clicked()),
630                 this, SLOT(change_adaptor()));
631         masterChildModule->childrenTW->setColumnCount(2);
632         masterChildModule->childrenTW->headerItem()->setText(0, qt_("Child Document"));
633         masterChildModule->childrenTW->headerItem()->setText(1, qt_("Include to Output"));
634         masterChildModule->childrenTW->resizeColumnToContents(1);
635         masterChildModule->childrenTW->resizeColumnToContents(2);
636
637         // output
638         outputModule = new UiWidget<Ui::OutputUi>;
639
640         connect(outputModule->xetexCB, SIGNAL(clicked()),
641                 this, SLOT(change_adaptor()));
642         connect(outputModule->xetexCB, SIGNAL(toggled(bool)),
643                 this, SLOT(xetexChanged(bool)));
644         connect(outputModule->defaultFormatCO, SIGNAL(activated(int)),
645                 this, SLOT(change_adaptor()));
646
647         // fonts
648         fontModule = new UiWidget<Ui::FontUi>;
649         connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
650                 this, SLOT(change_adaptor()));
651         connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
652                 this, SLOT(romanChanged(int)));
653         connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
654                 this, SLOT(change_adaptor()));
655         connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
656                 this, SLOT(sansChanged(int)));
657         connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
658                 this, SLOT(change_adaptor()));
659         connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
660                 this, SLOT(ttChanged(int)));
661         connect(fontModule->fontsDefaultCO, SIGNAL(activated(int)),
662                 this, SLOT(change_adaptor()));
663         connect(fontModule->fontencCO, SIGNAL(activated(int)),
664                 this, SLOT(change_adaptor()));
665         connect(fontModule->fontencCO, SIGNAL(activated(int)),
666                 this, SLOT(fontencChanged(int)));
667         connect(fontModule->fontencLE, SIGNAL(textChanged(const QString &)),
668                 this, SLOT(change_adaptor()));
669         connect(fontModule->fontsizeCO, SIGNAL(activated(int)),
670                 this, SLOT(change_adaptor()));
671         connect(fontModule->cjkFontLE, SIGNAL(textChanged(const QString &)),
672                 this, SLOT(change_adaptor()));
673         connect(fontModule->scaleSansSB, SIGNAL(valueChanged(int)),
674                 this, SLOT(change_adaptor()));
675         connect(fontModule->scaleTypewriterSB, SIGNAL(valueChanged(int)),
676                 this, SLOT(change_adaptor()));
677         connect(fontModule->fontScCB, SIGNAL(clicked()),
678                 this, SLOT(change_adaptor()));
679         connect(fontModule->fontOsfCB, SIGNAL(clicked()),
680                 this, SLOT(change_adaptor()));
681
682         updateFontlist();
683
684         fontModule->fontsizeCO->addItem(qt_("Default"));
685         fontModule->fontsizeCO->addItem(qt_("10"));
686         fontModule->fontsizeCO->addItem(qt_("11"));
687         fontModule->fontsizeCO->addItem(qt_("12"));
688
689         fontModule->fontencCO->addItem(qt_("Default"));
690         fontModule->fontencCO->addItem(qt_("Custom"));
691         fontModule->fontencCO->addItem(qt_("None (no fontenc)"));
692
693         for (int n = 0; GuiDocument::fontfamilies_gui[n][0]; ++n)
694                 fontModule->fontsDefaultCO->addItem(
695                         qt_(GuiDocument::fontfamilies_gui[n]));
696
697
698         pageLayoutModule = new UiWidget<Ui::PageLayoutUi>;
699         // page layout
700         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
701                 this, SLOT(papersizeChanged(int)));
702         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
703                 this, SLOT(papersizeChanged(int)));
704         connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
705                 this, SLOT(portraitChanged()));
706         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
707                 this, SLOT(change_adaptor()));
708         connect(pageLayoutModule->paperheightLE, SIGNAL(textChanged(const QString &)),
709                 this, SLOT(change_adaptor()));
710         connect(pageLayoutModule->paperwidthLE, SIGNAL(textChanged(const QString &)),
711                 this, SLOT(change_adaptor()));
712         connect(pageLayoutModule->paperwidthUnitCO, SIGNAL(activated(int)),
713                 this, SLOT(change_adaptor()));
714         connect(pageLayoutModule->paperheightUnitCO, SIGNAL(activated(int)),
715                 this, SLOT(change_adaptor()));
716         connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
717                 this, SLOT(change_adaptor()));
718         connect(pageLayoutModule->landscapeRB, SIGNAL(clicked()),
719                 this, SLOT(change_adaptor()));
720         connect(pageLayoutModule->facingPagesCB, SIGNAL(clicked()),
721                 this, SLOT(change_adaptor()));
722         connect(pageLayoutModule->pagestyleCO, SIGNAL(activated(int)),
723                 this, SLOT(change_adaptor()));
724         connect(pageLayoutModule->backgroundPB, SIGNAL(clicked()),
725                 this, SLOT(changeBackgroundColor()));
726         connect(pageLayoutModule->delbackgroundTB, SIGNAL(clicked()),
727                 this, SLOT(deleteBackgroundColor()));
728
729         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
730         pageLayoutModule->pagestyleCO->addItem(qt_("empty"));
731         pageLayoutModule->pagestyleCO->addItem(qt_("plain"));
732         pageLayoutModule->pagestyleCO->addItem(qt_("headings"));
733         pageLayoutModule->pagestyleCO->addItem(qt_("fancy"));
734         bc().addCheckedLineEdit(pageLayoutModule->paperheightLE,
735                 pageLayoutModule->paperheightL);
736         bc().addCheckedLineEdit(pageLayoutModule->paperwidthLE,
737                 pageLayoutModule->paperwidthL);
738
739         // paper
740         QComboBox * cb = pageLayoutModule->papersizeCO;
741         cb->addItem(qt_("Default"));
742         cb->addItem(qt_("Custom"));
743         cb->addItem(qt_("US letter"));
744         cb->addItem(qt_("US legal"));
745         cb->addItem(qt_("US executive"));
746         cb->addItem(qt_("A3"));
747         cb->addItem(qt_("A4"));
748         cb->addItem(qt_("A5"));
749         cb->addItem(qt_("B3"));
750         cb->addItem(qt_("B4"));
751         cb->addItem(qt_("B5"));
752         // remove the %-items from the unit choice
753         pageLayoutModule->paperwidthUnitCO->noPercents();
754         pageLayoutModule->paperheightUnitCO->noPercents();
755         pageLayoutModule->paperheightLE->setValidator(unsignedLengthValidator(
756                 pageLayoutModule->paperheightLE));
757         pageLayoutModule->paperwidthLE->setValidator(unsignedLengthValidator(
758                 pageLayoutModule->paperwidthLE));
759
760
761         marginsModule = new UiWidget<Ui::MarginsUi>;
762         // margins
763         connect(marginsModule->marginCB, SIGNAL(toggled(bool)),
764                 this, SLOT(setCustomMargins(bool)));
765         connect(marginsModule->marginCB, SIGNAL(clicked()),
766                 this, SLOT(change_adaptor()));
767         connect(marginsModule->topLE, SIGNAL(textChanged(QString)),
768                 this, SLOT(change_adaptor()));
769         connect(marginsModule->topUnit, SIGNAL(activated(int)),
770                 this, SLOT(change_adaptor()));
771         connect(marginsModule->bottomLE, SIGNAL(textChanged(QString)),
772                 this, SLOT(change_adaptor()));
773         connect(marginsModule->bottomUnit, SIGNAL(activated(int)),
774                 this, SLOT(change_adaptor()));
775         connect(marginsModule->innerLE, SIGNAL(textChanged(QString)),
776                 this, SLOT(change_adaptor()));
777         connect(marginsModule->innerUnit, SIGNAL(activated(int)),
778                 this, SLOT(change_adaptor()));
779         connect(marginsModule->outerLE, SIGNAL(textChanged(QString)),
780                 this, SLOT(change_adaptor()));
781         connect(marginsModule->outerUnit, SIGNAL(activated(int)),
782                 this, SLOT(change_adaptor()));
783         connect(marginsModule->headheightLE, SIGNAL(textChanged(QString)),
784                 this, SLOT(change_adaptor()));
785         connect(marginsModule->headheightUnit, SIGNAL(activated(int)),
786                 this, SLOT(change_adaptor()));
787         connect(marginsModule->headsepLE, SIGNAL(textChanged(QString)),
788                 this, SLOT(change_adaptor()));
789         connect(marginsModule->headsepUnit, SIGNAL(activated(int)),
790                 this, SLOT(change_adaptor()));
791         connect(marginsModule->footskipLE, SIGNAL(textChanged(QString)),
792                 this, SLOT(change_adaptor()));
793         connect(marginsModule->footskipUnit, SIGNAL(activated(int)),
794                 this, SLOT(change_adaptor()));
795         connect(marginsModule->columnsepLE, SIGNAL(textChanged(QString)),
796                 this, SLOT(change_adaptor()));
797         connect(marginsModule->columnsepUnit, SIGNAL(activated(int)),
798                 this, SLOT(change_adaptor()));
799         marginsModule->topLE->setValidator(unsignedLengthValidator(
800                 marginsModule->topLE));
801         marginsModule->bottomLE->setValidator(unsignedLengthValidator(
802                 marginsModule->bottomLE));
803         marginsModule->innerLE->setValidator(unsignedLengthValidator(
804                 marginsModule->innerLE));
805         marginsModule->outerLE->setValidator(unsignedLengthValidator(
806                 marginsModule->outerLE));
807         marginsModule->headsepLE->setValidator(unsignedLengthValidator(
808                 marginsModule->headsepLE));
809         marginsModule->headheightLE->setValidator(unsignedLengthValidator(
810                 marginsModule->headheightLE));
811         marginsModule->footskipLE->setValidator(unsignedLengthValidator(
812                 marginsModule->footskipLE));
813         marginsModule->columnsepLE->setValidator(unsignedLengthValidator(
814                 marginsModule->columnsepLE));
815
816         bc().addCheckedLineEdit(marginsModule->topLE,
817                 marginsModule->topL);
818         bc().addCheckedLineEdit(marginsModule->bottomLE,
819                 marginsModule->bottomL);
820         bc().addCheckedLineEdit(marginsModule->innerLE,
821                 marginsModule->innerL);
822         bc().addCheckedLineEdit(marginsModule->outerLE,
823                 marginsModule->outerL);
824         bc().addCheckedLineEdit(marginsModule->headsepLE,
825                 marginsModule->headsepL);
826         bc().addCheckedLineEdit(marginsModule->headheightLE,
827                 marginsModule->headheightL);
828         bc().addCheckedLineEdit(marginsModule->footskipLE,
829                 marginsModule->footskipL);
830         bc().addCheckedLineEdit(marginsModule->columnsepLE,
831                 marginsModule->columnsepL);
832
833
834         langModule = new UiWidget<Ui::LanguageUi>;
835         // language & quote
836         connect(langModule->languageCO, SIGNAL(activated(int)),
837                 this, SLOT(change_adaptor()));
838         connect(langModule->defaultencodingRB, SIGNAL(clicked()),
839                 this, SLOT(change_adaptor()));
840         connect(langModule->otherencodingRB, SIGNAL(clicked()),
841                 this, SLOT(change_adaptor()));
842         connect(langModule->encodingCO, SIGNAL(activated(int)),
843                 this, SLOT(change_adaptor()));
844         connect(langModule->quoteStyleCO, SIGNAL(activated(int)),
845                 this, SLOT(change_adaptor()));
846         // language & quotes
847         QAbstractItemModel * language_model = guiApp->languageModel();
848         // FIXME: it would be nice if sorting was enabled/disabled via a checkbox.
849         language_model->sort(0);
850         langModule->languageCO->setModel(language_model);
851
852         // Always put the default encoding in the first position.
853         langModule->encodingCO->addItem(qt_("Language Default (no inputenc)"));
854         QStringList encodinglist;
855         Encodings::const_iterator it = encodings.begin();
856         Encodings::const_iterator const end = encodings.end();
857         for (; it != end; ++it)
858                 encodinglist.append(qt_(it->guiName()));
859         encodinglist.sort();
860         langModule->encodingCO->addItems(encodinglist);
861
862         langModule->quoteStyleCO->addItem(qt_("``text''"));
863         langModule->quoteStyleCO->addItem(qt_("''text''"));
864         langModule->quoteStyleCO->addItem(qt_(",,text``"));
865         langModule->quoteStyleCO->addItem(qt_(",,text''"));
866         langModule->quoteStyleCO->addItem(qt_("<<text>>"));
867         langModule->quoteStyleCO->addItem(qt_(">>text<<"));
868
869
870         numberingModule = new UiWidget<Ui::NumberingUi>;
871         // numbering
872         connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
873                 this, SLOT(change_adaptor()));
874         connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
875                 this, SLOT(change_adaptor()));
876         connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
877                 this, SLOT(updateNumbering()));
878         connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
879                 this, SLOT(updateNumbering()));
880         numberingModule->tocTW->setColumnCount(3);
881         numberingModule->tocTW->headerItem()->setText(0, qt_("Example"));
882         numberingModule->tocTW->headerItem()->setText(1, qt_("Numbered"));
883         numberingModule->tocTW->headerItem()->setText(2, qt_("Appears in TOC"));
884
885
886         biblioModule = new UiWidget<Ui::BiblioUi>;
887         connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
888                 biblioModule->citationStyleL, SLOT(setEnabled(bool)));
889         connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
890                 biblioModule->citeStyleCO, SLOT(setEnabled(bool)));
891         // biblio
892         connect(biblioModule->citeDefaultRB, SIGNAL(clicked()),
893                 this, SLOT(change_adaptor()));
894         connect(biblioModule->citeNatbibRB, SIGNAL(clicked()),
895                 this, SLOT(change_adaptor()));
896         connect(biblioModule->citeStyleCO, SIGNAL(activated(int)),
897                 this, SLOT(change_adaptor()));
898         connect(biblioModule->citeJurabibRB, SIGNAL(clicked()),
899                 this, SLOT(change_adaptor()));
900         connect(biblioModule->bibtopicCB, SIGNAL(clicked()),
901                 this, SLOT(change_adaptor()));
902         connect(biblioModule->bibtexCO, SIGNAL(activated(int)),
903                 this, SLOT(bibtexChanged(int)));
904         connect(biblioModule->bibtexOptionsED, SIGNAL(textChanged(QString)),
905                 this, SLOT(change_adaptor()));
906         // biblio
907         biblioModule->citeStyleCO->addItem(qt_("Author-year"));
908         biblioModule->citeStyleCO->addItem(qt_("Numerical"));
909         biblioModule->citeStyleCO->setCurrentIndex(0);
910         
911         biblioModule->bibtexCO->clear();
912
913         biblioModule->bibtexCO->addItem(qt_("Default"), QString("default"));
914         for (set<string>::const_iterator it = lyxrc.bibtex_alternatives.begin();
915                              it != lyxrc.bibtex_alternatives.end(); ++it) {
916                 QString const command = toqstr(*it).left(toqstr(*it).indexOf(" "));
917                 biblioModule->bibtexCO->addItem(command, command);
918         }
919
920         // indices
921         indicesModule = new GuiIndices;
922         connect(indicesModule, SIGNAL(changed()),
923                 this, SLOT(change_adaptor()));
924
925
926         mathsModule = new UiWidget<Ui::MathsUi>;
927         connect(mathsModule->amsautoCB, SIGNAL(toggled(bool)),
928                 mathsModule->amsCB, SLOT(setDisabled(bool)));
929         connect(mathsModule->esintautoCB, SIGNAL(toggled(bool)),
930                 mathsModule->esintCB, SLOT(setDisabled(bool)));
931         connect(mathsModule->mhchemautoCB, SIGNAL(toggled(bool)),
932                 mathsModule->mhchemCB, SLOT(setDisabled(bool)));
933         // maths
934         connect(mathsModule->amsCB, SIGNAL(clicked()),
935                 this, SLOT(change_adaptor()));
936         connect(mathsModule->amsautoCB, SIGNAL(clicked()),
937                 this, SLOT(change_adaptor()));
938         connect(mathsModule->esintCB, SIGNAL(clicked()),
939                 this, SLOT(change_adaptor()));
940         connect(mathsModule->esintautoCB, SIGNAL(clicked()),
941                 this, SLOT(change_adaptor()));
942         connect(mathsModule->mhchemCB, SIGNAL(clicked()),
943                 this, SLOT(change_adaptor()));
944         connect(mathsModule->mhchemautoCB, SIGNAL(clicked()),
945                 this, SLOT(change_adaptor()));
946
947         latexModule = new UiWidget<Ui::LaTeXUi>;
948         // latex class
949         connect(latexModule->optionsLE, SIGNAL(textChanged(QString)),
950                 this, SLOT(change_adaptor()));
951         connect(latexModule->defaultOptionsCB, SIGNAL(clicked()),
952                 this, SLOT(change_adaptor()));
953         connect(latexModule->psdriverCO, SIGNAL(activated(int)),
954                 this, SLOT(change_adaptor()));
955         connect(latexModule->classCO, SIGNAL(activated(int)),
956                 this, SLOT(classChanged()));
957         connect(latexModule->classCO, SIGNAL(activated(int)),
958                 this, SLOT(change_adaptor()));
959         connect(latexModule->layoutPB, SIGNAL(clicked()),
960                 this, SLOT(browseLayout()));
961         connect(latexModule->layoutPB, SIGNAL(clicked()),
962                 this, SLOT(change_adaptor()));
963         connect(latexModule->childDocGB, SIGNAL(clicked()),
964                 this, SLOT(change_adaptor()));
965         connect(latexModule->childDocLE, SIGNAL(textChanged(QString)),
966                 this, SLOT(change_adaptor()));
967         connect(latexModule->childDocPB, SIGNAL(clicked()),
968                 this, SLOT(browseMaster()));
969         connect(latexModule->suppressDateCB, SIGNAL(clicked()),
970                 this, SLOT(change_adaptor()));
971
972         // postscript drivers
973         for (int n = 0; tex_graphics[n][0]; ++n) {
974                 QString enc = qt_(tex_graphics_gui[n]);
975                 latexModule->psdriverCO->addItem(enc);
976         }
977         // latex classes
978         latexModule->classCO->setModel(&classes_model_);
979         LayoutFileList const & bcl = LayoutFileList::get();
980         vector<LayoutFileIndex> classList = bcl.classList();
981         sort(classList.begin(), classList.end(), less_textclass_avail_desc());
982
983         vector<LayoutFileIndex>::const_iterator cit  = classList.begin();
984         vector<LayoutFileIndex>::const_iterator cen = classList.end();
985         for (int i = 0; cit != cen; ++cit, ++i) {
986                 LayoutFile const & tc = bcl[*cit];
987                 docstring item = (tc.isTeXClassAvailable()) ?
988                         from_utf8(tc.description()) :
989                         bformat(_("Unavailable: %1$s"), from_utf8(tc.description()));
990                 classes_model_.insertRow(i, toqstr(item), *cit);
991         }
992
993         // branches
994         branchesModule = new GuiBranches;
995         connect(branchesModule, SIGNAL(changed()),
996                 this, SLOT(change_adaptor()));
997         connect(branchesModule, SIGNAL(renameBranches(docstring const &, docstring const &)),
998                 this, SLOT(branchesRename(docstring const &, docstring const &)));
999         updateUnknownBranches();
1000
1001         // preamble
1002         preambleModule = new PreambleModule;
1003         connect(preambleModule, SIGNAL(changed()),
1004                 this, SLOT(change_adaptor()));
1005
1006         // bullets
1007         bulletsModule = new BulletsModule;
1008         connect(bulletsModule, SIGNAL(changed()),
1009                 this, SLOT(change_adaptor()));
1010
1011         // Modules
1012         modulesModule = new UiWidget<Ui::ModulesUi>;
1013         modulesModule->availableLV->header()->setVisible(false);
1014         selectionManager =
1015                 new ModuleSelectionManager(modulesModule->availableLV,
1016                         modulesModule->selectedLV,
1017                         modulesModule->addPB, modulesModule->deletePB,
1018                         modulesModule->upPB, modulesModule->downPB,
1019                         availableModel(), selectedModel(), this);
1020         connect(selectionManager, SIGNAL(updateHook()),
1021                 this, SLOT(updateModuleInfo()));
1022         connect(selectionManager, SIGNAL(updateHook()),
1023                 this, SLOT(change_adaptor()));
1024         connect(selectionManager, SIGNAL(selectionChanged()),
1025                 this, SLOT(modulesChanged()));
1026
1027         // PDF support
1028         pdfSupportModule = new UiWidget<Ui::PDFSupportUi>;
1029
1030         connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
1031                 this, SLOT(change_adaptor()));
1032         connect(pdfSupportModule->titleLE, SIGNAL(textChanged(QString)),
1033                 this, SLOT(change_adaptor()));
1034         connect(pdfSupportModule->authorLE, SIGNAL(textChanged(QString)),
1035                 this, SLOT(change_adaptor()));
1036         connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(QString)),
1037                 this, SLOT(change_adaptor()));
1038         connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(QString)),
1039                 this, SLOT(change_adaptor()));
1040         connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
1041                 this, SLOT(change_adaptor()));
1042         connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
1043                 this, SLOT(change_adaptor()));
1044         connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
1045                 this, SLOT(change_adaptor()));
1046         connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
1047                 this, SLOT(change_adaptor()));
1048         connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
1049                 this, SLOT(change_adaptor()));
1050         connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
1051                 this, SLOT(change_adaptor()));
1052         connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
1053                 this, SLOT(change_adaptor()));
1054         connect(pdfSupportModule->backrefCO, SIGNAL(activated(int)),
1055                 this, SLOT(change_adaptor()));
1056         connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
1057                 this, SLOT(change_adaptor()));
1058         connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
1059                 this, SLOT(change_adaptor()));
1060         connect(pdfSupportModule->optionsLE, SIGNAL(textChanged(QString)),
1061                 this, SLOT(change_adaptor()));
1062
1063         for (int i = 0; backref_opts[i][0]; ++i)
1064                 pdfSupportModule->backrefCO->addItem(qt_(backref_opts_gui[i]));
1065
1066         // float
1067         floatModule = new FloatPlacement;
1068         connect(floatModule, SIGNAL(changed()),
1069                 this, SLOT(change_adaptor()));
1070
1071         // listings
1072         listingsModule = new UiWidget<Ui::ListingsSettingsUi>;
1073         connect(listingsModule->listingsED, SIGNAL(textChanged()),
1074                 this, SLOT(change_adaptor()));
1075         connect(listingsModule->bypassCB, SIGNAL(clicked()), 
1076                 this, SLOT(change_adaptor()));
1077         connect(listingsModule->bypassCB, SIGNAL(clicked()), 
1078                 this, SLOT(setListingsMessage()));
1079         connect(listingsModule->listingsED, SIGNAL(textChanged()),
1080                 this, SLOT(setListingsMessage()));
1081         listingsModule->listingsTB->setPlainText(
1082                 qt_("Input listings parameters below. Enter ? for a list of parameters."));
1083
1084         docPS->addPanel(latexModule, qt_("Document Class"));
1085         docPS->addPanel(masterChildModule, qt_("Child Documents"));
1086         docPS->addPanel(modulesModule, qt_("Modules"));
1087         docPS->addPanel(fontModule, qt_("Fonts"));
1088         docPS->addPanel(textLayoutModule, qt_("Text Layout"));
1089         docPS->addPanel(pageLayoutModule, qt_("Page Layout"));
1090         docPS->addPanel(marginsModule, qt_("Page Margins"));
1091         docPS->addPanel(langModule, qt_("Language"));
1092         docPS->addPanel(numberingModule, qt_("Numbering & TOC"));
1093         docPS->addPanel(biblioModule, qt_("Bibliography"));
1094         docPS->addPanel(indicesModule, qt_("Indexes"));
1095         docPS->addPanel(pdfSupportModule, qt_("PDF Properties"));
1096         docPS->addPanel(mathsModule, qt_("Math Options"));
1097         docPS->addPanel(floatModule, qt_("Float Placement"));
1098         docPS->addPanel(listingsModule, qt_("Listings"));
1099         docPS->addPanel(bulletsModule, qt_("Bullets"));
1100         docPS->addPanel(branchesModule, qt_("Branches"));
1101         docPS->addPanel(outputModule, qt_("Output"));
1102         docPS->addPanel(preambleModule, qt_("LaTeX Preamble"));
1103         docPS->setCurrentPanel(qt_("Document Class"));
1104 // FIXME: hack to work around resizing bug in Qt >= 4.2
1105 // bug verified with Qt 4.2.{0-3} (JSpitzm)
1106 #if QT_VERSION >= 0x040200
1107         docPS->updateGeometry();
1108 #endif
1109 }
1110
1111
1112 void GuiDocument::showPreamble()
1113 {
1114         docPS->setCurrentPanel(qt_("LaTeX Preamble"));
1115 }
1116
1117
1118 void GuiDocument::saveDefaultClicked()
1119 {
1120         saveDocDefault();
1121 }
1122
1123
1124 void GuiDocument::useDefaultsClicked()
1125 {
1126         useClassDefaults();
1127 }
1128
1129
1130 void GuiDocument::change_adaptor()
1131 {
1132         changed();
1133 }
1134
1135
1136 void GuiDocument::includeonlyClicked(QTreeWidgetItem * item, int)
1137 {
1138         if (item == 0)
1139                 return;
1140
1141         string child = fromqstr(item->text(0));
1142         if (child.empty())
1143                 return;
1144
1145         if (std::find(includeonlys_.begin(),
1146                       includeonlys_.end(), child) != includeonlys_.end())
1147                 includeonlys_.remove(child);
1148         else
1149                 includeonlys_.push_back(child);
1150         
1151         updateIncludeonlys();
1152         changed();
1153 }
1154
1155
1156 QString GuiDocument::validateListingsParameters()
1157 {
1158         // use a cache here to avoid repeated validation
1159         // of the same parameters
1160         static string param_cache;
1161         static QString msg_cache;
1162         
1163         if (listingsModule->bypassCB->isChecked())
1164                 return QString();
1165
1166         string params = fromqstr(listingsModule->listingsED->toPlainText());
1167         if (params != param_cache) {
1168                 param_cache = params;
1169                 msg_cache = toqstr(InsetListingsParams(params).validate());
1170         }
1171         return msg_cache;
1172 }
1173
1174
1175 void GuiDocument::setListingsMessage()
1176 {
1177         static bool isOK = true;
1178         QString msg = validateListingsParameters();
1179         if (msg.isEmpty()) {
1180                 if (isOK)
1181                         return;
1182                 isOK = true;
1183                 // listingsTB->setTextColor("black");
1184                 listingsModule->listingsTB->setPlainText(
1185                         qt_("Input listings parameters below. "
1186                 "Enter ? for a list of parameters."));
1187         } else {
1188                 isOK = false;
1189                 // listingsTB->setTextColor("red");
1190                 listingsModule->listingsTB->setPlainText(msg);
1191         }
1192 }
1193
1194
1195 void GuiDocument::setLSpacing(int item)
1196 {
1197         textLayoutModule->lspacingLE->setEnabled(item == 3);
1198 }
1199
1200
1201 void GuiDocument::setIndent(int item)
1202 {
1203         bool const enable = (item == 1);
1204         textLayoutModule->indentLE->setEnabled(enable);
1205         textLayoutModule->indentLengthCO->setEnabled(enable);
1206         textLayoutModule->skipLE->setEnabled(false);
1207         textLayoutModule->skipLengthCO->setEnabled(false);
1208         isValid();
1209 }
1210
1211
1212 void GuiDocument::enableIndent(bool indent)
1213 {
1214         textLayoutModule->skipLE->setEnabled(!indent);
1215         textLayoutModule->skipLengthCO->setEnabled(!indent);
1216         if (indent)
1217                 setIndent(textLayoutModule->indentCO->currentIndex());
1218 }
1219
1220
1221 void GuiDocument::setSkip(int item)
1222 {
1223         bool const enable = (item == 3);
1224         textLayoutModule->skipLE->setEnabled(enable);
1225         textLayoutModule->skipLengthCO->setEnabled(enable);
1226         isValid();
1227 }
1228
1229
1230 void GuiDocument::enableSkip(bool skip)
1231 {
1232         textLayoutModule->indentLE->setEnabled(!skip);
1233         textLayoutModule->indentLengthCO->setEnabled(!skip);
1234         if (skip)
1235                 setSkip(textLayoutModule->skipCO->currentIndex());
1236 }
1237
1238
1239 void GuiDocument::portraitChanged()
1240 {
1241         setMargins(pageLayoutModule->papersizeCO->currentIndex());
1242 }
1243
1244
1245 void GuiDocument::setMargins(bool custom)
1246 {
1247         bool const extern_geometry =
1248                 documentClass().provides("geometry");
1249         marginsModule->marginCB->setEnabled(!extern_geometry);
1250         if (extern_geometry) {
1251                 marginsModule->marginCB->setChecked(false);
1252                 setCustomMargins(true);
1253                 return;
1254         }
1255         marginsModule->marginCB->setChecked(custom);
1256         setCustomMargins(custom);
1257 }
1258
1259
1260 void GuiDocument::papersizeChanged(int paper_size)
1261 {
1262         setCustomPapersize(paper_size == 1);
1263 }
1264
1265
1266 void GuiDocument::setCustomPapersize(bool custom)
1267 {
1268         pageLayoutModule->paperwidthL->setEnabled(custom);
1269         pageLayoutModule->paperwidthLE->setEnabled(custom);
1270         pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
1271         pageLayoutModule->paperheightL->setEnabled(custom);
1272         pageLayoutModule->paperheightLE->setEnabled(custom);
1273         pageLayoutModule->paperheightLE->setFocus();
1274         pageLayoutModule->paperheightUnitCO->setEnabled(custom);
1275 }
1276
1277
1278 void GuiDocument::setColSep()
1279 {
1280         setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
1281 }
1282
1283
1284 void GuiDocument::setCustomMargins(bool custom)
1285 {
1286         marginsModule->topL->setEnabled(!custom);
1287         marginsModule->topLE->setEnabled(!custom);
1288         marginsModule->topUnit->setEnabled(!custom);
1289
1290         marginsModule->bottomL->setEnabled(!custom);
1291         marginsModule->bottomLE->setEnabled(!custom);
1292         marginsModule->bottomUnit->setEnabled(!custom);
1293
1294         marginsModule->innerL->setEnabled(!custom);
1295         marginsModule->innerLE->setEnabled(!custom);
1296         marginsModule->innerUnit->setEnabled(!custom);
1297
1298         marginsModule->outerL->setEnabled(!custom);
1299         marginsModule->outerLE->setEnabled(!custom);
1300         marginsModule->outerUnit->setEnabled(!custom);
1301
1302         marginsModule->headheightL->setEnabled(!custom);
1303         marginsModule->headheightLE->setEnabled(!custom);
1304         marginsModule->headheightUnit->setEnabled(!custom);
1305
1306         marginsModule->headsepL->setEnabled(!custom);
1307         marginsModule->headsepLE->setEnabled(!custom);
1308         marginsModule->headsepUnit->setEnabled(!custom);
1309
1310         marginsModule->footskipL->setEnabled(!custom);
1311         marginsModule->footskipLE->setEnabled(!custom);
1312         marginsModule->footskipUnit->setEnabled(!custom);
1313
1314         bool const enableColSep = !custom && 
1315                         textLayoutModule->twoColumnCB->checkState() == Qt::Checked;
1316         marginsModule->columnsepL->setEnabled(enableColSep);
1317         marginsModule->columnsepLE->setEnabled(enableColSep);
1318         marginsModule->columnsepUnit->setEnabled(enableColSep);
1319 }
1320
1321 void GuiDocument::changeBackgroundColor()
1322 {
1323         QColor const & newColor = QColorDialog::getColor(
1324                 rgb2qcolor(set_backgroundcolor), asQWidget());
1325         if (!newColor.isValid())
1326                 return;
1327         // set the button color
1328         pageLayoutModule->backgroundPB->setStyleSheet(
1329                 colorButtonStyleSheet(newColor));
1330         // save color
1331         set_backgroundcolor = rgbFromHexName(fromqstr(newColor.name()));
1332         changed();
1333 }
1334
1335
1336 void GuiDocument::deleteBackgroundColor()
1337 {
1338         // set the button color back to white
1339         pageLayoutModule->backgroundPB->setStyleSheet(
1340                 colorButtonStyleSheet(QColor(Qt::white)));
1341         // save white as the set color
1342         set_backgroundcolor = rgbFromHexName("#ffffff");
1343         changed();
1344 }
1345
1346
1347 void GuiDocument::xetexChanged(bool xetex)
1348 {
1349         updateFontlist();
1350         updateDefaultFormat();
1351         langModule->encodingCO->setEnabled(!xetex &&
1352                 !langModule->defaultencodingRB->isChecked());
1353         langModule->defaultencodingRB->setEnabled(!xetex);
1354         langModule->otherencodingRB->setEnabled(!xetex);
1355
1356         fontModule->fontsDefaultCO->setEnabled(!xetex);
1357         fontModule->fontsDefaultLA->setEnabled(!xetex);
1358         fontModule->cjkFontLE->setEnabled(!xetex);
1359         fontModule->cjkFontLA->setEnabled(!xetex);
1360         string font;
1361         if (!xetex)
1362                 font = tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1363         bool scaleable = providesScale(font);
1364         fontModule->scaleSansSB->setEnabled(scaleable);
1365         fontModule->scaleSansLA->setEnabled(scaleable);
1366         if (!xetex)
1367                 font = tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1368         scaleable = providesScale(font);
1369         fontModule->scaleTypewriterSB->setEnabled(scaleable);
1370         fontModule->scaleTypewriterLA->setEnabled(scaleable);
1371         if (!xetex)
1372                 font = tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1373         fontModule->fontScCB->setEnabled(providesSC(font));
1374         fontModule->fontOsfCB->setEnabled(providesOSF(font));
1375         
1376         fontModule->fontencLA->setEnabled(!xetex);
1377         fontModule->fontencCO->setEnabled(!xetex);
1378         fontModule->fontencLE->setEnabled(!xetex);
1379 }
1380
1381
1382 void GuiDocument::updateFontsize(string const & items, string const & sel)
1383 {
1384         fontModule->fontsizeCO->clear();
1385         fontModule->fontsizeCO->addItem(qt_("Default"));
1386
1387         for (int n = 0; !token(items,'|',n).empty(); ++n)
1388                 fontModule->fontsizeCO->
1389                         addItem(toqstr(token(items,'|',n)));
1390
1391         for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
1392                 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
1393                         fontModule->fontsizeCO->setCurrentIndex(n);
1394                         break;
1395                 }
1396         }
1397 }
1398
1399
1400 void GuiDocument::updateFontlist()
1401 {
1402         fontModule->fontsRomanCO->clear();
1403         fontModule->fontsSansCO->clear();
1404         fontModule->fontsTypewriterCO->clear();
1405
1406         // With XeTeX, we have access to all system fonts, but not the LaTeX fonts
1407         if (outputModule->xetexCB->isChecked()) {
1408                 fontModule->fontsRomanCO->addItem(qt_("Default"));
1409                 fontModule->fontsSansCO->addItem(qt_("Default"));
1410                 fontModule->fontsTypewriterCO->addItem(qt_("Default"));
1411         
1412                 QFontDatabase fontdb;
1413                 QStringList families(fontdb.families());
1414                 for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
1415                         fontModule->fontsRomanCO->addItem(*it);
1416                         fontModule->fontsSansCO->addItem(*it);
1417                         fontModule->fontsTypewriterCO->addItem(*it);
1418                 }
1419                 return;
1420         }
1421
1422         for (int n = 0; tex_fonts_roman[n][0]; ++n) {
1423                 QString font = qt_(tex_fonts_roman_gui[n]);
1424                 if (!isFontAvailable(tex_fonts_roman[n]))
1425                         font += qt_(" (not installed)");
1426                 fontModule->fontsRomanCO->addItem(font);
1427         }
1428         for (int n = 0; tex_fonts_sans[n][0]; ++n) {
1429                 QString font = qt_(tex_fonts_sans_gui[n]);
1430                 if (!isFontAvailable(tex_fonts_sans[n]))
1431                         font += qt_(" (not installed)");
1432                 fontModule->fontsSansCO->addItem(font);
1433         }
1434         for (int n = 0; tex_fonts_monospaced[n][0]; ++n) {
1435                 QString font = qt_(tex_fonts_monospaced_gui[n]);
1436                 if (!isFontAvailable(tex_fonts_monospaced[n]))
1437                         font += qt_(" (not installed)");
1438                 fontModule->fontsTypewriterCO->addItem(font);
1439         }
1440 }
1441
1442
1443 void GuiDocument::fontencChanged(int item)
1444 {
1445         fontModule->fontencLE->setEnabled(item == 1);
1446 }
1447
1448
1449 void GuiDocument::romanChanged(int item)
1450 {
1451         if (outputModule->xetexCB->isChecked())
1452                 return;
1453         string const font = tex_fonts_roman[item];
1454         fontModule->fontScCB->setEnabled(providesSC(font));
1455         fontModule->fontOsfCB->setEnabled(providesOSF(font));
1456 }
1457
1458
1459 void GuiDocument::sansChanged(int item)
1460 {
1461         if (outputModule->xetexCB->isChecked())
1462                 return;
1463         string const font = tex_fonts_sans[item];
1464         bool scaleable = providesScale(font);
1465         fontModule->scaleSansSB->setEnabled(scaleable);
1466         fontModule->scaleSansLA->setEnabled(scaleable);
1467 }
1468
1469
1470 void GuiDocument::ttChanged(int item)
1471 {
1472         if (outputModule->xetexCB->isChecked())
1473                 return;
1474         string const font = tex_fonts_monospaced[item];
1475         bool scaleable = providesScale(font);
1476         fontModule->scaleTypewriterSB->setEnabled(scaleable);
1477         fontModule->scaleTypewriterLA->setEnabled(scaleable);
1478 }
1479
1480
1481 void GuiDocument::updatePagestyle(string const & items, string const & sel)
1482 {
1483         pagestyles.clear();
1484         pageLayoutModule->pagestyleCO->clear();
1485         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1486
1487         for (int n = 0; !token(items, '|', n).empty(); ++n) {
1488                 string style = token(items, '|', n);
1489                 QString style_gui = qt_(style);
1490                 pagestyles.push_back(pair<string, QString>(style, style_gui));
1491                 pageLayoutModule->pagestyleCO->addItem(style_gui);
1492         }
1493
1494         if (sel == "default") {
1495                 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
1496                 return;
1497         }
1498
1499         int nn = 0;
1500
1501         for (size_t i = 0; i < pagestyles.size(); ++i)
1502                 if (pagestyles[i].first == sel)
1503                         nn = pageLayoutModule->pagestyleCO->findText(pagestyles[i].second);
1504
1505         if (nn > 0)
1506                 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
1507 }
1508
1509
1510 void GuiDocument::browseLayout()
1511 {
1512         QString const label1 = qt_("Layouts|#o#O");
1513         QString const dir1 = toqstr(lyxrc.document_path);
1514         QStringList const filter(qt_("LyX Layout (*.layout)"));
1515         QString file = browseRelFile(QString(), bufferFilepath(),
1516                 qt_("Local layout file"), filter, false,
1517                 label1, dir1);
1518
1519         if (!file.endsWith(".layout"))
1520                 return;
1521
1522         FileName layoutFile = support::makeAbsPath(fromqstr(file),
1523                 fromqstr(bufferFilepath()));
1524         
1525         int const ret = Alert::prompt(_("Local layout file"),
1526                 _("The layout file you have selected is a local layout\n"
1527                   "file, not one in the system or user directory. Your\n"
1528                   "document may not work with this layout if you do not\n"
1529                   "keep the layout file in the document directory."),
1530                   1, 1, _("&Set Layout"), _("&Cancel"));
1531         if (ret == 1)
1532                 return;
1533
1534         // load the layout file
1535         LayoutFileList & bcl = LayoutFileList::get();
1536         string classname = layoutFile.onlyFileName();
1537         // this will update an existing layout if that layout has been loaded before.
1538         LayoutFileIndex name = bcl.addLocalLayout(
1539                 classname.substr(0, classname.size() - 7),
1540                 layoutFile.onlyPath().absFilename());
1541
1542         if (name.empty()) {
1543                 Alert::error(_("Error"),
1544                         _("Unable to read local layout file."));                
1545                 return;
1546         }
1547
1548         // do not trigger classChanged if there is no change.
1549         if (latexModule->classCO->currentText() == toqstr(name))
1550                 return;
1551                 
1552         // add to combo box
1553         int idx = latexModule->classCO->findText(toqstr(name));
1554         if (idx == -1) {
1555                 classes_model_.insertRow(0, toqstr(name), name);
1556                 latexModule->classCO->setCurrentIndex(0);
1557         } else
1558                 latexModule->classCO->setCurrentIndex(idx);
1559         
1560         classChanged();
1561 }
1562
1563
1564 void GuiDocument::browseMaster()
1565 {
1566         QString const title = qt_("Select master document");
1567         QString const dir1 = toqstr(lyxrc.document_path);
1568         QString const old = latexModule->childDocLE->text();
1569         QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
1570         QStringList const filter(qt_("LyX Files (*.lyx)"));
1571         QString file = browseRelFile(old, docpath, title, filter, false,
1572                 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
1573
1574         if (!file.isEmpty())
1575                 latexModule->childDocLE->setText(file);
1576 }
1577
1578
1579 void GuiDocument::classChanged()
1580 {
1581         int idx = latexModule->classCO->currentIndex();
1582         if (idx < 0) 
1583                 return;
1584         string const classname = classes_model_.getIDString(idx);
1585
1586         // check whether the selected modules have changed.
1587         bool modules_changed = false;
1588         unsigned int const srows = selectedModel()->rowCount();
1589         if (srows != bp_.getModules().size())
1590                 modules_changed = true;
1591         else {
1592                 list<string>::const_iterator mit = bp_.getModules().begin();
1593                 list<string>::const_iterator men = bp_.getModules().end();
1594                 for (unsigned int i = 0; i < srows && mit != men; ++i, ++mit)
1595                         if (selectedModel()->getIDString(i) != *mit) {
1596                                 modules_changed = true;
1597                                 break;
1598                         }
1599         }
1600
1601         if (modules_changed || lyxrc.auto_reset_options) {
1602                 if (applyPB->isEnabled()) {
1603                         int const ret = Alert::prompt(_("Unapplied changes"),
1604                                         _("Some changes in the dialog were not yet applied.\n"
1605                                         "If you do not apply now, they will be lost after this action."),
1606                                         1, 1, _("&Apply"), _("&Dismiss"));
1607                         if (ret == 0)
1608                                 applyView();
1609                 }
1610         }
1611
1612         // We load the TextClass as soon as it is selected. This is
1613         // necessary so that other options in the dialog can be updated
1614         // according to the new class. Note, however, that, if you use 
1615         // the scroll wheel when sitting on the combo box, we'll load a 
1616         // lot of TextClass objects very quickly....
1617         if (!bp_.setBaseClass(classname)) {
1618                 Alert::error(_("Error"), _("Unable to set document class."));
1619                 return;
1620         }
1621         if (lyxrc.auto_reset_options)
1622                 bp_.useClassDefaults();
1623
1624         // With the introduction of modules came a distinction between the base 
1625         // class and the document class. The former corresponds to the main layout 
1626         // file; the latter is that plus the modules (or the document-specific layout,
1627         // or  whatever else there could be). Our parameters come from the document 
1628         // class. So when we set the base class, we also need to recreate the document 
1629         // class. Otherwise, we still have the old one.
1630         bp_.makeDocumentClass();
1631         paramsToDialog();
1632 }
1633
1634
1635 void GuiDocument::bibtexChanged(int n)
1636 {
1637         biblioModule->bibtexOptionsED->setEnabled(n != 0);
1638         changed();
1639 }
1640
1641
1642 namespace {
1643         // This is an insanely complicated attempt to make this sort of thing
1644         // work with RTL languages.
1645         docstring formatStrVec(vector<string> const & v, docstring const & s) 
1646         {
1647                 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
1648                 if (v.size() == 0)
1649                         return docstring();
1650                 if (v.size() == 1) 
1651                         return from_utf8(v[0]);
1652                 if (v.size() == 2) {
1653                         docstring retval = _("%1$s and %2$s");
1654                         retval = subst(retval, _("and"), s);
1655                         return bformat(retval, from_utf8(v[0]), from_utf8(v[1]));
1656                 }
1657                 // The idea here is to format all but the last two items...
1658                 int const vSize = v.size();
1659                 docstring t2 = _("%1$s, %2$s");
1660                 docstring retval = from_utf8(v[0]);
1661                 for (int i = 1; i < vSize - 2; ++i)
1662                         retval = bformat(t2, retval, from_utf8(v[i])); 
1663                 //...and then to  plug them, and the last two, into this schema
1664                 docstring t = _("%1$s, %2$s, and %3$s");
1665                 t = subst(t, _("and"), s);
1666                 return bformat(t, retval, from_utf8(v[vSize - 2]), from_utf8(v[vSize - 1]));
1667         }
1668         
1669         vector<string> idsToNames(vector<string> const & idList)
1670         {
1671                 vector<string> retval;
1672                 vector<string>::const_iterator it  = idList.begin();
1673                 vector<string>::const_iterator end = idList.end();
1674                 for (; it != end; ++it) {
1675                         LyXModule const * const mod = theModuleList[*it];
1676                         if (!mod)
1677                                 retval.push_back(*it + " (Unavailable)");
1678                         else
1679                                 retval.push_back(mod->getName());
1680                 }
1681                 return retval;
1682         }
1683 }
1684
1685
1686 void GuiDocument::modulesToParams(BufferParams & bp)
1687 {
1688         // update list of loaded modules
1689         bp.clearLayoutModules();
1690         int const srows = modules_sel_model_.rowCount();
1691         for (int i = 0; i < srows; ++i)
1692                 bp.addLayoutModule(modules_sel_model_.getIDString(i));
1693
1694         // update the list of removed modules
1695         bp.clearRemovedModules();
1696         LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
1697         list<string>::const_iterator rit = reqmods.begin();
1698         list<string>::const_iterator ren = reqmods.end();
1699
1700         // check each of the default modules
1701         for (; rit != ren; rit++) {
1702                 list<string>::const_iterator mit = bp.getModules().begin();
1703                 list<string>::const_iterator men = bp.getModules().end();
1704                 bool found = false;
1705                 for (; mit != men; mit++) {
1706                         if (*rit == *mit) {
1707                                 found = true;
1708                                 break;
1709                         }
1710                 }
1711                 if (!found) {
1712                         // the module isn't present so must have been removed by the user
1713                         bp.addRemovedModule(*rit);
1714                 }
1715         }
1716 }
1717
1718 void GuiDocument::modulesChanged()
1719 {
1720         modulesToParams(bp_);
1721         bp_.makeDocumentClass();
1722         paramsToDialog();
1723 }
1724
1725
1726 void GuiDocument::updateModuleInfo()
1727 {
1728         selectionManager->update();
1729         
1730         //Module description
1731         bool const focus_on_selected = selectionManager->selectedFocused();
1732         QAbstractItemView * lv;
1733         if (focus_on_selected)
1734                 lv = modulesModule->selectedLV;
1735         else
1736                 lv= modulesModule->availableLV;
1737         if (lv->selectionModel()->selectedIndexes().isEmpty()) {
1738                 modulesModule->infoML->document()->clear();
1739                 return;
1740         }
1741         QModelIndex const & idx = lv->selectionModel()->currentIndex();
1742         GuiIdListModel const & id_model = 
1743                         focus_on_selected  ? modules_sel_model_ : modules_av_model_;
1744         string const modName = id_model.getIDString(idx.row());
1745         docstring desc = getModuleDescription(modName);
1746
1747         LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
1748         if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
1749                 if (!desc.empty())
1750                         desc += "\n";
1751                 desc += _("Module provided by document class.");
1752         }
1753
1754         vector<string> pkglist = getPackageList(modName);
1755         docstring pkgdesc = formatStrVec(pkglist, _("and"));
1756         if (!pkgdesc.empty()) {
1757                 if (!desc.empty())
1758                         desc += "\n";
1759                 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
1760         }
1761
1762         pkglist = getRequiredList(modName);
1763         if (!pkglist.empty()) {
1764                 vector<string> const reqdescs = idsToNames(pkglist);
1765                 pkgdesc = formatStrVec(reqdescs, _("or"));
1766                 if (!desc.empty())
1767                         desc += "\n";
1768                 desc += bformat(_("Module required: %1$s."), pkgdesc);
1769         }
1770
1771         pkglist = getExcludedList(modName);
1772         if (!pkglist.empty()) {
1773                 vector<string> const reqdescs = idsToNames(pkglist);
1774                 pkgdesc = formatStrVec(reqdescs, _( "and"));
1775                 if (!desc.empty())
1776                         desc += "\n";
1777                 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
1778         }
1779
1780         if (!isModuleAvailable(modName)) {
1781                 if (!desc.empty())
1782                         desc += "\n";
1783                 desc += _("WARNING: Some required packages are unavailable!");
1784         }
1785
1786         modulesModule->infoML->document()->setPlainText(toqstr(desc));
1787 }
1788
1789
1790 void GuiDocument::updateNumbering()
1791 {
1792         DocumentClass const & tclass = documentClass();
1793
1794         numberingModule->tocTW->setUpdatesEnabled(false);
1795         numberingModule->tocTW->clear();
1796
1797         int const depth = numberingModule->depthSL->value();
1798         int const toc = numberingModule->tocSL->value();
1799         QString const no = qt_("No");
1800         QString const yes = qt_("Yes");
1801         QTreeWidgetItem * item = 0;
1802
1803         DocumentClass::const_iterator lit = tclass.begin();
1804         DocumentClass::const_iterator len = tclass.end();
1805         for (; lit != len; ++lit) {
1806                 int const toclevel = lit->toclevel;
1807                 if (toclevel != Layout::NOT_IN_TOC && lit->labeltype == LABEL_COUNTER) {
1808                         item = new QTreeWidgetItem(numberingModule->tocTW);
1809                         item->setText(0, toqstr(translateIfPossible(lit->name())));
1810                         item->setText(1, (toclevel <= depth) ? yes : no);
1811                         item->setText(2, (toclevel <= toc) ? yes : no);
1812                 }
1813         }
1814
1815         numberingModule->tocTW->setUpdatesEnabled(true);
1816         numberingModule->tocTW->update();
1817 }
1818
1819
1820 void GuiDocument::updateDefaultFormat()
1821 {
1822         // make a copy in order to consider unapplied changes
1823         Buffer * tmpbuf = const_cast<Buffer *>(&buffer());
1824         tmpbuf->params().useXetex = outputModule->xetexCB->isChecked();
1825         int idx = latexModule->classCO->currentIndex();
1826         if (idx >= 0) {
1827                 string const classname = classes_model_.getIDString(idx);
1828                 tmpbuf->params().setBaseClass(classname);
1829                 tmpbuf->params().makeDocumentClass();
1830         }
1831         outputModule->defaultFormatCO->blockSignals(true);
1832         outputModule->defaultFormatCO->clear();
1833         outputModule->defaultFormatCO->addItem(qt_("Default"),
1834                                 QVariant(QString("default")));
1835         typedef vector<Format const *> Formats;
1836         Formats formats = tmpbuf->exportableFormats(true);
1837         Formats::const_iterator cit = formats.begin();
1838         Formats::const_iterator end = formats.end();
1839         for (; cit != end; ++cit)
1840                 outputModule->defaultFormatCO->addItem(qt_((*cit)->prettyname()),
1841                                 QVariant(toqstr((*cit)->name())));
1842         outputModule->defaultFormatCO->blockSignals(false);
1843 }
1844
1845
1846 bool GuiDocument::isChildIncluded(string const & child)
1847 {
1848         if (includeonlys_.empty())
1849                 return false;
1850         return (std::find(includeonlys_.begin(),
1851                           includeonlys_.end(), child) != includeonlys_.end());
1852 }
1853
1854
1855 void GuiDocument::applyView()
1856 {
1857         // preamble
1858         preambleModule->apply(bp_);
1859
1860         // date
1861         bp_.suppress_date = latexModule->suppressDateCB->isChecked();
1862
1863         // biblio
1864         bp_.setCiteEngine(ENGINE_BASIC);
1865
1866         if (biblioModule->citeNatbibRB->isChecked()) {
1867                 bool const use_numerical_citations =
1868                         biblioModule->citeStyleCO->currentIndex();
1869                 if (use_numerical_citations)
1870                         bp_.setCiteEngine(ENGINE_NATBIB_NUMERICAL);
1871                 else
1872                         bp_.setCiteEngine(ENGINE_NATBIB_AUTHORYEAR);
1873
1874         } else if (biblioModule->citeJurabibRB->isChecked())
1875                 bp_.setCiteEngine(ENGINE_JURABIB);
1876
1877         bp_.use_bibtopic =
1878                 biblioModule->bibtopicCB->isChecked();
1879
1880         string const bibtex_command =
1881                 fromqstr(biblioModule->bibtexCO->itemData(
1882                         biblioModule->bibtexCO->currentIndex()).toString());
1883         string const bibtex_options =
1884                 fromqstr(biblioModule->bibtexOptionsED->text());
1885         if (bibtex_command == "default" || bibtex_options.empty())
1886                 bp_.bibtex_command = bibtex_command;
1887         else
1888                 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
1889
1890         // Indices
1891         indicesModule->apply(bp_);
1892
1893         // language & quotes
1894         if (langModule->defaultencodingRB->isChecked()) {
1895                 bp_.inputenc = "auto";
1896         } else {
1897                 int i = langModule->encodingCO->currentIndex();
1898                 if (i == 0)
1899                         bp_.inputenc = "default";
1900                 else {
1901                         QString const enc_gui =
1902                                 langModule->encodingCO->currentText();
1903                         Encodings::const_iterator it = encodings.begin();
1904                         Encodings::const_iterator const end = encodings.end();
1905                         bool found = false;
1906                         for (; it != end; ++it) {
1907                                 if (qt_(it->guiName()) == enc_gui) {
1908                                         bp_.inputenc = it->latexName();
1909                                         found = true;
1910                                         break;
1911                                 }
1912                         }
1913                         if (!found) {
1914                                 // should not happen
1915                                 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
1916                                 bp_.inputenc = "default";
1917                         }
1918                 }
1919         }
1920
1921         InsetQuotes::QuoteLanguage lga = InsetQuotes::EnglishQuotes;
1922         switch (langModule->quoteStyleCO->currentIndex()) {
1923         case 0:
1924                 lga = InsetQuotes::EnglishQuotes;
1925                 break;
1926         case 1:
1927                 lga = InsetQuotes::SwedishQuotes;
1928                 break;
1929         case 2:
1930                 lga = InsetQuotes::GermanQuotes;
1931                 break;
1932         case 3:
1933                 lga = InsetQuotes::PolishQuotes;
1934                 break;
1935         case 4:
1936                 lga = InsetQuotes::FrenchQuotes;
1937                 break;
1938         case 5:
1939                 lga = InsetQuotes::DanishQuotes;
1940                 break;
1941         }
1942         bp_.quotes_language = lga;
1943
1944         QString const lang = langModule->languageCO->itemData(
1945                 langModule->languageCO->currentIndex()).toString();
1946         bp_.language = lyx::languages.getLanguage(fromqstr(lang));
1947
1948         // numbering
1949         if (bp_.documentClass().hasTocLevels()) {
1950                 bp_.tocdepth = numberingModule->tocSL->value();
1951                 bp_.secnumdepth = numberingModule->depthSL->value();
1952         }
1953
1954         // bullets
1955         bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
1956         bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
1957         bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
1958         bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
1959
1960         // packages
1961         bp_.graphicsDriver =
1962                 tex_graphics[latexModule->psdriverCO->currentIndex()];
1963         
1964         // text layout
1965         int idx = latexModule->classCO->currentIndex();
1966         if (idx >= 0) {
1967                 string const classname = classes_model_.getIDString(idx);
1968                 bp_.setBaseClass(classname);
1969         }
1970
1971         // Modules
1972         modulesToParams(bp_);
1973
1974         // Math
1975         if (mathsModule->amsautoCB->isChecked()) {
1976                 bp_.use_amsmath = BufferParams::package_auto;
1977         } else {
1978                 if (mathsModule->amsCB->isChecked())
1979                         bp_.use_amsmath = BufferParams::package_on;
1980                 else
1981                         bp_.use_amsmath = BufferParams::package_off;
1982         }
1983         if (mathsModule->esintautoCB->isChecked())
1984                 bp_.use_esint = BufferParams::package_auto;
1985         else {
1986                 if (mathsModule->esintCB->isChecked())
1987                         bp_.use_esint = BufferParams::package_on;
1988                 else
1989                         bp_.use_esint = BufferParams::package_off;
1990         }
1991         if (mathsModule->mhchemautoCB->isChecked())
1992                 bp_.use_mhchem = BufferParams::package_auto;
1993         else {
1994                 if (mathsModule->mhchemCB->isChecked())
1995                         bp_.use_mhchem = BufferParams::package_on;
1996                 else
1997                         bp_.use_mhchem = BufferParams::package_off;
1998         }
1999
2000         // Page Layout
2001         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
2002                 bp_.pagestyle = "default";
2003         else {
2004                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
2005                 for (size_t i = 0; i != pagestyles.size(); ++i)
2006                         if (pagestyles[i].second == style_gui)
2007                                 bp_.pagestyle = pagestyles[i].first;
2008         }
2009
2010         // Text Layout
2011         switch (textLayoutModule->lspacingCO->currentIndex()) {
2012         case 0:
2013                 bp_.spacing().set(Spacing::Single);
2014                 break;
2015         case 1:
2016                 bp_.spacing().set(Spacing::Onehalf);
2017                 break;
2018         case 2:
2019                 bp_.spacing().set(Spacing::Double);
2020                 break;
2021         case 3:
2022                 bp_.spacing().set(Spacing::Other,
2023                         widgetToDoubleStr(textLayoutModule->lspacingLE));
2024                 break;
2025         }
2026
2027         if (textLayoutModule->twoColumnCB->isChecked())
2028                 bp_.columns = 2;
2029         else
2030                 bp_.columns = 1;
2031
2032         if (textLayoutModule->indentRB->isChecked()) {
2033                 // if paragraphs are separated by an indentation
2034                 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
2035                 switch (textLayoutModule->indentCO->currentIndex()) {
2036                 case 0:
2037                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2038                         break;
2039                 case 1: {
2040                         HSpace indent = HSpace(
2041                                 widgetsToLength(textLayoutModule->indentLE,
2042                                 textLayoutModule->indentLengthCO)
2043                                 );
2044                         bp_.setIndentation(indent);
2045                         break;
2046                         }
2047                 default:
2048                         // this should never happen
2049                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2050                         break;
2051                 }
2052         } else {
2053                 // if paragraphs are separated by a skip
2054                 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
2055                 switch (textLayoutModule->skipCO->currentIndex()) {
2056                 case 0:
2057                         bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
2058                         break;
2059                 case 1:
2060                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2061                         break;
2062                 case 2:
2063                         bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
2064                         break;
2065                 case 3:
2066                         {
2067                         VSpace vs = VSpace(
2068                                 widgetsToLength(textLayoutModule->skipLE,
2069                                 textLayoutModule->skipLengthCO)
2070                                 );
2071                         bp_.setDefSkip(vs);
2072                         break;
2073                         }
2074                 default:
2075                         // this should never happen
2076                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2077                         break;
2078                 }
2079         }
2080
2081         bp_.options =
2082                 fromqstr(latexModule->optionsLE->text());
2083
2084         bp_.use_default_options =
2085                 latexModule->defaultOptionsCB->isChecked();
2086
2087         if (latexModule->childDocGB->isChecked())
2088                 bp_.master =
2089                         fromqstr(latexModule->childDocLE->text());
2090         else
2091                 bp_.master = string();
2092
2093         // Master/Child
2094         bp_.clearIncludedChildren();
2095         if (masterChildModule->includeonlyRB->isChecked()) {
2096                 list<string>::const_iterator it = includeonlys_.begin();
2097                 for (; it != includeonlys_.end() ; ++it) {
2098                         bp_.addIncludedChildren(*it);
2099                 }
2100         }
2101
2102         // Float Placement
2103         bp_.float_placement = floatModule->get();
2104
2105         // Listings
2106         // text should have passed validation
2107         bp_.listings_params =
2108                 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
2109
2110         // output
2111         bp_.defaultOutputFormat = fromqstr(outputModule->defaultFormatCO->itemData(
2112                 outputModule->defaultFormatCO->currentIndex()).toString());
2113
2114         bool const xetex = outputModule->xetexCB->isChecked();
2115         bp_.useXetex = xetex;
2116
2117         // fonts
2118         if (xetex) {
2119                 if (fontModule->fontsRomanCO->currentIndex() == 0)
2120                         bp_.fontsRoman = "default";
2121                 else
2122                         bp_.fontsRoman =
2123                                 fromqstr(fontModule->fontsRomanCO->currentText());
2124         
2125                 if (fontModule->fontsSansCO->currentIndex() == 0)
2126                         bp_.fontsSans = "default";
2127                 else
2128                         bp_.fontsSans =
2129                                 fromqstr(fontModule->fontsSansCO->currentText());
2130         
2131                 if (fontModule->fontsTypewriterCO->currentIndex() == 0)
2132                         bp_.fontsTypewriter = "default";
2133                 else
2134                         bp_.fontsTypewriter =
2135                                 fromqstr(fontModule->fontsTypewriterCO->currentText());
2136         } else {
2137                 bp_.fontsRoman =
2138                         tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
2139         
2140                 bp_.fontsSans =
2141                         tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
2142         
2143                 bp_.fontsTypewriter =
2144                         tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
2145         }
2146
2147         if (fontModule->fontencCO->currentIndex() == 0)
2148                 bp_.fontenc = "global";
2149         else if (fontModule->fontencCO->currentIndex() == 1)
2150                 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
2151         else if (fontModule->fontencCO->currentIndex() == 2)
2152                 bp_.fontenc = "default";
2153
2154         bp_.fontsCJK =
2155                 fromqstr(fontModule->cjkFontLE->text());
2156
2157         bp_.fontsSansScale = fontModule->scaleSansSB->value();
2158
2159         bp_.fontsTypewriterScale = fontModule->scaleTypewriterSB->value();
2160
2161         bp_.fontsSC = fontModule->fontScCB->isChecked();
2162
2163         bp_.fontsOSF = fontModule->fontOsfCB->isChecked();
2164
2165         if (xetex)
2166                 bp_.fontsDefaultFamily = "default";
2167         else
2168                 bp_.fontsDefaultFamily = GuiDocument::fontfamilies[
2169                         fontModule->fontsDefaultCO->currentIndex()];
2170
2171         if (fontModule->fontsizeCO->currentIndex() == 0)
2172                 bp_.fontsize = "default";
2173         else
2174                 bp_.fontsize =
2175                         fromqstr(fontModule->fontsizeCO->currentText());
2176
2177         // paper
2178         bp_.papersize = PAPER_SIZE(
2179                 pageLayoutModule->papersizeCO->currentIndex());
2180
2181         // custom, A3, B3 and B4 paper sizes need geometry
2182         int psize = pageLayoutModule->papersizeCO->currentIndex();
2183         bool geom_papersize = (psize == 1 || psize == 5 || psize == 8 || psize == 9);
2184
2185         bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
2186                 pageLayoutModule->paperwidthUnitCO);
2187
2188         bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
2189                 pageLayoutModule->paperheightUnitCO);
2190
2191         if (pageLayoutModule->facingPagesCB->isChecked())
2192                 bp_.sides = TwoSides;
2193         else
2194                 bp_.sides = OneSide;
2195
2196         if (pageLayoutModule->landscapeRB->isChecked())
2197                 bp_.orientation = ORIENTATION_LANDSCAPE;
2198         else
2199                 bp_.orientation = ORIENTATION_PORTRAIT;
2200
2201         bp_.backgroundcolor = set_backgroundcolor;
2202
2203         // margins
2204         bp_.use_geometry = !marginsModule->marginCB->isChecked()
2205                 || geom_papersize;
2206
2207         Ui::MarginsUi const * m = marginsModule;
2208
2209         bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
2210         bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
2211         bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
2212         bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
2213         bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
2214         bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
2215         bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
2216         bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
2217
2218         // branches
2219         branchesModule->apply(bp_);
2220
2221         // PDF support
2222         PDFOptions & pdf = bp_.pdfoptions();
2223         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
2224         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
2225         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
2226         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
2227         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
2228
2229         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
2230         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
2231         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
2232         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
2233
2234         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
2235         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
2236         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
2237         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
2238         pdf.backref =
2239                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
2240         if (pdfSupportModule->fullscreenCB->isChecked())
2241                 pdf.pagemode = pdf.pagemode_fullscreen;
2242         else
2243                 pdf.pagemode.clear();
2244         pdf.quoted_options = pdf.quoted_options_check(
2245                                 fromqstr(pdfSupportModule->optionsLE->text()));
2246 }
2247
2248
2249 void GuiDocument::paramsToDialog()
2250 {
2251         // set the default unit
2252         Length::UNIT const defaultUnit = Length::defaultUnit();
2253
2254         // preamble
2255         preambleModule->update(bp_, id());
2256
2257         // date
2258         latexModule->suppressDateCB->setChecked(bp_.suppress_date);
2259
2260         // biblio
2261         biblioModule->citeDefaultRB->setChecked(
2262                 bp_.citeEngine() == ENGINE_BASIC);
2263
2264         biblioModule->citeNatbibRB->setChecked(
2265                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL ||
2266                 bp_.citeEngine() == ENGINE_NATBIB_AUTHORYEAR);
2267
2268         biblioModule->citeStyleCO->setCurrentIndex(
2269                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL);
2270
2271         biblioModule->citeJurabibRB->setChecked(
2272                 bp_.citeEngine() == ENGINE_JURABIB);
2273
2274         biblioModule->bibtopicCB->setChecked(
2275                 bp_.use_bibtopic);
2276
2277         string command;
2278         string options =
2279                 split(bp_.bibtex_command, command, ' ');
2280
2281         int const bpos = biblioModule->bibtexCO->findData(toqstr(command));
2282         if (bpos != -1) {
2283                 biblioModule->bibtexCO->setCurrentIndex(bpos);
2284                 biblioModule->bibtexOptionsED->setText(toqstr(options).trimmed());
2285         } else {
2286                 biblioModule->bibtexCO->setCurrentIndex(0);
2287                 biblioModule->bibtexOptionsED->clear();
2288         }
2289         biblioModule->bibtexOptionsED->setEnabled(
2290                 biblioModule->bibtexCO->currentIndex() != 0);
2291
2292         // indices
2293         indicesModule->update(bp_);
2294
2295         // language & quotes
2296         int const pos = langModule->languageCO->findData(toqstr(
2297                 bp_.language->lang()));
2298         langModule->languageCO->setCurrentIndex(pos);
2299
2300         langModule->quoteStyleCO->setCurrentIndex(
2301                 bp_.quotes_language);
2302
2303         bool default_enc = true;
2304         if (bp_.inputenc != "auto") {
2305                 default_enc = false;
2306                 if (bp_.inputenc == "default") {
2307                         langModule->encodingCO->setCurrentIndex(0);
2308                 } else {
2309                         string enc_gui;
2310                         Encodings::const_iterator it = encodings.begin();
2311                         Encodings::const_iterator const end = encodings.end();
2312                         for (; it != end; ++it) {
2313                                 if (it->latexName() == bp_.inputenc) {
2314                                         enc_gui = it->guiName();
2315                                         break;
2316                                 }
2317                         }
2318                         int const i = langModule->encodingCO->findText(
2319                                         qt_(enc_gui));
2320                         if (i >= 0)
2321                                 langModule->encodingCO->setCurrentIndex(i);
2322                         else
2323                                 // unknown encoding. Set to default.
2324                                 default_enc = true;
2325                 }
2326         }
2327         langModule->defaultencodingRB->setChecked(default_enc);
2328         langModule->otherencodingRB->setChecked(!default_enc);
2329
2330         // numbering
2331         int const min_toclevel = documentClass().min_toclevel();
2332         int const max_toclevel = documentClass().max_toclevel();
2333         if (documentClass().hasTocLevels()) {
2334                 numberingModule->setEnabled(true);
2335                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
2336                 numberingModule->depthSL->setMaximum(max_toclevel);
2337                 numberingModule->depthSL->setValue(bp_.secnumdepth);
2338                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
2339                 numberingModule->tocSL->setMaximum(max_toclevel);
2340                 numberingModule->tocSL->setValue(bp_.tocdepth);
2341                 updateNumbering();
2342         } else {
2343                 numberingModule->setEnabled(false);
2344                 numberingModule->tocTW->clear();
2345         }
2346
2347         // bullets
2348         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
2349         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
2350         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
2351         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
2352         bulletsModule->init();
2353
2354         // packages
2355         int nitem = findToken(tex_graphics, bp_.graphicsDriver);
2356         if (nitem >= 0)
2357                 latexModule->psdriverCO->setCurrentIndex(nitem);
2358         updateModuleInfo();
2359         
2360         mathsModule->amsCB->setChecked(
2361                 bp_.use_amsmath == BufferParams::package_on);
2362         mathsModule->amsautoCB->setChecked(
2363                 bp_.use_amsmath == BufferParams::package_auto);
2364
2365         mathsModule->esintCB->setChecked(
2366                 bp_.use_esint == BufferParams::package_on);
2367         mathsModule->esintautoCB->setChecked(
2368                 bp_.use_esint == BufferParams::package_auto);
2369
2370         mathsModule->mhchemCB->setChecked(
2371                 bp_.use_mhchem == BufferParams::package_on);
2372         mathsModule->mhchemautoCB->setChecked(
2373                 bp_.use_mhchem == BufferParams::package_auto);
2374
2375         switch (bp_.spacing().getSpace()) {
2376                 case Spacing::Other: nitem = 3; break;
2377                 case Spacing::Double: nitem = 2; break;
2378                 case Spacing::Onehalf: nitem = 1; break;
2379                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
2380         }
2381
2382         // text layout
2383         string const & layoutID = bp_.baseClassID();
2384         setLayoutComboByIDString(layoutID);
2385
2386         updatePagestyle(documentClass().opt_pagestyle(),
2387                                  bp_.pagestyle);
2388
2389         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
2390         if (bp_.spacing().getSpace() == Spacing::Other) {
2391                 doubleToWidget(textLayoutModule->lspacingLE,
2392                         bp_.spacing().getValueAsString());
2393         }
2394         setLSpacing(nitem);
2395
2396         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
2397                 textLayoutModule->indentRB->setChecked(true);
2398                 string indentation = bp_.getIndentation().asLyXCommand();
2399                 int indent = 0;
2400                 if (indentation != "default") {
2401                         lengthToWidgets(textLayoutModule->indentLE,
2402                         textLayoutModule->indentLengthCO,
2403                         indentation, defaultUnit);
2404                         indent = 1;
2405                 }
2406                 textLayoutModule->indentCO->setCurrentIndex(indent);
2407                 setIndent(indent);
2408         } else {
2409                 textLayoutModule->skipRB->setChecked(true);
2410                 int skip = 0;
2411                 switch (bp_.getDefSkip().kind()) {
2412                 case VSpace::SMALLSKIP:
2413                         skip = 0;
2414                         break;
2415                 case VSpace::MEDSKIP:
2416                         skip = 1;
2417                         break;
2418                 case VSpace::BIGSKIP:
2419                         skip = 2;
2420                         break;
2421                 case VSpace::LENGTH:
2422                         {
2423                         skip = 3;
2424                         string const length = bp_.getDefSkip().asLyXCommand();
2425                         lengthToWidgets(textLayoutModule->skipLE,
2426                                 textLayoutModule->skipLengthCO,
2427                                 length, defaultUnit);
2428                         break;
2429                         }
2430                 default:
2431                         skip = 0;
2432                         break;
2433                 }
2434                 textLayoutModule->skipCO->setCurrentIndex(skip);
2435                 setSkip(skip);
2436         }
2437
2438         textLayoutModule->twoColumnCB->setChecked(
2439                 bp_.columns == 2);
2440
2441         if (!bp_.options.empty()) {
2442                 latexModule->optionsLE->setText(
2443                         toqstr(bp_.options));
2444         } else {
2445                 latexModule->optionsLE->setText(QString());
2446         }
2447
2448         // latex
2449         latexModule->defaultOptionsCB->setChecked(
2450                         bp_.use_default_options);
2451         updateSelectedModules();
2452         selectionManager->updateProvidedModules(
2453                         bp_.baseClass()->providedModules());
2454         selectionManager->updateExcludedModules(
2455                         bp_.baseClass()->excludedModules());
2456
2457         if (!documentClass().options().empty()) {
2458                 latexModule->defaultOptionsLE->setText(
2459                         toqstr(documentClass().options()));
2460         } else {
2461                 latexModule->defaultOptionsLE->setText(
2462                         toqstr(_("[No options predefined]")));
2463         }
2464
2465         latexModule->defaultOptionsLE->setEnabled(
2466                 bp_.use_default_options
2467                 && !documentClass().options().empty());
2468
2469         latexModule->defaultOptionsCB->setEnabled(
2470                 !documentClass().options().empty());
2471
2472         if (!bp_.master.empty()) {
2473                 latexModule->childDocGB->setChecked(true);
2474                 latexModule->childDocLE->setText(
2475                         toqstr(bp_.master));
2476         } else {
2477                 latexModule->childDocLE->setText(QString());
2478                 latexModule->childDocGB->setChecked(false);
2479         }
2480
2481         // Master/Child
2482         std::vector<Buffer *> children = buffer().getChildren(false);
2483         if (children.empty()) {
2484                 masterChildModule->setEnabled(false);
2485                 includeonlys_.clear();
2486         } else {
2487                 masterChildModule->setEnabled(true);
2488                 includeonlys_ = bp_.getIncludedChildren();
2489                 updateIncludeonlys();
2490         }
2491
2492         // Float Settings
2493         floatModule->set(bp_.float_placement);
2494
2495         // ListingsSettings
2496         // break listings_params to multiple lines
2497         string lstparams =
2498                 InsetListingsParams(bp_.listings_params).separatedParams();
2499         listingsModule->listingsED->setPlainText(toqstr(lstparams));
2500
2501         // Output
2502         // update combobox with formats
2503         updateDefaultFormat();
2504         int index = outputModule->defaultFormatCO->findData(toqstr(
2505                 bp_.defaultOutputFormat));
2506         // set to default if format is not found 
2507         if (index == -1)
2508                 index = 0;
2509         outputModule->defaultFormatCO->setCurrentIndex(index);
2510         outputModule->xetexCB->setEnabled(bp_.baseClass()->outputType() == lyx::LATEX);
2511         outputModule->xetexCB->setChecked(
2512                 bp_.baseClass()->outputType() == lyx::LATEX && bp_.useXetex);
2513
2514         // Fonts
2515         updateFontsize(documentClass().opt_fontsize(),
2516                         bp_.fontsize);
2517
2518         if (bp_.useXetex) {
2519                 fontModule->fontencLA->setEnabled(false);
2520                 fontModule->fontencCO->setEnabled(false);
2521                 fontModule->fontencLE->setEnabled(false);
2522                 for (int i = 0; i < fontModule->fontsRomanCO->count(); ++i) {
2523                         if (fontModule->fontsRomanCO->itemText(i) == toqstr(bp_.fontsRoman)) {
2524                                 fontModule->fontsRomanCO->setCurrentIndex(i);
2525                                 return;
2526                         }
2527                 }
2528                 
2529                 for (int i = 0; i < fontModule->fontsSansCO->count(); ++i) {
2530                         if (fontModule->fontsSansCO->itemText(i) == toqstr(bp_.fontsSans)) {
2531                                 fontModule->fontsSansCO->setCurrentIndex(i);
2532                                 return;
2533                         }
2534                 }
2535                 for (int i = 0; i < fontModule->fontsTypewriterCO->count(); ++i) {
2536                         if (fontModule->fontsTypewriterCO->itemText(i) == 
2537                                 toqstr(bp_.fontsTypewriter)) {
2538                                 fontModule->fontsTypewriterCO->setCurrentIndex(i);
2539                                 return;
2540                         }
2541                 }
2542         } else {
2543                 fontModule->fontencLA->setEnabled(true);
2544                 fontModule->fontencCO->setEnabled(true);
2545                 fontModule->fontencLE->setEnabled(true);
2546                 int n = findToken(tex_fonts_roman, bp_.fontsRoman);
2547                 if (n >= 0) {
2548                         fontModule->fontsRomanCO->setCurrentIndex(n);
2549                         romanChanged(n);
2550                 }
2551         
2552                 n = findToken(tex_fonts_sans, bp_.fontsSans);
2553                 if (n >= 0) {
2554                         fontModule->fontsSansCO->setCurrentIndex(n);
2555                         sansChanged(n);
2556                 }
2557         
2558                 n = findToken(tex_fonts_monospaced, bp_.fontsTypewriter);
2559                 if (n >= 0) {
2560                         fontModule->fontsTypewriterCO->setCurrentIndex(n);
2561                         ttChanged(n);
2562                 }
2563         }
2564
2565         if (!bp_.fontsCJK.empty())
2566                 fontModule->cjkFontLE->setText(
2567                         toqstr(bp_.fontsCJK));
2568         else
2569                 fontModule->cjkFontLE->setText(QString());
2570
2571         fontModule->fontScCB->setChecked(bp_.fontsSC);
2572         fontModule->fontOsfCB->setChecked(bp_.fontsOSF);
2573         fontModule->scaleSansSB->setValue(bp_.fontsSansScale);
2574         fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale);
2575
2576         int nn = findToken(GuiDocument::fontfamilies, bp_.fontsDefaultFamily);
2577         if (nn >= 0)
2578                 fontModule->fontsDefaultCO->setCurrentIndex(nn);
2579
2580         if (bp_.fontenc == "global")
2581                 fontModule->fontencCO->setCurrentIndex(0);
2582         else if (bp_.fontenc == "default")
2583                 fontModule->fontencCO->setCurrentIndex(2);
2584         else {
2585                 fontModule->fontencCO->setCurrentIndex(1);
2586                 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
2587         }
2588
2589         // paper
2590         bool const extern_geometry =
2591                 documentClass().provides("geometry");
2592         int const psize = bp_.papersize;
2593         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
2594         setCustomPapersize(!extern_geometry && psize == 1);
2595         pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
2596
2597         bool const landscape =
2598                 bp_.orientation == ORIENTATION_LANDSCAPE;
2599         pageLayoutModule->landscapeRB->setChecked(landscape);
2600         pageLayoutModule->portraitRB->setChecked(!landscape);
2601         pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
2602         pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
2603
2604         pageLayoutModule->facingPagesCB->setChecked(
2605                 bp_.sides == TwoSides);
2606
2607         pageLayoutModule->backgroundPB->setStyleSheet(
2608                 colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
2609         set_backgroundcolor = bp_.backgroundcolor;
2610
2611         lengthToWidgets(pageLayoutModule->paperwidthLE,
2612                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, defaultUnit);
2613         lengthToWidgets(pageLayoutModule->paperheightLE,
2614                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, defaultUnit);
2615
2616         // margins
2617         Ui::MarginsUi * m = marginsModule;
2618
2619         setMargins(!bp_.use_geometry);
2620
2621         lengthToWidgets(m->topLE, m->topUnit,
2622                 bp_.topmargin, defaultUnit);
2623
2624         lengthToWidgets(m->bottomLE, m->bottomUnit,
2625                 bp_.bottommargin, defaultUnit);
2626
2627         lengthToWidgets(m->innerLE, m->innerUnit,
2628                 bp_.leftmargin, defaultUnit);
2629
2630         lengthToWidgets(m->outerLE, m->outerUnit,
2631                 bp_.rightmargin, defaultUnit);
2632
2633         lengthToWidgets(m->headheightLE, m->headheightUnit,
2634                 bp_.headheight, defaultUnit);
2635
2636         lengthToWidgets(m->headsepLE, m->headsepUnit,
2637                 bp_.headsep, defaultUnit);
2638
2639         lengthToWidgets(m->footskipLE, m->footskipUnit,
2640                 bp_.footskip, defaultUnit);
2641
2642         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
2643                 bp_.columnsep, defaultUnit);
2644
2645         // branches
2646         updateUnknownBranches();
2647         branchesModule->update(bp_);
2648
2649         // PDF support
2650         PDFOptions const & pdf = bp_.pdfoptions();
2651         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
2652         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
2653         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
2654         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
2655         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
2656
2657         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
2658         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
2659         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
2660
2661         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
2662
2663         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
2664         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
2665         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
2666         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
2667
2668         nn = findToken(backref_opts, pdf.backref);
2669         if (nn >= 0)
2670                 pdfSupportModule->backrefCO->setCurrentIndex(nn);
2671
2672         pdfSupportModule->fullscreenCB->setChecked
2673                 (pdf.pagemode == pdf.pagemode_fullscreen);
2674
2675         pdfSupportModule->optionsLE->setText(
2676                 toqstr(pdf.quoted_options));
2677
2678         // Make sure that the bc is in the INITIAL state
2679         if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
2680                 bc().restore();
2681
2682         // clear changed branches cache
2683         changedBranches_.clear();
2684 }
2685
2686
2687 void GuiDocument::saveDocDefault()
2688 {
2689         // we have to apply the params first
2690         applyView();
2691         saveAsDefault();
2692 }
2693
2694
2695 void GuiDocument::updateAvailableModules() 
2696 {
2697         modules_av_model_.clear();
2698         list<modInfoStruct> const & modInfoList = getModuleInfo();
2699         list<modInfoStruct>::const_iterator mit = modInfoList.begin();
2700         list<modInfoStruct>::const_iterator men = modInfoList.end();
2701         for (int i = 0; mit != men; ++mit, ++i)
2702                 modules_av_model_.insertRow(i, mit->name, mit->id, 
2703                                 mit->description);
2704 }
2705
2706
2707 void GuiDocument::updateSelectedModules() 
2708 {
2709         modules_sel_model_.clear();
2710         list<modInfoStruct> const selModList = getSelectedModules();
2711         list<modInfoStruct>::const_iterator mit = selModList.begin();
2712         list<modInfoStruct>::const_iterator men = selModList.end();
2713         for (int i = 0; mit != men; ++mit, ++i)
2714                 modules_sel_model_.insertRow(i, mit->name, mit->id, 
2715                                 mit->description);
2716 }
2717
2718
2719 void GuiDocument::updateIncludeonlys()
2720 {
2721         masterChildModule->childrenTW->clear();
2722         QString const no = qt_("No");
2723         QString const yes = qt_("Yes");
2724
2725         if (includeonlys_.empty()) {
2726                 masterChildModule->includeallRB->setChecked(true);
2727                 masterChildModule->childrenTW->setEnabled(false);
2728         } else {
2729                 masterChildModule->includeonlyRB->setChecked(true);
2730                 masterChildModule->childrenTW->setEnabled(true);
2731         }
2732         QTreeWidgetItem * item = 0;
2733         std::vector<Buffer *> children = buffer().getChildren(false);
2734         vector<Buffer *>::const_iterator it  = children.begin();
2735         vector<Buffer *>::const_iterator end = children.end();
2736         bool has_unincluded = false;
2737         bool all_unincluded = true;
2738         for (; it != end; ++it) {
2739                 item = new QTreeWidgetItem(masterChildModule->childrenTW);
2740                 // FIXME Unicode
2741                 string const name =
2742                         to_utf8(makeRelPath(from_utf8((*it)->fileName().absFilename()),
2743                                                         from_utf8(buffer().filePath())));
2744                 item->setText(0, toqstr(name));
2745                 item->setText(1, isChildIncluded(name) ? yes : no);
2746                 if (!isChildIncluded(name))
2747                         has_unincluded = true;
2748                 else
2749                         all_unincluded = false;
2750         }
2751         // Both if all childs are included and if none is included
2752         // is equal to "include all" (i.e., ommit \includeonly).
2753         // Thus, reset the GUI.
2754         if (!has_unincluded || all_unincluded) {
2755                 masterChildModule->includeallRB->setChecked(true);
2756                 masterChildModule->childrenTW->setEnabled(false);
2757                 includeonlys_.clear();
2758         }
2759         // If all are included, we need to update again.
2760         if (!has_unincluded)
2761                 updateIncludeonlys();
2762 }
2763
2764
2765 void GuiDocument::updateContents()
2766 {
2767         // Nothing to do here as the document settings is not cursor dependant.
2768         return;
2769 }
2770
2771
2772 void GuiDocument::useClassDefaults()
2773 {
2774         if (applyPB->isEnabled()) {
2775                 int const ret = Alert::prompt(_("Unapplied changes"),
2776                                 _("Some changes in the dialog were not yet applied.\n"
2777                                   "If you do not apply now, they will be lost after this action."),
2778                                 1, 1, _("&Apply"), _("&Dismiss"));
2779                 if (ret == 0)
2780                         applyView();
2781         }
2782
2783         int idx = latexModule->classCO->currentIndex();
2784         string const classname = classes_model_.getIDString(idx);
2785         if (!bp_.setBaseClass(classname)) {
2786                 Alert::error(_("Error"), _("Unable to set document class."));
2787                 return;
2788         }
2789         bp_.useClassDefaults();
2790         paramsToDialog();
2791 }
2792
2793
2794 void GuiDocument::setLayoutComboByIDString(string const & idString)
2795 {
2796         int idx = classes_model_.findIDString(idString);
2797         if (idx < 0)
2798                 Alert::warning(_("Can't set layout!"), 
2799                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
2800         else 
2801                 latexModule->classCO->setCurrentIndex(idx);
2802 }
2803
2804
2805 bool GuiDocument::isValid()
2806 {
2807         return validateListingsParameters().isEmpty()
2808                 && (textLayoutModule->skipCO->currentIndex() != 3
2809                         || !textLayoutModule->skipLE->text().isEmpty()
2810                         || textLayoutModule->indentRB->isChecked())
2811                 && (textLayoutModule->indentCO->currentIndex() != 1
2812                         || !textLayoutModule->indentLE->text().isEmpty()
2813                         || textLayoutModule->skipRB->isChecked());
2814 }
2815
2816
2817 char const * const GuiDocument::fontfamilies[5] = {
2818         "default", "rmdefault", "sfdefault", "ttdefault", ""
2819 };
2820
2821
2822 char const * GuiDocument::fontfamilies_gui[5] = {
2823         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
2824 };
2825
2826
2827 bool GuiDocument::initialiseParams(string const &)
2828 {
2829         BufferView const * view = bufferview();
2830         if (!view) {
2831                 bp_ = BufferParams();
2832                 paramsToDialog();
2833                 return true;
2834         }
2835         bp_ = view->buffer().params();
2836         loadModuleInfo();
2837         updateAvailableModules();
2838         //FIXME It'd be nice to make sure here that the selected
2839         //modules are consistent: That required modules are actually
2840         //selected, and that we don't have conflicts. If so, we could
2841         //at least pop up a warning.
2842         paramsToDialog();
2843         return true;
2844 }
2845
2846
2847 void GuiDocument::clearParams()
2848 {
2849         bp_ = BufferParams();
2850 }
2851
2852
2853 BufferId GuiDocument::id() const
2854 {
2855         BufferView const * const view = bufferview();
2856         return view? &view->buffer() : 0;
2857 }
2858
2859
2860 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
2861 {
2862         return moduleNames_;
2863 }
2864
2865
2866 list<GuiDocument::modInfoStruct> const 
2867                 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
2868 {
2869         LayoutModuleList::const_iterator it =  mods.begin();
2870         LayoutModuleList::const_iterator end = mods.end();
2871         list<modInfoStruct> mInfo;
2872         for (; it != end; ++it) {
2873                 modInfoStruct m;
2874                 m.id = *it;
2875                 LyXModule const * const mod = theModuleList[*it];
2876                 if (mod)
2877                         // FIXME Unicode
2878                         m.name = toqstr(translateIfPossible(from_utf8(mod->getName())));
2879                 else 
2880                         m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
2881                 mInfo.push_back(m);
2882         }
2883         return mInfo;
2884 }
2885
2886
2887 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
2888 {
2889         return makeModuleInfo(params().getModules());
2890 }
2891
2892
2893 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
2894 {
2895         return makeModuleInfo(params().baseClass()->providedModules());
2896 }
2897
2898
2899 DocumentClass const & GuiDocument::documentClass() const
2900 {
2901         return bp_.documentClass();
2902 }
2903
2904
2905 static void dispatch_bufferparams(Dialog const & dialog,
2906         BufferParams const & bp, FuncCode lfun)
2907 {
2908         ostringstream ss;
2909         ss << "\\begin_header\n";
2910         bp.writeFile(ss);
2911         ss << "\\end_header\n";
2912         dialog.dispatch(FuncRequest(lfun, ss.str()));
2913 }
2914
2915
2916 void GuiDocument::dispatchParams()
2917 {
2918         // This must come first so that a language change is correctly noticed
2919         setLanguage();
2920
2921         // Apply the BufferParams. Note that this will set the base class
2922         // and then update the buffer's layout.
2923         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
2924
2925         if (!params().master.empty()) {
2926                 FileName const master_file = support::makeAbsPath(params().master,
2927                            support::onlyPath(buffer().absFileName()));
2928                 if (isLyXFilename(master_file.absFilename())) {
2929                         Buffer * master = checkAndLoadLyXFile(master_file);
2930                         if (master) {
2931                                 if (master->isChild(const_cast<Buffer *>(&buffer())))
2932                                         const_cast<Buffer &>(buffer()).setParent(master);
2933                                 else
2934                                         Alert::warning(_("Assigned master does not include this file"), 
2935                                                 bformat(_("You must include this file in the document\n"
2936                                                           "'%1$s' in order to use the master document\n"
2937                                                           "feature."), from_utf8(params().master)));
2938                         } else
2939                                 Alert::warning(_("Could not load master"), 
2940                                                 bformat(_("The master document '%1$s'\n"
2941                                                            "could not be loaded."),
2942                                                            from_utf8(params().master)));
2943                 }
2944         }
2945
2946         // Generate the colours requested by each new branch.
2947         BranchList & branchlist = params().branchlist();
2948         if (!branchlist.empty()) {
2949                 BranchList::const_iterator it = branchlist.begin();
2950                 BranchList::const_iterator const end = branchlist.end();
2951                 for (; it != end; ++it) {
2952                         docstring const & current_branch = it->branch();
2953                         Branch const * branch = branchlist.find(current_branch);
2954                         string const x11hexname = X11hexname(branch->color());
2955                         // display the new color
2956                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
2957                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
2958                 }
2959
2960                 // Open insets of selected branches, close deselected ones
2961                 dispatch(FuncRequest(LFUN_ALL_INSETS_TOGGLE,
2962                         "assign branch"));
2963         }
2964         // rename branches in the document
2965         executeBranchRenaming();
2966         // and clear changed branches cache
2967         changedBranches_.clear();
2968         
2969         // Generate the colours requested by indices.
2970         IndicesList & indiceslist = params().indiceslist();
2971         if (!indiceslist.empty()) {
2972                 IndicesList::const_iterator it = indiceslist.begin();
2973                 IndicesList::const_iterator const end = indiceslist.end();
2974                 for (; it != end; ++it) {
2975                         docstring const & current_index = it->shortcut();
2976                         Index const * index = indiceslist.findShortcut(current_index);
2977                         string const x11hexname = X11hexname(index->color());
2978                         // display the new color
2979                         docstring const str = current_index + ' ' + from_ascii(x11hexname);
2980                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
2981                 }
2982         }
2983         // FIXME: If we used an LFUN, we would not need those two lines:
2984         BufferView * bv = const_cast<BufferView *>(bufferview());
2985         bv->processUpdateFlags(Update::Force | Update::FitCursor);
2986 }
2987
2988
2989 void GuiDocument::setLanguage() const
2990 {
2991         Language const * const newL = bp_.language;
2992         if (buffer().params().language == newL)
2993                 return;
2994
2995         string const & lang_name = newL->lang();
2996         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
2997 }
2998
2999
3000 void GuiDocument::saveAsDefault() const
3001 {
3002         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
3003 }
3004
3005
3006 bool GuiDocument::isFontAvailable(string const & font) const
3007 {
3008         if (font == "default" || font == "cmr"
3009             || font == "cmss" || font == "cmtt")
3010                 // these are standard
3011                 return true;
3012         if (font == "lmodern" || font == "lmss" || font == "lmtt")
3013                 return LaTeXFeatures::isAvailable("lmodern");
3014         if (font == "times" || font == "palatino"
3015                  || font == "helvet" || font == "courier")
3016                 return LaTeXFeatures::isAvailable("psnfss");
3017         if (font == "cmbr" || font == "cmtl")
3018                 return LaTeXFeatures::isAvailable("cmbright");
3019         if (font == "utopia")
3020                 return LaTeXFeatures::isAvailable("utopia")
3021                         || LaTeXFeatures::isAvailable("fourier");
3022         if (font == "beraserif" || font == "berasans"
3023                 || font == "beramono")
3024                 return LaTeXFeatures::isAvailable("bera");
3025         return LaTeXFeatures::isAvailable(font);
3026 }
3027
3028
3029 bool GuiDocument::providesOSF(string const & font) const
3030 {
3031         if (outputModule->xetexCB->isChecked())
3032                 // FIXME: we should check if the fonts really
3033                 // have OSF support. But how?
3034                 return true;
3035         if (font == "cmr")
3036                 return isFontAvailable("eco");
3037         if (font == "palatino")
3038                 return isFontAvailable("mathpazo");
3039         return false;
3040 }
3041
3042
3043 bool GuiDocument::providesSC(string const & font) const
3044 {
3045         if (outputModule->xetexCB->isChecked())
3046                 return false;
3047         if (font == "palatino")
3048                 return isFontAvailable("mathpazo");
3049         if (font == "utopia")
3050                 return isFontAvailable("fourier");
3051         return false;
3052 }
3053
3054
3055 bool GuiDocument::providesScale(string const & font) const
3056 {
3057         if (outputModule->xetexCB->isChecked())
3058                 return true;
3059         return font == "helvet" || font == "luximono"
3060                 || font == "berasans"  || font == "beramono";
3061 }
3062
3063
3064 void GuiDocument::loadModuleInfo()
3065 {
3066         moduleNames_.clear();
3067         LyXModuleList::const_iterator it  = theModuleList.begin();
3068         LyXModuleList::const_iterator end = theModuleList.end();
3069         for (; it != end; ++it) {
3070                 modInfoStruct m;
3071                 m.id = it->getID();
3072                 // FIXME Unicode
3073                 m.name = toqstr(translateIfPossible(from_utf8(it->getName())));
3074                 // this is supposed to give us the first sentence of the description
3075                 // FIXME Unicode
3076                 QString desc =
3077                         toqstr(translateIfPossible(from_utf8(it->getDescription())));
3078                 int const pos = desc.indexOf(".");
3079                 if (pos > 0)
3080                         desc.truncate(pos + 1);
3081                 m.description = desc;
3082                 moduleNames_.push_back(m);
3083         }
3084 }
3085
3086
3087 void GuiDocument::updateUnknownBranches()
3088 {
3089         list<docstring> used_branches;
3090         buffer().getUsedBranches(used_branches);
3091         list<docstring>::const_iterator it = used_branches.begin();
3092         QStringList unknown_branches;
3093         for (; it != used_branches.end() ; ++it) {
3094                 if (!buffer().params().branchlist().find(*it))
3095                         unknown_branches.append(toqstr(*it));
3096         }
3097         branchesModule->setUnknownBranches(unknown_branches);
3098 }
3099
3100
3101 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
3102 {
3103         map<docstring, docstring>::iterator it = changedBranches_.begin();
3104         for (; it != changedBranches_.end() ; ++it) {
3105                 if (it->second == oldname) {
3106                         // branch has already been renamed
3107                         it->second = newname;
3108                         return;
3109                 }
3110         }
3111         // store new name
3112         changedBranches_[oldname] = newname;
3113 }
3114
3115
3116 void GuiDocument::executeBranchRenaming() const
3117 {
3118         map<docstring, docstring>::const_iterator it = changedBranches_.begin();
3119         for (; it != changedBranches_.end() ; ++it) {
3120                 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
3121                 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
3122         }
3123 }
3124
3125
3126 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
3127
3128
3129 } // namespace frontend
3130 } // namespace lyx
3131
3132 #include "moc_GuiDocument.cpp"