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