]> git.lyx.org Git - features.git/blob - src/frontends/qt4/GuiDocument.cpp
Remove old and out of date comment.
[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         //FIXME This should perhaps be more flexible and check whether, even 
354         //if this one is required, there is also an earlier one that is required.
355         //enable it if this module isn't 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         //NOTE This is less flexible than it might be. You could check whether, even 
394         //if this one is required, there is also an earlier one that is required.
395         //enable it if the preceding module isn't 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         // FIXME Note that by doing things this way, we load the TextClass
1336         // as soon as it is selected. So, if you use the scroll wheel when
1337         // sitting on the combo box, we'll load a lot of TextClass objects
1338         // very quickly. This could be changed.
1339         if (!bp_.setBaseClass(classname)) {
1340                 Alert::error(_("Error"), _("Unable to set document class."));
1341                 return;
1342         }
1343         if (lyxrc.auto_reset_options) {
1344                 if (applyPB->isEnabled()) {
1345                         int const ret = Alert::prompt(_("Unapplied changes"),
1346                                         _("Some changes in the dialog were not yet applied.\n"
1347                                         "If you do not apply now, they will be lost after this action."),
1348                                         1, 1, _("&Apply"), _("&Dismiss"));
1349                         if (ret == 0)
1350                                 applyView();
1351                 }
1352                 bp_.useClassDefaults();
1353         }
1354         // With the introduction of modules came a distinction between the base 
1355         // class  and the document class. The former corresponds to the main layout 
1356         // file; the  latter is that plus the modules (or the document-specific layout,
1357         // or  whatever else there could be). Our parameters come from the document 
1358         // class. So when we set the base class, we also need to recreate the document 
1359         // class. Otherwise, we still have the old one.
1360         bp_.makeDocumentClass();
1361         // FIXME There's a little bug here connected with auto_reset, namely,
1362         // that, if the preceding is skipped and the user has changed the
1363         // modules before changing the class, those changes will be lost on
1364         // update. But maybe that's what we want?
1365         updateSelectedModules();
1366         paramsToDialog(bp_);
1367 }
1368
1369
1370 namespace {
1371         // This is an insanely complicated attempt to make this sort of thing
1372         // work with RTL languages.
1373         docstring formatStrVec(vector<string> const & v, docstring const & s) 
1374         {
1375                 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
1376                 if (v.size() == 0)
1377                         return docstring();
1378                 if (v.size() == 1) 
1379                         return from_ascii(v[0]);
1380                 if (v.size() == 2) {
1381                         docstring retval = _("%1$s and %2$s");
1382                         retval = subst(retval, _("and"), s);
1383                         return bformat(retval, from_ascii(v[0]), from_ascii(v[1]));
1384                 }
1385                 // The idea here is to format all but the last two items...
1386                 int const vSize = v.size();
1387                 docstring t2 = _("%1$s, %2$s");
1388                 docstring retval = from_ascii(v[0]);
1389                 for (int i = 1; i < vSize - 2; ++i)
1390                         retval = bformat(t2, retval, from_ascii(v[i])); 
1391                 //...and then to  plug them, and the last two, into this schema
1392                 docstring t = _("%1$s, %2$s, and %3$s");
1393                 t = subst(t, _("and"), s);
1394                 return bformat(t, retval, from_ascii(v[vSize - 2]), from_ascii(v[vSize - 1]));
1395         }
1396         
1397         vector<string> idsToNames(vector<string> const & idList)
1398         {
1399                 vector<string> retval;
1400                 vector<string>::const_iterator it  = idList.begin();
1401                 vector<string>::const_iterator end = idList.end();
1402                 for (; it != end; ++it) {
1403                         LyXModule const * const mod = moduleList[*it];
1404                         if (!mod)
1405                                 retval.push_back(*it + " (Unavailable)");
1406                         else
1407                                 retval.push_back(mod->getName());
1408                 }
1409                 return retval;
1410         }
1411 }
1412
1413
1414 void GuiDocument::updateModuleInfo()
1415 {
1416         selectionManager->update();
1417         
1418         //Module description
1419         bool const focusOnSelected = selectionManager->selectedFocused();
1420         QListView const * const lv = 
1421                         focusOnSelected ? latexModule->selectedLV : latexModule->availableLV;
1422         if (lv->selectionModel()->selectedIndexes().isEmpty()) {
1423                 latexModule->infoML->document()->clear();
1424                 return;
1425         }
1426         QModelIndex const & idx = lv->selectionModel()->currentIndex();
1427         GuiIdListModel const & idModel = 
1428                         focusOnSelected  ? modules_sel_model_ : modules_av_model_;
1429         string const modName = idModel.getIDString(idx.row());
1430         docstring desc = getModuleDescription(modName);
1431
1432         vector<string> pkgList = getPackageList(modName);
1433         docstring pkgdesc = formatStrVec(pkgList, _("and"));
1434         if (!pkgdesc.empty()) {
1435                 if (!desc.empty())
1436                         desc += "\n";
1437                 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
1438         }
1439
1440         pkgList = getRequiredList(modName);
1441         if (!pkgList.empty()) {
1442                 vector<string> const reqDescs = idsToNames(pkgList);
1443                 pkgdesc = formatStrVec(reqDescs, _("or"));
1444                 if (!desc.empty())
1445                         desc += "\n";
1446                 desc += bformat(_("Module required: %1$s."), pkgdesc);
1447         }
1448
1449         pkgList = getExcludedList(modName);
1450         if (!pkgList.empty()) {
1451                 vector<string> const reqDescs = idsToNames(pkgList);
1452                 pkgdesc = formatStrVec(reqDescs, _( "and"));
1453                 if (!desc.empty())
1454                         desc += "\n";
1455                 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
1456         }
1457
1458         if (!isModuleAvailable(modName)) {
1459                 if (!desc.empty())
1460                         desc += "\n";
1461                 desc += _("WARNING: Some packages are unavailable!");
1462         }
1463
1464         latexModule->infoML->document()->setPlainText(toqstr(desc));
1465 }
1466
1467
1468 void GuiDocument::updateNumbering()
1469 {
1470         DocumentClass const & tclass = documentClass();
1471
1472         numberingModule->tocTW->setUpdatesEnabled(false);
1473         numberingModule->tocTW->clear();
1474
1475         int const depth = numberingModule->depthSL->value();
1476         int const toc = numberingModule->tocSL->value();
1477         QString const no = qt_("No");
1478         QString const yes = qt_("Yes");
1479         QTreeWidgetItem * item = 0;
1480
1481         DocumentClass::const_iterator lit = tclass.begin();
1482         DocumentClass::const_iterator len = tclass.end();
1483         for (; lit != len; ++lit) {
1484                 int const toclevel = lit->toclevel;
1485                 if (toclevel != Layout::NOT_IN_TOC && lit->labeltype == LABEL_COUNTER) {
1486                         item = new QTreeWidgetItem(numberingModule->tocTW);
1487                         item->setText(0, toqstr(translateIfPossible(lit->name())));
1488                         item->setText(1, (toclevel <= depth) ? yes : no);
1489                         item->setText(2, (toclevel <= toc) ? yes : no);
1490                 }
1491         }
1492
1493         numberingModule->tocTW->setUpdatesEnabled(true);
1494         numberingModule->tocTW->update();
1495 }
1496
1497
1498 void GuiDocument::apply(BufferParams & params)
1499 {
1500         // preamble
1501         preambleModule->apply(params);
1502
1503         // biblio
1504         params.setCiteEngine(ENGINE_BASIC);
1505
1506         if (biblioModule->citeNatbibRB->isChecked()) {
1507                 bool const use_numerical_citations =
1508                         biblioModule->citeStyleCO->currentIndex();
1509                 if (use_numerical_citations)
1510                         params.setCiteEngine(ENGINE_NATBIB_NUMERICAL);
1511                 else
1512                         params.setCiteEngine(ENGINE_NATBIB_AUTHORYEAR);
1513
1514         } else if (biblioModule->citeJurabibRB->isChecked())
1515                 params.setCiteEngine(ENGINE_JURABIB);
1516
1517         params.use_bibtopic =
1518                 biblioModule->bibtopicCB->isChecked();
1519
1520         // language & quotes
1521         if (langModule->defaultencodingRB->isChecked()) {
1522                 params.inputenc = "auto";
1523         } else {
1524                 int i = langModule->encodingCO->currentIndex();
1525                 if (i == 0)
1526                         params.inputenc = "default";
1527                 else {
1528                         QString const enc_gui =
1529                                 langModule->encodingCO->currentText();
1530                         Encodings::const_iterator it = encodings.begin();
1531                         Encodings::const_iterator const end = encodings.end();
1532                         bool found = false;
1533                         for (; it != end; ++it) {
1534                                 if (qt_(it->guiName()) == enc_gui) {
1535                                         params.inputenc = it->latexName();
1536                                         found = true;
1537                                         break;
1538                                 }
1539                         }
1540                         if (!found) {
1541                                 // should not happen
1542                                 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
1543                                 params.inputenc = "default";
1544                         }
1545                 }
1546         }
1547
1548         InsetQuotes::QuoteLanguage lga = InsetQuotes::EnglishQuotes;
1549         switch (langModule->quoteStyleCO->currentIndex()) {
1550         case 0:
1551                 lga = InsetQuotes::EnglishQuotes;
1552                 break;
1553         case 1:
1554                 lga = InsetQuotes::SwedishQuotes;
1555                 break;
1556         case 2:
1557                 lga = InsetQuotes::GermanQuotes;
1558                 break;
1559         case 3:
1560                 lga = InsetQuotes::PolishQuotes;
1561                 break;
1562         case 4:
1563                 lga = InsetQuotes::FrenchQuotes;
1564                 break;
1565         case 5:
1566                 lga = InsetQuotes::DanishQuotes;
1567                 break;
1568         }
1569         params.quotes_language = lga;
1570
1571         QString const lang = langModule->languageCO->itemData(
1572                 langModule->languageCO->currentIndex()).toString();
1573         params.language = lyx::languages.getLanguage(fromqstr(lang));
1574
1575         // numbering
1576         if (params.documentClass().hasTocLevels()) {
1577                 params.tocdepth = numberingModule->tocSL->value();
1578                 params.secnumdepth = numberingModule->depthSL->value();
1579         }
1580
1581         // bullets
1582         params.user_defined_bullet(0) = bulletsModule->bullet(0);
1583         params.user_defined_bullet(1) = bulletsModule->bullet(1);
1584         params.user_defined_bullet(2) = bulletsModule->bullet(2);
1585         params.user_defined_bullet(3) = bulletsModule->bullet(3);
1586
1587         // packages
1588         params.graphicsDriver =
1589                 tex_graphics[latexModule->psdriverCO->currentIndex()];
1590         
1591         // text layout
1592         int idx = latexModule->classCO->currentIndex();
1593         if (idx >= 0) {
1594                 string const classname = classes_model_.getIDString(idx);
1595                 params.setBaseClass(classname);
1596         }
1597
1598         // Modules
1599         params.clearLayoutModules();
1600         int const srows = modules_sel_model_.rowCount();
1601         vector<string> selModList;
1602         for (int i = 0; i < srows; ++i)
1603                 params.addLayoutModule(modules_sel_model_.getIDString(i));
1604         // update the list of removed modules
1605         params.clearRemovedModules();
1606         list<string> const & reqmods = params.baseClass()->defaultModules();
1607         list<string>::const_iterator rit = reqmods.begin();
1608         list<string>::const_iterator ren = reqmods.end();
1609         // check each of the required modules
1610         for (; rit != ren; rit++) {
1611                 vector<string>::const_iterator mit = params.getModules().begin();
1612                 vector<string>::const_iterator men = params.getModules().end();
1613                 bool found = false;
1614                 for (; mit != men; mit++) {
1615                         if (*rit == *mit) {
1616                                 found = true;
1617                                 break;
1618                         }
1619                 }
1620                 if (!found) {
1621                         // the module isn't present so must have been removed by the user
1622                         params.addRemovedModule(*rit);
1623                 }
1624         }
1625
1626         if (mathsModule->amsautoCB->isChecked()) {
1627                 params.use_amsmath = BufferParams::package_auto;
1628         } else {
1629                 if (mathsModule->amsCB->isChecked())
1630                         params.use_amsmath = BufferParams::package_on;
1631                 else
1632                         params.use_amsmath = BufferParams::package_off;
1633         }
1634
1635         if (mathsModule->esintautoCB->isChecked())
1636                 params.use_esint = BufferParams::package_auto;
1637         else {
1638                 if (mathsModule->esintCB->isChecked())
1639                         params.use_esint = BufferParams::package_on;
1640                 else
1641                         params.use_esint = BufferParams::package_off;
1642         }
1643
1644         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
1645                 params.pagestyle = "default";
1646         else {
1647                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
1648                 for (size_t i = 0; i != pagestyles.size(); ++i)
1649                         if (pagestyles[i].second == style_gui)
1650                                 params.pagestyle = pagestyles[i].first;
1651         }
1652
1653         switch (textLayoutModule->lspacingCO->currentIndex()) {
1654         case 0:
1655                 params.spacing().set(Spacing::Single);
1656                 break;
1657         case 1:
1658                 params.spacing().set(Spacing::Onehalf);
1659                 break;
1660         case 2:
1661                 params.spacing().set(Spacing::Double);
1662                 break;
1663         case 3:
1664                 params.spacing().set(Spacing::Other,
1665                         fromqstr(textLayoutModule->lspacingLE->text()));
1666                 break;
1667         }
1668
1669         if (textLayoutModule->twoColumnCB->isChecked())
1670                 params.columns = 2;
1671         else
1672                 params.columns = 1;
1673
1674         // text should have passed validation
1675         params.listings_params =
1676                 InsetListingsParams(fromqstr(textLayoutModule->listingsED->toPlainText())).params();
1677
1678         if (textLayoutModule->indentRB->isChecked())
1679                 params.paragraph_separation = BufferParams::ParagraphIndentSeparation;
1680         else
1681                 params.paragraph_separation = BufferParams::ParagraphSkipSeparation;
1682
1683         switch (textLayoutModule->skipCO->currentIndex()) {
1684         case 0:
1685                 params.setDefSkip(VSpace(VSpace::SMALLSKIP));
1686                 break;
1687         case 1:
1688                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
1689                 break;
1690         case 2:
1691                 params.setDefSkip(VSpace(VSpace::BIGSKIP));
1692                 break;
1693         case 3:
1694         {
1695                 VSpace vs = VSpace(
1696                         widgetsToLength(textLayoutModule->skipLE,
1697                                 textLayoutModule->skipLengthCO)
1698                         );
1699                 params.setDefSkip(vs);
1700                 break;
1701         }
1702         default:
1703                 // DocumentDefskipCB assures that this never happens
1704                 // so Assert then !!!  - jbl
1705                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
1706                 break;
1707         }
1708
1709         params.options =
1710                 fromqstr(latexModule->optionsLE->text());
1711
1712         params.use_default_options =
1713                 latexModule->defaultOptionsCB->isChecked();
1714
1715         if (latexModule->childDocGB->isChecked())
1716                 params.master =
1717                         fromqstr(latexModule->childDocLE->text());
1718         else
1719                 params.master = string();
1720
1721         params.float_placement = floatModule->get();
1722
1723         // fonts
1724         params.fontsRoman =
1725                 tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1726
1727         params.fontsSans =
1728                 tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1729
1730         params.fontsTypewriter =
1731                 tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1732
1733         params.fontsCJK =
1734                 fromqstr(fontModule->cjkFontLE->text());
1735
1736         params.fontsSansScale = fontModule->scaleSansSB->value();
1737
1738         params.fontsTypewriterScale = fontModule->scaleTypewriterSB->value();
1739
1740         params.fontsSC = fontModule->fontScCB->isChecked();
1741
1742         params.fontsOSF = fontModule->fontOsfCB->isChecked();
1743
1744         params.fontsDefaultFamily = GuiDocument::fontfamilies[
1745                 fontModule->fontsDefaultCO->currentIndex()];
1746
1747         if (fontModule->fontsizeCO->currentIndex() == 0)
1748                 params.fontsize = "default";
1749         else
1750                 params.fontsize =
1751                         fromqstr(fontModule->fontsizeCO->currentText());
1752
1753         // paper
1754         params.papersize = PAPER_SIZE(
1755                 pageLayoutModule->papersizeCO->currentIndex());
1756
1757         // custom, A3, B3 and B4 paper sizes need geometry
1758         int psize = pageLayoutModule->papersizeCO->currentIndex();
1759         bool geom_papersize = (psize == 1 || psize == 5 || psize == 8 || psize == 9);
1760
1761         params.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
1762                 pageLayoutModule->paperwidthUnitCO);
1763
1764         params.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
1765                 pageLayoutModule->paperheightUnitCO);
1766
1767         if (pageLayoutModule->facingPagesCB->isChecked())
1768                 params.sides = TwoSides;
1769         else
1770                 params.sides = OneSide;
1771
1772         if (pageLayoutModule->landscapeRB->isChecked())
1773                 params.orientation = ORIENTATION_LANDSCAPE;
1774         else
1775                 params.orientation = ORIENTATION_PORTRAIT;
1776
1777         // margins
1778         params.use_geometry = !marginsModule->marginCB->isChecked()
1779                 || geom_papersize;
1780
1781         Ui::MarginsUi const * m = marginsModule;
1782
1783         params.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
1784         params.topmargin = widgetsToLength(m->topLE, m->topUnit);
1785         params.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
1786         params.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
1787         params.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
1788         params.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
1789         params.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
1790         params.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
1791
1792         branchesModule->apply(params);
1793
1794         // PDF support
1795         PDFOptions & pdf = params.pdfoptions();
1796         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
1797         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
1798         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
1799         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
1800         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
1801
1802         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
1803         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
1804         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
1805         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
1806
1807         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
1808         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
1809         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
1810         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
1811         pdf.backref = pdfSupportModule->backrefCB->isChecked();
1812         pdf.pagebackref = pdfSupportModule->pagebackrefCB->isChecked();
1813         if (pdfSupportModule->fullscreenCB->isChecked())
1814                 pdf.pagemode = pdf.pagemode_fullscreen;
1815         else
1816                 pdf.pagemode.clear();
1817         pdf.quoted_options = pdf.quoted_options_check(
1818                                 fromqstr(pdfSupportModule->optionsLE->text()));
1819 }
1820
1821
1822 void GuiDocument::paramsToDialog(BufferParams const & params)
1823 {
1824         // set the default unit
1825         Length::UNIT defaultUnit = Length::CM;
1826         switch (lyxrc.default_papersize) {
1827                 case PAPER_DEFAULT: break;
1828
1829                 case PAPER_USLETTER:
1830                 case PAPER_USLEGAL:
1831                 case PAPER_USEXECUTIVE:
1832                         defaultUnit = Length::IN;
1833                         break;
1834
1835                 case PAPER_A3:
1836                 case PAPER_A4:
1837                 case PAPER_A5:
1838                 case PAPER_B3:
1839                 case PAPER_B4:
1840                 case PAPER_B5:
1841                         defaultUnit = Length::CM;
1842                         break;
1843                 case PAPER_CUSTOM:
1844                         break;
1845         }
1846
1847         // preamble
1848         preambleModule->update(params, id());
1849
1850         // biblio
1851         biblioModule->citeDefaultRB->setChecked(
1852                 params.citeEngine() == ENGINE_BASIC);
1853
1854         biblioModule->citeNatbibRB->setChecked(
1855                 params.citeEngine() == ENGINE_NATBIB_NUMERICAL ||
1856                 params.citeEngine() == ENGINE_NATBIB_AUTHORYEAR);
1857
1858         biblioModule->citeStyleCO->setCurrentIndex(
1859                 params.citeEngine() == ENGINE_NATBIB_NUMERICAL);
1860
1861         biblioModule->citeJurabibRB->setChecked(
1862                 params.citeEngine() == ENGINE_JURABIB);
1863
1864         biblioModule->bibtopicCB->setChecked(
1865                 params.use_bibtopic);
1866
1867         // language & quotes
1868         int const pos = langModule->languageCO->findData(toqstr(
1869                 params.language->lang()));
1870         langModule->languageCO->setCurrentIndex(pos);
1871
1872         langModule->quoteStyleCO->setCurrentIndex(
1873                 params.quotes_language);
1874
1875         bool default_enc = true;
1876         if (params.inputenc != "auto") {
1877                 default_enc = false;
1878                 if (params.inputenc == "default") {
1879                         langModule->encodingCO->setCurrentIndex(0);
1880                 } else {
1881                         string enc_gui;
1882                         Encodings::const_iterator it = encodings.begin();
1883                         Encodings::const_iterator const end = encodings.end();
1884                         for (; it != end; ++it) {
1885                                 if (it->latexName() == params.inputenc) {
1886                                         enc_gui = it->guiName();
1887                                         break;
1888                                 }
1889                         }
1890                         int const i = langModule->encodingCO->findText(
1891                                         qt_(enc_gui));
1892                         if (i >= 0)
1893                                 langModule->encodingCO->setCurrentIndex(i);
1894                         else
1895                                 // unknown encoding. Set to default.
1896                                 default_enc = true;
1897                 }
1898         }
1899         langModule->defaultencodingRB->setChecked(default_enc);
1900         langModule->otherencodingRB->setChecked(!default_enc);
1901
1902         // numbering
1903         int const min_toclevel = documentClass().min_toclevel();
1904         int const max_toclevel = documentClass().max_toclevel();
1905         if (documentClass().hasTocLevels()) {
1906                 numberingModule->setEnabled(true);
1907                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
1908                 numberingModule->depthSL->setMaximum(max_toclevel);
1909                 numberingModule->depthSL->setValue(params.secnumdepth);
1910                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
1911                 numberingModule->tocSL->setMaximum(max_toclevel);
1912                 numberingModule->tocSL->setValue(params.tocdepth);
1913                 updateNumbering();
1914         } else {
1915                 numberingModule->setEnabled(false);
1916                 numberingModule->tocTW->clear();
1917         }
1918
1919         // bullets
1920         bulletsModule->setBullet(0, params.user_defined_bullet(0));
1921         bulletsModule->setBullet(1, params.user_defined_bullet(1));
1922         bulletsModule->setBullet(2, params.user_defined_bullet(2));
1923         bulletsModule->setBullet(3, params.user_defined_bullet(3));
1924         bulletsModule->init();
1925
1926         // packages
1927         int nitem = findToken(tex_graphics, params.graphicsDriver);
1928         if (nitem >= 0)
1929                 latexModule->psdriverCO->setCurrentIndex(nitem);
1930         updateModuleInfo();
1931         
1932         mathsModule->amsCB->setChecked(
1933                 params.use_amsmath == BufferParams::package_on);
1934         mathsModule->amsautoCB->setChecked(
1935                 params.use_amsmath == BufferParams::package_auto);
1936
1937         mathsModule->esintCB->setChecked(
1938                 params.use_esint == BufferParams::package_on);
1939         mathsModule->esintautoCB->setChecked(
1940                 params.use_esint == BufferParams::package_auto);
1941
1942         switch (params.spacing().getSpace()) {
1943                 case Spacing::Other: nitem = 3; break;
1944                 case Spacing::Double: nitem = 2; break;
1945                 case Spacing::Onehalf: nitem = 1; break;
1946                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
1947         }
1948
1949         // text layout
1950         string const & layoutID = params.baseClassID();
1951         setLayoutComboByIDString(layoutID);
1952
1953         updatePagestyle(documentClass().opt_pagestyle(),
1954                                  params.pagestyle);
1955
1956         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
1957         if (params.spacing().getSpace() == Spacing::Other) {
1958                 textLayoutModule->lspacingLE->setText(
1959                         toqstr(params.spacing().getValueAsString()));
1960         }
1961         setLSpacing(nitem);
1962
1963         if (params.paragraph_separation == BufferParams::ParagraphIndentSeparation)
1964                 textLayoutModule->indentRB->setChecked(true);
1965         else
1966                 textLayoutModule->skipRB->setChecked(true);
1967
1968         int skip = 0;
1969         switch (params.getDefSkip().kind()) {
1970         case VSpace::SMALLSKIP:
1971                 skip = 0;
1972                 break;
1973         case VSpace::MEDSKIP:
1974                 skip = 1;
1975                 break;
1976         case VSpace::BIGSKIP:
1977                 skip = 2;
1978                 break;
1979         case VSpace::LENGTH:
1980         {
1981                 skip = 3;
1982                 string const length = params.getDefSkip().asLyXCommand();
1983                 lengthToWidgets(textLayoutModule->skipLE,
1984                         textLayoutModule->skipLengthCO,
1985                         length, defaultUnit);
1986                 break;
1987         }
1988         default:
1989                 skip = 0;
1990                 break;
1991         }
1992         textLayoutModule->skipCO->setCurrentIndex(skip);
1993         setSkip(skip);
1994
1995         textLayoutModule->twoColumnCB->setChecked(
1996                 params.columns == 2);
1997
1998         // break listings_params to multiple lines
1999         string lstparams =
2000                 InsetListingsParams(params.listings_params).separatedParams();
2001         textLayoutModule->listingsED->setPlainText(toqstr(lstparams));
2002
2003         if (!params.options.empty()) {
2004                 latexModule->optionsLE->setText(
2005                         toqstr(params.options));
2006         } else {
2007                 latexModule->optionsLE->setText(QString());
2008         }
2009
2010         latexModule->defaultOptionsCB->setChecked(
2011                 params.use_default_options);
2012
2013         if (!documentClass().options().empty()) {
2014                 latexModule->defaultOptionsLE->setText(
2015                         toqstr(documentClass().options()));
2016         } else {
2017                 latexModule->defaultOptionsLE->setText(
2018                         toqstr(_("[No options predefined]")));
2019         }
2020
2021         latexModule->defaultOptionsLE->setEnabled(
2022                 params.use_default_options
2023                 && !documentClass().options().empty());
2024
2025         latexModule->defaultOptionsCB->setEnabled(
2026                 !documentClass().options().empty());
2027
2028         if (!params.master.empty()) {
2029                 latexModule->childDocGB->setChecked(true);
2030                 latexModule->childDocLE->setText(
2031                         toqstr(params.master));
2032         } else {
2033                 latexModule->childDocLE->setText(QString());
2034                 latexModule->childDocGB->setChecked(false);
2035         }
2036
2037         floatModule->set(params.float_placement);
2038
2039         // Fonts
2040         updateFontsize(documentClass().opt_fontsize(),
2041                         params.fontsize);
2042
2043         int n = findToken(tex_fonts_roman, params.fontsRoman);
2044         if (n >= 0) {
2045                 fontModule->fontsRomanCO->setCurrentIndex(n);
2046                 romanChanged(n);
2047         }
2048
2049         n = findToken(tex_fonts_sans, params.fontsSans);
2050         if (n >= 0)     {
2051                 fontModule->fontsSansCO->setCurrentIndex(n);
2052                 sansChanged(n);
2053         }
2054
2055         n = findToken(tex_fonts_monospaced, params.fontsTypewriter);
2056         if (n >= 0) {
2057                 fontModule->fontsTypewriterCO->setCurrentIndex(n);
2058                 ttChanged(n);
2059         }
2060
2061         if (!params.fontsCJK.empty())
2062                 fontModule->cjkFontLE->setText(
2063                         toqstr(params.fontsCJK));
2064         else
2065                 fontModule->cjkFontLE->setText(QString());
2066
2067         fontModule->fontScCB->setChecked(params.fontsSC);
2068         fontModule->fontOsfCB->setChecked(params.fontsOSF);
2069         fontModule->scaleSansSB->setValue(params.fontsSansScale);
2070         fontModule->scaleTypewriterSB->setValue(params.fontsTypewriterScale);
2071         n = findToken(GuiDocument::fontfamilies, params.fontsDefaultFamily);
2072         if (n >= 0)
2073                 fontModule->fontsDefaultCO->setCurrentIndex(n);
2074
2075         // paper
2076         int const psize = params.papersize;
2077         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
2078         setCustomPapersize(psize);
2079
2080         bool const landscape =
2081                 params.orientation == ORIENTATION_LANDSCAPE;
2082         pageLayoutModule->landscapeRB->setChecked(landscape);
2083         pageLayoutModule->portraitRB->setChecked(!landscape);
2084
2085         pageLayoutModule->facingPagesCB->setChecked(
2086                 params.sides == TwoSides);
2087
2088
2089         lengthToWidgets(pageLayoutModule->paperwidthLE,
2090                 pageLayoutModule->paperwidthUnitCO, params.paperwidth, defaultUnit);
2091
2092         lengthToWidgets(pageLayoutModule->paperheightLE,
2093                 pageLayoutModule->paperheightUnitCO, params.paperheight, defaultUnit);
2094
2095         // margins
2096         Ui::MarginsUi * m = marginsModule;
2097
2098         setMargins(!params.use_geometry);
2099
2100         lengthToWidgets(m->topLE, m->topUnit,
2101                 params.topmargin, defaultUnit);
2102
2103         lengthToWidgets(m->bottomLE, m->bottomUnit,
2104                 params.bottommargin, defaultUnit);
2105
2106         lengthToWidgets(m->innerLE, m->innerUnit,
2107                 params.leftmargin, defaultUnit);
2108
2109         lengthToWidgets(m->outerLE, m->outerUnit,
2110                 params.rightmargin, defaultUnit);
2111
2112         lengthToWidgets(m->headheightLE, m->headheightUnit,
2113                 params.headheight, defaultUnit);
2114
2115         lengthToWidgets(m->headsepLE, m->headsepUnit,
2116                 params.headsep, defaultUnit);
2117
2118         lengthToWidgets(m->footskipLE, m->footskipUnit,
2119                 params.footskip, defaultUnit);
2120
2121         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
2122                 params.columnsep, defaultUnit);
2123
2124         branchesModule->update(params);
2125
2126         // PDF support
2127         PDFOptions const & pdf = params.pdfoptions();
2128         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
2129         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
2130         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
2131         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
2132         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
2133
2134         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
2135         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
2136         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
2137
2138         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
2139
2140         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
2141         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
2142         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
2143         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
2144         pdfSupportModule->backrefCB->setChecked(pdf.backref);
2145         pdfSupportModule->pagebackrefCB->setChecked(pdf.pagebackref);
2146         pdfSupportModule->fullscreenCB->setChecked
2147                 (pdf.pagemode == pdf.pagemode_fullscreen);
2148
2149         pdfSupportModule->optionsLE->setText(
2150                 toqstr(pdf.quoted_options));
2151 }
2152
2153
2154 void GuiDocument::applyView()
2155 {
2156         apply(params());
2157 }
2158
2159
2160 void GuiDocument::saveDocDefault()
2161 {
2162         // we have to apply the params first
2163         applyView();
2164         saveAsDefault();
2165 }
2166
2167
2168 void GuiDocument::updateAvailableModules() 
2169 {
2170         modules_av_model_.clear();
2171         vector<modInfoStruct> const & modInfoList = getModuleInfo();
2172         int const mSize = modInfoList.size();
2173         for (int i = 0; i != mSize; ++i) {
2174                 modInfoStruct const & modInfo = modInfoList[i];
2175                 modules_av_model_.insertRow(i, modInfo.name, modInfo.id, 
2176                                 modInfo.description);
2177         }
2178 }
2179
2180
2181 void GuiDocument::updateSelectedModules() 
2182 {
2183         modules_sel_model_.clear();
2184         vector<modInfoStruct> const selModList = getSelectedModules();
2185         int const sSize = selModList.size();
2186         for (int i = 0; i != sSize; ++i) {
2187                 modInfoStruct const & modInfo = selModList[i];
2188                 modules_sel_model_.insertRow(i, modInfo.name, modInfo.id,
2189                                 modInfo.description);
2190         }
2191 }
2192
2193
2194 void GuiDocument::updateContents()
2195 {
2196         // Nothing to do here as the document settings is not cursor dependant.
2197         return;
2198 }
2199
2200
2201 void GuiDocument::useClassDefaults()
2202 {
2203         if (applyPB->isEnabled()) {
2204                 int const ret = Alert::prompt(_("Unapplied changes"),
2205                                 _("Some changes in the dialog were not yet applied.\n"
2206                                   "If you do not apply now, they will be lost after this action."),
2207                                 1, 1, _("&Apply"), _("&Dismiss"));
2208                 if (ret == 0)
2209                         applyView();
2210         }
2211
2212         int idx = latexModule->classCO->currentIndex();
2213         string const classname = classes_model_.getIDString(idx);
2214         if (!bp_.setBaseClass(classname)) {
2215                 Alert::error(_("Error"), _("Unable to set document class."));
2216                 return;
2217         }
2218         bp_.useClassDefaults();
2219         paramsToDialog(bp_);
2220 }
2221
2222
2223 void GuiDocument::setLayoutComboByIDString(std::string const & idString)
2224 {
2225         int idx = classes_model_.findIDString(idString);
2226         if (idx < 0)
2227                 Alert::warning(_("Can't set layout!"), 
2228                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
2229         else 
2230                 latexModule->classCO->setCurrentIndex(idx);
2231 }
2232
2233
2234 bool GuiDocument::isValid()
2235 {
2236         return validateListingsParameters().isEmpty()
2237                 && (textLayoutModule->skipCO->currentIndex() != 3
2238                         || !textLayoutModule->skipLE->text().isEmpty());
2239 }
2240
2241
2242 char const * const GuiDocument::fontfamilies[5] = {
2243         "default", "rmdefault", "sfdefault", "ttdefault", ""
2244 };
2245
2246
2247 char const * GuiDocument::fontfamilies_gui[5] = {
2248         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
2249 };
2250
2251
2252 bool GuiDocument::initialiseParams(string const &)
2253 {
2254         BufferView const * view = bufferview();
2255         if (!view) {
2256                 bp_ = BufferParams();
2257                 paramsToDialog(bp_);
2258                 return true;
2259         }
2260         bp_ = view->buffer().params();
2261         loadModuleInfo();
2262         updateAvailableModules();
2263         updateSelectedModules();
2264         //FIXME It'd be nice to make sure here that the selected
2265         //modules are consistent: That required modules are actually
2266         //selected, and that we don't have conflicts. If so, we could
2267         //at least pop up a warning.
2268         paramsToDialog(bp_);
2269         return true;
2270 }
2271
2272
2273 void GuiDocument::clearParams()
2274 {
2275         bp_ = BufferParams();
2276 }
2277
2278
2279 BufferId GuiDocument::id() const
2280 {
2281         BufferView const * const view = bufferview();
2282         return view? &view->buffer() : 0;
2283 }
2284
2285
2286 vector<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
2287 {
2288         return moduleNames_;
2289 }
2290
2291
2292 vector<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
2293 {
2294         vector<string> const & mods = params().getModules();
2295         vector<string>::const_iterator it =  mods.begin();
2296         vector<string>::const_iterator end = mods.end();
2297         vector<modInfoStruct> mInfo;
2298         for (; it != end; ++it) {
2299                 modInfoStruct m;
2300                 m.id = *it;
2301                 LyXModule * mod = moduleList[*it];
2302                 if (mod)
2303                         m.name = qt_(mod->getName());
2304                 else 
2305                         m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
2306                 mInfo.push_back(m);
2307         }
2308         return mInfo;
2309 }
2310
2311
2312 DocumentClass const & GuiDocument::documentClass() const
2313 {
2314         return bp_.documentClass();
2315 }
2316
2317
2318 static void dispatch_bufferparams(Dialog const & dialog,
2319         BufferParams const & bp, FuncCode lfun)
2320 {
2321         ostringstream ss;
2322         ss << "\\begin_header\n";
2323         bp.writeFile(ss);
2324         ss << "\\end_header\n";
2325         dialog.dispatch(FuncRequest(lfun, ss.str()));
2326 }
2327
2328
2329 void GuiDocument::dispatchParams()
2330 {
2331         // This must come first so that a language change is correctly noticed
2332         setLanguage();
2333
2334         // Apply the BufferParams. Note that this will set the base class
2335         // and then update the buffer's layout.
2336         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
2337
2338         if (!params().master.empty()) {
2339                 FileName const master_file = support::makeAbsPath(params().master,
2340                            support::onlyPath(buffer().absFileName()));
2341                 if (isLyXFilename(master_file.absFilename())) {
2342                         Buffer * master = checkAndLoadLyXFile(master_file);
2343                         const_cast<Buffer &>(buffer()).setParent(master);
2344                 }
2345         }
2346
2347         // Generate the colours requested by each new branch.
2348         BranchList & branchlist = params().branchlist();
2349         if (!branchlist.empty()) {
2350                 BranchList::const_iterator it = branchlist.begin();
2351                 BranchList::const_iterator const end = branchlist.end();
2352                 for (; it != end; ++it) {
2353                         docstring const & current_branch = it->branch();
2354                         Branch const * branch = branchlist.find(current_branch);
2355                         string const x11hexname = X11hexname(branch->color());
2356                         // display the new color
2357                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
2358                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
2359                 }
2360
2361                 // Open insets of selected branches, close deselected ones
2362                 dispatch(FuncRequest(LFUN_ALL_INSETS_TOGGLE,
2363                         "assign branch"));
2364         }
2365         // FIXME: If we used an LFUN, we would not need those two lines:
2366         BufferView * bv = const_cast<BufferView *>(bufferview());
2367         bv->processUpdateFlags(Update::Force | Update::FitCursor);
2368 }
2369
2370
2371 void GuiDocument::setLanguage() const
2372 {
2373         Language const * const newL = bp_.language;
2374         if (buffer().params().language == newL)
2375                 return;
2376
2377         string const & lang_name = newL->lang();
2378         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
2379 }
2380
2381
2382 void GuiDocument::saveAsDefault() const
2383 {
2384         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
2385 }
2386
2387
2388 bool GuiDocument::isFontAvailable(string const & font) const
2389 {
2390         if (font == "default" || font == "cmr"
2391             || font == "cmss" || font == "cmtt")
2392                 // these are standard
2393                 return true;
2394         if (font == "lmodern" || font == "lmss" || font == "lmtt")
2395                 return LaTeXFeatures::isAvailable("lmodern");
2396         if (font == "times" || font == "palatino"
2397                  || font == "helvet" || font == "courier")
2398                 return LaTeXFeatures::isAvailable("psnfss");
2399         if (font == "cmbr" || font == "cmtl")
2400                 return LaTeXFeatures::isAvailable("cmbright");
2401         if (font == "utopia")
2402                 return LaTeXFeatures::isAvailable("utopia")
2403                         || LaTeXFeatures::isAvailable("fourier");
2404         if (font == "beraserif" || font == "berasans"
2405                 || font == "beramono")
2406                 return LaTeXFeatures::isAvailable("bera");
2407         return LaTeXFeatures::isAvailable(font);
2408 }
2409
2410
2411 bool GuiDocument::providesOSF(string const & font) const
2412 {
2413         if (font == "cmr")
2414                 return isFontAvailable("eco");
2415         if (font == "palatino")
2416                 return isFontAvailable("mathpazo");
2417         return false;
2418 }
2419
2420
2421 bool GuiDocument::providesSC(string const & font) const
2422 {
2423         if (font == "palatino")
2424                 return isFontAvailable("mathpazo");
2425         if (font == "utopia")
2426                 return isFontAvailable("fourier");
2427         return false;
2428 }
2429
2430
2431 bool GuiDocument::providesScale(string const & font) const
2432 {
2433         return font == "helvet" || font == "luximono"
2434                 || font == "berasans"  || font == "beramono";
2435 }
2436
2437
2438 void GuiDocument::loadModuleInfo()
2439 {
2440         moduleNames_.clear();
2441         LyXModuleList::const_iterator it  = moduleList.begin();
2442         LyXModuleList::const_iterator end = moduleList.end();
2443         for (; it != end; ++it) {
2444                 modInfoStruct m;
2445                 m.id = it->getID();
2446                 m.name = qt_(it->getName());
2447                 // this is supposed to give us the first sentence of the description
2448                 QString desc = qt_(it->getDescription());
2449                 int const pos = desc.indexOf(".");
2450                 if (pos > 0)
2451                         desc.truncate(pos + 1);
2452                 m.description = desc;
2453                 moduleNames_.push_back(m);
2454         }
2455 }
2456
2457
2458 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
2459
2460
2461 } // namespace frontend
2462 } // namespace lyx
2463
2464 #include "GuiDocument_moc.cpp"