]> git.lyx.org Git - features.git/blob - src/frontends/qt4/GuiDocument.cpp
Create new Module panel in document settings and decrease vertical
[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         // postscript drivers
910         for (int n = 0; tex_graphics[n][0]; ++n) {
911                 QString enc = qt_(tex_graphics_gui[n]);
912                 latexModule->psdriverCO->addItem(enc);
913         }
914         // latex classes
915         latexModule->classCO->setModel(&classes_model_);
916         LayoutFileList const & bcl = LayoutFileList::get();
917         vector<LayoutFileIndex> classList = bcl.classList();
918         sort(classList.begin(), classList.end(), less_textclass_avail_desc());
919
920         vector<LayoutFileIndex>::const_iterator cit  = classList.begin();
921         vector<LayoutFileIndex>::const_iterator cen = classList.end();
922         for (int i = 0; cit != cen; ++cit, ++i) {
923                 LayoutFile const & tc = bcl[*cit];
924                 docstring item = (tc.isTeXClassAvailable()) ?
925                         from_utf8(tc.description()) :
926                         bformat(_("Unavailable: %1$s"), from_utf8(tc.description()));
927                 classes_model_.insertRow(i, toqstr(item), *cit);
928         }
929
930         // branches
931         branchesModule = new GuiBranches;
932         connect(branchesModule, SIGNAL(changed()),
933                 this, SLOT(change_adaptor()));
934
935         // preamble
936         preambleModule = new PreambleModule;
937         connect(preambleModule, SIGNAL(changed()),
938                 this, SLOT(change_adaptor()));
939
940         // bullets
941         bulletsModule = new BulletsModule;
942         connect(bulletsModule, SIGNAL(changed()),
943                 this, SLOT(change_adaptor()));
944
945         // Modules
946         modulesModule = new UiWidget<Ui::ModulesUi>;
947
948         selectionManager =
949                 new ModuleSelectionManager(modulesModule->availableLV,
950                         modulesModule->selectedLV,
951                         modulesModule->addPB, modulesModule->deletePB,
952                         modulesModule->upPB, modulesModule->downPB,
953                         availableModel(), selectedModel());
954         connect(selectionManager, SIGNAL(updateHook()),
955                 this, SLOT(updateModuleInfo()));
956         connect(selectionManager, SIGNAL(updateHook()),
957                 this, SLOT(change_adaptor()));
958
959
960         // PDF support
961         pdfSupportModule = new UiWidget<Ui::PDFSupportUi>;
962
963         connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
964                 this, SLOT(change_adaptor()));
965         connect(pdfSupportModule->titleLE, SIGNAL(textChanged(QString)),
966                 this, SLOT(change_adaptor()));
967         connect(pdfSupportModule->authorLE, SIGNAL(textChanged(QString)),
968                 this, SLOT(change_adaptor()));
969         connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(QString)),
970                 this, SLOT(change_adaptor()));
971         connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(QString)),
972                 this, SLOT(change_adaptor()));
973         connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
974                 this, SLOT(change_adaptor()));
975         connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
976                 this, SLOT(change_adaptor()));
977         connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
978                 this, SLOT(change_adaptor()));
979         connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
980                 this, SLOT(change_adaptor()));
981         connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
982                 this, SLOT(change_adaptor()));
983         connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
984                 this, SLOT(change_adaptor()));
985         connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
986                 this, SLOT(change_adaptor()));
987         connect(pdfSupportModule->backrefCO, SIGNAL(activated(int)),
988                 this, SLOT(change_adaptor()));
989         connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
990                 this, SLOT(change_adaptor()));
991         connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
992                 this, SLOT(change_adaptor()));
993         connect(pdfSupportModule->optionsLE, SIGNAL(textChanged(QString)),
994                 this, SLOT(change_adaptor()));
995
996         for (int i = 0; backref_opts[i][0]; ++i)
997                 pdfSupportModule->backrefCO->addItem(qt_(backref_opts_gui[i]));
998
999         // float
1000         floatModule = new FloatPlacement;
1001         connect(floatModule, SIGNAL(changed()),
1002                 this, SLOT(change_adaptor()));
1003
1004         docPS->addPanel(latexModule, qt_("Document Class"));
1005         docPS->addPanel(modulesModule, qt_("Modules"));
1006         docPS->addPanel(fontModule, qt_("Fonts"));
1007         docPS->addPanel(textLayoutModule, qt_("Text Layout"));
1008         docPS->addPanel(pageLayoutModule, qt_("Page Layout"));
1009         docPS->addPanel(marginsModule, qt_("Page Margins"));
1010         docPS->addPanel(langModule, qt_("Language"));
1011         docPS->addPanel(numberingModule, qt_("Numbering & TOC"));
1012         docPS->addPanel(biblioModule, qt_("Bibliography"));
1013         docPS->addPanel(pdfSupportModule, qt_("PDF Properties"));
1014         docPS->addPanel(mathsModule, qt_("Math Options"));
1015         docPS->addPanel(floatModule, qt_("Float Placement"));
1016         docPS->addPanel(bulletsModule, qt_("Bullets"));
1017         docPS->addPanel(branchesModule, qt_("Branches"));
1018         docPS->addPanel(preambleModule, qt_("LaTeX Preamble"));
1019         docPS->setCurrentPanel(qt_("Document Class"));
1020 // FIXME: hack to work around resizing bug in Qt >= 4.2
1021 // bug verified with Qt 4.2.{0-3} (JSpitzm)
1022 #if QT_VERSION >= 0x040200
1023         docPS->updateGeometry();
1024 #endif
1025 }
1026
1027
1028 void GuiDocument::showPreamble()
1029 {
1030         docPS->setCurrentPanel(qt_("LaTeX Preamble"));
1031 }
1032
1033
1034 void GuiDocument::saveDefaultClicked()
1035 {
1036         saveDocDefault();
1037 }
1038
1039
1040 void GuiDocument::useDefaultsClicked()
1041 {
1042         useClassDefaults();
1043 }
1044
1045
1046 void GuiDocument::change_adaptor()
1047 {
1048         changed();
1049 }
1050
1051
1052 QString GuiDocument::validateListingsParameters()
1053 {
1054         // use a cache here to avoid repeated validation
1055         // of the same parameters
1056         static string param_cache;
1057         static QString msg_cache;
1058         
1059         if (textLayoutModule->bypassCB->isChecked())
1060                 return QString();
1061
1062         string params = fromqstr(textLayoutModule->listingsED->toPlainText());
1063         if (params != param_cache) {
1064                 param_cache = params;
1065                 msg_cache = toqstr(InsetListingsParams(params).validate());
1066         }
1067         return msg_cache;
1068 }
1069
1070
1071 void GuiDocument::setListingsMessage()
1072 {
1073         static bool isOK = true;
1074         QString msg = validateListingsParameters();
1075         if (msg.isEmpty()) {
1076                 if (isOK)
1077                         return;
1078                 isOK = true;
1079                 // listingsTB->setTextColor("black");
1080                 textLayoutModule->listingsTB->setPlainText(
1081                         qt_("Input listings parameters on the right. "
1082                 "Enter ? for a list of parameters."));
1083         } else {
1084                 isOK = false;
1085                 // listingsTB->setTextColor("red");
1086                 textLayoutModule->listingsTB->setPlainText(msg);
1087         }
1088 }
1089
1090
1091 void GuiDocument::setLSpacing(int item)
1092 {
1093         textLayoutModule->lspacingLE->setEnabled(item == 3);
1094 }
1095
1096
1097 void GuiDocument::setSkip(int item)
1098 {
1099         bool const enable = (item == 3);
1100         textLayoutModule->skipLE->setEnabled(enable);
1101         textLayoutModule->skipLengthCO->setEnabled(enable);
1102 }
1103
1104
1105 void GuiDocument::enableSkip(bool skip)
1106 {
1107         textLayoutModule->skipCO->setEnabled(skip);
1108         textLayoutModule->skipLE->setEnabled(skip);
1109         textLayoutModule->skipLengthCO->setEnabled(skip);
1110         if (skip)
1111                 setSkip(textLayoutModule->skipCO->currentIndex());
1112 }
1113
1114 void GuiDocument::portraitChanged()
1115 {
1116         setMargins(pageLayoutModule->papersizeCO->currentIndex());
1117 }
1118
1119 void GuiDocument::setMargins(bool custom)
1120 {
1121         marginsModule->marginCB->setChecked(custom);
1122         setCustomMargins(custom);
1123 }
1124
1125
1126 void GuiDocument::setCustomPapersize(int papersize)
1127 {
1128         bool const custom = (papersize == 1);
1129
1130         pageLayoutModule->paperwidthL->setEnabled(custom);
1131         pageLayoutModule->paperwidthLE->setEnabled(custom);
1132         pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
1133         pageLayoutModule->paperheightL->setEnabled(custom);
1134         pageLayoutModule->paperheightLE->setEnabled(custom);
1135         pageLayoutModule->paperheightLE->setFocus();
1136         pageLayoutModule->paperheightUnitCO->setEnabled(custom);
1137 }
1138
1139
1140 void GuiDocument::setColSep()
1141 {
1142         setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
1143 }
1144
1145
1146 void GuiDocument::setCustomMargins(bool custom)
1147 {
1148         marginsModule->topL->setEnabled(!custom);
1149         marginsModule->topLE->setEnabled(!custom);
1150         marginsModule->topUnit->setEnabled(!custom);
1151
1152         marginsModule->bottomL->setEnabled(!custom);
1153         marginsModule->bottomLE->setEnabled(!custom);
1154         marginsModule->bottomUnit->setEnabled(!custom);
1155
1156         marginsModule->innerL->setEnabled(!custom);
1157         marginsModule->innerLE->setEnabled(!custom);
1158         marginsModule->innerUnit->setEnabled(!custom);
1159
1160         marginsModule->outerL->setEnabled(!custom);
1161         marginsModule->outerLE->setEnabled(!custom);
1162         marginsModule->outerUnit->setEnabled(!custom);
1163
1164         marginsModule->headheightL->setEnabled(!custom);
1165         marginsModule->headheightLE->setEnabled(!custom);
1166         marginsModule->headheightUnit->setEnabled(!custom);
1167
1168         marginsModule->headsepL->setEnabled(!custom);
1169         marginsModule->headsepLE->setEnabled(!custom);
1170         marginsModule->headsepUnit->setEnabled(!custom);
1171
1172         marginsModule->footskipL->setEnabled(!custom);
1173         marginsModule->footskipLE->setEnabled(!custom);
1174         marginsModule->footskipUnit->setEnabled(!custom);
1175
1176         bool const enableColSep = !custom && 
1177                         textLayoutModule->twoColumnCB->checkState() == Qt::Checked;
1178         marginsModule->columnsepL->setEnabled(enableColSep);
1179         marginsModule->columnsepLE->setEnabled(enableColSep);
1180         marginsModule->columnsepUnit->setEnabled(enableColSep);
1181 }
1182
1183
1184 void GuiDocument::updateFontsize(string const & items, string const & sel)
1185 {
1186         fontModule->fontsizeCO->clear();
1187         fontModule->fontsizeCO->addItem(qt_("Default"));
1188
1189         for (int n = 0; !token(items,'|',n).empty(); ++n)
1190                 fontModule->fontsizeCO->
1191                         addItem(toqstr(token(items,'|',n)));
1192
1193         for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
1194                 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
1195                         fontModule->fontsizeCO->setCurrentIndex(n);
1196                         break;
1197                 }
1198         }
1199 }
1200
1201
1202 void GuiDocument::romanChanged(int item)
1203 {
1204         string const font = tex_fonts_roman[item];
1205         fontModule->fontScCB->setEnabled(providesSC(font));
1206         fontModule->fontOsfCB->setEnabled(providesOSF(font));
1207 }
1208
1209
1210 void GuiDocument::sansChanged(int item)
1211 {
1212         string const font = tex_fonts_sans[item];
1213         bool scaleable = providesScale(font);
1214         fontModule->scaleSansSB->setEnabled(scaleable);
1215         fontModule->scaleSansLA->setEnabled(scaleable);
1216 }
1217
1218
1219 void GuiDocument::ttChanged(int item)
1220 {
1221         string const font = tex_fonts_monospaced[item];
1222         bool scaleable = providesScale(font);
1223         fontModule->scaleTypewriterSB->setEnabled(scaleable);
1224         fontModule->scaleTypewriterLA->setEnabled(scaleable);
1225 }
1226
1227
1228 void GuiDocument::updatePagestyle(string const & items, string const & sel)
1229 {
1230         pagestyles.clear();
1231         pageLayoutModule->pagestyleCO->clear();
1232         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1233
1234         for (int n = 0; !token(items, '|', n).empty(); ++n) {
1235                 string style = token(items, '|', n);
1236                 QString style_gui = qt_(style);
1237                 pagestyles.push_back(pair<string, QString>(style, style_gui));
1238                 pageLayoutModule->pagestyleCO->addItem(style_gui);
1239         }
1240
1241         if (sel == "default") {
1242                 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
1243                 return;
1244         }
1245
1246         int nn = 0;
1247
1248         for (size_t i = 0; i < pagestyles.size(); ++i)
1249                 if (pagestyles[i].first == sel)
1250                         nn = pageLayoutModule->pagestyleCO->findText(pagestyles[i].second);
1251
1252         if (nn > 0)
1253                 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
1254 }
1255
1256
1257 void GuiDocument::browseLayout()
1258 {
1259         QString const label1 = qt_("Layouts|#o#O");
1260         QString const dir1 = toqstr(lyxrc.document_path);
1261         QStringList const filter(qt_("LyX Layout (*.layout)"));
1262         QString file = browseRelFile(QString(), bufferFilepath(),
1263                 qt_("Local layout file"), filter, false,
1264                 label1, dir1);
1265
1266         if (!file.endsWith(".layout"))
1267                 return;
1268
1269         FileName layoutFile = support::makeAbsPath(fromqstr(file),
1270                 fromqstr(bufferFilepath()));
1271         
1272         int const ret = Alert::prompt(_("Local layout file"),
1273                 _("The layout file you have selected is a local layout\n"
1274                   "file, not one in the system or user directory. Your\n"
1275                   "document may not work with this layout if you do not\n"
1276                   "keep the layout file in the document directory."),
1277                   1, 1, _("&Set Layout"), _("&Cancel"));
1278         if (ret == 1)
1279                 return;
1280
1281         // load the layout file
1282         LayoutFileList & bcl = LayoutFileList::get();
1283         string classname = layoutFile.onlyFileName();
1284         // this will update an existing layout if that layout has been loaded before.
1285         LayoutFileIndex name = bcl.addLocalLayout(
1286                 classname.substr(0, classname.size() - 7),
1287                 layoutFile.onlyPath().absFilename());
1288
1289         if (name.empty()) {
1290                 Alert::error(_("Error"),
1291                         _("Unable to read local layout file."));                
1292                 return;
1293         }
1294
1295         // do not trigger classChanged if there is no change.
1296         if (latexModule->classCO->currentText() == toqstr(name))
1297                 return;
1298                 
1299         // add to combo box
1300         int idx = latexModule->classCO->findText(toqstr(name));
1301         if (idx == -1) {
1302                 classes_model_.insertRow(0, toqstr(name), name);
1303                 latexModule->classCO->setCurrentIndex(0);
1304         } else
1305                 latexModule->classCO->setCurrentIndex(idx);
1306         
1307         classChanged();
1308 }
1309
1310
1311 void GuiDocument::browseMaster()
1312 {
1313         QString const title = qt_("Select master document");
1314         QString const dir1 = toqstr(lyxrc.document_path);
1315         QString const old = latexModule->childDocLE->text();
1316         QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
1317         QStringList const filter(qt_("LyX Files (*.lyx)"));
1318         QString file = browseRelFile(old, docpath, title, filter, false,
1319                 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
1320
1321         latexModule->childDocLE->setText(file);
1322 }
1323
1324
1325 void GuiDocument::classChanged()
1326 {
1327         int idx = latexModule->classCO->currentIndex();
1328         if (idx < 0) 
1329                 return;
1330         string const classname = classes_model_.getIDString(idx);
1331
1332         // check whether the selected modules have changed.
1333         bool modulesChanged = false;
1334         unsigned int const srows = selectedModel()->rowCount();
1335         if (srows != bp_.getModules().size())
1336                 modulesChanged = true;
1337         else {
1338                 list<string>::const_iterator mit = bp_.getModules().begin();
1339                 list<string>::const_iterator men = bp_.getModules().end();
1340                 for (unsigned int i = 0; i < srows && mit != men; ++i, ++mit)
1341                         if (selectedModel()->getIDString(i) != *mit) {
1342                                 modulesChanged = true;
1343                                 break;
1344                         }
1345         }
1346
1347         if (modulesChanged || lyxrc.auto_reset_options) {
1348                 if (applyPB->isEnabled()) {
1349                         int const ret = Alert::prompt(_("Unapplied changes"),
1350                                         _("Some changes in the dialog were not yet applied.\n"
1351                                         "If you do not apply now, they will be lost after this action."),
1352                                         1, 1, _("&Apply"), _("&Dismiss"));
1353                         if (ret == 0)
1354                                 applyView();
1355                 }
1356         }
1357
1358         // We load the TextClass as soon as it is selected. This is
1359         // necessary so that other options in the dialog can be updated
1360         // according to the new class. Note, however, that, if you use 
1361         // the scroll wheel when sitting on the combo box, we'll load a 
1362         // lot of TextClass objects very quickly....
1363         if (!bp_.setBaseClass(classname)) {
1364                 Alert::error(_("Error"), _("Unable to set document class."));
1365                 return;
1366         }
1367         if (lyxrc.auto_reset_options)
1368                 bp_.useClassDefaults();
1369
1370         // With the introduction of modules came a distinction between the base 
1371         // class and the document class. The former corresponds to the main layout 
1372         // file; the latter is that plus the modules (or the document-specific layout,
1373         // or  whatever else there could be). Our parameters come from the document 
1374         // class. So when we set the base class, we also need to recreate the document 
1375         // class. Otherwise, we still have the old one.
1376         bp_.makeDocumentClass();
1377         // the new class may require some default modules.
1378         updateSelectedModules();
1379         paramsToDialog();
1380 }
1381
1382
1383 namespace {
1384         // This is an insanely complicated attempt to make this sort of thing
1385         // work with RTL languages.
1386         docstring formatStrVec(vector<string> const & v, docstring const & s) 
1387         {
1388                 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
1389                 if (v.size() == 0)
1390                         return docstring();
1391                 if (v.size() == 1) 
1392                         return from_ascii(v[0]);
1393                 if (v.size() == 2) {
1394                         docstring retval = _("%1$s and %2$s");
1395                         retval = subst(retval, _("and"), s);
1396                         return bformat(retval, from_ascii(v[0]), from_ascii(v[1]));
1397                 }
1398                 // The idea here is to format all but the last two items...
1399                 int const vSize = v.size();
1400                 docstring t2 = _("%1$s, %2$s");
1401                 docstring retval = from_ascii(v[0]);
1402                 for (int i = 1; i < vSize - 2; ++i)
1403                         retval = bformat(t2, retval, from_ascii(v[i])); 
1404                 //...and then to  plug them, and the last two, into this schema
1405                 docstring t = _("%1$s, %2$s, and %3$s");
1406                 t = subst(t, _("and"), s);
1407                 return bformat(t, retval, from_ascii(v[vSize - 2]), from_ascii(v[vSize - 1]));
1408         }
1409         
1410         vector<string> idsToNames(vector<string> const & idList)
1411         {
1412                 vector<string> retval;
1413                 vector<string>::const_iterator it  = idList.begin();
1414                 vector<string>::const_iterator end = idList.end();
1415                 for (; it != end; ++it) {
1416                         LyXModule const * const mod = moduleList[*it];
1417                         if (!mod)
1418                                 retval.push_back(*it + " (Unavailable)");
1419                         else
1420                                 retval.push_back(mod->getName());
1421                 }
1422                 return retval;
1423         }
1424 }
1425
1426
1427 void GuiDocument::updateModuleInfo()
1428 {
1429         selectionManager->update();
1430         
1431         //Module description
1432         bool const focusOnSelected = selectionManager->selectedFocused();
1433         QListView const * const lv = 
1434                         focusOnSelected ? modulesModule->selectedLV : modulesModule->availableLV;
1435         if (lv->selectionModel()->selectedIndexes().isEmpty()) {
1436                 modulesModule->infoML->document()->clear();
1437                 return;
1438         }
1439         QModelIndex const & idx = lv->selectionModel()->currentIndex();
1440         GuiIdListModel const & idModel = 
1441                         focusOnSelected  ? modules_sel_model_ : modules_av_model_;
1442         string const modName = idModel.getIDString(idx.row());
1443         docstring desc = getModuleDescription(modName);
1444
1445         vector<string> pkgList = getPackageList(modName);
1446         docstring pkgdesc = formatStrVec(pkgList, _("and"));
1447         if (!pkgdesc.empty()) {
1448                 if (!desc.empty())
1449                         desc += "\n";
1450                 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
1451         }
1452
1453         pkgList = getRequiredList(modName);
1454         if (!pkgList.empty()) {
1455                 vector<string> const reqDescs = idsToNames(pkgList);
1456                 pkgdesc = formatStrVec(reqDescs, _("or"));
1457                 if (!desc.empty())
1458                         desc += "\n";
1459                 desc += bformat(_("Module required: %1$s."), pkgdesc);
1460         }
1461
1462         pkgList = getExcludedList(modName);
1463         if (!pkgList.empty()) {
1464                 vector<string> const reqDescs = idsToNames(pkgList);
1465                 pkgdesc = formatStrVec(reqDescs, _( "and"));
1466                 if (!desc.empty())
1467                         desc += "\n";
1468                 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
1469         }
1470
1471         if (!isModuleAvailable(modName)) {
1472                 if (!desc.empty())
1473                         desc += "\n";
1474                 desc += _("WARNING: Some required packages are unavailable!");
1475         }
1476
1477         modulesModule->infoML->document()->setPlainText(toqstr(desc));
1478 }
1479
1480
1481 void GuiDocument::updateNumbering()
1482 {
1483         DocumentClass const & tclass = documentClass();
1484
1485         numberingModule->tocTW->setUpdatesEnabled(false);
1486         numberingModule->tocTW->clear();
1487
1488         int const depth = numberingModule->depthSL->value();
1489         int const toc = numberingModule->tocSL->value();
1490         QString const no = qt_("No");
1491         QString const yes = qt_("Yes");
1492         QTreeWidgetItem * item = 0;
1493
1494         DocumentClass::const_iterator lit = tclass.begin();
1495         DocumentClass::const_iterator len = tclass.end();
1496         for (; lit != len; ++lit) {
1497                 int const toclevel = lit->toclevel;
1498                 if (toclevel != Layout::NOT_IN_TOC && lit->labeltype == LABEL_COUNTER) {
1499                         item = new QTreeWidgetItem(numberingModule->tocTW);
1500                         item->setText(0, toqstr(translateIfPossible(lit->name())));
1501                         item->setText(1, (toclevel <= depth) ? yes : no);
1502                         item->setText(2, (toclevel <= toc) ? yes : no);
1503                 }
1504         }
1505
1506         numberingModule->tocTW->setUpdatesEnabled(true);
1507         numberingModule->tocTW->update();
1508 }
1509
1510
1511 void GuiDocument::apply(BufferParams & params)
1512 {
1513         // preamble
1514         preambleModule->apply(params);
1515
1516         // biblio
1517         params.setCiteEngine(ENGINE_BASIC);
1518
1519         if (biblioModule->citeNatbibRB->isChecked()) {
1520                 bool const use_numerical_citations =
1521                         biblioModule->citeStyleCO->currentIndex();
1522                 if (use_numerical_citations)
1523                         params.setCiteEngine(ENGINE_NATBIB_NUMERICAL);
1524                 else
1525                         params.setCiteEngine(ENGINE_NATBIB_AUTHORYEAR);
1526
1527         } else if (biblioModule->citeJurabibRB->isChecked())
1528                 params.setCiteEngine(ENGINE_JURABIB);
1529
1530         params.use_bibtopic =
1531                 biblioModule->bibtopicCB->isChecked();
1532
1533         // language & quotes
1534         if (langModule->defaultencodingRB->isChecked()) {
1535                 params.inputenc = "auto";
1536         } else {
1537                 int i = langModule->encodingCO->currentIndex();
1538                 if (i == 0)
1539                         params.inputenc = "default";
1540                 else {
1541                         QString const enc_gui =
1542                                 langModule->encodingCO->currentText();
1543                         Encodings::const_iterator it = encodings.begin();
1544                         Encodings::const_iterator const end = encodings.end();
1545                         bool found = false;
1546                         for (; it != end; ++it) {
1547                                 if (qt_(it->guiName()) == enc_gui) {
1548                                         params.inputenc = it->latexName();
1549                                         found = true;
1550                                         break;
1551                                 }
1552                         }
1553                         if (!found) {
1554                                 // should not happen
1555                                 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
1556                                 params.inputenc = "default";
1557                         }
1558                 }
1559         }
1560
1561         InsetQuotes::QuoteLanguage lga = InsetQuotes::EnglishQuotes;
1562         switch (langModule->quoteStyleCO->currentIndex()) {
1563         case 0:
1564                 lga = InsetQuotes::EnglishQuotes;
1565                 break;
1566         case 1:
1567                 lga = InsetQuotes::SwedishQuotes;
1568                 break;
1569         case 2:
1570                 lga = InsetQuotes::GermanQuotes;
1571                 break;
1572         case 3:
1573                 lga = InsetQuotes::PolishQuotes;
1574                 break;
1575         case 4:
1576                 lga = InsetQuotes::FrenchQuotes;
1577                 break;
1578         case 5:
1579                 lga = InsetQuotes::DanishQuotes;
1580                 break;
1581         }
1582         params.quotes_language = lga;
1583
1584         QString const lang = langModule->languageCO->itemData(
1585                 langModule->languageCO->currentIndex()).toString();
1586         params.language = lyx::languages.getLanguage(fromqstr(lang));
1587
1588         // numbering
1589         if (params.documentClass().hasTocLevels()) {
1590                 params.tocdepth = numberingModule->tocSL->value();
1591                 params.secnumdepth = numberingModule->depthSL->value();
1592         }
1593
1594         // bullets
1595         params.user_defined_bullet(0) = bulletsModule->bullet(0);
1596         params.user_defined_bullet(1) = bulletsModule->bullet(1);
1597         params.user_defined_bullet(2) = bulletsModule->bullet(2);
1598         params.user_defined_bullet(3) = bulletsModule->bullet(3);
1599
1600         // packages
1601         params.graphicsDriver =
1602                 tex_graphics[latexModule->psdriverCO->currentIndex()];
1603         
1604         // text layout
1605         int idx = latexModule->classCO->currentIndex();
1606         if (idx >= 0) {
1607                 string const classname = classes_model_.getIDString(idx);
1608                 params.setBaseClass(classname);
1609         }
1610
1611         // Modules
1612         params.clearLayoutModules();
1613         int const srows = modules_sel_model_.rowCount();
1614         vector<string> selModList;
1615         for (int i = 0; i < srows; ++i)
1616                 params.addLayoutModule(modules_sel_model_.getIDString(i));
1617         // update the list of removed modules
1618         params.clearRemovedModules();
1619         list<string> const & reqmods = params.baseClass()->defaultModules();
1620         list<string>::const_iterator rit = reqmods.begin();
1621         list<string>::const_iterator ren = reqmods.end();
1622         // check each of the required modules
1623         for (; rit != ren; rit++) {
1624                 list<string>::const_iterator mit = params.getModules().begin();
1625                 list<string>::const_iterator men = params.getModules().end();
1626                 bool found = false;
1627                 for (; mit != men; mit++) {
1628                         if (*rit == *mit) {
1629                                 found = true;
1630                                 break;
1631                         }
1632                 }
1633                 if (!found) {
1634                         // the module isn't present so must have been removed by the user
1635                         params.addRemovedModule(*rit);
1636                 }
1637         }
1638
1639         if (mathsModule->amsautoCB->isChecked()) {
1640                 params.use_amsmath = BufferParams::package_auto;
1641         } else {
1642                 if (mathsModule->amsCB->isChecked())
1643                         params.use_amsmath = BufferParams::package_on;
1644                 else
1645                         params.use_amsmath = BufferParams::package_off;
1646         }
1647
1648         if (mathsModule->esintautoCB->isChecked())
1649                 params.use_esint = BufferParams::package_auto;
1650         else {
1651                 if (mathsModule->esintCB->isChecked())
1652                         params.use_esint = BufferParams::package_on;
1653                 else
1654                         params.use_esint = BufferParams::package_off;
1655         }
1656
1657         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
1658                 params.pagestyle = "default";
1659         else {
1660                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
1661                 for (size_t i = 0; i != pagestyles.size(); ++i)
1662                         if (pagestyles[i].second == style_gui)
1663                                 params.pagestyle = pagestyles[i].first;
1664         }
1665
1666         switch (textLayoutModule->lspacingCO->currentIndex()) {
1667         case 0:
1668                 params.spacing().set(Spacing::Single);
1669                 break;
1670         case 1:
1671                 params.spacing().set(Spacing::Onehalf);
1672                 break;
1673         case 2:
1674                 params.spacing().set(Spacing::Double);
1675                 break;
1676         case 3:
1677                 params.spacing().set(Spacing::Other,
1678                         fromqstr(textLayoutModule->lspacingLE->text()));
1679                 break;
1680         }
1681
1682         if (textLayoutModule->twoColumnCB->isChecked())
1683                 params.columns = 2;
1684         else
1685                 params.columns = 1;
1686
1687         // text should have passed validation
1688         params.listings_params =
1689                 InsetListingsParams(fromqstr(textLayoutModule->listingsED->toPlainText())).params();
1690
1691         if (textLayoutModule->indentRB->isChecked())
1692                 params.paragraph_separation = BufferParams::ParagraphIndentSeparation;
1693         else
1694                 params.paragraph_separation = BufferParams::ParagraphSkipSeparation;
1695
1696         switch (textLayoutModule->skipCO->currentIndex()) {
1697         case 0:
1698                 params.setDefSkip(VSpace(VSpace::SMALLSKIP));
1699                 break;
1700         case 1:
1701                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
1702                 break;
1703         case 2:
1704                 params.setDefSkip(VSpace(VSpace::BIGSKIP));
1705                 break;
1706         case 3:
1707         {
1708                 VSpace vs = VSpace(
1709                         widgetsToLength(textLayoutModule->skipLE,
1710                                 textLayoutModule->skipLengthCO)
1711                         );
1712                 params.setDefSkip(vs);
1713                 break;
1714         }
1715         default:
1716                 // DocumentDefskipCB assures that this never happens
1717                 // so Assert then !!!  - jbl
1718                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
1719                 break;
1720         }
1721
1722         params.options =
1723                 fromqstr(latexModule->optionsLE->text());
1724
1725         params.use_default_options =
1726                 latexModule->defaultOptionsCB->isChecked();
1727
1728         if (latexModule->childDocGB->isChecked())
1729                 params.master =
1730                         fromqstr(latexModule->childDocLE->text());
1731         else
1732                 params.master = string();
1733
1734         params.float_placement = floatModule->get();
1735
1736         // fonts
1737         params.fontsRoman =
1738                 tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1739
1740         params.fontsSans =
1741                 tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1742
1743         params.fontsTypewriter =
1744                 tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1745
1746         params.fontsCJK =
1747                 fromqstr(fontModule->cjkFontLE->text());
1748
1749         params.fontsSansScale = fontModule->scaleSansSB->value();
1750
1751         params.fontsTypewriterScale = fontModule->scaleTypewriterSB->value();
1752
1753         params.fontsSC = fontModule->fontScCB->isChecked();
1754
1755         params.fontsOSF = fontModule->fontOsfCB->isChecked();
1756
1757         params.fontsDefaultFamily = GuiDocument::fontfamilies[
1758                 fontModule->fontsDefaultCO->currentIndex()];
1759
1760         if (fontModule->fontsizeCO->currentIndex() == 0)
1761                 params.fontsize = "default";
1762         else
1763                 params.fontsize =
1764                         fromqstr(fontModule->fontsizeCO->currentText());
1765
1766         // paper
1767         params.papersize = PAPER_SIZE(
1768                 pageLayoutModule->papersizeCO->currentIndex());
1769
1770         // custom, A3, B3 and B4 paper sizes need geometry
1771         int psize = pageLayoutModule->papersizeCO->currentIndex();
1772         bool geom_papersize = (psize == 1 || psize == 5 || psize == 8 || psize == 9);
1773
1774         params.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
1775                 pageLayoutModule->paperwidthUnitCO);
1776
1777         params.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
1778                 pageLayoutModule->paperheightUnitCO);
1779
1780         if (pageLayoutModule->facingPagesCB->isChecked())
1781                 params.sides = TwoSides;
1782         else
1783                 params.sides = OneSide;
1784
1785         if (pageLayoutModule->landscapeRB->isChecked())
1786                 params.orientation = ORIENTATION_LANDSCAPE;
1787         else
1788                 params.orientation = ORIENTATION_PORTRAIT;
1789
1790         // margins
1791         params.use_geometry = !marginsModule->marginCB->isChecked()
1792                 || geom_papersize;
1793
1794         Ui::MarginsUi const * m = marginsModule;
1795
1796         params.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
1797         params.topmargin = widgetsToLength(m->topLE, m->topUnit);
1798         params.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
1799         params.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
1800         params.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
1801         params.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
1802         params.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
1803         params.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
1804
1805         branchesModule->apply(params);
1806
1807         // PDF support
1808         PDFOptions & pdf = params.pdfoptions();
1809         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
1810         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
1811         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
1812         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
1813         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
1814
1815         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
1816         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
1817         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
1818         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
1819
1820         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
1821         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
1822         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
1823         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
1824         pdf.backref =
1825                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
1826         if (pdfSupportModule->fullscreenCB->isChecked())
1827                 pdf.pagemode = pdf.pagemode_fullscreen;
1828         else
1829                 pdf.pagemode.clear();
1830         pdf.quoted_options = pdf.quoted_options_check(
1831                                 fromqstr(pdfSupportModule->optionsLE->text()));
1832 }
1833
1834
1835 void GuiDocument::paramsToDialog()
1836 {
1837         // set the default unit
1838         Length::UNIT defaultUnit = Length::CM;
1839         switch (lyxrc.default_papersize) {
1840                 case PAPER_DEFAULT: break;
1841
1842                 case PAPER_USLETTER:
1843                 case PAPER_USLEGAL:
1844                 case PAPER_USEXECUTIVE:
1845                         defaultUnit = Length::IN;
1846                         break;
1847
1848                 case PAPER_A3:
1849                 case PAPER_A4:
1850                 case PAPER_A5:
1851                 case PAPER_B3:
1852                 case PAPER_B4:
1853                 case PAPER_B5:
1854                         defaultUnit = Length::CM;
1855                         break;
1856                 case PAPER_CUSTOM:
1857                         break;
1858         }
1859
1860         // preamble
1861         preambleModule->update(bp_, id());
1862
1863         // biblio
1864         biblioModule->citeDefaultRB->setChecked(
1865                 bp_.citeEngine() == ENGINE_BASIC);
1866
1867         biblioModule->citeNatbibRB->setChecked(
1868                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL ||
1869                 bp_.citeEngine() == ENGINE_NATBIB_AUTHORYEAR);
1870
1871         biblioModule->citeStyleCO->setCurrentIndex(
1872                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL);
1873
1874         biblioModule->citeJurabibRB->setChecked(
1875                 bp_.citeEngine() == ENGINE_JURABIB);
1876
1877         biblioModule->bibtopicCB->setChecked(
1878                 bp_.use_bibtopic);
1879
1880         // language & quotes
1881         int const pos = langModule->languageCO->findData(toqstr(
1882                 bp_.language->lang()));
1883         langModule->languageCO->setCurrentIndex(pos);
1884
1885         langModule->quoteStyleCO->setCurrentIndex(
1886                 bp_.quotes_language);
1887
1888         bool default_enc = true;
1889         if (bp_.inputenc != "auto") {
1890                 default_enc = false;
1891                 if (bp_.inputenc == "default") {
1892                         langModule->encodingCO->setCurrentIndex(0);
1893                 } else {
1894                         string enc_gui;
1895                         Encodings::const_iterator it = encodings.begin();
1896                         Encodings::const_iterator const end = encodings.end();
1897                         for (; it != end; ++it) {
1898                                 if (it->latexName() == bp_.inputenc) {
1899                                         enc_gui = it->guiName();
1900                                         break;
1901                                 }
1902                         }
1903                         int const i = langModule->encodingCO->findText(
1904                                         qt_(enc_gui));
1905                         if (i >= 0)
1906                                 langModule->encodingCO->setCurrentIndex(i);
1907                         else
1908                                 // unknown encoding. Set to default.
1909                                 default_enc = true;
1910                 }
1911         }
1912         langModule->defaultencodingRB->setChecked(default_enc);
1913         langModule->otherencodingRB->setChecked(!default_enc);
1914
1915         // numbering
1916         int const min_toclevel = documentClass().min_toclevel();
1917         int const max_toclevel = documentClass().max_toclevel();
1918         if (documentClass().hasTocLevels()) {
1919                 numberingModule->setEnabled(true);
1920                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
1921                 numberingModule->depthSL->setMaximum(max_toclevel);
1922                 numberingModule->depthSL->setValue(bp_.secnumdepth);
1923                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
1924                 numberingModule->tocSL->setMaximum(max_toclevel);
1925                 numberingModule->tocSL->setValue(bp_.tocdepth);
1926                 updateNumbering();
1927         } else {
1928                 numberingModule->setEnabled(false);
1929                 numberingModule->tocTW->clear();
1930         }
1931
1932         // bullets
1933         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
1934         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
1935         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
1936         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
1937         bulletsModule->init();
1938
1939         // packages
1940         int nitem = findToken(tex_graphics, bp_.graphicsDriver);
1941         if (nitem >= 0)
1942                 latexModule->psdriverCO->setCurrentIndex(nitem);
1943         updateModuleInfo();
1944         
1945         mathsModule->amsCB->setChecked(
1946                 bp_.use_amsmath == BufferParams::package_on);
1947         mathsModule->amsautoCB->setChecked(
1948                 bp_.use_amsmath == BufferParams::package_auto);
1949
1950         mathsModule->esintCB->setChecked(
1951                 bp_.use_esint == BufferParams::package_on);
1952         mathsModule->esintautoCB->setChecked(
1953                 bp_.use_esint == BufferParams::package_auto);
1954
1955         switch (bp_.spacing().getSpace()) {
1956                 case Spacing::Other: nitem = 3; break;
1957                 case Spacing::Double: nitem = 2; break;
1958                 case Spacing::Onehalf: nitem = 1; break;
1959                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
1960         }
1961
1962         // text layout
1963         string const & layoutID = bp_.baseClassID();
1964         setLayoutComboByIDString(layoutID);
1965
1966         updatePagestyle(documentClass().opt_pagestyle(),
1967                                  bp_.pagestyle);
1968
1969         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
1970         if (bp_.spacing().getSpace() == Spacing::Other) {
1971                 textLayoutModule->lspacingLE->setText(
1972                         toqstr(bp_.spacing().getValueAsString()));
1973         }
1974         setLSpacing(nitem);
1975
1976         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation)
1977                 textLayoutModule->indentRB->setChecked(true);
1978         else
1979                 textLayoutModule->skipRB->setChecked(true);
1980
1981         int skip = 0;
1982         switch (bp_.getDefSkip().kind()) {
1983         case VSpace::SMALLSKIP:
1984                 skip = 0;
1985                 break;
1986         case VSpace::MEDSKIP:
1987                 skip = 1;
1988                 break;
1989         case VSpace::BIGSKIP:
1990                 skip = 2;
1991                 break;
1992         case VSpace::LENGTH:
1993         {
1994                 skip = 3;
1995                 string const length = bp_.getDefSkip().asLyXCommand();
1996                 lengthToWidgets(textLayoutModule->skipLE,
1997                         textLayoutModule->skipLengthCO,
1998                         length, defaultUnit);
1999                 break;
2000         }
2001         default:
2002                 skip = 0;
2003                 break;
2004         }
2005         textLayoutModule->skipCO->setCurrentIndex(skip);
2006         setSkip(skip);
2007
2008         textLayoutModule->twoColumnCB->setChecked(
2009                 bp_.columns == 2);
2010
2011         // break listings_params to multiple lines
2012         string lstparams =
2013                 InsetListingsParams(bp_.listings_params).separatedParams();
2014         textLayoutModule->listingsED->setPlainText(toqstr(lstparams));
2015
2016         if (!bp_.options.empty()) {
2017                 latexModule->optionsLE->setText(
2018                         toqstr(bp_.options));
2019         } else {
2020                 latexModule->optionsLE->setText(QString());
2021         }
2022
2023         // latex
2024         latexModule->defaultOptionsCB->setChecked(
2025                         bp_.use_default_options);
2026
2027         if (!documentClass().options().empty()) {
2028                 latexModule->defaultOptionsLE->setText(
2029                         toqstr(documentClass().options()));
2030         } else {
2031                 latexModule->defaultOptionsLE->setText(
2032                         toqstr(_("[No options predefined]")));
2033         }
2034
2035         latexModule->defaultOptionsLE->setEnabled(
2036                 bp_.use_default_options
2037                 && !documentClass().options().empty());
2038
2039         latexModule->defaultOptionsCB->setEnabled(
2040                 !documentClass().options().empty());
2041
2042         if (!bp_.master.empty()) {
2043                 latexModule->childDocGB->setChecked(true);
2044                 latexModule->childDocLE->setText(
2045                         toqstr(bp_.master));
2046         } else {
2047                 latexModule->childDocLE->setText(QString());
2048                 latexModule->childDocGB->setChecked(false);
2049         }
2050
2051         floatModule->set(bp_.float_placement);
2052
2053         // Fonts
2054         updateFontsize(documentClass().opt_fontsize(),
2055                         bp_.fontsize);
2056
2057         int n = findToken(tex_fonts_roman, bp_.fontsRoman);
2058         if (n >= 0) {
2059                 fontModule->fontsRomanCO->setCurrentIndex(n);
2060                 romanChanged(n);
2061         }
2062
2063         n = findToken(tex_fonts_sans, bp_.fontsSans);
2064         if (n >= 0)     {
2065                 fontModule->fontsSansCO->setCurrentIndex(n);
2066                 sansChanged(n);
2067         }
2068
2069         n = findToken(tex_fonts_monospaced, bp_.fontsTypewriter);
2070         if (n >= 0) {
2071                 fontModule->fontsTypewriterCO->setCurrentIndex(n);
2072                 ttChanged(n);
2073         }
2074
2075         if (!bp_.fontsCJK.empty())
2076                 fontModule->cjkFontLE->setText(
2077                         toqstr(bp_.fontsCJK));
2078         else
2079                 fontModule->cjkFontLE->setText(QString());
2080
2081         fontModule->fontScCB->setChecked(bp_.fontsSC);
2082         fontModule->fontOsfCB->setChecked(bp_.fontsOSF);
2083         fontModule->scaleSansSB->setValue(bp_.fontsSansScale);
2084         fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale);
2085         n = findToken(GuiDocument::fontfamilies, bp_.fontsDefaultFamily);
2086         if (n >= 0)
2087                 fontModule->fontsDefaultCO->setCurrentIndex(n);
2088
2089         // paper
2090         int const psize = bp_.papersize;
2091         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
2092         setCustomPapersize(psize);
2093
2094         bool const landscape =
2095                 bp_.orientation == ORIENTATION_LANDSCAPE;
2096         pageLayoutModule->landscapeRB->setChecked(landscape);
2097         pageLayoutModule->portraitRB->setChecked(!landscape);
2098
2099         pageLayoutModule->facingPagesCB->setChecked(
2100                 bp_.sides == TwoSides);
2101
2102
2103         lengthToWidgets(pageLayoutModule->paperwidthLE,
2104                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, defaultUnit);
2105
2106         lengthToWidgets(pageLayoutModule->paperheightLE,
2107                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, defaultUnit);
2108
2109         // margins
2110         Ui::MarginsUi * m = marginsModule;
2111
2112         setMargins(!bp_.use_geometry);
2113
2114         lengthToWidgets(m->topLE, m->topUnit,
2115                 bp_.topmargin, defaultUnit);
2116
2117         lengthToWidgets(m->bottomLE, m->bottomUnit,
2118                 bp_.bottommargin, defaultUnit);
2119
2120         lengthToWidgets(m->innerLE, m->innerUnit,
2121                 bp_.leftmargin, defaultUnit);
2122
2123         lengthToWidgets(m->outerLE, m->outerUnit,
2124                 bp_.rightmargin, defaultUnit);
2125
2126         lengthToWidgets(m->headheightLE, m->headheightUnit,
2127                 bp_.headheight, defaultUnit);
2128
2129         lengthToWidgets(m->headsepLE, m->headsepUnit,
2130                 bp_.headsep, defaultUnit);
2131
2132         lengthToWidgets(m->footskipLE, m->footskipUnit,
2133                 bp_.footskip, defaultUnit);
2134
2135         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
2136                 bp_.columnsep, defaultUnit);
2137
2138         branchesModule->update(bp_);
2139
2140         // PDF support
2141         PDFOptions const & pdf = bp_.pdfoptions();
2142         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
2143         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
2144         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
2145         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
2146         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
2147
2148         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
2149         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
2150         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
2151
2152         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
2153
2154         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
2155         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
2156         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
2157         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
2158
2159         n = findToken(backref_opts, pdf.backref);
2160         if (n >= 0)
2161                 pdfSupportModule->backrefCO->setCurrentIndex(n);
2162
2163         pdfSupportModule->fullscreenCB->setChecked
2164                 (pdf.pagemode == pdf.pagemode_fullscreen);
2165
2166         pdfSupportModule->optionsLE->setText(
2167                 toqstr(pdf.quoted_options));
2168 }
2169
2170
2171 void GuiDocument::applyView()
2172 {
2173         apply(params());
2174 }
2175
2176
2177 void GuiDocument::saveDocDefault()
2178 {
2179         // we have to apply the params first
2180         applyView();
2181         saveAsDefault();
2182 }
2183
2184
2185 void GuiDocument::updateAvailableModules() 
2186 {
2187         modules_av_model_.clear();
2188         list<modInfoStruct> const & modInfoList = getModuleInfo();
2189         list<modInfoStruct>::const_iterator mit = modInfoList.begin();
2190         list<modInfoStruct>::const_iterator men = modInfoList.end();
2191         for (int i = 0; mit != men; ++mit, ++i)
2192                 modules_av_model_.insertRow(i, mit->name, mit->id, 
2193                                 mit->description);
2194 }
2195
2196
2197 void GuiDocument::updateSelectedModules() 
2198 {
2199         modules_sel_model_.clear();
2200         list<modInfoStruct> const selModList = getSelectedModules();
2201         list<modInfoStruct>::const_iterator mit = selModList.begin();
2202         list<modInfoStruct>::const_iterator men = selModList.end();
2203         for (int i = 0; mit != men; ++mit, ++i)
2204                 modules_sel_model_.insertRow(i, mit->name, mit->id, 
2205                                 mit->description);
2206 }
2207
2208
2209 void GuiDocument::updateContents()
2210 {
2211         // Nothing to do here as the document settings is not cursor dependant.
2212         return;
2213 }
2214
2215
2216 void GuiDocument::useClassDefaults()
2217 {
2218         if (applyPB->isEnabled()) {
2219                 int const ret = Alert::prompt(_("Unapplied changes"),
2220                                 _("Some changes in the dialog were not yet applied.\n"
2221                                   "If you do not apply now, they will be lost after this action."),
2222                                 1, 1, _("&Apply"), _("&Dismiss"));
2223                 if (ret == 0)
2224                         applyView();
2225         }
2226
2227         int idx = latexModule->classCO->currentIndex();
2228         string const classname = classes_model_.getIDString(idx);
2229         if (!bp_.setBaseClass(classname)) {
2230                 Alert::error(_("Error"), _("Unable to set document class."));
2231                 return;
2232         }
2233         bp_.useClassDefaults();
2234         paramsToDialog();
2235 }
2236
2237
2238 void GuiDocument::setLayoutComboByIDString(string const & idString)
2239 {
2240         int idx = classes_model_.findIDString(idString);
2241         if (idx < 0)
2242                 Alert::warning(_("Can't set layout!"), 
2243                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
2244         else 
2245                 latexModule->classCO->setCurrentIndex(idx);
2246 }
2247
2248
2249 bool GuiDocument::isValid()
2250 {
2251         return validateListingsParameters().isEmpty()
2252                 && (textLayoutModule->skipCO->currentIndex() != 3
2253                         || !textLayoutModule->skipLE->text().isEmpty());
2254 }
2255
2256
2257 char const * const GuiDocument::fontfamilies[5] = {
2258         "default", "rmdefault", "sfdefault", "ttdefault", ""
2259 };
2260
2261
2262 char const * GuiDocument::fontfamilies_gui[5] = {
2263         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
2264 };
2265
2266
2267 bool GuiDocument::initialiseParams(string const &)
2268 {
2269         BufferView const * view = bufferview();
2270         if (!view) {
2271                 bp_ = BufferParams();
2272                 paramsToDialog();
2273                 return true;
2274         }
2275         bp_ = view->buffer().params();
2276         loadModuleInfo();
2277         updateAvailableModules();
2278         updateSelectedModules();
2279         //FIXME It'd be nice to make sure here that the selected
2280         //modules are consistent: That required modules are actually
2281         //selected, and that we don't have conflicts. If so, we could
2282         //at least pop up a warning.
2283         paramsToDialog();
2284         return true;
2285 }
2286
2287
2288 void GuiDocument::clearParams()
2289 {
2290         bp_ = BufferParams();
2291 }
2292
2293
2294 BufferId GuiDocument::id() const
2295 {
2296         BufferView const * const view = bufferview();
2297         return view? &view->buffer() : 0;
2298 }
2299
2300
2301 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
2302 {
2303         return moduleNames_;
2304 }
2305
2306
2307 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
2308 {
2309         list<string> const & mods = params().getModules();
2310         list<string>::const_iterator it =  mods.begin();
2311         list<string>::const_iterator end = mods.end();
2312         list<modInfoStruct> mInfo;
2313         for (; it != end; ++it) {
2314                 modInfoStruct m;
2315                 m.id = *it;
2316                 LyXModule * mod = moduleList[*it];
2317                 if (mod)
2318                         m.name = qt_(mod->getName());
2319                 else 
2320                         m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
2321                 mInfo.push_back(m);
2322         }
2323         return mInfo;
2324 }
2325
2326
2327 DocumentClass const & GuiDocument::documentClass() const
2328 {
2329         return bp_.documentClass();
2330 }
2331
2332
2333 static void dispatch_bufferparams(Dialog const & dialog,
2334         BufferParams const & bp, FuncCode lfun)
2335 {
2336         ostringstream ss;
2337         ss << "\\begin_header\n";
2338         bp.writeFile(ss);
2339         ss << "\\end_header\n";
2340         dialog.dispatch(FuncRequest(lfun, ss.str()));
2341 }
2342
2343
2344 void GuiDocument::dispatchParams()
2345 {
2346         // This must come first so that a language change is correctly noticed
2347         setLanguage();
2348
2349         // Apply the BufferParams. Note that this will set the base class
2350         // and then update the buffer's layout.
2351         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
2352
2353         if (!params().master.empty()) {
2354                 FileName const master_file = support::makeAbsPath(params().master,
2355                            support::onlyPath(buffer().absFileName()));
2356                 if (isLyXFilename(master_file.absFilename())) {
2357                         Buffer * master = checkAndLoadLyXFile(master_file);
2358                         const_cast<Buffer &>(buffer()).setParent(master);
2359                 }
2360         }
2361
2362         // Generate the colours requested by each new branch.
2363         BranchList & branchlist = params().branchlist();
2364         if (!branchlist.empty()) {
2365                 BranchList::const_iterator it = branchlist.begin();
2366                 BranchList::const_iterator const end = branchlist.end();
2367                 for (; it != end; ++it) {
2368                         docstring const & current_branch = it->branch();
2369                         Branch const * branch = branchlist.find(current_branch);
2370                         string const x11hexname = X11hexname(branch->color());
2371                         // display the new color
2372                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
2373                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
2374                 }
2375
2376                 // Open insets of selected branches, close deselected ones
2377                 dispatch(FuncRequest(LFUN_ALL_INSETS_TOGGLE,
2378                         "assign branch"));
2379         }
2380         // FIXME: If we used an LFUN, we would not need those two lines:
2381         BufferView * bv = const_cast<BufferView *>(bufferview());
2382         bv->processUpdateFlags(Update::Force | Update::FitCursor);
2383 }
2384
2385
2386 void GuiDocument::setLanguage() const
2387 {
2388         Language const * const newL = bp_.language;
2389         if (buffer().params().language == newL)
2390                 return;
2391
2392         string const & lang_name = newL->lang();
2393         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
2394 }
2395
2396
2397 void GuiDocument::saveAsDefault() const
2398 {
2399         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
2400 }
2401
2402
2403 bool GuiDocument::isFontAvailable(string const & font) const
2404 {
2405         if (font == "default" || font == "cmr"
2406             || font == "cmss" || font == "cmtt")
2407                 // these are standard
2408                 return true;
2409         if (font == "lmodern" || font == "lmss" || font == "lmtt")
2410                 return LaTeXFeatures::isAvailable("lmodern");
2411         if (font == "times" || font == "palatino"
2412                  || font == "helvet" || font == "courier")
2413                 return LaTeXFeatures::isAvailable("psnfss");
2414         if (font == "cmbr" || font == "cmtl")
2415                 return LaTeXFeatures::isAvailable("cmbright");
2416         if (font == "utopia")
2417                 return LaTeXFeatures::isAvailable("utopia")
2418                         || LaTeXFeatures::isAvailable("fourier");
2419         if (font == "beraserif" || font == "berasans"
2420                 || font == "beramono")
2421                 return LaTeXFeatures::isAvailable("bera");
2422         return LaTeXFeatures::isAvailable(font);
2423 }
2424
2425
2426 bool GuiDocument::providesOSF(string const & font) const
2427 {
2428         if (font == "cmr")
2429                 return isFontAvailable("eco");
2430         if (font == "palatino")
2431                 return isFontAvailable("mathpazo");
2432         return false;
2433 }
2434
2435
2436 bool GuiDocument::providesSC(string const & font) const
2437 {
2438         if (font == "palatino")
2439                 return isFontAvailable("mathpazo");
2440         if (font == "utopia")
2441                 return isFontAvailable("fourier");
2442         return false;
2443 }
2444
2445
2446 bool GuiDocument::providesScale(string const & font) const
2447 {
2448         return font == "helvet" || font == "luximono"
2449                 || font == "berasans"  || font == "beramono";
2450 }
2451
2452
2453 void GuiDocument::loadModuleInfo()
2454 {
2455         moduleNames_.clear();
2456         LyXModuleList::const_iterator it  = moduleList.begin();
2457         LyXModuleList::const_iterator end = moduleList.end();
2458         for (; it != end; ++it) {
2459                 modInfoStruct m;
2460                 m.id = it->getID();
2461                 m.name = qt_(it->getName());
2462                 // this is supposed to give us the first sentence of the description
2463                 QString desc = qt_(it->getDescription());
2464                 int const pos = desc.indexOf(".");
2465                 if (pos > 0)
2466                         desc.truncate(pos + 1);
2467                 m.description = desc;
2468                 moduleNames_.push_back(m);
2469         }
2470 }
2471
2472
2473 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
2474
2475
2476 } // namespace frontend
2477 } // namespace lyx
2478
2479 #include "GuiDocument_moc.cpp"