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