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