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