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