]> git.lyx.org Git - features.git/blob - src/frontends/qt4/GuiDocument.cpp
Remove now duplicated code.
[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 availSels = 
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 || availSels.isEmpty() || isSelected(availSels.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 preModName = getSelectedModel()->getIDString(curRow - 1);
360         upPB->setEnabled(find(reqs.begin(), reqs.end(), preModName) == 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 modulesChanged = false;
1299         unsigned int const srows = selectedModel()->rowCount();
1300         if (srows != bp_.getModules().size())
1301                 modulesChanged = 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                                 modulesChanged = true;
1308                                 break;
1309                         }
1310         }
1311
1312         if (modulesChanged || 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         vector<string> selModList;
1398         for (int i = 0; i < srows; ++i)
1399                 bp_.addLayoutModule(modules_sel_model_.getIDString(i));
1400
1401         // update the list of removed modules
1402         bp_.clearRemovedModules();
1403         list<string> const & reqmods = bp_.baseClass()->defaultModules();
1404         list<string>::const_iterator rit = reqmods.begin();
1405         list<string>::const_iterator ren = reqmods.end();
1406
1407         // check each of the default modules
1408         for (; rit != ren; rit++) {
1409                 list<string>::const_iterator mit = bp_.getModules().begin();
1410                 list<string>::const_iterator men = bp_.getModules().end();
1411                 bool found = false;
1412                 for (; mit != men; mit++) {
1413                         if (*rit == *mit) {
1414                                 found = true;
1415                                 break;
1416                         }
1417                 }
1418                 if (!found) {
1419                         // the module isn't present so must have been removed by the user
1420                         bp_.addRemovedModule(*rit);
1421                 }
1422         }
1423         bp_.makeDocumentClass();
1424         paramsToDialog();
1425 }
1426
1427
1428 void GuiDocument::updateModuleInfo()
1429 {
1430         selectionManager->update();
1431         
1432         //Module description
1433         bool const focusOnSelected = selectionManager->selectedFocused();
1434         QListView const * const lv = 
1435                         focusOnSelected ? modulesModule->selectedLV : modulesModule->availableLV;
1436         if (lv->selectionModel()->selectedIndexes().isEmpty()) {
1437                 modulesModule->infoML->document()->clear();
1438                 return;
1439         }
1440         QModelIndex const & idx = lv->selectionModel()->currentIndex();
1441         GuiIdListModel const & idModel = 
1442                         focusOnSelected  ? modules_sel_model_ : modules_av_model_;
1443         string const modName = idModel.getIDString(idx.row());
1444         docstring desc = getModuleDescription(modName);
1445
1446         vector<string> pkgList = getPackageList(modName);
1447         docstring pkgdesc = formatStrVec(pkgList, _("and"));
1448         if (!pkgdesc.empty()) {
1449                 if (!desc.empty())
1450                         desc += "\n";
1451                 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
1452         }
1453
1454         pkgList = getRequiredList(modName);
1455         if (!pkgList.empty()) {
1456                 vector<string> const reqDescs = idsToNames(pkgList);
1457                 pkgdesc = formatStrVec(reqDescs, _("or"));
1458                 if (!desc.empty())
1459                         desc += "\n";
1460                 desc += bformat(_("Module required: %1$s."), pkgdesc);
1461         }
1462
1463         pkgList = getExcludedList(modName);
1464         if (!pkgList.empty()) {
1465                 vector<string> const reqDescs = idsToNames(pkgList);
1466                 pkgdesc = formatStrVec(reqDescs, _( "and"));
1467                 if (!desc.empty())
1468                         desc += "\n";
1469                 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
1470         }
1471
1472         if (!isModuleAvailable(modName)) {
1473                 if (!desc.empty())
1474                         desc += "\n";
1475                 desc += _("WARNING: Some required packages are unavailable!");
1476         }
1477
1478         modulesModule->infoML->document()->setPlainText(toqstr(desc));
1479 }
1480
1481
1482 void GuiDocument::updateNumbering()
1483 {
1484         DocumentClass const & tclass = documentClass();
1485
1486         numberingModule->tocTW->setUpdatesEnabled(false);
1487         numberingModule->tocTW->clear();
1488
1489         int const depth = numberingModule->depthSL->value();
1490         int const toc = numberingModule->tocSL->value();
1491         QString const no = qt_("No");
1492         QString const yes = qt_("Yes");
1493         QTreeWidgetItem * item = 0;
1494
1495         DocumentClass::const_iterator lit = tclass.begin();
1496         DocumentClass::const_iterator len = tclass.end();
1497         for (; lit != len; ++lit) {
1498                 int const toclevel = lit->toclevel;
1499                 if (toclevel != Layout::NOT_IN_TOC && lit->labeltype == LABEL_COUNTER) {
1500                         item = new QTreeWidgetItem(numberingModule->tocTW);
1501                         item->setText(0, toqstr(translateIfPossible(lit->name())));
1502                         item->setText(1, (toclevel <= depth) ? yes : no);
1503                         item->setText(2, (toclevel <= toc) ? yes : no);
1504                 }
1505         }
1506
1507         numberingModule->tocTW->setUpdatesEnabled(true);
1508         numberingModule->tocTW->update();
1509 }
1510
1511
1512 void GuiDocument::apply(BufferParams & params)
1513 {
1514         // preamble
1515         preambleModule->apply(params);
1516
1517         // biblio
1518         params.setCiteEngine(ENGINE_BASIC);
1519
1520         if (biblioModule->citeNatbibRB->isChecked()) {
1521                 bool const use_numerical_citations =
1522                         biblioModule->citeStyleCO->currentIndex();
1523                 if (use_numerical_citations)
1524                         params.setCiteEngine(ENGINE_NATBIB_NUMERICAL);
1525                 else
1526                         params.setCiteEngine(ENGINE_NATBIB_AUTHORYEAR);
1527
1528         } else if (biblioModule->citeJurabibRB->isChecked())
1529                 params.setCiteEngine(ENGINE_JURABIB);
1530
1531         params.use_bibtopic =
1532                 biblioModule->bibtopicCB->isChecked();
1533
1534         // language & quotes
1535         if (langModule->defaultencodingRB->isChecked()) {
1536                 params.inputenc = "auto";
1537         } else {
1538                 int i = langModule->encodingCO->currentIndex();
1539                 if (i == 0)
1540                         params.inputenc = "default";
1541                 else {
1542                         QString const enc_gui =
1543                                 langModule->encodingCO->currentText();
1544                         Encodings::const_iterator it = encodings.begin();
1545                         Encodings::const_iterator const end = encodings.end();
1546                         bool found = false;
1547                         for (; it != end; ++it) {
1548                                 if (qt_(it->guiName()) == enc_gui) {
1549                                         params.inputenc = it->latexName();
1550                                         found = true;
1551                                         break;
1552                                 }
1553                         }
1554                         if (!found) {
1555                                 // should not happen
1556                                 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
1557                                 params.inputenc = "default";
1558                         }
1559                 }
1560         }
1561
1562         InsetQuotes::QuoteLanguage lga = InsetQuotes::EnglishQuotes;
1563         switch (langModule->quoteStyleCO->currentIndex()) {
1564         case 0:
1565                 lga = InsetQuotes::EnglishQuotes;
1566                 break;
1567         case 1:
1568                 lga = InsetQuotes::SwedishQuotes;
1569                 break;
1570         case 2:
1571                 lga = InsetQuotes::GermanQuotes;
1572                 break;
1573         case 3:
1574                 lga = InsetQuotes::PolishQuotes;
1575                 break;
1576         case 4:
1577                 lga = InsetQuotes::FrenchQuotes;
1578                 break;
1579         case 5:
1580                 lga = InsetQuotes::DanishQuotes;
1581                 break;
1582         }
1583         params.quotes_language = lga;
1584
1585         QString const lang = langModule->languageCO->itemData(
1586                 langModule->languageCO->currentIndex()).toString();
1587         params.language = lyx::languages.getLanguage(fromqstr(lang));
1588
1589         // numbering
1590         if (params.documentClass().hasTocLevels()) {
1591                 params.tocdepth = numberingModule->tocSL->value();
1592                 params.secnumdepth = numberingModule->depthSL->value();
1593         }
1594
1595         // bullets
1596         params.user_defined_bullet(0) = bulletsModule->bullet(0);
1597         params.user_defined_bullet(1) = bulletsModule->bullet(1);
1598         params.user_defined_bullet(2) = bulletsModule->bullet(2);
1599         params.user_defined_bullet(3) = bulletsModule->bullet(3);
1600
1601         // packages
1602         params.graphicsDriver =
1603                 tex_graphics[latexModule->psdriverCO->currentIndex()];
1604         
1605         // text layout
1606         int idx = latexModule->classCO->currentIndex();
1607         if (idx >= 0) {
1608                 string const classname = classes_model_.getIDString(idx);
1609                 params.setBaseClass(classname);
1610         }
1611
1612         // Modules
1613         params.clearLayoutModules();
1614         int const srows = modules_sel_model_.rowCount();
1615         vector<string> selModList;
1616         for (int i = 0; i < srows; ++i)
1617                 params.addLayoutModule(modules_sel_model_.getIDString(i));
1618         // update the list of removed modules
1619         params.clearRemovedModules();
1620         list<string> const & reqmods = params.baseClass()->defaultModules();
1621         list<string>::const_iterator rit = reqmods.begin();
1622         list<string>::const_iterator ren = reqmods.end();
1623         // check each of the required modules
1624         for (; rit != ren; rit++) {
1625                 list<string>::const_iterator mit = params.getModules().begin();
1626                 list<string>::const_iterator men = params.getModules().end();
1627                 bool found = false;
1628                 for (; mit != men; mit++) {
1629                         if (*rit == *mit) {
1630                                 found = true;
1631                                 break;
1632                         }
1633                 }
1634                 if (!found) {
1635                         // the module isn't present so must have been removed by the user
1636                         params.addRemovedModule(*rit);
1637                 }
1638         }
1639
1640         if (mathsModule->amsautoCB->isChecked()) {
1641                 params.use_amsmath = BufferParams::package_auto;
1642         } else {
1643                 if (mathsModule->amsCB->isChecked())
1644                         params.use_amsmath = BufferParams::package_on;
1645                 else
1646                         params.use_amsmath = BufferParams::package_off;
1647         }
1648
1649         if (mathsModule->esintautoCB->isChecked())
1650                 params.use_esint = BufferParams::package_auto;
1651         else {
1652                 if (mathsModule->esintCB->isChecked())
1653                         params.use_esint = BufferParams::package_on;
1654                 else
1655                         params.use_esint = BufferParams::package_off;
1656         }
1657
1658         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
1659                 params.pagestyle = "default";
1660         else {
1661                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
1662                 for (size_t i = 0; i != pagestyles.size(); ++i)
1663                         if (pagestyles[i].second == style_gui)
1664                                 params.pagestyle = pagestyles[i].first;
1665         }
1666
1667         switch (textLayoutModule->lspacingCO->currentIndex()) {
1668         case 0:
1669                 params.spacing().set(Spacing::Single);
1670                 break;
1671         case 1:
1672                 params.spacing().set(Spacing::Onehalf);
1673                 break;
1674         case 2:
1675                 params.spacing().set(Spacing::Double);
1676                 break;
1677         case 3:
1678                 params.spacing().set(Spacing::Other,
1679                         fromqstr(textLayoutModule->lspacingLE->text()));
1680                 break;
1681         }
1682
1683         if (textLayoutModule->twoColumnCB->isChecked())
1684                 params.columns = 2;
1685         else
1686                 params.columns = 1;
1687
1688         // text should have passed validation
1689         params.listings_params =
1690                 InsetListingsParams(fromqstr(textLayoutModule->listingsED->toPlainText())).params();
1691
1692         if (textLayoutModule->indentRB->isChecked())
1693                 params.paragraph_separation = BufferParams::ParagraphIndentSeparation;
1694         else
1695                 params.paragraph_separation = BufferParams::ParagraphSkipSeparation;
1696
1697         switch (textLayoutModule->skipCO->currentIndex()) {
1698         case 0:
1699                 params.setDefSkip(VSpace(VSpace::SMALLSKIP));
1700                 break;
1701         case 1:
1702                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
1703                 break;
1704         case 2:
1705                 params.setDefSkip(VSpace(VSpace::BIGSKIP));
1706                 break;
1707         case 3:
1708         {
1709                 VSpace vs = VSpace(
1710                         widgetsToLength(textLayoutModule->skipLE,
1711                                 textLayoutModule->skipLengthCO)
1712                         );
1713                 params.setDefSkip(vs);
1714                 break;
1715         }
1716         default:
1717                 // DocumentDefskipCB assures that this never happens
1718                 // so Assert then !!!  - jbl
1719                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
1720                 break;
1721         }
1722
1723         params.options =
1724                 fromqstr(latexModule->optionsLE->text());
1725
1726         params.use_default_options =
1727                 latexModule->defaultOptionsCB->isChecked();
1728
1729         if (latexModule->childDocGB->isChecked())
1730                 params.master =
1731                         fromqstr(latexModule->childDocLE->text());
1732         else
1733                 params.master = string();
1734
1735         params.float_placement = floatModule->get();
1736
1737         // fonts
1738         params.fontsRoman =
1739                 tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1740
1741         params.fontsSans =
1742                 tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1743
1744         params.fontsTypewriter =
1745                 tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1746
1747         params.fontsCJK =
1748                 fromqstr(fontModule->cjkFontLE->text());
1749
1750         params.fontsSansScale = fontModule->scaleSansSB->value();
1751
1752         params.fontsTypewriterScale = fontModule->scaleTypewriterSB->value();
1753
1754         params.fontsSC = fontModule->fontScCB->isChecked();
1755
1756         params.fontsOSF = fontModule->fontOsfCB->isChecked();
1757
1758         params.fontsDefaultFamily = GuiDocument::fontfamilies[
1759                 fontModule->fontsDefaultCO->currentIndex()];
1760
1761         if (fontModule->fontsizeCO->currentIndex() == 0)
1762                 params.fontsize = "default";
1763         else
1764                 params.fontsize =
1765                         fromqstr(fontModule->fontsizeCO->currentText());
1766
1767         // paper
1768         params.papersize = PAPER_SIZE(
1769                 pageLayoutModule->papersizeCO->currentIndex());
1770
1771         // custom, A3, B3 and B4 paper sizes need geometry
1772         int psize = pageLayoutModule->papersizeCO->currentIndex();
1773         bool geom_papersize = (psize == 1 || psize == 5 || psize == 8 || psize == 9);
1774
1775         params.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
1776                 pageLayoutModule->paperwidthUnitCO);
1777
1778         params.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
1779                 pageLayoutModule->paperheightUnitCO);
1780
1781         if (pageLayoutModule->facingPagesCB->isChecked())
1782                 params.sides = TwoSides;
1783         else
1784                 params.sides = OneSide;
1785
1786         if (pageLayoutModule->landscapeRB->isChecked())
1787                 params.orientation = ORIENTATION_LANDSCAPE;
1788         else
1789                 params.orientation = ORIENTATION_PORTRAIT;
1790
1791         // margins
1792         params.use_geometry = !marginsModule->marginCB->isChecked()
1793                 || geom_papersize;
1794
1795         Ui::MarginsUi const * m = marginsModule;
1796
1797         params.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
1798         params.topmargin = widgetsToLength(m->topLE, m->topUnit);
1799         params.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
1800         params.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
1801         params.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
1802         params.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
1803         params.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
1804         params.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
1805
1806         branchesModule->apply(params);
1807
1808         // PDF support
1809         PDFOptions & pdf = params.pdfoptions();
1810         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
1811         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
1812         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
1813         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
1814         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
1815
1816         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
1817         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
1818         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
1819         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
1820
1821         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
1822         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
1823         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
1824         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
1825         pdf.backref =
1826                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
1827         if (pdfSupportModule->fullscreenCB->isChecked())
1828                 pdf.pagemode = pdf.pagemode_fullscreen;
1829         else
1830                 pdf.pagemode.clear();
1831         pdf.quoted_options = pdf.quoted_options_check(
1832                                 fromqstr(pdfSupportModule->optionsLE->text()));
1833 }
1834
1835
1836 void GuiDocument::paramsToDialog()
1837 {
1838         // set the default unit
1839         Length::UNIT defaultUnit = Length::CM;
1840         switch (lyxrc.default_papersize) {
1841                 case PAPER_DEFAULT: break;
1842
1843                 case PAPER_USLETTER:
1844                 case PAPER_USLEGAL:
1845                 case PAPER_USEXECUTIVE:
1846                         defaultUnit = Length::IN;
1847                         break;
1848
1849                 case PAPER_A3:
1850                 case PAPER_A4:
1851                 case PAPER_A5:
1852                 case PAPER_B3:
1853                 case PAPER_B4:
1854                 case PAPER_B5:
1855                         defaultUnit = Length::CM;
1856                         break;
1857                 case PAPER_CUSTOM:
1858                         break;
1859         }
1860
1861         // preamble
1862         preambleModule->update(bp_, id());
1863
1864         // biblio
1865         biblioModule->citeDefaultRB->setChecked(
1866                 bp_.citeEngine() == ENGINE_BASIC);
1867
1868         biblioModule->citeNatbibRB->setChecked(
1869                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL ||
1870                 bp_.citeEngine() == ENGINE_NATBIB_AUTHORYEAR);
1871
1872         biblioModule->citeStyleCO->setCurrentIndex(
1873                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL);
1874
1875         biblioModule->citeJurabibRB->setChecked(
1876                 bp_.citeEngine() == ENGINE_JURABIB);
1877
1878         biblioModule->bibtopicCB->setChecked(
1879                 bp_.use_bibtopic);
1880
1881         // language & quotes
1882         int const pos = langModule->languageCO->findData(toqstr(
1883                 bp_.language->lang()));
1884         langModule->languageCO->setCurrentIndex(pos);
1885
1886         langModule->quoteStyleCO->setCurrentIndex(
1887                 bp_.quotes_language);
1888
1889         bool default_enc = true;
1890         if (bp_.inputenc != "auto") {
1891                 default_enc = false;
1892                 if (bp_.inputenc == "default") {
1893                         langModule->encodingCO->setCurrentIndex(0);
1894                 } else {
1895                         string enc_gui;
1896                         Encodings::const_iterator it = encodings.begin();
1897                         Encodings::const_iterator const end = encodings.end();
1898                         for (; it != end; ++it) {
1899                                 if (it->latexName() == bp_.inputenc) {
1900                                         enc_gui = it->guiName();
1901                                         break;
1902                                 }
1903                         }
1904                         int const i = langModule->encodingCO->findText(
1905                                         qt_(enc_gui));
1906                         if (i >= 0)
1907                                 langModule->encodingCO->setCurrentIndex(i);
1908                         else
1909                                 // unknown encoding. Set to default.
1910                                 default_enc = true;
1911                 }
1912         }
1913         langModule->defaultencodingRB->setChecked(default_enc);
1914         langModule->otherencodingRB->setChecked(!default_enc);
1915
1916         // numbering
1917         int const min_toclevel = documentClass().min_toclevel();
1918         int const max_toclevel = documentClass().max_toclevel();
1919         if (documentClass().hasTocLevels()) {
1920                 numberingModule->setEnabled(true);
1921                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
1922                 numberingModule->depthSL->setMaximum(max_toclevel);
1923                 numberingModule->depthSL->setValue(bp_.secnumdepth);
1924                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
1925                 numberingModule->tocSL->setMaximum(max_toclevel);
1926                 numberingModule->tocSL->setValue(bp_.tocdepth);
1927                 updateNumbering();
1928         } else {
1929                 numberingModule->setEnabled(false);
1930                 numberingModule->tocTW->clear();
1931         }
1932
1933         // bullets
1934         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
1935         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
1936         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
1937         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
1938         bulletsModule->init();
1939
1940         // packages
1941         int nitem = findToken(tex_graphics, bp_.graphicsDriver);
1942         if (nitem >= 0)
1943                 latexModule->psdriverCO->setCurrentIndex(nitem);
1944         updateModuleInfo();
1945         
1946         mathsModule->amsCB->setChecked(
1947                 bp_.use_amsmath == BufferParams::package_on);
1948         mathsModule->amsautoCB->setChecked(
1949                 bp_.use_amsmath == BufferParams::package_auto);
1950
1951         mathsModule->esintCB->setChecked(
1952                 bp_.use_esint == BufferParams::package_on);
1953         mathsModule->esintautoCB->setChecked(
1954                 bp_.use_esint == BufferParams::package_auto);
1955
1956         switch (bp_.spacing().getSpace()) {
1957                 case Spacing::Other: nitem = 3; break;
1958                 case Spacing::Double: nitem = 2; break;
1959                 case Spacing::Onehalf: nitem = 1; break;
1960                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
1961         }
1962
1963         // text layout
1964         string const & layoutID = bp_.baseClassID();
1965         setLayoutComboByIDString(layoutID);
1966
1967         updatePagestyle(documentClass().opt_pagestyle(),
1968                                  bp_.pagestyle);
1969
1970         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
1971         if (bp_.spacing().getSpace() == Spacing::Other) {
1972                 textLayoutModule->lspacingLE->setText(
1973                         toqstr(bp_.spacing().getValueAsString()));
1974         }
1975         setLSpacing(nitem);
1976
1977         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation)
1978                 textLayoutModule->indentRB->setChecked(true);
1979         else
1980                 textLayoutModule->skipRB->setChecked(true);
1981
1982         int skip = 0;
1983         switch (bp_.getDefSkip().kind()) {
1984         case VSpace::SMALLSKIP:
1985                 skip = 0;
1986                 break;
1987         case VSpace::MEDSKIP:
1988                 skip = 1;
1989                 break;
1990         case VSpace::BIGSKIP:
1991                 skip = 2;
1992                 break;
1993         case VSpace::LENGTH:
1994         {
1995                 skip = 3;
1996                 string const length = bp_.getDefSkip().asLyXCommand();
1997                 lengthToWidgets(textLayoutModule->skipLE,
1998                         textLayoutModule->skipLengthCO,
1999                         length, defaultUnit);
2000                 break;
2001         }
2002         default:
2003                 skip = 0;
2004                 break;
2005         }
2006         textLayoutModule->skipCO->setCurrentIndex(skip);
2007         setSkip(skip);
2008
2009         textLayoutModule->twoColumnCB->setChecked(
2010                 bp_.columns == 2);
2011
2012         // break listings_params to multiple lines
2013         string lstparams =
2014                 InsetListingsParams(bp_.listings_params).separatedParams();
2015         textLayoutModule->listingsED->setPlainText(toqstr(lstparams));
2016
2017         if (!bp_.options.empty()) {
2018                 latexModule->optionsLE->setText(
2019                         toqstr(bp_.options));
2020         } else {
2021                 latexModule->optionsLE->setText(QString());
2022         }
2023
2024         // latex
2025         latexModule->defaultOptionsCB->setChecked(
2026                         bp_.use_default_options);
2027
2028         if (!documentClass().options().empty()) {
2029                 latexModule->defaultOptionsLE->setText(
2030                         toqstr(documentClass().options()));
2031         } else {
2032                 latexModule->defaultOptionsLE->setText(
2033                         toqstr(_("[No options predefined]")));
2034         }
2035
2036         latexModule->defaultOptionsLE->setEnabled(
2037                 bp_.use_default_options
2038                 && !documentClass().options().empty());
2039
2040         latexModule->defaultOptionsCB->setEnabled(
2041                 !documentClass().options().empty());
2042
2043         if (!bp_.master.empty()) {
2044                 latexModule->childDocGB->setChecked(true);
2045                 latexModule->childDocLE->setText(
2046                         toqstr(bp_.master));
2047         } else {
2048                 latexModule->childDocLE->setText(QString());
2049                 latexModule->childDocGB->setChecked(false);
2050         }
2051
2052         floatModule->set(bp_.float_placement);
2053
2054         // Fonts
2055         updateFontsize(documentClass().opt_fontsize(),
2056                         bp_.fontsize);
2057
2058         int n = findToken(tex_fonts_roman, bp_.fontsRoman);
2059         if (n >= 0) {
2060                 fontModule->fontsRomanCO->setCurrentIndex(n);
2061                 romanChanged(n);
2062         }
2063
2064         n = findToken(tex_fonts_sans, bp_.fontsSans);
2065         if (n >= 0)     {
2066                 fontModule->fontsSansCO->setCurrentIndex(n);
2067                 sansChanged(n);
2068         }
2069
2070         n = findToken(tex_fonts_monospaced, bp_.fontsTypewriter);
2071         if (n >= 0) {
2072                 fontModule->fontsTypewriterCO->setCurrentIndex(n);
2073                 ttChanged(n);
2074         }
2075
2076         if (!bp_.fontsCJK.empty())
2077                 fontModule->cjkFontLE->setText(
2078                         toqstr(bp_.fontsCJK));
2079         else
2080                 fontModule->cjkFontLE->setText(QString());
2081
2082         fontModule->fontScCB->setChecked(bp_.fontsSC);
2083         fontModule->fontOsfCB->setChecked(bp_.fontsOSF);
2084         fontModule->scaleSansSB->setValue(bp_.fontsSansScale);
2085         fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale);
2086         n = findToken(GuiDocument::fontfamilies, bp_.fontsDefaultFamily);
2087         if (n >= 0)
2088                 fontModule->fontsDefaultCO->setCurrentIndex(n);
2089
2090         // paper
2091         int const psize = bp_.papersize;
2092         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
2093         setCustomPapersize(psize);
2094
2095         bool const landscape =
2096                 bp_.orientation == ORIENTATION_LANDSCAPE;
2097         pageLayoutModule->landscapeRB->setChecked(landscape);
2098         pageLayoutModule->portraitRB->setChecked(!landscape);
2099
2100         pageLayoutModule->facingPagesCB->setChecked(
2101                 bp_.sides == TwoSides);
2102
2103
2104         lengthToWidgets(pageLayoutModule->paperwidthLE,
2105                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, defaultUnit);
2106
2107         lengthToWidgets(pageLayoutModule->paperheightLE,
2108                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, defaultUnit);
2109
2110         // margins
2111         Ui::MarginsUi * m = marginsModule;
2112
2113         setMargins(!bp_.use_geometry);
2114
2115         lengthToWidgets(m->topLE, m->topUnit,
2116                 bp_.topmargin, defaultUnit);
2117
2118         lengthToWidgets(m->bottomLE, m->bottomUnit,
2119                 bp_.bottommargin, defaultUnit);
2120
2121         lengthToWidgets(m->innerLE, m->innerUnit,
2122                 bp_.leftmargin, defaultUnit);
2123
2124         lengthToWidgets(m->outerLE, m->outerUnit,
2125                 bp_.rightmargin, defaultUnit);
2126
2127         lengthToWidgets(m->headheightLE, m->headheightUnit,
2128                 bp_.headheight, defaultUnit);
2129
2130         lengthToWidgets(m->headsepLE, m->headsepUnit,
2131                 bp_.headsep, defaultUnit);
2132
2133         lengthToWidgets(m->footskipLE, m->footskipUnit,
2134                 bp_.footskip, defaultUnit);
2135
2136         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
2137                 bp_.columnsep, defaultUnit);
2138
2139         branchesModule->update(bp_);
2140
2141         // PDF support
2142         PDFOptions const & pdf = bp_.pdfoptions();
2143         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
2144         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
2145         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
2146         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
2147         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
2148
2149         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
2150         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
2151         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
2152
2153         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
2154
2155         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
2156         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
2157         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
2158         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
2159
2160         n = findToken(backref_opts, pdf.backref);
2161         if (n >= 0)
2162                 pdfSupportModule->backrefCO->setCurrentIndex(n);
2163
2164         pdfSupportModule->fullscreenCB->setChecked
2165                 (pdf.pagemode == pdf.pagemode_fullscreen);
2166
2167         pdfSupportModule->optionsLE->setText(
2168                 toqstr(pdf.quoted_options));
2169 }
2170
2171
2172 void GuiDocument::applyView()
2173 {
2174         apply(params());
2175 }
2176
2177
2178 void GuiDocument::saveDocDefault()
2179 {
2180         // we have to apply the params first
2181         applyView();
2182         saveAsDefault();
2183 }
2184
2185
2186 void GuiDocument::updateAvailableModules() 
2187 {
2188         modules_av_model_.clear();
2189         list<modInfoStruct> const & modInfoList = getModuleInfo();
2190         list<modInfoStruct>::const_iterator mit = modInfoList.begin();
2191         list<modInfoStruct>::const_iterator men = modInfoList.end();
2192         for (int i = 0; mit != men; ++mit, ++i)
2193                 modules_av_model_.insertRow(i, mit->name, mit->id, 
2194                                 mit->description);
2195 }
2196
2197
2198 void GuiDocument::updateSelectedModules() 
2199 {
2200         modules_sel_model_.clear();
2201         list<modInfoStruct> const selModList = getSelectedModules();
2202         list<modInfoStruct>::const_iterator mit = selModList.begin();
2203         list<modInfoStruct>::const_iterator men = selModList.end();
2204         for (int i = 0; mit != men; ++mit, ++i)
2205                 modules_sel_model_.insertRow(i, mit->name, mit->id, 
2206                                 mit->description);
2207 }
2208
2209
2210 void GuiDocument::updateContents()
2211 {
2212         // Nothing to do here as the document settings is not cursor dependant.
2213         return;
2214 }
2215
2216
2217 void GuiDocument::useClassDefaults()
2218 {
2219         if (applyPB->isEnabled()) {
2220                 int const ret = Alert::prompt(_("Unapplied changes"),
2221                                 _("Some changes in the dialog were not yet applied.\n"
2222                                   "If you do not apply now, they will be lost after this action."),
2223                                 1, 1, _("&Apply"), _("&Dismiss"));
2224                 if (ret == 0)
2225                         applyView();
2226         }
2227
2228         int idx = latexModule->classCO->currentIndex();
2229         string const classname = classes_model_.getIDString(idx);
2230         if (!bp_.setBaseClass(classname)) {
2231                 Alert::error(_("Error"), _("Unable to set document class."));
2232                 return;
2233         }
2234         bp_.useClassDefaults();
2235         paramsToDialog();
2236 }
2237
2238
2239 void GuiDocument::setLayoutComboByIDString(string const & idString)
2240 {
2241         int idx = classes_model_.findIDString(idString);
2242         if (idx < 0)
2243                 Alert::warning(_("Can't set layout!"), 
2244                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
2245         else 
2246                 latexModule->classCO->setCurrentIndex(idx);
2247 }
2248
2249
2250 bool GuiDocument::isValid()
2251 {
2252         return validateListingsParameters().isEmpty()
2253                 && (textLayoutModule->skipCO->currentIndex() != 3
2254                         || !textLayoutModule->skipLE->text().isEmpty());
2255 }
2256
2257
2258 char const * const GuiDocument::fontfamilies[5] = {
2259         "default", "rmdefault", "sfdefault", "ttdefault", ""
2260 };
2261
2262
2263 char const * GuiDocument::fontfamilies_gui[5] = {
2264         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
2265 };
2266
2267
2268 bool GuiDocument::initialiseParams(string const &)
2269 {
2270         BufferView const * view = bufferview();
2271         if (!view) {
2272                 bp_ = BufferParams();
2273                 paramsToDialog();
2274                 return true;
2275         }
2276         bp_ = view->buffer().params();
2277         loadModuleInfo();
2278         updateAvailableModules();
2279         updateSelectedModules();
2280         //FIXME It'd be nice to make sure here that the selected
2281         //modules are consistent: That required modules are actually
2282         //selected, and that we don't have conflicts. If so, we could
2283         //at least pop up a warning.
2284         paramsToDialog();
2285         return true;
2286 }
2287
2288
2289 void GuiDocument::clearParams()
2290 {
2291         bp_ = BufferParams();
2292 }
2293
2294
2295 BufferId GuiDocument::id() const
2296 {
2297         BufferView const * const view = bufferview();
2298         return view? &view->buffer() : 0;
2299 }
2300
2301
2302 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
2303 {
2304         return moduleNames_;
2305 }
2306
2307
2308 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
2309 {
2310         list<string> const & mods = params().getModules();
2311         list<string>::const_iterator it =  mods.begin();
2312         list<string>::const_iterator end = mods.end();
2313         list<modInfoStruct> mInfo;
2314         for (; it != end; ++it) {
2315                 modInfoStruct m;
2316                 m.id = *it;
2317                 LyXModule * mod = moduleList[*it];
2318                 if (mod)
2319                         m.name = qt_(mod->getName());
2320                 else 
2321                         m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
2322                 mInfo.push_back(m);
2323         }
2324         return mInfo;
2325 }
2326
2327
2328 DocumentClass const & GuiDocument::documentClass() const
2329 {
2330         return bp_.documentClass();
2331 }
2332
2333
2334 static void dispatch_bufferparams(Dialog const & dialog,
2335         BufferParams const & bp, FuncCode lfun)
2336 {
2337         ostringstream ss;
2338         ss << "\\begin_header\n";
2339         bp.writeFile(ss);
2340         ss << "\\end_header\n";
2341         dialog.dispatch(FuncRequest(lfun, ss.str()));
2342 }
2343
2344
2345 void GuiDocument::dispatchParams()
2346 {
2347         // This must come first so that a language change is correctly noticed
2348         setLanguage();
2349
2350         // Apply the BufferParams. Note that this will set the base class
2351         // and then update the buffer's layout.
2352         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
2353
2354         if (!params().master.empty()) {
2355                 FileName const master_file = support::makeAbsPath(params().master,
2356                            support::onlyPath(buffer().absFileName()));
2357                 if (isLyXFilename(master_file.absFilename())) {
2358                         Buffer * master = checkAndLoadLyXFile(master_file);
2359                         const_cast<Buffer &>(buffer()).setParent(master);
2360                 }
2361         }
2362
2363         // Generate the colours requested by each new branch.
2364         BranchList & branchlist = params().branchlist();
2365         if (!branchlist.empty()) {
2366                 BranchList::const_iterator it = branchlist.begin();
2367                 BranchList::const_iterator const end = branchlist.end();
2368                 for (; it != end; ++it) {
2369                         docstring const & current_branch = it->branch();
2370                         Branch const * branch = branchlist.find(current_branch);
2371                         string const x11hexname = X11hexname(branch->color());
2372                         // display the new color
2373                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
2374                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
2375                 }
2376
2377                 // Open insets of selected branches, close deselected ones
2378                 dispatch(FuncRequest(LFUN_ALL_INSETS_TOGGLE,
2379                         "assign branch"));
2380         }
2381         // FIXME: If we used an LFUN, we would not need those two lines:
2382         BufferView * bv = const_cast<BufferView *>(bufferview());
2383         bv->processUpdateFlags(Update::Force | Update::FitCursor);
2384 }
2385
2386
2387 void GuiDocument::setLanguage() const
2388 {
2389         Language const * const newL = bp_.language;
2390         if (buffer().params().language == newL)
2391                 return;
2392
2393         string const & lang_name = newL->lang();
2394         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
2395 }
2396
2397
2398 void GuiDocument::saveAsDefault() const
2399 {
2400         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
2401 }
2402
2403
2404 bool GuiDocument::isFontAvailable(string const & font) const
2405 {
2406         if (font == "default" || font == "cmr"
2407             || font == "cmss" || font == "cmtt")
2408                 // these are standard
2409                 return true;
2410         if (font == "lmodern" || font == "lmss" || font == "lmtt")
2411                 return LaTeXFeatures::isAvailable("lmodern");
2412         if (font == "times" || font == "palatino"
2413                  || font == "helvet" || font == "courier")
2414                 return LaTeXFeatures::isAvailable("psnfss");
2415         if (font == "cmbr" || font == "cmtl")
2416                 return LaTeXFeatures::isAvailable("cmbright");
2417         if (font == "utopia")
2418                 return LaTeXFeatures::isAvailable("utopia")
2419                         || LaTeXFeatures::isAvailable("fourier");
2420         if (font == "beraserif" || font == "berasans"
2421                 || font == "beramono")
2422                 return LaTeXFeatures::isAvailable("bera");
2423         return LaTeXFeatures::isAvailable(font);
2424 }
2425
2426
2427 bool GuiDocument::providesOSF(string const & font) const
2428 {
2429         if (font == "cmr")
2430                 return isFontAvailable("eco");
2431         if (font == "palatino")
2432                 return isFontAvailable("mathpazo");
2433         return false;
2434 }
2435
2436
2437 bool GuiDocument::providesSC(string const & font) const
2438 {
2439         if (font == "palatino")
2440                 return isFontAvailable("mathpazo");
2441         if (font == "utopia")
2442                 return isFontAvailable("fourier");
2443         return false;
2444 }
2445
2446
2447 bool GuiDocument::providesScale(string const & font) const
2448 {
2449         return font == "helvet" || font == "luximono"
2450                 || font == "berasans"  || font == "beramono";
2451 }
2452
2453
2454 void GuiDocument::loadModuleInfo()
2455 {
2456         moduleNames_.clear();
2457         LyXModuleList::const_iterator it  = moduleList.begin();
2458         LyXModuleList::const_iterator end = moduleList.end();
2459         for (; it != end; ++it) {
2460                 modInfoStruct m;
2461                 m.id = it->getID();
2462                 m.name = qt_(it->getName());
2463                 // this is supposed to give us the first sentence of the description
2464                 QString desc = qt_(it->getDescription());
2465                 int const pos = desc.indexOf(".");
2466                 if (pos > 0)
2467                         desc.truncate(pos + 1);
2468                 m.description = desc;
2469                 moduleNames_.push_back(m);
2470         }
2471 }
2472
2473
2474 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
2475
2476
2477 } // namespace frontend
2478 } // namespace lyx
2479
2480 #include "GuiDocument_moc.cpp"