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