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