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