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