]> git.lyx.org Git - features.git/blob - src/frontends/qt4/GuiDocument.cpp
Correct the order of the tests here. Messed this up in previous commit.
[features.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 "GuiSelectionManager.h"
19 #include "LaTeXHighlighter.h"
20 #include "LengthCombo.h"
21 #include "PanelStack.h"
22 #include "Validator.h"
23
24 #include "LayoutFile.h"
25 #include "BranchList.h"
26 #include "buffer_funcs.h"
27 #include "Buffer.h"
28 #include "BufferParams.h"
29 #include "BufferView.h"
30 #include "Color.h"
31 #include "Encoding.h"
32 #include "FloatPlacement.h"
33 #include "FuncRequest.h"
34 #include "Language.h"
35 #include "LaTeXFeatures.h"
36 #include "Layout.h"
37 #include "LyXRC.h" // defaultUnit
38 #include "ModuleList.h"
39 #include "OutputParams.h"
40 #include "PDFOptions.h"
41 #include "qt_helpers.h"
42 #include "Spacing.h"
43
44 #include "insets/InsetListingsParams.h"
45
46 #include "support/debug.h"
47 #include "support/FileName.h"
48 #include "support/filetools.h"
49 #include "support/gettext.h"
50 #include "support/lstrings.h"
51
52 #include "frontends/alert.h"
53
54 #include <QAbstractItemModel>
55 #include <QCloseEvent>
56 #include <QScrollBar>
57 #include <QTextCursor>
58
59 #include <sstream>
60 #include <vector>
61
62 #ifdef IN
63 #undef IN
64 #endif
65
66
67 using namespace std;
68 using namespace lyx::support;
69
70
71 namespace {
72
73 char const * const tex_graphics[] =
74 {
75         "default", "dvialw", "dvilaser", "dvipdf", "dvipdfm", "dvipdfmx",
76         "dvips", "dvipsone", "dvitops", "dviwin", "dviwindo", "dvi2ps", "emtex",
77         "ln", "oztex", "pctexhp", "pctexps", "pctexwin", "pctex32", "pdftex",
78         "psprint", "pubps", "tcidvi", "textures", "truetex", "vtex", "xdvi",
79         "xetex", "none", ""
80 };
81
82
83 char const * const tex_graphics_gui[] =
84 {
85         N_("Default"), "dvialw", "DviLaser", "dvipdf", "DVIPDFM", "DVIPDFMx",
86         "Dvips", "DVIPSONE", "DVItoPS", "DVIWIN", "DVIWindo", "dvi2ps", "EmTeX",
87         "LN", "OzTeX", "pctexhp", "pctexps", "pctexwin", "PCTeX32", "pdfTeX",
88         "psprint", "pubps", "tcidvi", "Textures", "TrueTeX", "VTeX", "xdvi",
89         "XeTeX", N_("None"), ""
90 };
91
92
93 char const * const tex_fonts_roman[] =
94 {
95         "default", "cmr", "lmodern", "ae", "times", "palatino",
96         "charter", "newcent", "bookman", "utopia", "beraserif",
97         "ccfonts", "chancery", ""
98 };
99
100
101 char const * tex_fonts_roman_gui[] =
102 {
103         N_("Default"), N_("Computer Modern Roman"), N_("Latin Modern Roman"),
104         N_("AE (Almost European)"), N_("Times Roman"), N_("Palatino"),
105         N_("Bitstream Charter"), N_("New Century Schoolbook"), N_("Bookman"),
106         N_("Utopia"),  N_("Bera Serif"), N_("Concrete Roman"), N_("Zapf Chancery"),
107         ""
108 };
109
110
111 char const * const tex_fonts_sans[] =
112 {
113         "default", "cmss", "lmss", "helvet", "avant", "berasans", "cmbr", ""
114 };
115
116
117 char const * tex_fonts_sans_gui[] =
118 {
119         N_("Default"), N_("Computer Modern Sans"), N_("Latin Modern Sans"),
120         N_("Helvetica"), N_("Avant Garde"), N_("Bera Sans"), N_("CM Bright"), ""
121 };
122
123
124 char const * const tex_fonts_monospaced[] =
125 {
126         "default", "cmtt", "lmtt", "courier", "beramono", "luximono", "cmtl", ""
127 };
128
129
130 char const * tex_fonts_monospaced_gui[] =
131 {
132         N_("Default"), N_("Computer Modern Typewriter"),
133         N_("Latin Modern Typewriter"), N_("Courier"), N_("Bera Mono"),
134         N_("LuxiMono"), N_("CM Typewriter Light"), ""
135 };
136
137
138 char const * backref_opts[] =
139 {
140         "false", "section", "slide", "page", ""
141 };
142
143
144 char const * backref_opts_gui[] =
145 {
146         N_("Off"), N_("Section"), N_("Slide"), N_("Page"), ""
147 };
148
149
150 vector<pair<string, QString> > pagestyles;
151
152
153 } // anonymous namespace
154
155 namespace lyx {
156
157 namespace {
158 // used when sorting the textclass list.
159 class less_textclass_avail_desc
160         : public binary_function<string, string, int>
161 {
162 public:
163         bool operator()(string const & lhs, string const & rhs) const
164         {
165                 // Ordering criteria:
166                 //   1. Availability of text class
167                 //   2. Description (lexicographic)
168                 LayoutFile const & tc1 = LayoutFileList::get()[lhs];
169                 LayoutFile const & tc2 = LayoutFileList::get()[rhs];
170                 return (tc1.isTeXClassAvailable() && !tc2.isTeXClassAvailable()) ||
171                         (tc1.isTeXClassAvailable() == tc2.isTeXClassAvailable() &&
172                          _(tc1.description()) < _(tc2.description()));
173         }
174 };
175
176 }
177
178 namespace frontend {
179 namespace {
180
181 vector<string> getRequiredList(string const & modName) 
182 {
183         LyXModule const * const mod = moduleList[modName];
184         if (!mod)
185                 return vector<string>(); //empty such thing
186         return mod->getRequiredModules();
187 }
188
189
190 vector<string> getExcludedList(string const & modName)
191 {
192         LyXModule const * const mod = moduleList[modName];
193         if (!mod)
194                 return vector<string>(); //empty such thing
195         return mod->getExcludedModules();
196 }
197
198
199 docstring getModuleDescription(string const & modName)
200 {
201         LyXModule const * const mod = moduleList[modName];
202         if (!mod)
203                 return _("Module not found!");
204         return _(mod->getDescription());
205 }
206
207
208 vector<string> getPackageList(string const & modName)
209 {
210         LyXModule const * const mod = moduleList[modName];
211         if (!mod)
212                 return vector<string>(); //empty such thing
213         return mod->getPackageList();
214 }
215
216
217 bool isModuleAvailable(string const & modName)
218 {
219         LyXModule * mod = moduleList[modName];
220         if (!mod)
221                 return false;
222         return mod->isAvailable();
223 }
224
225 } // anonymous namespace
226
227
228 /////////////////////////////////////////////////////////////////////
229 //
230 // ModuleSelectionManager
231 //
232 /////////////////////////////////////////////////////////////////////
233
234 /// SelectionManager for use with modules
235 class ModuleSelectionManager : public GuiSelectionManager 
236 {
237 public:
238         ModuleSelectionManager(
239                 QListView * availableLV, 
240                 QListView * selectedLV,
241                 QPushButton * addPB, 
242                 QPushButton * delPB, 
243                 QPushButton * upPB, 
244                 QPushButton * downPB,
245                 GuiIdListModel * availableModel,
246                 GuiIdListModel * selectedModel)
247         : GuiSelectionManager(availableLV, selectedLV, addPB, delPB,
248                         upPB, downPB, availableModel, selectedModel)
249                 {}
250 private:
251         ///
252         virtual void updateAddPB();
253         ///
254         virtual void updateUpPB();
255         ///
256         virtual void updateDownPB();
257         ///
258         virtual void updateDelPB();
259         /// returns availableModel as a GuiIdListModel
260         GuiIdListModel * getAvailableModel() 
261         {
262                 return dynamic_cast<GuiIdListModel *>(availableModel);
263         }
264         /// returns selectedModel as a GuiIdListModel
265         GuiIdListModel * getSelectedModel() 
266         {
267                 return dynamic_cast<GuiIdListModel *>(selectedModel);
268         }
269 };
270
271 void ModuleSelectionManager::updateAddPB() 
272 {
273         int const arows = availableModel->rowCount();
274         QModelIndexList const availSels = 
275                         availableLV->selectionModel()->selectedIndexes();
276         if (arows == 0 || availSels.isEmpty()  || isSelected(availSels.first())) {
277                 addPB->setEnabled(false);
278                 return;
279         }
280         
281         QModelIndex const & idx = availableLV->selectionModel()->currentIndex();
282         string const modName = getAvailableModel()->getIDString(idx.row());
283         vector<string> reqs = getRequiredList(modName);
284         vector<string> excl = getExcludedList(modName);
285         
286         if (reqs.empty() && excl.empty()) {
287                 addPB->setEnabled(true);
288                 return;
289         }
290
291         int const srows = selectedModel->rowCount();
292         vector<string> selModList;
293         for (int i = 0; i < srows; ++i)
294                 selModList.push_back(getSelectedModel()->getIDString(i));
295
296         vector<string>::const_iterator selModStart = selModList.begin();
297         vector<string>::const_iterator selModEnd   = selModList.end();
298         
299         // Check whether some required module is available
300         if (!reqs.empty()) {
301                 bool foundOne = false;
302                 vector<string>::const_iterator it  = reqs.begin();
303                 vector<string>::const_iterator end = reqs.end();
304                 for (; it != end; ++it) {
305                         if (find(selModStart, selModEnd, *it) != selModEnd) {
306                                 foundOne = true;
307                                 break;
308                         }
309                 }
310                 if (!foundOne) {
311                         addPB->setEnabled(false);
312                         return;
313                 }
314         }
315         
316         // Check whether any excluded module is being used
317         if (!excl.empty()) {
318                 vector<string>::const_iterator it  = excl.begin();
319                 vector<string>::const_iterator end = excl.end();
320                 for (; it != end; ++it) {
321                         if (find(selModStart, selModEnd, *it) != selModEnd) {
322                                 addPB->setEnabled(false);
323                                 return;
324                         }
325                 }
326         }
327
328         addPB->setEnabled(true);
329 }
330
331
332 void ModuleSelectionManager::updateDownPB()
333 {
334         int const srows = selectedModel->rowCount();
335         if (srows == 0) {
336                 downPB->setEnabled(false);
337                 return;
338         }
339         QModelIndex const & curIdx = selectedLV->selectionModel()->currentIndex();
340         int const curRow = curIdx.row();
341         if (curRow < 0 || curRow >= srows - 1) { // invalid or last item
342                 downPB->setEnabled(false);
343                 return;
344         }
345
346         // determine whether immediately succeding element requires this one
347         string const curModName = getSelectedModel()->getIDString(curRow);
348         string const nextModName = getSelectedModel()->getIDString(curRow + 1);
349
350         vector<string> reqs = getRequiredList(nextModName);
351
352         // if it doesn't require anything....
353         if (reqs.empty()) {
354                 downPB->setEnabled(true);
355                 return;
356         }
357
358         // Enable it if this module isn't required.
359         // FIXME This should perhaps be more flexible and check whether, even 
360         // if the next one is required, there is also an earlier one that will do.
361         downPB->setEnabled(
362                         find(reqs.begin(), reqs.end(), curModName) == reqs.end());
363 }
364
365 void ModuleSelectionManager::updateUpPB() 
366 {
367         int const srows = selectedModel->rowCount();
368         if (srows == 0) {
369                 upPB->setEnabled(false);
370                 return;
371         }
372
373         QModelIndex const & curIdx = selectedLV->selectionModel()->currentIndex();
374         int curRow = curIdx.row();
375         if (curRow <= 0 || curRow > srows - 1) { // first item or invalid
376                 upPB->setEnabled(false);
377                 return;
378         }
379         string const curModName = getSelectedModel()->getIDString(curRow);
380
381         // determine whether immediately preceding element is required by this one
382         vector<string> reqs = getRequiredList(curModName);
383         
384         // if this one doesn't require anything....
385         if (reqs.empty()) {
386                 upPB->setEnabled(true);
387                 return;
388         }
389
390         string preModName = getSelectedModel()->getIDString(curRow - 1);
391
392         // Enable it if the preceding module isn't required.
393         // NOTE This is less flexible than it might be. We could check whether, even 
394         // if the previous one is required, there is an earlier one that would do.
395         upPB->setEnabled(find(reqs.begin(), reqs.end(), preModName) == reqs.end());
396 }
397
398 void ModuleSelectionManager::updateDelPB() 
399 {
400         int const srows = selectedModel->rowCount();
401         if (srows == 0) {
402                 deletePB->setEnabled(false);
403                 return;
404         }
405         
406         QModelIndex const & curIdx = 
407                 selectedLV->selectionModel()->currentIndex();
408         int const curRow = curIdx.row();
409         if (curRow < 0 || curRow >= srows) { // invalid index?
410                 deletePB->setEnabled(false);
411                 return;
412         }
413                 
414         // determine whether some LATER module requires this one
415         // NOTE Things are arranged so that this is the only way there
416         // can be a problem. At least, we hope so.
417         QString const curModName = curIdx.data().toString();
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(), fromqstr(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 << std::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 << std::endl;
442                         // do we satisfy the require? 
443                         if (find(reqs.begin(), reqs.end(), mod) != reqs.end()) {
444                                 // lyxerr << mod << " does the trick." << std::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." << std::endl;
452                         deletePB->setEnabled(false);
453                         return;
454                 }
455         }
456         // lyxerr << "All's well that ends well." << std::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         connect(textLayoutModule->skipRB, SIGNAL(clicked()),
559                 this, SLOT(change_adaptor()));
560         connect(textLayoutModule->indentRB, SIGNAL(clicked()),
561                 this, SLOT(change_adaptor()));
562         connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
563                 this, SLOT(change_adaptor()));
564         connect(textLayoutModule->skipLE, SIGNAL(textChanged(const QString &)),
565                 this, SLOT(change_adaptor()));
566         connect(textLayoutModule->skipLengthCO, SIGNAL(activated(int)),
567                 this, SLOT(change_adaptor()));
568         connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
569                 this, SLOT(setSkip(int)));
570         connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
571                 this, SLOT(enableSkip(bool)));
572         connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
573                 this, SLOT(change_adaptor()));
574         connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
575                 this, SLOT(setColSep()));
576         connect(textLayoutModule->listingsED, SIGNAL(textChanged()),
577                 this, SLOT(change_adaptor()));
578         connect(textLayoutModule->bypassCB, SIGNAL(clicked()), 
579                 this, SLOT(change_adaptor()));
580         connect(textLayoutModule->bypassCB, SIGNAL(clicked()), 
581                 this, SLOT(setListingsMessage()));
582         connect(textLayoutModule->listingsED, SIGNAL(textChanged()),
583                 this, SLOT(setListingsMessage()));
584         textLayoutModule->listingsTB->setPlainText(
585                 qt_("Input listings parameters on the right. Enter ? for a list of parameters."));
586         textLayoutModule->lspacingLE->setValidator(new QDoubleValidator(
587                 textLayoutModule->lspacingLE));
588         textLayoutModule->skipLE->setValidator(unsignedLengthValidator(
589                 textLayoutModule->skipLE));
590
591         textLayoutModule->skipCO->addItem(qt_("SmallSkip"));
592         textLayoutModule->skipCO->addItem(qt_("MedSkip"));
593         textLayoutModule->skipCO->addItem(qt_("BigSkip"));
594         textLayoutModule->skipCO->addItem(qt_("Length"));
595         // remove the %-items from the unit choice
596         textLayoutModule->skipLengthCO->noPercents();
597         textLayoutModule->lspacingCO->insertItem(
598                 Spacing::Single, qt_("Single"));
599         textLayoutModule->lspacingCO->insertItem(
600                 Spacing::Onehalf, qt_("OneHalf"));
601         textLayoutModule->lspacingCO->insertItem(
602                 Spacing::Double, qt_("Double"));
603         textLayoutModule->lspacingCO->insertItem(
604                 Spacing::Other, qt_("Custom"));
605
606         // initialize the length validator
607         bc().addCheckedLineEdit(textLayoutModule->skipLE);
608
609         fontModule = new UiWidget<Ui::FontUi>;
610         // fonts
611         connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
612                 this, SLOT(change_adaptor()));
613         connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
614                 this, SLOT(romanChanged(int)));
615         connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
616                 this, SLOT(change_adaptor()));
617         connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
618                 this, SLOT(sansChanged(int)));
619         connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
620                 this, SLOT(change_adaptor()));
621         connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
622                 this, SLOT(ttChanged(int)));
623         connect(fontModule->fontsDefaultCO, SIGNAL(activated(int)),
624                 this, SLOT(change_adaptor()));
625         connect(fontModule->fontsizeCO, SIGNAL(activated(int)),
626                 this, SLOT(change_adaptor()));
627         connect(fontModule->cjkFontLE, SIGNAL(textChanged(const QString &)),
628                 this, SLOT(change_adaptor()));
629         connect(fontModule->scaleSansSB, SIGNAL(valueChanged(int)),
630                 this, SLOT(change_adaptor()));
631         connect(fontModule->scaleTypewriterSB, SIGNAL(valueChanged(int)),
632                 this, SLOT(change_adaptor()));
633         connect(fontModule->fontScCB, SIGNAL(clicked()),
634                 this, SLOT(change_adaptor()));
635         connect(fontModule->fontOsfCB, SIGNAL(clicked()),
636                 this, SLOT(change_adaptor()));
637
638         for (int n = 0; tex_fonts_roman[n][0]; ++n) {
639                 QString font = qt_(tex_fonts_roman_gui[n]);
640                 if (!isFontAvailable(tex_fonts_roman[n]))
641                         font += qt_(" (not installed)");
642                 fontModule->fontsRomanCO->addItem(font);
643         }
644         for (int n = 0; tex_fonts_sans[n][0]; ++n) {
645                 QString font = qt_(tex_fonts_sans_gui[n]);
646                 if (!isFontAvailable(tex_fonts_sans[n]))
647                         font += qt_(" (not installed)");
648                 fontModule->fontsSansCO->addItem(font);
649         }
650         for (int n = 0; tex_fonts_monospaced[n][0]; ++n) {
651                 QString font = qt_(tex_fonts_monospaced_gui[n]);
652                 if (!isFontAvailable(tex_fonts_monospaced[n]))
653                         font += qt_(" (not installed)");
654                 fontModule->fontsTypewriterCO->addItem(font);
655         }
656
657         fontModule->fontsizeCO->addItem(qt_("Default"));
658         fontModule->fontsizeCO->addItem(qt_("10"));
659         fontModule->fontsizeCO->addItem(qt_("11"));
660         fontModule->fontsizeCO->addItem(qt_("12"));
661
662         for (int n = 0; GuiDocument::fontfamilies_gui[n][0]; ++n)
663                 fontModule->fontsDefaultCO->addItem(
664                         qt_(GuiDocument::fontfamilies_gui[n]));
665
666
667         pageLayoutModule = new UiWidget<Ui::PageLayoutUi>;
668         // page layout
669         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
670                 this, SLOT(setCustomPapersize(int)));
671         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
672                 this, SLOT(setCustomPapersize(int)));
673         connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
674                 this, SLOT(portraitChanged()));
675         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
676                 this, SLOT(change_adaptor()));
677         connect(pageLayoutModule->paperheightLE, SIGNAL(textChanged(const QString &)),
678                 this, SLOT(change_adaptor()));
679         connect(pageLayoutModule->paperwidthLE, SIGNAL(textChanged(const QString &)),
680                 this, SLOT(change_adaptor()));
681         connect(pageLayoutModule->paperwidthUnitCO, SIGNAL(activated(int)),
682                 this, SLOT(change_adaptor()));
683         connect(pageLayoutModule->paperheightUnitCO, SIGNAL(activated(int)),
684                 this, SLOT(change_adaptor()));
685         connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
686                 this, SLOT(change_adaptor()));
687         connect(pageLayoutModule->landscapeRB, SIGNAL(clicked()),
688                 this, SLOT(change_adaptor()));
689         connect(pageLayoutModule->facingPagesCB, SIGNAL(clicked()),
690                 this, SLOT(change_adaptor()));
691         connect(pageLayoutModule->pagestyleCO, SIGNAL(activated(int)),
692                 this, SLOT(change_adaptor()));
693
694         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
695         pageLayoutModule->pagestyleCO->addItem(qt_("empty"));
696         pageLayoutModule->pagestyleCO->addItem(qt_("plain"));
697         pageLayoutModule->pagestyleCO->addItem(qt_("headings"));
698         pageLayoutModule->pagestyleCO->addItem(qt_("fancy"));
699         bc().addCheckedLineEdit(pageLayoutModule->paperheightLE,
700                 pageLayoutModule->paperheightL);
701         bc().addCheckedLineEdit(pageLayoutModule->paperwidthLE,
702                 pageLayoutModule->paperwidthL);
703
704         // paper
705         QComboBox * cb = pageLayoutModule->papersizeCO;
706         cb->addItem(qt_("Default"));
707         cb->addItem(qt_("Custom"));
708         cb->addItem(qt_("US letter"));
709         cb->addItem(qt_("US legal"));
710         cb->addItem(qt_("US executive"));
711         cb->addItem(qt_("A3"));
712         cb->addItem(qt_("A4"));
713         cb->addItem(qt_("A5"));
714         cb->addItem(qt_("B3"));
715         cb->addItem(qt_("B4"));
716         cb->addItem(qt_("B5"));
717         // remove the %-items from the unit choice
718         pageLayoutModule->paperwidthUnitCO->noPercents();
719         pageLayoutModule->paperheightUnitCO->noPercents();
720         pageLayoutModule->paperheightLE->setValidator(unsignedLengthValidator(
721                 pageLayoutModule->paperheightLE));
722         pageLayoutModule->paperwidthLE->setValidator(unsignedLengthValidator(
723                 pageLayoutModule->paperwidthLE));
724
725
726         marginsModule = new UiWidget<Ui::MarginsUi>;
727         // margins
728         connect(marginsModule->marginCB, SIGNAL(toggled(bool)),
729                 this, SLOT(setCustomMargins(bool)));
730         connect(marginsModule->marginCB, SIGNAL(clicked()),
731                 this, SLOT(change_adaptor()));
732         connect(marginsModule->topLE, SIGNAL(textChanged(QString)),
733                 this, SLOT(change_adaptor()));
734         connect(marginsModule->topUnit, SIGNAL(activated(int)),
735                 this, SLOT(change_adaptor()));
736         connect(marginsModule->bottomLE, SIGNAL(textChanged(QString)),
737                 this, SLOT(change_adaptor()));
738         connect(marginsModule->bottomUnit, SIGNAL(activated(int)),
739                 this, SLOT(change_adaptor()));
740         connect(marginsModule->innerLE, SIGNAL(textChanged(QString)),
741                 this, SLOT(change_adaptor()));
742         connect(marginsModule->innerUnit, SIGNAL(activated(int)),
743                 this, SLOT(change_adaptor()));
744         connect(marginsModule->outerLE, SIGNAL(textChanged(QString)),
745                 this, SLOT(change_adaptor()));
746         connect(marginsModule->outerUnit, SIGNAL(activated(int)),
747                 this, SLOT(change_adaptor()));
748         connect(marginsModule->headheightLE, SIGNAL(textChanged(QString)),
749                 this, SLOT(change_adaptor()));
750         connect(marginsModule->headheightUnit, SIGNAL(activated(int)),
751                 this, SLOT(change_adaptor()));
752         connect(marginsModule->headsepLE, SIGNAL(textChanged(QString)),
753                 this, SLOT(change_adaptor()));
754         connect(marginsModule->headsepUnit, SIGNAL(activated(int)),
755                 this, SLOT(change_adaptor()));
756         connect(marginsModule->footskipLE, SIGNAL(textChanged(QString)),
757                 this, SLOT(change_adaptor()));
758         connect(marginsModule->footskipUnit, SIGNAL(activated(int)),
759                 this, SLOT(change_adaptor()));
760         connect(marginsModule->columnsepLE, SIGNAL(textChanged(QString)),
761                 this, SLOT(change_adaptor()));
762         connect(marginsModule->columnsepUnit, SIGNAL(activated(int)),
763                 this, SLOT(change_adaptor()));
764         marginsModule->topLE->setValidator(unsignedLengthValidator(
765                 marginsModule->topLE));
766         marginsModule->bottomLE->setValidator(unsignedLengthValidator(
767                 marginsModule->bottomLE));
768         marginsModule->innerLE->setValidator(unsignedLengthValidator(
769                 marginsModule->innerLE));
770         marginsModule->outerLE->setValidator(unsignedLengthValidator(
771                 marginsModule->outerLE));
772         marginsModule->headsepLE->setValidator(unsignedLengthValidator(
773                 marginsModule->headsepLE));
774         marginsModule->headheightLE->setValidator(unsignedLengthValidator(
775                 marginsModule->headheightLE));
776         marginsModule->footskipLE->setValidator(unsignedLengthValidator(
777                 marginsModule->footskipLE));
778         marginsModule->columnsepLE->setValidator(unsignedLengthValidator(
779                 marginsModule->columnsepLE));
780
781         bc().addCheckedLineEdit(marginsModule->topLE,
782                 marginsModule->topL);
783         bc().addCheckedLineEdit(marginsModule->bottomLE,
784                 marginsModule->bottomL);
785         bc().addCheckedLineEdit(marginsModule->innerLE,
786                 marginsModule->innerL);
787         bc().addCheckedLineEdit(marginsModule->outerLE,
788                 marginsModule->outerL);
789         bc().addCheckedLineEdit(marginsModule->headsepLE,
790                 marginsModule->headsepL);
791         bc().addCheckedLineEdit(marginsModule->headheightLE,
792                 marginsModule->headheightL);
793         bc().addCheckedLineEdit(marginsModule->footskipLE,
794                 marginsModule->footskipL);
795         bc().addCheckedLineEdit(marginsModule->columnsepLE,
796                 marginsModule->columnsepL);
797
798
799         langModule = new UiWidget<Ui::LanguageUi>;
800         // language & quote
801         connect(langModule->languageCO, SIGNAL(activated(int)),
802                 this, SLOT(change_adaptor()));
803         connect(langModule->defaultencodingRB, SIGNAL(clicked()),
804                 this, SLOT(change_adaptor()));
805         connect(langModule->otherencodingRB, SIGNAL(clicked()),
806                 this, SLOT(change_adaptor()));
807         connect(langModule->encodingCO, SIGNAL(activated(int)),
808                 this, SLOT(change_adaptor()));
809         connect(langModule->quoteStyleCO, SIGNAL(activated(int)),
810                 this, SLOT(change_adaptor()));
811         // language & quotes
812         QAbstractItemModel * language_model = guiApp->languageModel();
813         // FIXME: it would be nice if sorting was enabled/disabled via a checkbox.
814         language_model->sort(0);
815         langModule->languageCO->setModel(language_model);
816
817         // Always put the default encoding in the first position.
818         langModule->encodingCO->addItem(qt_("Language Default (no inputenc)"));
819         QStringList encodinglist;
820         Encodings::const_iterator it = encodings.begin();
821         Encodings::const_iterator const end = encodings.end();
822         for (; it != end; ++it)
823                 encodinglist.append(qt_(it->guiName()));
824         encodinglist.sort();
825         langModule->encodingCO->addItems(encodinglist);
826
827         langModule->quoteStyleCO->addItem(qt_("``text''"));
828         langModule->quoteStyleCO->addItem(qt_("''text''"));
829         langModule->quoteStyleCO->addItem(qt_(",,text``"));
830         langModule->quoteStyleCO->addItem(qt_(",,text''"));
831         langModule->quoteStyleCO->addItem(qt_("<<text>>"));
832         langModule->quoteStyleCO->addItem(qt_(">>text<<"));
833
834
835         numberingModule = new UiWidget<Ui::NumberingUi>;
836         // numbering
837         connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
838                 this, SLOT(change_adaptor()));
839         connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
840                 this, SLOT(change_adaptor()));
841         connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
842                 this, SLOT(updateNumbering()));
843         connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
844                 this, SLOT(updateNumbering()));
845         numberingModule->tocTW->setColumnCount(3);
846         numberingModule->tocTW->headerItem()->setText(0, qt_("Example"));
847         numberingModule->tocTW->headerItem()->setText(1, qt_("Numbered"));
848         numberingModule->tocTW->headerItem()->setText(2, qt_("Appears in TOC"));
849
850
851         biblioModule = new UiWidget<Ui::BiblioUi>;
852         connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
853                 biblioModule->citationStyleL, SLOT(setEnabled(bool)));
854         connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
855                 biblioModule->citeStyleCO, SLOT(setEnabled(bool)));
856         // biblio
857         connect(biblioModule->citeDefaultRB, SIGNAL(clicked()),
858                 this, SLOT(change_adaptor()));
859         connect(biblioModule->citeNatbibRB, SIGNAL(clicked()),
860                 this, SLOT(change_adaptor()));
861         connect(biblioModule->citeStyleCO, SIGNAL(activated(int)),
862                 this, SLOT(change_adaptor()));
863         connect(biblioModule->citeJurabibRB, SIGNAL(clicked()),
864                 this, SLOT(change_adaptor()));
865         connect(biblioModule->bibtopicCB, SIGNAL(clicked()),
866                 this, SLOT(change_adaptor()));
867         // biblio
868         biblioModule->citeStyleCO->addItem(qt_("Author-year"));
869         biblioModule->citeStyleCO->addItem(qt_("Numerical"));
870         biblioModule->citeStyleCO->setCurrentIndex(0);
871
872
873         mathsModule = new UiWidget<Ui::MathsUi>;
874         connect(mathsModule->amsautoCB, SIGNAL(toggled(bool)),
875                 mathsModule->amsCB, SLOT(setDisabled(bool)));
876         connect(mathsModule->esintautoCB, SIGNAL(toggled(bool)),
877                 mathsModule->esintCB, SLOT(setDisabled(bool)));
878         // maths
879         connect(mathsModule->amsCB, SIGNAL(clicked()),
880                 this, SLOT(change_adaptor()));
881         connect(mathsModule->amsautoCB, SIGNAL(clicked()),
882                 this, SLOT(change_adaptor()));
883         connect(mathsModule->esintCB, SIGNAL(clicked()),
884                 this, SLOT(change_adaptor()));
885         connect(mathsModule->esintautoCB, SIGNAL(clicked()),
886                 this, SLOT(change_adaptor()));
887
888         latexModule = new UiWidget<Ui::LaTeXUi>;
889         // latex class
890         connect(latexModule->optionsLE, SIGNAL(textChanged(QString)),
891                 this, SLOT(change_adaptor()));
892         connect(latexModule->defaultOptionsCB, SIGNAL(clicked()),
893                 this, SLOT(change_adaptor()));
894         connect(latexModule->psdriverCO, SIGNAL(activated(int)),
895                 this, SLOT(change_adaptor()));
896         connect(latexModule->classCO, SIGNAL(activated(int)),
897                 this, SLOT(classChanged()));
898         connect(latexModule->classCO, SIGNAL(activated(int)),
899                 this, SLOT(change_adaptor()));
900         connect(latexModule->layoutPB, SIGNAL(clicked()),
901                 this, SLOT(browseLayout()));
902         connect(latexModule->layoutPB, SIGNAL(clicked()),
903                 this, SLOT(change_adaptor()));
904         connect(latexModule->childDocGB, SIGNAL(clicked()),
905                 this, SLOT(change_adaptor()));
906         connect(latexModule->childDocLE, SIGNAL(textChanged(QString)),
907                 this, SLOT(change_adaptor()));
908         connect(latexModule->childDocPB, SIGNAL(clicked()),
909                 this, SLOT(browseMaster()));
910         
911         selectionManager =
912                 new ModuleSelectionManager(latexModule->availableLV,
913                         latexModule->selectedLV, 
914                         latexModule->addPB, latexModule->deletePB, 
915                         latexModule->upPB, latexModule->downPB, 
916                         availableModel(), selectedModel());
917         connect(selectionManager, SIGNAL(updateHook()),
918                 this, SLOT(updateModuleInfo()));
919         connect(selectionManager, SIGNAL(updateHook()),
920                 this, SLOT(change_adaptor()));
921         
922         // postscript drivers
923         for (int n = 0; tex_graphics[n][0]; ++n) {
924                 QString enc = qt_(tex_graphics_gui[n]);
925                 latexModule->psdriverCO->addItem(enc);
926         }
927         // latex classes
928         latexModule->classCO->setModel(&classes_model_);
929         LayoutFileList const & bcl = LayoutFileList::get();
930         vector<LayoutFileIndex> classList = bcl.classList();
931         sort(classList.begin(), classList.end(), less_textclass_avail_desc());
932
933         vector<LayoutFileIndex>::const_iterator cit  = classList.begin();
934         vector<LayoutFileIndex>::const_iterator cen = classList.end();
935         for (int i = 0; cit != cen; ++cit, ++i) {
936                 LayoutFile const & tc = bcl[*cit];
937                 docstring item = (tc.isTeXClassAvailable()) ?
938                         from_utf8(tc.description()) :
939                         bformat(_("Unavailable: %1$s"), from_utf8(tc.description()));
940                 classes_model_.insertRow(i, toqstr(item), *cit);
941         }
942
943         // branches
944         branchesModule = new GuiBranches;
945         connect(branchesModule, SIGNAL(changed()),
946                 this, SLOT(change_adaptor()));
947
948         // preamble
949         preambleModule = new PreambleModule;
950         connect(preambleModule, SIGNAL(changed()),
951                 this, SLOT(change_adaptor()));
952
953         // bullets
954         bulletsModule = new BulletsModule;
955         connect(bulletsModule, SIGNAL(changed()),
956                 this, SLOT(change_adaptor()));
957
958         // PDF support
959         pdfSupportModule = new UiWidget<Ui::PDFSupportUi>;
960
961         connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
962                 this, SLOT(change_adaptor()));
963         connect(pdfSupportModule->titleLE, SIGNAL(textChanged(QString)),
964                 this, SLOT(change_adaptor()));
965         connect(pdfSupportModule->authorLE, SIGNAL(textChanged(QString)),
966                 this, SLOT(change_adaptor()));
967         connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(QString)),
968                 this, SLOT(change_adaptor()));
969         connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(QString)),
970                 this, SLOT(change_adaptor()));
971         connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
972                 this, SLOT(change_adaptor()));
973         connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
974                 this, SLOT(change_adaptor()));
975         connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
976                 this, SLOT(change_adaptor()));
977         connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
978                 this, SLOT(change_adaptor()));
979         connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
980                 this, SLOT(change_adaptor()));
981         connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
982                 this, SLOT(change_adaptor()));
983         connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
984                 this, SLOT(change_adaptor()));
985         connect(pdfSupportModule->backrefCO, SIGNAL(activated(int)),
986                 this, SLOT(change_adaptor()));
987         connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
988                 this, SLOT(change_adaptor()));
989         connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
990                 this, SLOT(change_adaptor()));
991         connect(pdfSupportModule->optionsLE, SIGNAL(textChanged(QString)),
992                 this, SLOT(change_adaptor()));
993
994         for (int i = 0; backref_opts[i][0]; ++i)
995                 pdfSupportModule->backrefCO->addItem(qt_(backref_opts_gui[i]));
996
997         // float
998         floatModule = new FloatPlacement;
999         connect(floatModule, SIGNAL(changed()),
1000                 this, SLOT(change_adaptor()));
1001
1002         docPS->addPanel(latexModule, qt_("Document Class"));
1003         docPS->addPanel(fontModule, qt_("Fonts"));
1004         docPS->addPanel(textLayoutModule, qt_("Text Layout"));
1005         docPS->addPanel(pageLayoutModule, qt_("Page Layout"));
1006         docPS->addPanel(marginsModule, qt_("Page Margins"));
1007         docPS->addPanel(langModule, qt_("Language"));
1008         docPS->addPanel(numberingModule, qt_("Numbering & TOC"));
1009         docPS->addPanel(biblioModule, qt_("Bibliography"));
1010         docPS->addPanel(pdfSupportModule, qt_("PDF Properties"));
1011         docPS->addPanel(mathsModule, qt_("Math Options"));
1012         docPS->addPanel(floatModule, qt_("Float Placement"));
1013         docPS->addPanel(bulletsModule, qt_("Bullets"));
1014         docPS->addPanel(branchesModule, qt_("Branches"));
1015         docPS->addPanel(preambleModule, qt_("LaTeX Preamble"));
1016         docPS->setCurrentPanel(qt_("Document Class"));
1017 // FIXME: hack to work around resizing bug in Qt >= 4.2
1018 // bug verified with Qt 4.2.{0-3} (JSpitzm)
1019 #if QT_VERSION >= 0x040200
1020         docPS->updateGeometry();
1021 #endif
1022 }
1023
1024
1025 void GuiDocument::showPreamble()
1026 {
1027         docPS->setCurrentPanel(qt_("LaTeX Preamble"));
1028 }
1029
1030
1031 void GuiDocument::saveDefaultClicked()
1032 {
1033         saveDocDefault();
1034 }
1035
1036
1037 void GuiDocument::useDefaultsClicked()
1038 {
1039         useClassDefaults();
1040 }
1041
1042
1043 void GuiDocument::change_adaptor()
1044 {
1045         changed();
1046 }
1047
1048
1049 QString GuiDocument::validateListingsParameters()
1050 {
1051         // use a cache here to avoid repeated validation
1052         // of the same parameters
1053         static string param_cache;
1054         static QString msg_cache;
1055         
1056         if (textLayoutModule->bypassCB->isChecked())
1057                 return QString();
1058
1059         string params = fromqstr(textLayoutModule->listingsED->toPlainText());
1060         if (params != param_cache) {
1061                 param_cache = params;
1062                 msg_cache = toqstr(InsetListingsParams(params).validate());
1063         }
1064         return msg_cache;
1065 }
1066
1067
1068 void GuiDocument::setListingsMessage()
1069 {
1070         static bool isOK = true;
1071         QString msg = validateListingsParameters();
1072         if (msg.isEmpty()) {
1073                 if (isOK)
1074                         return;
1075                 isOK = true;
1076                 // listingsTB->setTextColor("black");
1077                 textLayoutModule->listingsTB->setPlainText(
1078                         qt_("Input listings parameters on the right. "
1079                 "Enter ? for a list of parameters."));
1080         } else {
1081                 isOK = false;
1082                 // listingsTB->setTextColor("red");
1083                 textLayoutModule->listingsTB->setPlainText(msg);
1084         }
1085 }
1086
1087
1088 void GuiDocument::setLSpacing(int item)
1089 {
1090         textLayoutModule->lspacingLE->setEnabled(item == 3);
1091 }
1092
1093
1094 void GuiDocument::setSkip(int item)
1095 {
1096         bool const enable = (item == 3);
1097         textLayoutModule->skipLE->setEnabled(enable);
1098         textLayoutModule->skipLengthCO->setEnabled(enable);
1099 }
1100
1101
1102 void GuiDocument::enableSkip(bool skip)
1103 {
1104         textLayoutModule->skipCO->setEnabled(skip);
1105         textLayoutModule->skipLE->setEnabled(skip);
1106         textLayoutModule->skipLengthCO->setEnabled(skip);
1107         if (skip)
1108                 setSkip(textLayoutModule->skipCO->currentIndex());
1109 }
1110
1111 void GuiDocument::portraitChanged()
1112 {
1113         setMargins(pageLayoutModule->papersizeCO->currentIndex());
1114 }
1115
1116 void GuiDocument::setMargins(bool custom)
1117 {
1118         marginsModule->marginCB->setChecked(custom);
1119         setCustomMargins(custom);
1120 }
1121
1122
1123 void GuiDocument::setCustomPapersize(int papersize)
1124 {
1125         bool const custom = (papersize == 1);
1126
1127         pageLayoutModule->paperwidthL->setEnabled(custom);
1128         pageLayoutModule->paperwidthLE->setEnabled(custom);
1129         pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
1130         pageLayoutModule->paperheightL->setEnabled(custom);
1131         pageLayoutModule->paperheightLE->setEnabled(custom);
1132         pageLayoutModule->paperheightLE->setFocus();
1133         pageLayoutModule->paperheightUnitCO->setEnabled(custom);
1134 }
1135
1136
1137 void GuiDocument::setColSep()
1138 {
1139         setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
1140 }
1141
1142
1143 void GuiDocument::setCustomMargins(bool custom)
1144 {
1145         marginsModule->topL->setEnabled(!custom);
1146         marginsModule->topLE->setEnabled(!custom);
1147         marginsModule->topUnit->setEnabled(!custom);
1148
1149         marginsModule->bottomL->setEnabled(!custom);
1150         marginsModule->bottomLE->setEnabled(!custom);
1151         marginsModule->bottomUnit->setEnabled(!custom);
1152
1153         marginsModule->innerL->setEnabled(!custom);
1154         marginsModule->innerLE->setEnabled(!custom);
1155         marginsModule->innerUnit->setEnabled(!custom);
1156
1157         marginsModule->outerL->setEnabled(!custom);
1158         marginsModule->outerLE->setEnabled(!custom);
1159         marginsModule->outerUnit->setEnabled(!custom);
1160
1161         marginsModule->headheightL->setEnabled(!custom);
1162         marginsModule->headheightLE->setEnabled(!custom);
1163         marginsModule->headheightUnit->setEnabled(!custom);
1164
1165         marginsModule->headsepL->setEnabled(!custom);
1166         marginsModule->headsepLE->setEnabled(!custom);
1167         marginsModule->headsepUnit->setEnabled(!custom);
1168
1169         marginsModule->footskipL->setEnabled(!custom);
1170         marginsModule->footskipLE->setEnabled(!custom);
1171         marginsModule->footskipUnit->setEnabled(!custom);
1172
1173         bool const enableColSep = !custom && 
1174                         textLayoutModule->twoColumnCB->checkState() == Qt::Checked;
1175         marginsModule->columnsepL->setEnabled(enableColSep);
1176         marginsModule->columnsepLE->setEnabled(enableColSep);
1177         marginsModule->columnsepUnit->setEnabled(enableColSep);
1178 }
1179
1180
1181 void GuiDocument::updateFontsize(string const & items, string const & sel)
1182 {
1183         fontModule->fontsizeCO->clear();
1184         fontModule->fontsizeCO->addItem(qt_("Default"));
1185
1186         for (int n = 0; !token(items,'|',n).empty(); ++n)
1187                 fontModule->fontsizeCO->
1188                         addItem(toqstr(token(items,'|',n)));
1189
1190         for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
1191                 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
1192                         fontModule->fontsizeCO->setCurrentIndex(n);
1193                         break;
1194                 }
1195         }
1196 }
1197
1198
1199 void GuiDocument::romanChanged(int item)
1200 {
1201         string const font = tex_fonts_roman[item];
1202         fontModule->fontScCB->setEnabled(providesSC(font));
1203         fontModule->fontOsfCB->setEnabled(providesOSF(font));
1204 }
1205
1206
1207 void GuiDocument::sansChanged(int item)
1208 {
1209         string const font = tex_fonts_sans[item];
1210         bool scaleable = providesScale(font);
1211         fontModule->scaleSansSB->setEnabled(scaleable);
1212         fontModule->scaleSansLA->setEnabled(scaleable);
1213 }
1214
1215
1216 void GuiDocument::ttChanged(int item)
1217 {
1218         string const font = tex_fonts_monospaced[item];
1219         bool scaleable = providesScale(font);
1220         fontModule->scaleTypewriterSB->setEnabled(scaleable);
1221         fontModule->scaleTypewriterLA->setEnabled(scaleable);
1222 }
1223
1224
1225 void GuiDocument::updatePagestyle(string const & items, string const & sel)
1226 {
1227         pagestyles.clear();
1228         pageLayoutModule->pagestyleCO->clear();
1229         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1230
1231         for (int n = 0; !token(items, '|', n).empty(); ++n) {
1232                 string style = token(items, '|', n);
1233                 QString style_gui = qt_(style);
1234                 pagestyles.push_back(pair<string, QString>(style, style_gui));
1235                 pageLayoutModule->pagestyleCO->addItem(style_gui);
1236         }
1237
1238         if (sel == "default") {
1239                 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
1240                 return;
1241         }
1242
1243         int nn = 0;
1244
1245         for (size_t i = 0; i < pagestyles.size(); ++i)
1246                 if (pagestyles[i].first == sel)
1247                         nn = pageLayoutModule->pagestyleCO->findText(pagestyles[i].second);
1248
1249         if (nn > 0)
1250                 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
1251 }
1252
1253
1254 void GuiDocument::browseLayout()
1255 {
1256         QString const label1 = qt_("Layouts|#o#O");
1257         QString const dir1 = toqstr(lyxrc.document_path);
1258         QStringList const filter(qt_("LyX Layout (*.layout)"));
1259         QString file = browseRelFile(QString(), bufferFilepath(),
1260                 qt_("Local layout file"), filter, false,
1261                 label1, dir1);
1262
1263         if (!file.endsWith(".layout"))
1264                 return;
1265
1266         FileName layoutFile = support::makeAbsPath(fromqstr(file),
1267                 fromqstr(bufferFilepath()));
1268         
1269         int const ret = Alert::prompt(_("Local layout file"),
1270                 _("The layout file you have selected is a local layout\n"
1271                   "file, not one in the system or user directory. Your\n"
1272                   "document may not work with this layout if you do not\n"
1273                   "keep the layout file in the document directory."),
1274                   1, 1, _("&Set Layout"), _("&Cancel"));
1275         if (ret == 1)
1276                 return;
1277
1278         // load the layout file
1279         LayoutFileList & bcl = LayoutFileList::get();
1280         string classname = layoutFile.onlyFileName();
1281         // this will update an existing layout if that layout has been loaded before.
1282         LayoutFileIndex name = bcl.addLocalLayout(
1283                 classname.substr(0, classname.size() - 7),
1284                 layoutFile.onlyPath().absFilename());
1285
1286         if (name.empty()) {
1287                 Alert::error(_("Error"),
1288                         _("Unable to read local layout file."));                
1289                 return;
1290         }
1291
1292         // do not trigger classChanged if there is no change.
1293         if (latexModule->classCO->currentText() == toqstr(name))
1294                 return;
1295                 
1296         // add to combo box
1297         int idx = latexModule->classCO->findText(toqstr(name));
1298         if (idx == -1) {
1299                 classes_model_.insertRow(0, toqstr(name), name);
1300                 latexModule->classCO->setCurrentIndex(0);
1301         } else
1302                 latexModule->classCO->setCurrentIndex(idx);
1303         
1304         classChanged();
1305 }
1306
1307
1308 void GuiDocument::browseMaster()
1309 {
1310         QString const title = qt_("Select master document");
1311         QString const dir1 = toqstr(lyxrc.document_path);
1312         QString const old = latexModule->childDocLE->text();
1313         QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
1314         QStringList const filter(qt_("LyX Files (*.lyx)"));
1315         QString file = browseRelFile(old, docpath, title, filter, false,
1316                 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
1317
1318         latexModule->childDocLE->setText(file);
1319 }
1320
1321
1322 void GuiDocument::classChanged()
1323 {
1324         int idx = latexModule->classCO->currentIndex();
1325         if (idx < 0) 
1326                 return;
1327         string const classname = classes_model_.getIDString(idx);
1328
1329         // check whether the selected modules have changed.
1330         bool modulesChanged = false;
1331         unsigned int const srows = selectedModel()->rowCount();
1332         if (srows != bp_.getModules().size())
1333                 modulesChanged = true;
1334         else {
1335                 list<string>::const_iterator mit = bp_.getModules().begin();
1336                 list<string>::const_iterator men = bp_.getModules().end();
1337                 for (unsigned int i = 0; i < srows && mit != men; ++i, ++mit)
1338                         if (selectedModel()->getIDString(i) != *mit) {
1339                                 modulesChanged = true;
1340                                 break;
1341                         }
1342         }
1343
1344         if (modulesChanged || lyxrc.auto_reset_options) {
1345                 if (applyPB->isEnabled()) {
1346                         int const ret = Alert::prompt(_("Unapplied changes"),
1347                                         _("Some changes in the dialog were not yet applied.\n"
1348                                         "If you do not apply now, they will be lost after this action."),
1349                                         1, 1, _("&Apply"), _("&Dismiss"));
1350                         if (ret == 0)
1351                                 applyView();
1352                 }
1353         }
1354
1355         // We load the TextClass as soon as it is selected. This is
1356         // necessary so that other options in the dialog can be updated
1357         // according to the new class. Note, however, that, if you use 
1358         // the scroll wheel when sitting on the combo box, we'll load a 
1359         // lot of TextClass objects very quickly....
1360         if (!bp_.setBaseClass(classname)) {
1361                 Alert::error(_("Error"), _("Unable to set document class."));
1362                 return;
1363         }
1364         if (lyxrc.auto_reset_options)
1365                 bp_.useClassDefaults();
1366
1367         // With the introduction of modules came a distinction between the base 
1368         // class and the document class. The former corresponds to the main layout 
1369         // file; the latter is that plus the modules (or the document-specific layout,
1370         // or  whatever else there could be). Our parameters come from the document 
1371         // class. So when we set the base class, we also need to recreate the document 
1372         // class. Otherwise, we still have the old one.
1373         bp_.makeDocumentClass();
1374         // the new class may require some default modules.
1375         updateSelectedModules();
1376         paramsToDialog();
1377 }
1378
1379
1380 namespace {
1381         // This is an insanely complicated attempt to make this sort of thing
1382         // work with RTL languages.
1383         docstring formatStrVec(vector<string> const & v, docstring const & s) 
1384         {
1385                 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
1386                 if (v.size() == 0)
1387                         return docstring();
1388                 if (v.size() == 1) 
1389                         return from_ascii(v[0]);
1390                 if (v.size() == 2) {
1391                         docstring retval = _("%1$s and %2$s");
1392                         retval = subst(retval, _("and"), s);
1393                         return bformat(retval, from_ascii(v[0]), from_ascii(v[1]));
1394                 }
1395                 // The idea here is to format all but the last two items...
1396                 int const vSize = v.size();
1397                 docstring t2 = _("%1$s, %2$s");
1398                 docstring retval = from_ascii(v[0]);
1399                 for (int i = 1; i < vSize - 2; ++i)
1400                         retval = bformat(t2, retval, from_ascii(v[i])); 
1401                 //...and then to  plug them, and the last two, into this schema
1402                 docstring t = _("%1$s, %2$s, and %3$s");
1403                 t = subst(t, _("and"), s);
1404                 return bformat(t, retval, from_ascii(v[vSize - 2]), from_ascii(v[vSize - 1]));
1405         }
1406         
1407         vector<string> idsToNames(vector<string> const & idList)
1408         {
1409                 vector<string> retval;
1410                 vector<string>::const_iterator it  = idList.begin();
1411                 vector<string>::const_iterator end = idList.end();
1412                 for (; it != end; ++it) {
1413                         LyXModule const * const mod = moduleList[*it];
1414                         if (!mod)
1415                                 retval.push_back(*it + " (Unavailable)");
1416                         else
1417                                 retval.push_back(mod->getName());
1418                 }
1419                 return retval;
1420         }
1421 }
1422
1423
1424 void GuiDocument::updateModuleInfo()
1425 {
1426         selectionManager->update();
1427         
1428         //Module description
1429         bool const focusOnSelected = selectionManager->selectedFocused();
1430         QListView const * const lv = 
1431                         focusOnSelected ? latexModule->selectedLV : latexModule->availableLV;
1432         if (lv->selectionModel()->selectedIndexes().isEmpty()) {
1433                 latexModule->infoML->document()->clear();
1434                 return;
1435         }
1436         QModelIndex const & idx = lv->selectionModel()->currentIndex();
1437         GuiIdListModel const & idModel = 
1438                         focusOnSelected  ? modules_sel_model_ : modules_av_model_;
1439         string const modName = idModel.getIDString(idx.row());
1440         docstring desc = getModuleDescription(modName);
1441
1442         vector<string> pkgList = getPackageList(modName);
1443         docstring pkgdesc = formatStrVec(pkgList, _("and"));
1444         if (!pkgdesc.empty()) {
1445                 if (!desc.empty())
1446                         desc += "\n";
1447                 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
1448         }
1449
1450         pkgList = getRequiredList(modName);
1451         if (!pkgList.empty()) {
1452                 vector<string> const reqDescs = idsToNames(pkgList);
1453                 pkgdesc = formatStrVec(reqDescs, _("or"));
1454                 if (!desc.empty())
1455                         desc += "\n";
1456                 desc += bformat(_("Module required: %1$s."), pkgdesc);
1457         }
1458
1459         pkgList = getExcludedList(modName);
1460         if (!pkgList.empty()) {
1461                 vector<string> const reqDescs = idsToNames(pkgList);
1462                 pkgdesc = formatStrVec(reqDescs, _( "and"));
1463                 if (!desc.empty())
1464                         desc += "\n";
1465                 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
1466         }
1467
1468         if (!isModuleAvailable(modName)) {
1469                 if (!desc.empty())
1470                         desc += "\n";
1471                 desc += _("WARNING: Some packages are unavailable!");
1472         }
1473
1474         latexModule->infoML->document()->setPlainText(toqstr(desc));
1475 }
1476
1477
1478 void GuiDocument::updateNumbering()
1479 {
1480         DocumentClass const & tclass = documentClass();
1481
1482         numberingModule->tocTW->setUpdatesEnabled(false);
1483         numberingModule->tocTW->clear();
1484
1485         int const depth = numberingModule->depthSL->value();
1486         int const toc = numberingModule->tocSL->value();
1487         QString const no = qt_("No");
1488         QString const yes = qt_("Yes");
1489         QTreeWidgetItem * item = 0;
1490
1491         DocumentClass::const_iterator lit = tclass.begin();
1492         DocumentClass::const_iterator len = tclass.end();
1493         for (; lit != len; ++lit) {
1494                 int const toclevel = lit->toclevel;
1495                 if (toclevel != Layout::NOT_IN_TOC && lit->labeltype == LABEL_COUNTER) {
1496                         item = new QTreeWidgetItem(numberingModule->tocTW);
1497                         item->setText(0, toqstr(translateIfPossible(lit->name())));
1498                         item->setText(1, (toclevel <= depth) ? yes : no);
1499                         item->setText(2, (toclevel <= toc) ? yes : no);
1500                 }
1501         }
1502
1503         numberingModule->tocTW->setUpdatesEnabled(true);
1504         numberingModule->tocTW->update();
1505 }
1506
1507
1508 void GuiDocument::apply(BufferParams & params)
1509 {
1510         // preamble
1511         preambleModule->apply(params);
1512
1513         // biblio
1514         params.setCiteEngine(ENGINE_BASIC);
1515
1516         if (biblioModule->citeNatbibRB->isChecked()) {
1517                 bool const use_numerical_citations =
1518                         biblioModule->citeStyleCO->currentIndex();
1519                 if (use_numerical_citations)
1520                         params.setCiteEngine(ENGINE_NATBIB_NUMERICAL);
1521                 else
1522                         params.setCiteEngine(ENGINE_NATBIB_AUTHORYEAR);
1523
1524         } else if (biblioModule->citeJurabibRB->isChecked())
1525                 params.setCiteEngine(ENGINE_JURABIB);
1526
1527         params.use_bibtopic =
1528                 biblioModule->bibtopicCB->isChecked();
1529
1530         // language & quotes
1531         if (langModule->defaultencodingRB->isChecked()) {
1532                 params.inputenc = "auto";
1533         } else {
1534                 int i = langModule->encodingCO->currentIndex();
1535                 if (i == 0)
1536                         params.inputenc = "default";
1537                 else {
1538                         QString const enc_gui =
1539                                 langModule->encodingCO->currentText();
1540                         Encodings::const_iterator it = encodings.begin();
1541                         Encodings::const_iterator const end = encodings.end();
1542                         bool found = false;
1543                         for (; it != end; ++it) {
1544                                 if (qt_(it->guiName()) == enc_gui) {
1545                                         params.inputenc = it->latexName();
1546                                         found = true;
1547                                         break;
1548                                 }
1549                         }
1550                         if (!found) {
1551                                 // should not happen
1552                                 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
1553                                 params.inputenc = "default";
1554                         }
1555                 }
1556         }
1557
1558         InsetQuotes::QuoteLanguage lga = InsetQuotes::EnglishQuotes;
1559         switch (langModule->quoteStyleCO->currentIndex()) {
1560         case 0:
1561                 lga = InsetQuotes::EnglishQuotes;
1562                 break;
1563         case 1:
1564                 lga = InsetQuotes::SwedishQuotes;
1565                 break;
1566         case 2:
1567                 lga = InsetQuotes::GermanQuotes;
1568                 break;
1569         case 3:
1570                 lga = InsetQuotes::PolishQuotes;
1571                 break;
1572         case 4:
1573                 lga = InsetQuotes::FrenchQuotes;
1574                 break;
1575         case 5:
1576                 lga = InsetQuotes::DanishQuotes;
1577                 break;
1578         }
1579         params.quotes_language = lga;
1580
1581         QString const lang = langModule->languageCO->itemData(
1582                 langModule->languageCO->currentIndex()).toString();
1583         params.language = lyx::languages.getLanguage(fromqstr(lang));
1584
1585         // numbering
1586         if (params.documentClass().hasTocLevels()) {
1587                 params.tocdepth = numberingModule->tocSL->value();
1588                 params.secnumdepth = numberingModule->depthSL->value();
1589         }
1590
1591         // bullets
1592         params.user_defined_bullet(0) = bulletsModule->bullet(0);
1593         params.user_defined_bullet(1) = bulletsModule->bullet(1);
1594         params.user_defined_bullet(2) = bulletsModule->bullet(2);
1595         params.user_defined_bullet(3) = bulletsModule->bullet(3);
1596
1597         // packages
1598         params.graphicsDriver =
1599                 tex_graphics[latexModule->psdriverCO->currentIndex()];
1600         
1601         // text layout
1602         int idx = latexModule->classCO->currentIndex();
1603         if (idx >= 0) {
1604                 string const classname = classes_model_.getIDString(idx);
1605                 params.setBaseClass(classname);
1606         }
1607
1608         // Modules
1609         params.clearLayoutModules();
1610         int const srows = modules_sel_model_.rowCount();
1611         vector<string> selModList;
1612         for (int i = 0; i < srows; ++i)
1613                 params.addLayoutModule(modules_sel_model_.getIDString(i));
1614         // update the list of removed modules
1615         params.clearRemovedModules();
1616         list<string> const & reqmods = params.baseClass()->defaultModules();
1617         list<string>::const_iterator rit = reqmods.begin();
1618         list<string>::const_iterator ren = reqmods.end();
1619         // check each of the required modules
1620         for (; rit != ren; rit++) {
1621                 list<string>::const_iterator mit = params.getModules().begin();
1622                 list<string>::const_iterator men = params.getModules().end();
1623                 bool found = false;
1624                 for (; mit != men; mit++) {
1625                         if (*rit == *mit) {
1626                                 found = true;
1627                                 break;
1628                         }
1629                 }
1630                 if (!found) {
1631                         // the module isn't present so must have been removed by the user
1632                         params.addRemovedModule(*rit);
1633                 }
1634         }
1635
1636         if (mathsModule->amsautoCB->isChecked()) {
1637                 params.use_amsmath = BufferParams::package_auto;
1638         } else {
1639                 if (mathsModule->amsCB->isChecked())
1640                         params.use_amsmath = BufferParams::package_on;
1641                 else
1642                         params.use_amsmath = BufferParams::package_off;
1643         }
1644
1645         if (mathsModule->esintautoCB->isChecked())
1646                 params.use_esint = BufferParams::package_auto;
1647         else {
1648                 if (mathsModule->esintCB->isChecked())
1649                         params.use_esint = BufferParams::package_on;
1650                 else
1651                         params.use_esint = BufferParams::package_off;
1652         }
1653
1654         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
1655                 params.pagestyle = "default";
1656         else {
1657                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
1658                 for (size_t i = 0; i != pagestyles.size(); ++i)
1659                         if (pagestyles[i].second == style_gui)
1660                                 params.pagestyle = pagestyles[i].first;
1661         }
1662
1663         switch (textLayoutModule->lspacingCO->currentIndex()) {
1664         case 0:
1665                 params.spacing().set(Spacing::Single);
1666                 break;
1667         case 1:
1668                 params.spacing().set(Spacing::Onehalf);
1669                 break;
1670         case 2:
1671                 params.spacing().set(Spacing::Double);
1672                 break;
1673         case 3:
1674                 params.spacing().set(Spacing::Other,
1675                         fromqstr(textLayoutModule->lspacingLE->text()));
1676                 break;
1677         }
1678
1679         if (textLayoutModule->twoColumnCB->isChecked())
1680                 params.columns = 2;
1681         else
1682                 params.columns = 1;
1683
1684         // text should have passed validation
1685         params.listings_params =
1686                 InsetListingsParams(fromqstr(textLayoutModule->listingsED->toPlainText())).params();
1687
1688         if (textLayoutModule->indentRB->isChecked())
1689                 params.paragraph_separation = BufferParams::ParagraphIndentSeparation;
1690         else
1691                 params.paragraph_separation = BufferParams::ParagraphSkipSeparation;
1692
1693         switch (textLayoutModule->skipCO->currentIndex()) {
1694         case 0:
1695                 params.setDefSkip(VSpace(VSpace::SMALLSKIP));
1696                 break;
1697         case 1:
1698                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
1699                 break;
1700         case 2:
1701                 params.setDefSkip(VSpace(VSpace::BIGSKIP));
1702                 break;
1703         case 3:
1704         {
1705                 VSpace vs = VSpace(
1706                         widgetsToLength(textLayoutModule->skipLE,
1707                                 textLayoutModule->skipLengthCO)
1708                         );
1709                 params.setDefSkip(vs);
1710                 break;
1711         }
1712         default:
1713                 // DocumentDefskipCB assures that this never happens
1714                 // so Assert then !!!  - jbl
1715                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
1716                 break;
1717         }
1718
1719         params.options =
1720                 fromqstr(latexModule->optionsLE->text());
1721
1722         params.use_default_options =
1723                 latexModule->defaultOptionsCB->isChecked();
1724
1725         if (latexModule->childDocGB->isChecked())
1726                 params.master =
1727                         fromqstr(latexModule->childDocLE->text());
1728         else
1729                 params.master = string();
1730
1731         params.float_placement = floatModule->get();
1732
1733         // fonts
1734         params.fontsRoman =
1735                 tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1736
1737         params.fontsSans =
1738                 tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1739
1740         params.fontsTypewriter =
1741                 tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1742
1743         params.fontsCJK =
1744                 fromqstr(fontModule->cjkFontLE->text());
1745
1746         params.fontsSansScale = fontModule->scaleSansSB->value();
1747
1748         params.fontsTypewriterScale = fontModule->scaleTypewriterSB->value();
1749
1750         params.fontsSC = fontModule->fontScCB->isChecked();
1751
1752         params.fontsOSF = fontModule->fontOsfCB->isChecked();
1753
1754         params.fontsDefaultFamily = GuiDocument::fontfamilies[
1755                 fontModule->fontsDefaultCO->currentIndex()];
1756
1757         if (fontModule->fontsizeCO->currentIndex() == 0)
1758                 params.fontsize = "default";
1759         else
1760                 params.fontsize =
1761                         fromqstr(fontModule->fontsizeCO->currentText());
1762
1763         // paper
1764         params.papersize = PAPER_SIZE(
1765                 pageLayoutModule->papersizeCO->currentIndex());
1766
1767         // custom, A3, B3 and B4 paper sizes need geometry
1768         int psize = pageLayoutModule->papersizeCO->currentIndex();
1769         bool geom_papersize = (psize == 1 || psize == 5 || psize == 8 || psize == 9);
1770
1771         params.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
1772                 pageLayoutModule->paperwidthUnitCO);
1773
1774         params.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
1775                 pageLayoutModule->paperheightUnitCO);
1776
1777         if (pageLayoutModule->facingPagesCB->isChecked())
1778                 params.sides = TwoSides;
1779         else
1780                 params.sides = OneSide;
1781
1782         if (pageLayoutModule->landscapeRB->isChecked())
1783                 params.orientation = ORIENTATION_LANDSCAPE;
1784         else
1785                 params.orientation = ORIENTATION_PORTRAIT;
1786
1787         // margins
1788         params.use_geometry = !marginsModule->marginCB->isChecked()
1789                 || geom_papersize;
1790
1791         Ui::MarginsUi const * m = marginsModule;
1792
1793         params.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
1794         params.topmargin = widgetsToLength(m->topLE, m->topUnit);
1795         params.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
1796         params.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
1797         params.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
1798         params.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
1799         params.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
1800         params.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
1801
1802         branchesModule->apply(params);
1803
1804         // PDF support
1805         PDFOptions & pdf = params.pdfoptions();
1806         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
1807         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
1808         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
1809         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
1810         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
1811
1812         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
1813         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
1814         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
1815         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
1816
1817         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
1818         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
1819         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
1820         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
1821         pdf.backref =
1822                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
1823         if (pdfSupportModule->fullscreenCB->isChecked())
1824                 pdf.pagemode = pdf.pagemode_fullscreen;
1825         else
1826                 pdf.pagemode.clear();
1827         pdf.quoted_options = pdf.quoted_options_check(
1828                                 fromqstr(pdfSupportModule->optionsLE->text()));
1829 }
1830
1831
1832 void GuiDocument::paramsToDialog()
1833 {
1834         // set the default unit
1835         Length::UNIT defaultUnit = Length::CM;
1836         switch (lyxrc.default_papersize) {
1837                 case PAPER_DEFAULT: break;
1838
1839                 case PAPER_USLETTER:
1840                 case PAPER_USLEGAL:
1841                 case PAPER_USEXECUTIVE:
1842                         defaultUnit = Length::IN;
1843                         break;
1844
1845                 case PAPER_A3:
1846                 case PAPER_A4:
1847                 case PAPER_A5:
1848                 case PAPER_B3:
1849                 case PAPER_B4:
1850                 case PAPER_B5:
1851                         defaultUnit = Length::CM;
1852                         break;
1853                 case PAPER_CUSTOM:
1854                         break;
1855         }
1856
1857         // preamble
1858         preambleModule->update(bp_, id());
1859
1860         // biblio
1861         biblioModule->citeDefaultRB->setChecked(
1862                 bp_.citeEngine() == ENGINE_BASIC);
1863
1864         biblioModule->citeNatbibRB->setChecked(
1865                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL ||
1866                 bp_.citeEngine() == ENGINE_NATBIB_AUTHORYEAR);
1867
1868         biblioModule->citeStyleCO->setCurrentIndex(
1869                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL);
1870
1871         biblioModule->citeJurabibRB->setChecked(
1872                 bp_.citeEngine() == ENGINE_JURABIB);
1873
1874         biblioModule->bibtopicCB->setChecked(
1875                 bp_.use_bibtopic);
1876
1877         // language & quotes
1878         int const pos = langModule->languageCO->findData(toqstr(
1879                 bp_.language->lang()));
1880         langModule->languageCO->setCurrentIndex(pos);
1881
1882         langModule->quoteStyleCO->setCurrentIndex(
1883                 bp_.quotes_language);
1884
1885         bool default_enc = true;
1886         if (bp_.inputenc != "auto") {
1887                 default_enc = false;
1888                 if (bp_.inputenc == "default") {
1889                         langModule->encodingCO->setCurrentIndex(0);
1890                 } else {
1891                         string enc_gui;
1892                         Encodings::const_iterator it = encodings.begin();
1893                         Encodings::const_iterator const end = encodings.end();
1894                         for (; it != end; ++it) {
1895                                 if (it->latexName() == bp_.inputenc) {
1896                                         enc_gui = it->guiName();
1897                                         break;
1898                                 }
1899                         }
1900                         int const i = langModule->encodingCO->findText(
1901                                         qt_(enc_gui));
1902                         if (i >= 0)
1903                                 langModule->encodingCO->setCurrentIndex(i);
1904                         else
1905                                 // unknown encoding. Set to default.
1906                                 default_enc = true;
1907                 }
1908         }
1909         langModule->defaultencodingRB->setChecked(default_enc);
1910         langModule->otherencodingRB->setChecked(!default_enc);
1911
1912         // numbering
1913         int const min_toclevel = documentClass().min_toclevel();
1914         int const max_toclevel = documentClass().max_toclevel();
1915         if (documentClass().hasTocLevels()) {
1916                 numberingModule->setEnabled(true);
1917                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
1918                 numberingModule->depthSL->setMaximum(max_toclevel);
1919                 numberingModule->depthSL->setValue(bp_.secnumdepth);
1920                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
1921                 numberingModule->tocSL->setMaximum(max_toclevel);
1922                 numberingModule->tocSL->setValue(bp_.tocdepth);
1923                 updateNumbering();
1924         } else {
1925                 numberingModule->setEnabled(false);
1926                 numberingModule->tocTW->clear();
1927         }
1928
1929         // bullets
1930         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
1931         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
1932         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
1933         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
1934         bulletsModule->init();
1935
1936         // packages
1937         int nitem = findToken(tex_graphics, bp_.graphicsDriver);
1938         if (nitem >= 0)
1939                 latexModule->psdriverCO->setCurrentIndex(nitem);
1940         updateModuleInfo();
1941         
1942         mathsModule->amsCB->setChecked(
1943                 bp_.use_amsmath == BufferParams::package_on);
1944         mathsModule->amsautoCB->setChecked(
1945                 bp_.use_amsmath == BufferParams::package_auto);
1946
1947         mathsModule->esintCB->setChecked(
1948                 bp_.use_esint == BufferParams::package_on);
1949         mathsModule->esintautoCB->setChecked(
1950                 bp_.use_esint == BufferParams::package_auto);
1951
1952         switch (bp_.spacing().getSpace()) {
1953                 case Spacing::Other: nitem = 3; break;
1954                 case Spacing::Double: nitem = 2; break;
1955                 case Spacing::Onehalf: nitem = 1; break;
1956                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
1957         }
1958
1959         // text layout
1960         string const & layoutID = bp_.baseClassID();
1961         setLayoutComboByIDString(layoutID);
1962
1963         updatePagestyle(documentClass().opt_pagestyle(),
1964                                  bp_.pagestyle);
1965
1966         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
1967         if (bp_.spacing().getSpace() == Spacing::Other) {
1968                 textLayoutModule->lspacingLE->setText(
1969                         toqstr(bp_.spacing().getValueAsString()));
1970         }
1971         setLSpacing(nitem);
1972
1973         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation)
1974                 textLayoutModule->indentRB->setChecked(true);
1975         else
1976                 textLayoutModule->skipRB->setChecked(true);
1977
1978         int skip = 0;
1979         switch (bp_.getDefSkip().kind()) {
1980         case VSpace::SMALLSKIP:
1981                 skip = 0;
1982                 break;
1983         case VSpace::MEDSKIP:
1984                 skip = 1;
1985                 break;
1986         case VSpace::BIGSKIP:
1987                 skip = 2;
1988                 break;
1989         case VSpace::LENGTH:
1990         {
1991                 skip = 3;
1992                 string const length = bp_.getDefSkip().asLyXCommand();
1993                 lengthToWidgets(textLayoutModule->skipLE,
1994                         textLayoutModule->skipLengthCO,
1995                         length, defaultUnit);
1996                 break;
1997         }
1998         default:
1999                 skip = 0;
2000                 break;
2001         }
2002         textLayoutModule->skipCO->setCurrentIndex(skip);
2003         setSkip(skip);
2004
2005         textLayoutModule->twoColumnCB->setChecked(
2006                 bp_.columns == 2);
2007
2008         // break listings_params to multiple lines
2009         string lstparams =
2010                 InsetListingsParams(bp_.listings_params).separatedParams();
2011         textLayoutModule->listingsED->setPlainText(toqstr(lstparams));
2012
2013         if (!bp_.options.empty()) {
2014                 latexModule->optionsLE->setText(
2015                         toqstr(bp_.options));
2016         } else {
2017                 latexModule->optionsLE->setText(QString());
2018         }
2019
2020         // latex
2021         latexModule->defaultOptionsCB->setChecked(
2022                         bp_.use_default_options);
2023
2024         if (!documentClass().options().empty()) {
2025                 latexModule->defaultOptionsLE->setText(
2026                         toqstr(documentClass().options()));
2027         } else {
2028                 latexModule->defaultOptionsLE->setText(
2029                         toqstr(_("[No options predefined]")));
2030         }
2031
2032         latexModule->defaultOptionsLE->setEnabled(
2033                 bp_.use_default_options
2034                 && !documentClass().options().empty());
2035
2036         latexModule->defaultOptionsCB->setEnabled(
2037                 !documentClass().options().empty());
2038
2039         if (!bp_.master.empty()) {
2040                 latexModule->childDocGB->setChecked(true);
2041                 latexModule->childDocLE->setText(
2042                         toqstr(bp_.master));
2043         } else {
2044                 latexModule->childDocLE->setText(QString());
2045                 latexModule->childDocGB->setChecked(false);
2046         }
2047
2048         floatModule->set(bp_.float_placement);
2049
2050         // Fonts
2051         updateFontsize(documentClass().opt_fontsize(),
2052                         bp_.fontsize);
2053
2054         int n = findToken(tex_fonts_roman, bp_.fontsRoman);
2055         if (n >= 0) {
2056                 fontModule->fontsRomanCO->setCurrentIndex(n);
2057                 romanChanged(n);
2058         }
2059
2060         n = findToken(tex_fonts_sans, bp_.fontsSans);
2061         if (n >= 0)     {
2062                 fontModule->fontsSansCO->setCurrentIndex(n);
2063                 sansChanged(n);
2064         }
2065
2066         n = findToken(tex_fonts_monospaced, bp_.fontsTypewriter);
2067         if (n >= 0) {
2068                 fontModule->fontsTypewriterCO->setCurrentIndex(n);
2069                 ttChanged(n);
2070         }
2071
2072         if (!bp_.fontsCJK.empty())
2073                 fontModule->cjkFontLE->setText(
2074                         toqstr(bp_.fontsCJK));
2075         else
2076                 fontModule->cjkFontLE->setText(QString());
2077
2078         fontModule->fontScCB->setChecked(bp_.fontsSC);
2079         fontModule->fontOsfCB->setChecked(bp_.fontsOSF);
2080         fontModule->scaleSansSB->setValue(bp_.fontsSansScale);
2081         fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale);
2082         n = findToken(GuiDocument::fontfamilies, bp_.fontsDefaultFamily);
2083         if (n >= 0)
2084                 fontModule->fontsDefaultCO->setCurrentIndex(n);
2085
2086         // paper
2087         int const psize = bp_.papersize;
2088         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
2089         setCustomPapersize(psize);
2090
2091         bool const landscape =
2092                 bp_.orientation == ORIENTATION_LANDSCAPE;
2093         pageLayoutModule->landscapeRB->setChecked(landscape);
2094         pageLayoutModule->portraitRB->setChecked(!landscape);
2095
2096         pageLayoutModule->facingPagesCB->setChecked(
2097                 bp_.sides == TwoSides);
2098
2099
2100         lengthToWidgets(pageLayoutModule->paperwidthLE,
2101                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, defaultUnit);
2102
2103         lengthToWidgets(pageLayoutModule->paperheightLE,
2104                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, defaultUnit);
2105
2106         // margins
2107         Ui::MarginsUi * m = marginsModule;
2108
2109         setMargins(!bp_.use_geometry);
2110
2111         lengthToWidgets(m->topLE, m->topUnit,
2112                 bp_.topmargin, defaultUnit);
2113
2114         lengthToWidgets(m->bottomLE, m->bottomUnit,
2115                 bp_.bottommargin, defaultUnit);
2116
2117         lengthToWidgets(m->innerLE, m->innerUnit,
2118                 bp_.leftmargin, defaultUnit);
2119
2120         lengthToWidgets(m->outerLE, m->outerUnit,
2121                 bp_.rightmargin, defaultUnit);
2122
2123         lengthToWidgets(m->headheightLE, m->headheightUnit,
2124                 bp_.headheight, defaultUnit);
2125
2126         lengthToWidgets(m->headsepLE, m->headsepUnit,
2127                 bp_.headsep, defaultUnit);
2128
2129         lengthToWidgets(m->footskipLE, m->footskipUnit,
2130                 bp_.footskip, defaultUnit);
2131
2132         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
2133                 bp_.columnsep, defaultUnit);
2134
2135         branchesModule->update(bp_);
2136
2137         // PDF support
2138         PDFOptions const & pdf = bp_.pdfoptions();
2139         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
2140         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
2141         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
2142         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
2143         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
2144
2145         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
2146         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
2147         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
2148
2149         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
2150
2151         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
2152         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
2153         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
2154         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
2155
2156         n = findToken(backref_opts, pdf.backref);
2157         if (n >= 0)
2158                 pdfSupportModule->backrefCO->setCurrentIndex(n);
2159
2160         pdfSupportModule->fullscreenCB->setChecked
2161                 (pdf.pagemode == pdf.pagemode_fullscreen);
2162
2163         pdfSupportModule->optionsLE->setText(
2164                 toqstr(pdf.quoted_options));
2165 }
2166
2167
2168 void GuiDocument::applyView()
2169 {
2170         apply(params());
2171 }
2172
2173
2174 void GuiDocument::saveDocDefault()
2175 {
2176         // we have to apply the params first
2177         applyView();
2178         saveAsDefault();
2179 }
2180
2181
2182 void GuiDocument::updateAvailableModules() 
2183 {
2184         modules_av_model_.clear();
2185         list<modInfoStruct> const & modInfoList = getModuleInfo();
2186         list<modInfoStruct>::const_iterator mit = modInfoList.begin();
2187         list<modInfoStruct>::const_iterator men = modInfoList.end();
2188         for (int i = 0; mit != men; ++mit, ++i)
2189                 modules_av_model_.insertRow(i, mit->name, mit->id, 
2190                                 mit->description);
2191 }
2192
2193
2194 void GuiDocument::updateSelectedModules() 
2195 {
2196         modules_sel_model_.clear();
2197         list<modInfoStruct> const selModList = getSelectedModules();
2198         list<modInfoStruct>::const_iterator mit = selModList.begin();
2199         list<modInfoStruct>::const_iterator men = selModList.end();
2200         for (int i = 0; mit != men; ++mit, ++i)
2201                 modules_sel_model_.insertRow(i, mit->name, mit->id, 
2202                                 mit->description);
2203 }
2204
2205
2206 void GuiDocument::updateContents()
2207 {
2208         // Nothing to do here as the document settings is not cursor dependant.
2209         return;
2210 }
2211
2212
2213 void GuiDocument::useClassDefaults()
2214 {
2215         if (applyPB->isEnabled()) {
2216                 int const ret = Alert::prompt(_("Unapplied changes"),
2217                                 _("Some changes in the dialog were not yet applied.\n"
2218                                   "If you do not apply now, they will be lost after this action."),
2219                                 1, 1, _("&Apply"), _("&Dismiss"));
2220                 if (ret == 0)
2221                         applyView();
2222         }
2223
2224         int idx = latexModule->classCO->currentIndex();
2225         string const classname = classes_model_.getIDString(idx);
2226         if (!bp_.setBaseClass(classname)) {
2227                 Alert::error(_("Error"), _("Unable to set document class."));
2228                 return;
2229         }
2230         bp_.useClassDefaults();
2231         paramsToDialog();
2232 }
2233
2234
2235 void GuiDocument::setLayoutComboByIDString(string const & idString)
2236 {
2237         int idx = classes_model_.findIDString(idString);
2238         if (idx < 0)
2239                 Alert::warning(_("Can't set layout!"), 
2240                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
2241         else 
2242                 latexModule->classCO->setCurrentIndex(idx);
2243 }
2244
2245
2246 bool GuiDocument::isValid()
2247 {
2248         return validateListingsParameters().isEmpty()
2249                 && (textLayoutModule->skipCO->currentIndex() != 3
2250                         || !textLayoutModule->skipLE->text().isEmpty());
2251 }
2252
2253
2254 char const * const GuiDocument::fontfamilies[5] = {
2255         "default", "rmdefault", "sfdefault", "ttdefault", ""
2256 };
2257
2258
2259 char const * GuiDocument::fontfamilies_gui[5] = {
2260         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
2261 };
2262
2263
2264 bool GuiDocument::initialiseParams(string const &)
2265 {
2266         BufferView const * view = bufferview();
2267         if (!view) {
2268                 bp_ = BufferParams();
2269                 paramsToDialog();
2270                 return true;
2271         }
2272         bp_ = view->buffer().params();
2273         loadModuleInfo();
2274         updateAvailableModules();
2275         updateSelectedModules();
2276         //FIXME It'd be nice to make sure here that the selected
2277         //modules are consistent: That required modules are actually
2278         //selected, and that we don't have conflicts. If so, we could
2279         //at least pop up a warning.
2280         paramsToDialog();
2281         return true;
2282 }
2283
2284
2285 void GuiDocument::clearParams()
2286 {
2287         bp_ = BufferParams();
2288 }
2289
2290
2291 BufferId GuiDocument::id() const
2292 {
2293         BufferView const * const view = bufferview();
2294         return view? &view->buffer() : 0;
2295 }
2296
2297
2298 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
2299 {
2300         return moduleNames_;
2301 }
2302
2303
2304 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
2305 {
2306         list<string> const & mods = params().getModules();
2307         list<string>::const_iterator it =  mods.begin();
2308         list<string>::const_iterator end = mods.end();
2309         list<modInfoStruct> mInfo;
2310         for (; it != end; ++it) {
2311                 modInfoStruct m;
2312                 m.id = *it;
2313                 LyXModule * mod = moduleList[*it];
2314                 if (mod)
2315                         m.name = qt_(mod->getName());
2316                 else 
2317                         m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
2318                 mInfo.push_back(m);
2319         }
2320         return mInfo;
2321 }
2322
2323
2324 DocumentClass const & GuiDocument::documentClass() const
2325 {
2326         return bp_.documentClass();
2327 }
2328
2329
2330 static void dispatch_bufferparams(Dialog const & dialog,
2331         BufferParams const & bp, FuncCode lfun)
2332 {
2333         ostringstream ss;
2334         ss << "\\begin_header\n";
2335         bp.writeFile(ss);
2336         ss << "\\end_header\n";
2337         dialog.dispatch(FuncRequest(lfun, ss.str()));
2338 }
2339
2340
2341 void GuiDocument::dispatchParams()
2342 {
2343         // This must come first so that a language change is correctly noticed
2344         setLanguage();
2345
2346         // Apply the BufferParams. Note that this will set the base class
2347         // and then update the buffer's layout.
2348         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
2349
2350         if (!params().master.empty()) {
2351                 FileName const master_file = support::makeAbsPath(params().master,
2352                            support::onlyPath(buffer().absFileName()));
2353                 if (isLyXFilename(master_file.absFilename())) {
2354                         Buffer * master = checkAndLoadLyXFile(master_file);
2355                         const_cast<Buffer &>(buffer()).setParent(master);
2356                 }
2357         }
2358
2359         // Generate the colours requested by each new branch.
2360         BranchList & branchlist = params().branchlist();
2361         if (!branchlist.empty()) {
2362                 BranchList::const_iterator it = branchlist.begin();
2363                 BranchList::const_iterator const end = branchlist.end();
2364                 for (; it != end; ++it) {
2365                         docstring const & current_branch = it->branch();
2366                         Branch const * branch = branchlist.find(current_branch);
2367                         string const x11hexname = X11hexname(branch->color());
2368                         // display the new color
2369                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
2370                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
2371                 }
2372
2373                 // Open insets of selected branches, close deselected ones
2374                 dispatch(FuncRequest(LFUN_ALL_INSETS_TOGGLE,
2375                         "assign branch"));
2376         }
2377         // FIXME: If we used an LFUN, we would not need those two lines:
2378         BufferView * bv = const_cast<BufferView *>(bufferview());
2379         bv->processUpdateFlags(Update::Force | Update::FitCursor);
2380 }
2381
2382
2383 void GuiDocument::setLanguage() const
2384 {
2385         Language const * const newL = bp_.language;
2386         if (buffer().params().language == newL)
2387                 return;
2388
2389         string const & lang_name = newL->lang();
2390         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
2391 }
2392
2393
2394 void GuiDocument::saveAsDefault() const
2395 {
2396         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
2397 }
2398
2399
2400 bool GuiDocument::isFontAvailable(string const & font) const
2401 {
2402         if (font == "default" || font == "cmr"
2403             || font == "cmss" || font == "cmtt")
2404                 // these are standard
2405                 return true;
2406         if (font == "lmodern" || font == "lmss" || font == "lmtt")
2407                 return LaTeXFeatures::isAvailable("lmodern");
2408         if (font == "times" || font == "palatino"
2409                  || font == "helvet" || font == "courier")
2410                 return LaTeXFeatures::isAvailable("psnfss");
2411         if (font == "cmbr" || font == "cmtl")
2412                 return LaTeXFeatures::isAvailable("cmbright");
2413         if (font == "utopia")
2414                 return LaTeXFeatures::isAvailable("utopia")
2415                         || LaTeXFeatures::isAvailable("fourier");
2416         if (font == "beraserif" || font == "berasans"
2417                 || font == "beramono")
2418                 return LaTeXFeatures::isAvailable("bera");
2419         return LaTeXFeatures::isAvailable(font);
2420 }
2421
2422
2423 bool GuiDocument::providesOSF(string const & font) const
2424 {
2425         if (font == "cmr")
2426                 return isFontAvailable("eco");
2427         if (font == "palatino")
2428                 return isFontAvailable("mathpazo");
2429         return false;
2430 }
2431
2432
2433 bool GuiDocument::providesSC(string const & font) const
2434 {
2435         if (font == "palatino")
2436                 return isFontAvailable("mathpazo");
2437         if (font == "utopia")
2438                 return isFontAvailable("fourier");
2439         return false;
2440 }
2441
2442
2443 bool GuiDocument::providesScale(string const & font) const
2444 {
2445         return font == "helvet" || font == "luximono"
2446                 || font == "berasans"  || font == "beramono";
2447 }
2448
2449
2450 void GuiDocument::loadModuleInfo()
2451 {
2452         moduleNames_.clear();
2453         LyXModuleList::const_iterator it  = moduleList.begin();
2454         LyXModuleList::const_iterator end = moduleList.end();
2455         for (; it != end; ++it) {
2456                 modInfoStruct m;
2457                 m.id = it->getID();
2458                 m.name = qt_(it->getName());
2459                 // this is supposed to give us the first sentence of the description
2460                 QString desc = qt_(it->getDescription());
2461                 int const pos = desc.indexOf(".");
2462                 if (pos > 0)
2463                         desc.truncate(pos + 1);
2464                 m.description = desc;
2465                 moduleNames_.push_back(m);
2466         }
2467 }
2468
2469
2470 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
2471
2472
2473 } // namespace frontend
2474 } // namespace lyx
2475
2476 #include "GuiDocument_moc.cpp"