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