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