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