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