]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiDocument.cpp
This commit adds some new functionality to the modules stuff. In particular, it intro...
[lyx.git] / src / frontends / qt4 / GuiDocument.cpp
1 /**
2  * \file GuiDocument.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Edwin Leuven
7  * \author Richard Heck (modules)
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "GuiDocument.h"
15
16 #include "BranchList.h"
17 #include "buffer_funcs.h"
18 #include "Buffer.h"
19 #include "BufferParams.h"
20 #include "BufferView.h"
21 #include "Color.h"
22 #include "EmbeddedFiles.h"
23 #include "Encoding.h"
24 #include "FloatPlacement.h"
25 #include "FuncRequest.h"
26 #include "support/gettext.h"
27 #include "GuiBranches.h"
28 #include "Language.h"
29 #include "LaTeXFeatures.h"
30 #include "LaTeXHighlighter.h"
31 #include "Layout.h"
32 #include "LengthCombo.h"
33 #include "LyXRC.h" // defaultUnit
34 #include "ModuleList.h"
35 #include "OutputParams.h"
36 #include "PanelStack.h"
37 #include "PDFOptions.h"
38 #include "qt_helpers.h"
39 #include "Spacing.h"
40 #include "TextClassList.h"
41 #include "Validator.h"
42
43 #include "insets/InsetListingsParams.h"
44
45 #include "support/FileName.h"
46 #include "support/filetools.h"
47 #include "support/lstrings.h"
48
49 #include <boost/bind.hpp>
50
51 #include <QCloseEvent>
52 #include <QScrollBar>
53 #include <QTextCursor>
54
55 #include <algorithm>
56 #include <sstream>
57
58 using namespace std;
59 using namespace lyx::support;
60
61 ///
62 template<class Pair>
63 vector<typename Pair::second_type> const
64 getSecond(vector<Pair> const & pr)
65 {
66          vector<typename Pair::second_type> tmp(pr.size());
67          transform(pr.begin(), pr.end(), tmp.begin(),
68                                          boost::bind(&Pair::second, _1));
69          return tmp;
70 }
71
72 char const * const tex_graphics[] =
73 {
74         "default", "dvips", "dvitops", "emtex",
75         "ln", "oztex", "textures", "none", ""
76 };
77
78
79 char const * const tex_graphics_gui[] =
80 {
81         N_("Default"), "Dvips", "DVItoPS", "EmTeX",
82         "LN", "OzTeX", "Textures", N_("None"), ""
83 };
84
85
86 char const * const tex_fonts_roman[] =
87 {
88         "default", "cmr", "lmodern", "ae", "times", "palatino",
89         "charter", "newcent", "bookman", "utopia", "beraserif",
90         "ccfonts", "chancery", ""
91 };
92
93
94 char const * tex_fonts_roman_gui[] =
95 {
96         N_("Default"), N_("Computer Modern Roman"), N_("Latin Modern Roman"),
97         N_("AE (Almost European)"), N_("Times Roman"), N_("Palatino"),
98         N_("Bitstream Charter"), N_("New Century Schoolbook"), N_("Bookman"),
99         N_("Utopia"),  N_("Bera Serif"), N_("Concrete Roman"), N_("Zapf Chancery"),
100         ""
101 };
102
103
104 char const * const tex_fonts_sans[] =
105 {
106         "default", "cmss", "lmss", "helvet", "avant", "berasans", "cmbr", ""
107 };
108
109
110 char const * tex_fonts_sans_gui[] =
111 {
112         N_("Default"), N_("Computer Modern Sans"), N_("Latin Modern Sans"),
113         N_("Helvetica"), N_("Avant Garde"), N_("Bera Sans"), N_("CM Bright"), ""
114 };
115
116
117 char const * const tex_fonts_monospaced[] =
118 {
119         "default", "cmtt", "lmtt", "courier", "beramono", "luximono", "cmtl", ""
120 };
121
122
123 char const * tex_fonts_monospaced_gui[] =
124 {
125         N_("Default"), N_("Computer Modern Typewriter"),
126         N_("Latin Modern Typewriter"), N_("Courier"), N_("Bera Mono"),
127         N_("LuxiMono"), N_("CM Typewriter Light"), ""
128 };
129
130
131 vector<pair<string, lyx::docstring> > pagestyles;
132
133
134 namespace lyx {
135 namespace frontend {
136
137 namespace {
138         vector<string> getRequiredList(string const & modName) 
139         {
140                 LyXModule const * const mod = moduleList[modName];
141                 if (!mod)
142                         return vector<string>(); //empty such thing
143                 return mod->getRequiredModules();
144         }
145
146
147         vector<string> getExcludedList(string const & modName)
148         {
149                 LyXModule const * const mod = moduleList[modName];
150                 if (!mod)
151                         return vector<string>(); //empty such thing
152                 return mod->getExcludedModules();
153         }
154
155
156         docstring getModuleDescription(string const & modName)
157         {
158                 LyXModule const * const mod = moduleList[modName];
159                 if (!mod)
160                         return _("Module not found!");
161                 return from_ascii(mod->getDescription());
162         }
163
164
165         vector<string> getPackageList(string const & modName)
166         {
167                 LyXModule const * const mod = moduleList[modName];
168                 if (!mod)
169                         return vector<string>(); //empty such thing
170                 return mod->getPackageList();
171         }
172
173
174         bool isModuleAvailable(string const & modName)
175         {
176                 LyXModule * mod = moduleList[modName];
177                 if (!mod)
178                         return false;
179                 return mod->isAvailable();
180         }
181 } //anonymous namespace
182
183
184 ModuleSelMan::ModuleSelMan(
185         QListView * availableLV, 
186         QListView * selectedLV,
187         QPushButton * addPB, 
188         QPushButton * delPB, 
189         QPushButton * upPB, 
190         QPushButton * downPB,
191         QStringListModel * availableModel,
192         QStringListModel * selectedModel) :
193 GuiSelectionManager(availableLV, selectedLV, addPB, delPB,
194                     upPB, downPB, availableModel, selectedModel) 
195 {}
196         
197         
198 void ModuleSelMan::updateAddPB() 
199 {
200         int const arows = availableLV->model()->rowCount();
201         QModelIndexList const availSels = 
202                         availableLV->selectionModel()->selectedIndexes();
203         if (arows == 0 || availSels.isEmpty()  || isSelected(availSels.first())) {
204                 addPB->setEnabled(false);
205                 return;
206         }
207         
208         QModelIndex const & idx = availableLV->selectionModel()->currentIndex();
209         string const modName = fromqstr(idx.data().toString());
210         vector<string> reqs = getRequiredList(modName);
211         vector<string> excl = getExcludedList(modName);
212         
213         if (reqs.empty() && excl.empty()) {
214                 addPB->setEnabled(true);
215                 return;
216         }
217
218         QStringList const & qsl = selectedModel->stringList();
219         
220         //Check whether some required module is available
221         if (!reqs.empty()) {
222                 bool foundOne = false;
223                 vector<string>::const_iterator it  = reqs.begin();
224                 vector<string>::const_iterator end = reqs.end();
225                 for (; it != end; ++it) {
226                         if (qsl.contains(toqstr(*it))) {
227                                 foundOne = true;
228                                 break;
229                         }
230                 }
231                 if (!foundOne) {
232                         addPB->setEnabled(false);
233                         return;
234                 }
235         }
236         
237         //Check whether any excluded module is being used
238         if (!excl.empty()) {
239                 vector<string>::const_iterator it  = excl.begin();
240                 vector<string>::const_iterator end = excl.end();
241                 for (; it != end; ++it) {
242                         if (qsl.contains(toqstr(*it))) {
243                                 addPB->setEnabled(false);
244                                 return;
245                         }
246                 }
247         }
248
249         addPB->setEnabled(true);
250 }
251
252
253 /////////////////////////////////////////////////////////////////////
254 //
255 // PreambleModule
256 //
257 /////////////////////////////////////////////////////////////////////
258
259 PreambleModule::PreambleModule(): current_id_(0)
260 {
261         // This is not a memory leak. The object will be destroyed
262         // with this.
263         (void) new LaTeXHighlighter(preambleTE->document());
264         setFocusProxy(preambleTE);
265         connect(preambleTE, SIGNAL(textChanged()), this, SIGNAL(changed()));
266 }
267
268
269 void PreambleModule::update(BufferParams const & params, BufferId id)
270 {
271         QString preamble = toqstr(params.preamble);
272         // Nothing to do if the params and preamble are unchanged.
273         if (id == current_id_
274                 && preamble == preambleTE->document()->toPlainText())
275                 return;
276
277         QTextCursor cur = preambleTE->textCursor();
278         // Save the coords before switching to the new one.
279         preamble_coords_[current_id_] =
280                 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
281
282         // Save the params address for further use.
283         current_id_ = id;
284         preambleTE->document()->setPlainText(preamble);
285         Coords::const_iterator it = preamble_coords_.find(current_id_);
286         if (it == preamble_coords_.end())
287                 // First time we open this one.
288                 preamble_coords_[current_id_] = make_pair(0,0);
289         else {
290                 // Restore saved coords.
291                 QTextCursor cur = preambleTE->textCursor();
292                 cur.setPosition(it->second.first);
293                 preambleTE->setTextCursor(cur);
294                 preambleTE->verticalScrollBar()->setValue(it->second.second);
295         }
296 }
297
298
299 void PreambleModule::apply(BufferParams & params)
300 {
301         params.preamble = fromqstr(preambleTE->document()->toPlainText());
302 }
303
304
305 void PreambleModule::closeEvent(QCloseEvent * e)
306 {
307         // Save the coords before closing.
308         QTextCursor cur = preambleTE->textCursor();
309         preamble_coords_[current_id_] =
310                 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
311         e->accept();
312 }
313
314
315 /////////////////////////////////////////////////////////////////////
316 //
317 // DocumentDialog
318 //
319 /////////////////////////////////////////////////////////////////////
320
321
322
323 GuiDocument::GuiDocument(GuiView & lv)
324         : GuiDialog(lv, "document")
325 {
326         setupUi(this);
327         setViewTitle(_("Document Settings"));
328
329         lang_ = getSecond(getLanguageData(false));
330
331         connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
332         connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
333         connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
334         connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore()));
335
336         connect(savePB, SIGNAL(clicked()), this, SLOT(saveDefaultClicked()));
337         connect(defaultPB, SIGNAL(clicked()), this, SLOT(useDefaultsClicked()));
338
339         // Manage the restore, ok, apply, restore and cancel/close buttons
340         bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
341         bc().setOK(okPB);
342         bc().setApply(applyPB);
343         bc().setCancel(closePB);
344         bc().setRestore(restorePB);
345
346         textLayoutModule = new UiWidget<Ui::TextLayoutUi>;
347         // text layout
348         connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
349                 this, SLOT(change_adaptor()));
350         connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
351                 this, SLOT(setLSpacing(int)));
352         connect(textLayoutModule->lspacingLE, SIGNAL(textChanged(const QString&)),
353                 this, SLOT(change_adaptor()));
354         connect(textLayoutModule->skipRB, SIGNAL(clicked()),
355                 this, SLOT(change_adaptor()));
356         connect(textLayoutModule->indentRB, SIGNAL(clicked()),
357                 this, SLOT(change_adaptor()));
358         connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
359                 this, SLOT(change_adaptor()));
360         connect(textLayoutModule->skipLE, SIGNAL(textChanged(const QString &)),
361                 this, SLOT(change_adaptor()));
362         connect(textLayoutModule->skipLengthCO, SIGNAL(activated(int)),
363                 this, SLOT(change_adaptor()));
364         connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
365                 this, SLOT(setSkip(int)));
366         connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
367                 this, SLOT(enableSkip(bool)));
368         connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
369                 this, SLOT(change_adaptor()));
370         connect(textLayoutModule->listingsED, SIGNAL(textChanged()),
371                 this, SLOT(change_adaptor()));
372         connect(textLayoutModule->bypassCB, SIGNAL(clicked()), 
373                 this, SLOT(change_adaptor()));
374         connect(textLayoutModule->bypassCB, SIGNAL(clicked()), 
375                 this, SLOT(set_listings_msg()));
376         connect(textLayoutModule->listingsED, SIGNAL(textChanged()),
377                 this, SLOT(set_listings_msg()));
378         textLayoutModule->listingsTB->setPlainText(
379                 qt_("Input listings parameters on the right. Enter ? for a list of parameters."));
380         textLayoutModule->lspacingLE->setValidator(new QDoubleValidator(
381                 textLayoutModule->lspacingLE));
382         textLayoutModule->skipLE->setValidator(unsignedLengthValidator(
383                 textLayoutModule->skipLE));
384
385         textLayoutModule->skipCO->addItem(qt_("SmallSkip"));
386         textLayoutModule->skipCO->addItem(qt_("MedSkip"));
387         textLayoutModule->skipCO->addItem(qt_("BigSkip"));
388         textLayoutModule->skipCO->addItem(qt_("Length"));
389         // remove the %-items from the unit choice
390         textLayoutModule->skipLengthCO->noPercents();
391         textLayoutModule->lspacingCO->insertItem(
392                 Spacing::Single, qt_("Single"));
393         textLayoutModule->lspacingCO->insertItem(
394                 Spacing::Onehalf, qt_("OneHalf"));
395         textLayoutModule->lspacingCO->insertItem(
396                 Spacing::Double, qt_("Double"));
397         textLayoutModule->lspacingCO->insertItem(
398                 Spacing::Other, qt_("Custom"));
399
400         // initialize the length validator
401         bc().addCheckedLineEdit(textLayoutModule->skipLE);
402
403         fontModule = new UiWidget<Ui::FontUi>;
404         // fonts
405         connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
406                 this, SLOT(change_adaptor()));
407         connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
408                 this, SLOT(romanChanged(int)));
409         connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
410                 this, SLOT(change_adaptor()));
411         connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
412                 this, SLOT(sansChanged(int)));
413         connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
414                 this, SLOT(change_adaptor()));
415         connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
416                 this, SLOT(ttChanged(int)));
417         connect(fontModule->fontsDefaultCO, SIGNAL(activated(int)),
418                 this, SLOT(change_adaptor()));
419         connect(fontModule->fontsizeCO, SIGNAL(activated(int)),
420                 this, SLOT(change_adaptor()));
421         connect(fontModule->scaleSansSB, SIGNAL(valueChanged(int)),
422                 this, SLOT(change_adaptor()));
423         connect(fontModule->scaleTypewriterSB, SIGNAL(valueChanged(int)),
424                 this, SLOT(change_adaptor()));
425         connect(fontModule->fontScCB, SIGNAL(clicked()),
426                 this, SLOT(change_adaptor()));
427         connect(fontModule->fontOsfCB, SIGNAL(clicked()),
428                 this, SLOT(change_adaptor()));
429
430         for (int n = 0; tex_fonts_roman[n][0]; ++n) {
431                 QString font = qt_(tex_fonts_roman_gui[n]);
432                 if (!isFontAvailable(tex_fonts_roman[n]))
433                         font += qt_(" (not installed)");
434                 fontModule->fontsRomanCO->addItem(font);
435         }
436         for (int n = 0; tex_fonts_sans[n][0]; ++n) {
437                 QString font = qt_(tex_fonts_sans_gui[n]);
438                 if (!isFontAvailable(tex_fonts_sans[n]))
439                         font += qt_(" (not installed)");
440                 fontModule->fontsSansCO->addItem(font);
441         }
442         for (int n = 0; tex_fonts_monospaced[n][0]; ++n) {
443                 QString font = qt_(tex_fonts_monospaced_gui[n]);
444                 if (!isFontAvailable(tex_fonts_monospaced[n]))
445                         font += qt_(" (not installed)");
446                 fontModule->fontsTypewriterCO->addItem(font);
447         }
448
449         fontModule->fontsizeCO->addItem(qt_("Default"));
450         fontModule->fontsizeCO->addItem(qt_("10"));
451         fontModule->fontsizeCO->addItem(qt_("11"));
452         fontModule->fontsizeCO->addItem(qt_("12"));
453
454         for (int n = 0; GuiDocument::fontfamilies_gui[n][0]; ++n)
455                 fontModule->fontsDefaultCO->addItem(
456                         qt_(GuiDocument::fontfamilies_gui[n]));
457
458
459         pageLayoutModule = new UiWidget<Ui::PageLayoutUi>;
460         // page layout
461         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
462                 this, SLOT(setCustomPapersize(int)));
463         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
464                 this, SLOT(setCustomPapersize(int)));
465         connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
466                 this, SLOT(portraitChanged()));
467         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
468                 this, SLOT(change_adaptor()));
469         connect(pageLayoutModule->paperheightLE, SIGNAL(textChanged(const QString &)),
470                 this, SLOT(change_adaptor()));
471         connect(pageLayoutModule->paperwidthLE, SIGNAL(textChanged(const QString &)),
472                 this, SLOT(change_adaptor()));
473         connect(pageLayoutModule->paperwidthUnitCO, SIGNAL(activated(int)),
474                 this, SLOT(change_adaptor()));
475         connect(pageLayoutModule->paperheightUnitCO, SIGNAL(activated(int)),
476                 this, SLOT(change_adaptor()));
477         connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
478                 this, SLOT(change_adaptor()));
479         connect(pageLayoutModule->landscapeRB, SIGNAL(clicked()),
480                 this, SLOT(change_adaptor()));
481         connect(pageLayoutModule->facingPagesCB, SIGNAL(clicked()),
482                 this, SLOT(change_adaptor()));
483         connect(pageLayoutModule->pagestyleCO, SIGNAL(activated(int)),
484                 this, SLOT(change_adaptor()));
485
486         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
487         pageLayoutModule->pagestyleCO->addItem(qt_("empty"));
488         pageLayoutModule->pagestyleCO->addItem(qt_("plain"));
489         pageLayoutModule->pagestyleCO->addItem(qt_("headings"));
490         pageLayoutModule->pagestyleCO->addItem(qt_("fancy"));
491         bc().addCheckedLineEdit(pageLayoutModule->paperheightLE,
492                 pageLayoutModule->paperheightL);
493         bc().addCheckedLineEdit(pageLayoutModule->paperwidthLE,
494                 pageLayoutModule->paperwidthL);
495
496         // paper
497         QComboBox * cb = pageLayoutModule->papersizeCO;
498         cb->addItem(qt_("Default"));
499         cb->addItem(qt_("Custom"));
500         cb->addItem(qt_("US letter"));
501         cb->addItem(qt_("US legal"));
502         cb->addItem(qt_("US executive"));
503         cb->addItem(qt_("A3"));
504         cb->addItem(qt_("A4"));
505         cb->addItem(qt_("A5"));
506         cb->addItem(qt_("B3"));
507         cb->addItem(qt_("B4"));
508         cb->addItem(qt_("B5"));
509         // remove the %-items from the unit choice
510         pageLayoutModule->paperwidthUnitCO->noPercents();
511         pageLayoutModule->paperheightUnitCO->noPercents();
512         pageLayoutModule->paperheightLE->setValidator(unsignedLengthValidator(
513                 pageLayoutModule->paperheightLE));
514         pageLayoutModule->paperwidthLE->setValidator(unsignedLengthValidator(
515                 pageLayoutModule->paperwidthLE));
516
517
518         marginsModule = new UiWidget<Ui::MarginsUi>;
519         // margins
520         connect(marginsModule->marginCB, SIGNAL(toggled(bool)),
521                 this, SLOT(setCustomMargins(bool)));
522         connect(marginsModule->marginCB, SIGNAL(clicked()),
523                 this, SLOT(change_adaptor()));
524         connect(marginsModule->topLE, SIGNAL(textChanged(const QString &)),
525                 this, SLOT(change_adaptor()));
526         connect(marginsModule->topUnit, SIGNAL(activated(int)),
527                 this, SLOT(change_adaptor()));
528         connect(marginsModule->bottomLE, SIGNAL(textChanged(const QString &)),
529                 this, SLOT(change_adaptor()));
530         connect(marginsModule->bottomUnit, SIGNAL(activated(int)),
531                 this, SLOT(change_adaptor()));
532         connect(marginsModule->innerLE, SIGNAL(textChanged(const QString &)),
533                 this, SLOT(change_adaptor()));
534         connect(marginsModule->innerUnit, SIGNAL(activated(int)),
535                 this, SLOT(change_adaptor()));
536         connect(marginsModule->outerLE, SIGNAL(textChanged(const QString &)),
537                 this, SLOT(change_adaptor()));
538         connect(marginsModule->outerUnit, SIGNAL(activated(int)),
539                 this, SLOT(change_adaptor()));
540         connect(marginsModule->headheightLE, SIGNAL(textChanged(const QString &)),
541                 this, SLOT(change_adaptor()));
542         connect(marginsModule->headheightUnit, SIGNAL(activated(int)),
543                 this, SLOT(change_adaptor()));
544         connect(marginsModule->headsepLE, SIGNAL(textChanged(const QString &)),
545                 this, SLOT(change_adaptor()));
546         connect(marginsModule->headsepUnit, SIGNAL(activated(int)),
547                 this, SLOT(change_adaptor()));
548         connect(marginsModule->footskipLE, SIGNAL(textChanged(const QString&)),
549                 this, SLOT(change_adaptor()));
550         connect(marginsModule->footskipUnit, SIGNAL(activated(int)),
551                 this, SLOT(change_adaptor()));
552         marginsModule->topLE->setValidator(unsignedLengthValidator(
553                 marginsModule->topLE));
554         marginsModule->bottomLE->setValidator(unsignedLengthValidator(
555                 marginsModule->bottomLE));
556         marginsModule->innerLE->setValidator(unsignedLengthValidator(
557                 marginsModule->innerLE));
558         marginsModule->outerLE->setValidator(unsignedLengthValidator(
559                 marginsModule->outerLE));
560         marginsModule->headsepLE->setValidator(unsignedLengthValidator(
561                 marginsModule->headsepLE));
562         marginsModule->headheightLE->setValidator(unsignedLengthValidator(
563                 marginsModule->headheightLE));
564         marginsModule->footskipLE->setValidator(unsignedLengthValidator(
565                 marginsModule->footskipLE));
566
567         bc().addCheckedLineEdit(marginsModule->topLE,
568                 marginsModule->topL);
569         bc().addCheckedLineEdit(marginsModule->bottomLE,
570                 marginsModule->bottomL);
571         bc().addCheckedLineEdit(marginsModule->innerLE,
572                 marginsModule->innerL);
573         bc().addCheckedLineEdit(marginsModule->outerLE,
574                 marginsModule->outerL);
575         bc().addCheckedLineEdit(marginsModule->headsepLE,
576                 marginsModule->headsepL);
577         bc().addCheckedLineEdit(marginsModule->headheightLE,
578                 marginsModule->headheightL);
579         bc().addCheckedLineEdit(marginsModule->footskipLE,
580                 marginsModule->footskipL);
581
582
583         langModule = new UiWidget<Ui::LanguageUi>;
584         // language & quote
585         connect(langModule->languageCO, SIGNAL(activated(int)),
586                 this, SLOT(change_adaptor()));
587         connect(langModule->defaultencodingRB, SIGNAL(clicked()),
588                 this, SLOT(change_adaptor()));
589         connect(langModule->otherencodingRB, SIGNAL(clicked()),
590                 this, SLOT(change_adaptor()));
591         connect(langModule->encodingCO, SIGNAL(activated(int)),
592                 this, SLOT(change_adaptor()));
593         connect(langModule->quoteStyleCO, SIGNAL(activated(int)),
594                 this, SLOT(change_adaptor()));
595         // language & quotes
596         vector<LanguagePair> const langs = getLanguageData(false);
597         vector<LanguagePair>::const_iterator lit  = langs.begin();
598         vector<LanguagePair>::const_iterator lend = langs.end();
599         for (; lit != lend; ++lit) {
600                 langModule->languageCO->addItem(toqstr(lit->first));
601         }
602
603         // Always put the default encoding in the first position.
604         // It is special because the displayed text is translated.
605         langModule->encodingCO->addItem(qt_("LaTeX default"));
606         Encodings::const_iterator it = encodings.begin();
607         Encodings::const_iterator const end = encodings.end();
608         for (; it != end; ++it)
609                 langModule->encodingCO->addItem(toqstr(it->latexName()));
610
611         langModule->quoteStyleCO->addItem(qt_("``text''"));
612         langModule->quoteStyleCO->addItem(qt_("''text''"));
613         langModule->quoteStyleCO->addItem(qt_(",,text``"));
614         langModule->quoteStyleCO->addItem(qt_(",,text''"));
615         langModule->quoteStyleCO->addItem(qt_("<<text>>"));
616         langModule->quoteStyleCO->addItem(qt_(">>text<<"));
617
618
619
620         numberingModule = new UiWidget<Ui::NumberingUi>;
621         // numbering
622         connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
623                 this, SLOT(change_adaptor()));
624         connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
625                 this, SLOT(change_adaptor()));
626         connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
627                 this, SLOT(updateNumbering()));
628         connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
629                 this, SLOT(updateNumbering()));
630         numberingModule->tocTW->setColumnCount(3);
631         numberingModule->tocTW->headerItem()->setText(0, qt_("Example"));
632         numberingModule->tocTW->headerItem()->setText(1, qt_("Numbered"));
633         numberingModule->tocTW->headerItem()->setText(2, qt_("Appears in TOC"));
634
635
636         biblioModule = new UiWidget<Ui::BiblioUi>;
637         connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
638                 biblioModule->citationStyleL, SLOT(setEnabled(bool)));
639         connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
640                 biblioModule->citeStyleCO, SLOT(setEnabled(bool)));
641         // biblio
642         connect(biblioModule->citeDefaultRB, SIGNAL(clicked()),
643                 this, SLOT(change_adaptor()));
644         connect(biblioModule->citeNatbibRB, SIGNAL(clicked()),
645                 this, SLOT(change_adaptor()));
646         connect(biblioModule->citeStyleCO, SIGNAL(activated(int)),
647                 this, SLOT(change_adaptor()));
648         connect(biblioModule->citeJurabibRB, SIGNAL(clicked()),
649                 this, SLOT(change_adaptor()));
650         connect(biblioModule->bibtopicCB, SIGNAL(clicked()),
651                 this, SLOT(change_adaptor()));
652         // biblio
653         biblioModule->citeStyleCO->addItem(qt_("Author-year"));
654         biblioModule->citeStyleCO->addItem(qt_("Numerical"));
655         biblioModule->citeStyleCO->setCurrentIndex(0);
656
657
658         mathsModule = new UiWidget<Ui::MathsUi>;
659         connect(mathsModule->amsautoCB, SIGNAL(toggled(bool)),
660                 mathsModule->amsCB, SLOT(setDisabled(bool)));
661         connect(mathsModule->esintautoCB, SIGNAL(toggled(bool)),
662                 mathsModule->esintCB, SLOT(setDisabled(bool)));
663         // maths
664         connect(mathsModule->amsCB, SIGNAL(clicked()),
665                 this, SLOT(change_adaptor()));
666         connect(mathsModule->amsautoCB, SIGNAL(clicked()),
667                 this, SLOT(change_adaptor()));
668         connect(mathsModule->esintCB, SIGNAL(clicked()),
669                 this, SLOT(change_adaptor()));
670         connect(mathsModule->esintautoCB, SIGNAL(clicked()),
671                 this, SLOT(change_adaptor()));
672
673         latexModule = new UiWidget<Ui::LaTeXUi>;
674         // latex class
675         connect(latexModule->classCO, SIGNAL(activated(int)),
676                 this, SLOT(change_adaptor()));
677         connect(latexModule->optionsLE, SIGNAL(textChanged(const QString &)),
678                 this, SLOT(change_adaptor()));
679         connect(latexModule->psdriverCO, SIGNAL(activated(int)),
680                 this, SLOT(change_adaptor()));
681         connect(latexModule->classCO, SIGNAL(activated(int)),
682                 this, SLOT(classChanged()));
683         
684         selectionManager = 
685                 new ModuleSelMan(latexModule->availableLV, latexModule->selectedLV, 
686                         latexModule->addPB, latexModule->deletePB, 
687                         latexModule->upPB, latexModule->downPB, 
688                         availableModel(), selectedModel());
689         connect(selectionManager, SIGNAL(updateHook()),
690                 this, SLOT(updateModuleInfo()));
691         connect(selectionManager, SIGNAL(updateHook()),
692                 this, SLOT(change_adaptor()));
693         
694         // postscript drivers
695         for (int n = 0; tex_graphics[n][0]; ++n) {
696                 QString enc = qt_(tex_graphics_gui[n]);
697                 latexModule->psdriverCO->addItem(enc);
698         }
699         // latex classes
700         //FIXME This seems too involved with the kernel. Some of this
701         //should be moved to the kernel---which should perhaps just
702         //give us a list of entries or something of the sort.
703         for (TextClassList::const_iterator cit = textclasslist.begin();
704              cit != textclasslist.end(); ++cit) {
705                 if (cit->isTeXClassAvailable()) {
706                         latexModule->classCO->addItem(toqstr(cit->description()));
707                 } else {
708                         docstring item =
709                                 bformat(_("Unavailable: %1$s"), from_utf8(cit->description()));
710                         latexModule->classCO->addItem(toqstr(item));
711                 }
712         }
713
714         // branches
715         branchesModule = new GuiBranches;
716         connect(branchesModule, SIGNAL(changed()),
717                 this, SLOT(change_adaptor()));
718
719         // preamble
720         preambleModule = new PreambleModule;
721         connect(preambleModule, SIGNAL(changed()),
722                 this, SLOT(change_adaptor()));
723
724         // bullets
725         bulletsModule = new BulletsModule;
726         connect(bulletsModule, SIGNAL(changed()),
727                 this, SLOT(change_adaptor()));
728
729         // embedded files
730         embeddedFilesModule = new UiWidget<Ui::EmbeddedFilesUi>;
731         connect(embeddedFilesModule->bundleCB, SIGNAL(toggled(bool)),
732                 this, SLOT(change_adaptor()));
733         connect(embeddedFilesModule->addPB, SIGNAL(clicked()),
734                 this, SLOT(change_adaptor()));
735         connect(embeddedFilesModule->removePB, SIGNAL(clicked()),
736                 this, SLOT(change_adaptor()));
737
738         // PDF support
739         pdfSupportModule = new UiWidget<Ui::PDFSupportUi>;
740
741         connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
742                 this, SLOT(change_adaptor()));
743         connect(pdfSupportModule->titleLE, SIGNAL(textChanged(const QString &)),
744                 this, SLOT(change_adaptor()));
745         connect(pdfSupportModule->authorLE, SIGNAL(textChanged(const QString &)),
746                 this, SLOT(change_adaptor()));
747         connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(const QString &)),
748                 this, SLOT(change_adaptor()));
749         connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(const QString &)),
750                 this, SLOT(change_adaptor()));
751         connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
752                 this, SLOT(change_adaptor()));
753         connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
754                 this, SLOT(change_adaptor()));
755         connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
756                 this, SLOT(change_adaptor()));
757         connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
758                 this, SLOT(change_adaptor()));
759         connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
760                 this, SLOT(change_adaptor()));
761         connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
762                 this, SLOT(change_adaptor()));
763         connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
764                 this, SLOT(change_adaptor()));
765         connect(pdfSupportModule->backrefCB, SIGNAL(toggled(bool)),
766                 this, SLOT(change_adaptor()));
767         connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
768                 this, SLOT(change_adaptor()));
769         connect(pdfSupportModule->pagebackrefCB, SIGNAL(toggled(bool)),
770                 this, SLOT(change_adaptor()));
771         connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
772                 this, SLOT(change_adaptor()));
773         connect(pdfSupportModule->optionsLE, SIGNAL(textChanged(const QString &)),
774                 this, SLOT(change_adaptor()));
775
776         // float
777         floatModule = new FloatPlacement;
778         connect(floatModule, SIGNAL(changed()),
779                 this, SLOT(change_adaptor()));
780
781         docPS->addPanel(latexModule, _("Document Class"));
782         docPS->addPanel(fontModule, _("Fonts"));
783         docPS->addPanel(textLayoutModule, _("Text Layout"));
784         docPS->addPanel(pageLayoutModule, _("Page Layout"));
785         docPS->addPanel(marginsModule, _("Page Margins"));
786         docPS->addPanel(langModule, _("Language"));
787         docPS->addPanel(numberingModule, _("Numbering & TOC"));
788         docPS->addPanel(biblioModule, _("Bibliography"));
789         docPS->addPanel(pdfSupportModule, _("PDF Properties"));
790         docPS->addPanel(mathsModule, _("Math Options"));
791         docPS->addPanel(floatModule, _("Float Placement"));
792         docPS->addPanel(bulletsModule, _("Bullets"));
793         docPS->addPanel(branchesModule, _("Branches"));
794         docPS->addPanel(embeddedFilesModule, _("Embedded Files"));
795         docPS->addPanel(preambleModule, _("LaTeX Preamble"));
796         docPS->setCurrentPanel(_("Document Class"));
797 // FIXME: hack to work around resizing bug in Qt >= 4.2
798 // bug verified with Qt 4.2.{0-3} (JSpitzm)
799 #if QT_VERSION >= 0x040200
800         docPS->updateGeometry();
801 #endif
802 }
803
804
805 void GuiDocument::showPreamble()
806 {
807         docPS->setCurrentPanel(_("LaTeX Preamble"));
808 }
809
810
811 void GuiDocument::saveDefaultClicked()
812 {
813         saveDocDefault();
814 }
815
816
817 void GuiDocument::useDefaultsClicked()
818 {
819         useClassDefaults();
820 }
821
822
823 void GuiDocument::change_adaptor()
824 {
825         changed();
826 }
827
828
829 docstring GuiDocument::validate_listings_params()
830 {
831         // use a cache here to avoid repeated validation
832         // of the same parameters
833         static string param_cache = string();
834         static docstring msg_cache = docstring();
835         
836         if (textLayoutModule->bypassCB->isChecked())
837                 return docstring();
838
839         string params = fromqstr(textLayoutModule->listingsED->toPlainText());
840         if (params != param_cache) {
841                 param_cache = params;
842                 msg_cache = InsetListingsParams(params).validate();
843         }
844         return msg_cache;
845 }
846
847
848 void GuiDocument::set_listings_msg()
849 {
850         static bool isOK = true;
851         docstring msg = validate_listings_params();
852         if (msg.empty()) {
853                 if (isOK)
854                         return;
855                 isOK = true;
856                 // listingsTB->setTextColor("black");
857                 textLayoutModule->listingsTB->setPlainText(
858                         qt_("Input listings parameters on the right. Enter ? for a list of parameters."));
859         } else {
860                 isOK = false;
861                 // listingsTB->setTextColor("red");
862                 textLayoutModule->listingsTB->setPlainText(toqstr(msg));
863         }
864 }
865
866
867 void GuiDocument::closeEvent(QCloseEvent * e)
868 {
869         slotClose();
870         e->accept();
871 }
872
873
874 void GuiDocument::setLSpacing(int item)
875 {
876         textLayoutModule->lspacingLE->setEnabled(item == 3);
877 }
878
879
880 void GuiDocument::setSkip(int item)
881 {
882         bool const enable = (item == 3);
883         textLayoutModule->skipLE->setEnabled(enable);
884         textLayoutModule->skipLengthCO->setEnabled(enable);
885 }
886
887
888 void GuiDocument::enableSkip(bool skip)
889 {
890         textLayoutModule->skipCO->setEnabled(skip);
891         textLayoutModule->skipLE->setEnabled(skip);
892         textLayoutModule->skipLengthCO->setEnabled(skip);
893         if (skip)
894                 setSkip(textLayoutModule->skipCO->currentIndex());
895 }
896
897 void GuiDocument::portraitChanged()
898 {
899         setMargins(pageLayoutModule->papersizeCO->currentIndex());
900 }
901
902 void GuiDocument::setMargins(bool custom)
903 {
904         marginsModule->marginCB->setChecked(custom);
905         setCustomMargins(custom);
906 }
907
908
909 void GuiDocument::setCustomPapersize(int papersize)
910 {
911         bool const custom = (papersize == 1);
912
913         pageLayoutModule->paperwidthL->setEnabled(custom);
914         pageLayoutModule->paperwidthLE->setEnabled(custom);
915         pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
916         pageLayoutModule->paperheightL->setEnabled(custom);
917         pageLayoutModule->paperheightLE->setEnabled(custom);
918         pageLayoutModule->paperheightLE->setFocus();
919         pageLayoutModule->paperheightUnitCO->setEnabled(custom);
920 }
921
922
923 void GuiDocument::setCustomMargins(bool custom)
924 {
925         marginsModule->topL->setEnabled(!custom);
926         marginsModule->topLE->setEnabled(!custom);
927         marginsModule->topUnit->setEnabled(!custom);
928
929         marginsModule->bottomL->setEnabled(!custom);
930         marginsModule->bottomLE->setEnabled(!custom);
931         marginsModule->bottomUnit->setEnabled(!custom);
932
933         marginsModule->innerL->setEnabled(!custom);
934         marginsModule->innerLE->setEnabled(!custom);
935         marginsModule->innerUnit->setEnabled(!custom);
936
937         marginsModule->outerL->setEnabled(!custom);
938         marginsModule->outerLE->setEnabled(!custom);
939         marginsModule->outerUnit->setEnabled(!custom);
940
941         marginsModule->headheightL->setEnabled(!custom);
942         marginsModule->headheightLE->setEnabled(!custom);
943         marginsModule->headheightUnit->setEnabled(!custom);
944
945         marginsModule->headsepL->setEnabled(!custom);
946         marginsModule->headsepLE->setEnabled(!custom);
947         marginsModule->headsepUnit->setEnabled(!custom);
948
949         marginsModule->footskipL->setEnabled(!custom);
950         marginsModule->footskipLE->setEnabled(!custom);
951         marginsModule->footskipUnit->setEnabled(!custom);
952 }
953
954
955 void GuiDocument::updateFontsize(string const & items, string const & sel)
956 {
957         fontModule->fontsizeCO->clear();
958         fontModule->fontsizeCO->addItem(qt_("Default"));
959
960         for (int n = 0; !token(items,'|',n).empty(); ++n)
961                 fontModule->fontsizeCO->
962                         addItem(toqstr(token(items,'|',n)));
963
964         for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
965                 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
966                         fontModule->fontsizeCO->setCurrentIndex(n);
967                         break;
968                 }
969         }
970 }
971
972
973 void GuiDocument::romanChanged(int item)
974 {
975         string const font = tex_fonts_roman[item];
976         fontModule->fontScCB->setEnabled(providesSC(font));
977         fontModule->fontOsfCB->setEnabled(providesOSF(font));
978 }
979
980
981 void GuiDocument::sansChanged(int item)
982 {
983         string const font = tex_fonts_sans[item];
984         bool scaleable = providesScale(font);
985         fontModule->scaleSansSB->setEnabled(scaleable);
986         fontModule->scaleSansLA->setEnabled(scaleable);
987 }
988
989
990 void GuiDocument::ttChanged(int item)
991 {
992         string const font = tex_fonts_monospaced[item];
993         bool scaleable = providesScale(font);
994         fontModule->scaleTypewriterSB->setEnabled(scaleable);
995         fontModule->scaleTypewriterLA->setEnabled(scaleable);
996 }
997
998
999 void GuiDocument::updatePagestyle(string const & items, string const & sel)
1000 {
1001         pagestyles.clear();
1002         pageLayoutModule->pagestyleCO->clear();
1003         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1004
1005         for (int n = 0; !token(items,'|',n).empty(); ++n) {
1006                 string style = token(items, '|', n);
1007                 docstring style_gui = _(style);
1008                 pagestyles.push_back(pair<string, docstring>(style, style_gui));
1009                 pageLayoutModule->pagestyleCO->addItem(toqstr(style_gui));
1010         }
1011
1012         if (sel == "default") {
1013                 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
1014                 return;
1015         }
1016
1017         int nn = 0;
1018
1019         for (size_t i = 0; i < pagestyles.size(); ++i)
1020                 if (pagestyles[i].first == sel)
1021                         nn = pageLayoutModule->pagestyleCO->findText(
1022                                         toqstr(pagestyles[i].second));
1023
1024         if (nn > 0)
1025                 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
1026 }
1027
1028
1029 void GuiDocument::classChanged()
1030 {
1031         textclass_type const tc = latexModule->classCO->currentIndex();
1032         bp_.setBaseClass(tc);
1033         if (lyxrc.auto_reset_options)
1034                 bp_.useClassDefaults();
1035         updateContents();
1036 }
1037
1038
1039 namespace {
1040         //This is an insanely complicated attempt to make this sort of thing
1041         //work with RTL languages.
1042         docstring formatStrVec(vector<string> const & v, docstring const & s) 
1043         {
1044                 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
1045                 int const vSize = v.size();
1046                 if (v.size() == 0)
1047                         return docstring();
1048                 else if (v.size() == 1) 
1049                         return from_ascii(v[0]);
1050                 else if (v.size() == 2) {
1051                         docstring retval = _("%1$s and %2$s");
1052                         retval = subst(retval, _("and"), s);
1053                         return bformat(retval, from_ascii(v[0]), from_ascii(v[1]));
1054                 }
1055                 //The idea here is to format all but the last two items...
1056                 docstring t2 = _("%1$s, %2$s");
1057                 docstring retval = from_ascii(v[0]);
1058                 for (int i = 1; i < vSize - 2; ++i)
1059                         retval = bformat(t2, retval, from_ascii(v[i])); 
1060                 //...and then to  plug them, and the last two, into this schema
1061                 docstring t = _("%1$s, %2$s, and %3$s");
1062                 t = subst(t, _("and"), s);
1063                 return bformat(t, retval, from_ascii(v[vSize - 2]), from_ascii(v[vSize - 1]));
1064         }
1065 }
1066
1067
1068 void GuiDocument::updateModuleInfo()
1069 {
1070         selectionManager->update();
1071         //Module description
1072         QListView const * const lv = selectionManager->selectedFocused() ?
1073                                      latexModule->selectedLV :
1074                                      latexModule->availableLV;
1075         if (lv->selectionModel()->selectedIndexes().isEmpty())
1076                 latexModule->infoML->document()->clear();
1077         else {
1078                 QModelIndex const & idx = lv->selectionModel()->currentIndex();
1079                 string const modName = fromqstr(idx.data().toString());
1080                 docstring desc = getModuleDescription(modName);
1081
1082                 vector<string> pkgList = getPackageList(modName);
1083                 docstring pkgdesc = formatStrVec(pkgList, _("and"));
1084                 if (!pkgdesc.empty()) {
1085                         if (!desc.empty())
1086                                 desc += "\n";
1087                         desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
1088                 }
1089
1090                 pkgList = getRequiredList(modName);
1091                 pkgdesc = formatStrVec(pkgList, _("or"));
1092                 if (!pkgdesc.empty()) {
1093                         if (!desc.empty())
1094                                 desc += "\n";
1095                         desc += bformat(_("Module required: %1$s."), pkgdesc);
1096                 }
1097
1098                 pkgList = getExcludedList(modName);
1099                 pkgdesc = formatStrVec(pkgList, _( "and"));
1100                 if (!pkgdesc.empty()) {
1101                         if (!desc.empty())
1102                                 desc += "\n";
1103                         desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
1104                 }
1105
1106                 if (!isModuleAvailable(modName)) {
1107                         if (!desc.empty())
1108                                 desc += "\n";
1109                         desc += _("WARNING: Some packages are unavailable!");
1110                 }
1111                 latexModule->infoML->document()->setPlainText(toqstr(desc));
1112         }
1113 }
1114
1115
1116 void GuiDocument::updateEmbeddedFileList()
1117 {
1118         embeddedFilesModule->filesLW->clear();
1119         // add current embedded files
1120         EmbeddedFileList & files = buffer().embeddedFiles();
1121         files.update(buffer());
1122         EmbeddedFileList::iterator fit = files.begin();
1123         EmbeddedFileList::iterator fit_end = files.end();
1124         for (; fit != fit_end; ++fit) {
1125                 QString label = toqstr(fit->relFilename(buffer().filePath()));
1126                 if (fit->refCount() > 1)
1127                         label += " (" + QString::number(fit->refCount()) + ")";
1128                 QListWidgetItem * item = new QListWidgetItem(label);
1129                 item->setFlags(item->flags() | Qt::ItemIsSelectable
1130                         | Qt::ItemIsUserCheckable);
1131                 if(fit->embedded())
1132                         item->setCheckState(Qt::Checked);
1133                 else
1134                         item->setCheckState(Qt::Unchecked);
1135                 // index of the currently used ParConstIterator
1136                 embeddedFilesModule->filesLW->addItem(item);
1137         }
1138 }
1139
1140
1141 void GuiDocument::updateNumbering()
1142 {
1143         TextClass const & tclass = bp_.getTextClass();
1144
1145         numberingModule->tocTW->setUpdatesEnabled(false);
1146         numberingModule->tocTW->clear();
1147
1148         int const depth = numberingModule->depthSL->value();
1149         int const toc = numberingModule->tocSL->value();
1150         QString const no = qt_("No");
1151         QString const yes = qt_("Yes");
1152         TextClass::const_iterator end = tclass.end();
1153         TextClass::const_iterator cit = tclass.begin();
1154         QTreeWidgetItem * item = 0;
1155         for ( ; cit != end ; ++cit) {
1156                 int const toclevel = (*cit)->toclevel;
1157                 if (toclevel != Layout::NOT_IN_TOC
1158                     && (*cit)->labeltype == LABEL_COUNTER) {
1159                         item = new QTreeWidgetItem(numberingModule->tocTW);
1160                         item->setText(0, toqstr(translateIfPossible((*cit)->name())));
1161                         item->setText(1, (toclevel <= depth) ? yes : no);
1162                         item->setText(2, (toclevel <= toc) ? yes : no);
1163                 }
1164         }
1165
1166         numberingModule->tocTW->setUpdatesEnabled(true);
1167         numberingModule->tocTW->update();
1168 }
1169
1170
1171 void GuiDocument::apply(BufferParams & params)
1172 {
1173         // preamble
1174         preambleModule->apply(params);
1175
1176         // biblio
1177         params.setCiteEngine(biblio::ENGINE_BASIC);
1178
1179         if (biblioModule->citeNatbibRB->isChecked()) {
1180                 bool const use_numerical_citations =
1181                         biblioModule->citeStyleCO->currentIndex();
1182                 if (use_numerical_citations)
1183                         params.setCiteEngine(biblio::ENGINE_NATBIB_NUMERICAL);
1184                 else
1185                         params.setCiteEngine(biblio::ENGINE_NATBIB_AUTHORYEAR);
1186
1187         } else if (biblioModule->citeJurabibRB->isChecked())
1188                 params.setCiteEngine(biblio::ENGINE_JURABIB);
1189
1190         params.use_bibtopic =
1191                 biblioModule->bibtopicCB->isChecked();
1192
1193         // language & quotes
1194         if (langModule->defaultencodingRB->isChecked()) {
1195                 params.inputenc = "auto";
1196         } else {
1197                 int i = langModule->encodingCO->currentIndex();
1198                 if (i == 0)
1199                         params.inputenc = "default";
1200                 else
1201                         params.inputenc =
1202                                 fromqstr(langModule->encodingCO->currentText());
1203         }
1204
1205         InsetQuotes::quote_language lga = InsetQuotes::EnglishQ;
1206         switch (langModule->quoteStyleCO->currentIndex()) {
1207         case 0:
1208                 lga = InsetQuotes::EnglishQ;
1209                 break;
1210         case 1:
1211                 lga = InsetQuotes::SwedishQ;
1212                 break;
1213         case 2:
1214                 lga = InsetQuotes::GermanQ;
1215                 break;
1216         case 3:
1217                 lga = InsetQuotes::PolishQ;
1218                 break;
1219         case 4:
1220                 lga = InsetQuotes::FrenchQ;
1221                 break;
1222         case 5:
1223                 lga = InsetQuotes::DanishQ;
1224                 break;
1225         }
1226         params.quotes_language = lga;
1227
1228         int const pos = langModule->languageCO->currentIndex();
1229         params.language = lyx::languages.getLanguage(lang_[pos]);
1230
1231         // numbering
1232         if (params.getTextClass().hasTocLevels()) {
1233                 params.tocdepth = numberingModule->tocSL->value();
1234                 params.secnumdepth = numberingModule->depthSL->value();
1235         }
1236
1237         // bullets
1238         params.user_defined_bullet(0) = bulletsModule->getBullet(0);
1239         params.user_defined_bullet(1) = bulletsModule->getBullet(1);
1240         params.user_defined_bullet(2) = bulletsModule->getBullet(2);
1241         params.user_defined_bullet(3) = bulletsModule->getBullet(3);
1242
1243         // packages
1244         params.graphicsDriver =
1245                 tex_graphics[latexModule->psdriverCO->currentIndex()];
1246         
1247         // text layout
1248         params.setBaseClass(latexModule->classCO->currentIndex());
1249
1250         // Modules
1251         params.clearLayoutModules();
1252         QStringList const selMods = selectedModel()->stringList();
1253         for (int i = 0; i != selMods.size(); ++i)
1254                 params.addLayoutModule(lyx::fromqstr(selMods[i]));
1255
1256         if (mathsModule->amsautoCB->isChecked()) {
1257                 params.use_amsmath = BufferParams::package_auto;
1258         } else {
1259                 if (mathsModule->amsCB->isChecked())
1260                         params.use_amsmath = BufferParams::package_on;
1261                 else
1262                         params.use_amsmath = BufferParams::package_off;
1263         }
1264
1265         if (mathsModule->esintautoCB->isChecked())
1266                 params.use_esint = BufferParams::package_auto;
1267         else {
1268                 if (mathsModule->esintCB->isChecked())
1269                         params.use_esint = BufferParams::package_on;
1270                 else
1271                         params.use_esint = BufferParams::package_off;
1272         }
1273
1274         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
1275                 params.pagestyle = "default";
1276         else {
1277                 docstring style_gui =
1278                         qstring_to_ucs4(pageLayoutModule->pagestyleCO->currentText());
1279                 for (size_t i = 0; i < pagestyles.size(); ++i)
1280                         if (pagestyles[i].second == style_gui)
1281                                 params.pagestyle = pagestyles[i].first;
1282         }
1283
1284         switch (textLayoutModule->lspacingCO->currentIndex()) {
1285         case 0:
1286                 params.spacing().set(Spacing::Single);
1287                 break;
1288         case 1:
1289                 params.spacing().set(Spacing::Onehalf);
1290                 break;
1291         case 2:
1292                 params.spacing().set(Spacing::Double);
1293                 break;
1294         case 3:
1295                 params.spacing().set(Spacing::Other,
1296                         fromqstr(textLayoutModule->lspacingLE->text()));
1297                 break;
1298         }
1299
1300         if (textLayoutModule->twoColumnCB->isChecked())
1301                 params.columns = 2;
1302         else
1303                 params.columns = 1;
1304
1305         // text should have passed validation
1306         params.listings_params =
1307                 InsetListingsParams(fromqstr(textLayoutModule->listingsED->toPlainText())).params();
1308
1309         if (textLayoutModule->indentRB->isChecked())
1310                 params.paragraph_separation = BufferParams::PARSEP_INDENT;
1311         else
1312                 params.paragraph_separation = BufferParams::PARSEP_SKIP;
1313
1314         switch (textLayoutModule->skipCO->currentIndex()) {
1315         case 0:
1316                 params.setDefSkip(VSpace(VSpace::SMALLSKIP));
1317                 break;
1318         case 1:
1319                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
1320                 break;
1321         case 2:
1322                 params.setDefSkip(VSpace(VSpace::BIGSKIP));
1323                 break;
1324         case 3:
1325         {
1326                 VSpace vs = VSpace(
1327                         widgetsToLength(textLayoutModule->skipLE,
1328                                 textLayoutModule->skipLengthCO)
1329                         );
1330                 params.setDefSkip(vs);
1331                 break;
1332         }
1333         default:
1334                 // DocumentDefskipCB assures that this never happens
1335                 // so Assert then !!!  - jbl
1336                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
1337                 break;
1338         }
1339
1340         params.options =
1341                 fromqstr(latexModule->optionsLE->text());
1342
1343         params.float_placement = floatModule->get();
1344
1345         // fonts
1346         params.fontsRoman =
1347                 tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1348
1349         params.fontsSans =
1350                 tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1351
1352         params.fontsTypewriter =
1353                 tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1354
1355         params.fontsSansScale = fontModule->scaleSansSB->value();
1356
1357         params.fontsTypewriterScale = fontModule->scaleTypewriterSB->value();
1358
1359         params.fontsSC = fontModule->fontScCB->isChecked();
1360
1361         params.fontsOSF = fontModule->fontOsfCB->isChecked();
1362
1363         params.fontsDefaultFamily = GuiDocument::fontfamilies[
1364                 fontModule->fontsDefaultCO->currentIndex()];
1365
1366         if (fontModule->fontsizeCO->currentIndex() == 0)
1367                 params.fontsize = "default";
1368         else
1369                 params.fontsize =
1370                         fromqstr(fontModule->fontsizeCO->currentText());
1371
1372         // paper
1373         params.papersize = PAPER_SIZE(
1374                 pageLayoutModule->papersizeCO->currentIndex());
1375
1376         // custom, A3, B3 and B4 paper sizes need geometry
1377         int psize = pageLayoutModule->papersizeCO->currentIndex();
1378         bool geom_papersize = (psize == 1 || psize == 5 || psize == 8 || psize == 9);
1379
1380         params.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
1381                 pageLayoutModule->paperwidthUnitCO);
1382
1383         params.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
1384                 pageLayoutModule->paperheightUnitCO);
1385
1386         if (pageLayoutModule->facingPagesCB->isChecked())
1387                 params.sides = TwoSides;
1388         else
1389                 params.sides = OneSide;
1390
1391         if (pageLayoutModule->landscapeRB->isChecked())
1392                 params.orientation = ORIENTATION_LANDSCAPE;
1393         else
1394                 params.orientation = ORIENTATION_PORTRAIT;
1395
1396         // margins
1397         params.use_geometry =
1398                 (!marginsModule->marginCB->isChecked()
1399                 || geom_papersize);
1400
1401         Ui::MarginsUi const * m(marginsModule);
1402
1403         params.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
1404         params.topmargin = widgetsToLength(m->topLE, m->topUnit);
1405         params.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
1406         params.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
1407         params.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
1408         params.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
1409         params.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
1410
1411         branchesModule->apply(params);
1412
1413         // PDF support
1414         PDFOptions & pdf = params.pdfoptions();
1415         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
1416         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
1417         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
1418         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
1419         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
1420
1421         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
1422         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
1423         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
1424         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
1425
1426         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
1427         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
1428         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
1429         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
1430         pdf.backref = pdfSupportModule->backrefCB->isChecked();
1431         pdf.pagebackref = pdfSupportModule->pagebackrefCB->isChecked();
1432         if (pdfSupportModule->fullscreenCB->isChecked())
1433                 pdf.pagemode = pdf.pagemode_fullscreen;
1434         else
1435                 pdf.pagemode.clear();
1436         pdf.quoted_options = fromqstr(pdfSupportModule->optionsLE->text());
1437
1438         // Embedded files
1439         // FIXME
1440 }
1441
1442
1443 /** Return the position of val in the vector if found.
1444     If not found, return 0.
1445  */
1446 template<class A>
1447 static size_t findPos(vector<A> const & vec, A const & val)
1448 {
1449         typename vector<A>::const_iterator it =
1450                 find(vec.begin(), vec.end(), val);
1451         if (it == vec.end())
1452                 return 0;
1453         return distance(vec.begin(), it);
1454 }
1455
1456
1457 void GuiDocument::updateParams()
1458 {
1459         updateParams(bp_);
1460 }
1461
1462
1463 void GuiDocument::updateParams(BufferParams const & params)
1464 {
1465         // set the default unit
1466         Length::UNIT defaultUnit = Length::CM;
1467         switch (lyxrc.default_papersize) {
1468                 case PAPER_DEFAULT: break;
1469
1470                 case PAPER_USLETTER:
1471                 case PAPER_USLEGAL:
1472                 case PAPER_USEXECUTIVE:
1473                         defaultUnit = Length::IN;
1474                         break;
1475
1476                 case PAPER_A3:
1477                 case PAPER_A4:
1478                 case PAPER_A5:
1479                 case PAPER_B3:
1480                 case PAPER_B4:
1481                 case PAPER_B5:
1482                         defaultUnit = Length::CM;
1483                         break;
1484                 case PAPER_CUSTOM:
1485                         break;
1486         }
1487
1488         // preamble
1489         preambleModule->update(params, id());
1490
1491         // biblio
1492         biblioModule->citeDefaultRB->setChecked(
1493                 params.getEngine() == biblio::ENGINE_BASIC);
1494
1495         biblioModule->citeNatbibRB->setChecked(
1496                 params.getEngine() == biblio::ENGINE_NATBIB_NUMERICAL ||
1497                 params.getEngine() == biblio::ENGINE_NATBIB_AUTHORYEAR);
1498
1499         biblioModule->citeStyleCO->setCurrentIndex(
1500                 params.getEngine() == biblio::ENGINE_NATBIB_NUMERICAL);
1501
1502         biblioModule->citeJurabibRB->setChecked(
1503                 params.getEngine() == biblio::ENGINE_JURABIB);
1504
1505         biblioModule->bibtopicCB->setChecked(
1506                 params.use_bibtopic);
1507
1508         // language & quotes
1509         int const pos = int(findPos(lang_,
1510                                     params.language->lang()));
1511         langModule->languageCO->setCurrentIndex(pos);
1512
1513         langModule->quoteStyleCO->setCurrentIndex(
1514                 params.quotes_language);
1515
1516         bool default_enc = true;
1517         if (params.inputenc != "auto") {
1518                 default_enc = false;
1519                 if (params.inputenc == "default") {
1520                         langModule->encodingCO->setCurrentIndex(0);
1521                 } else {
1522                         int const i = langModule->encodingCO->findText(
1523                                         toqstr(params.inputenc));
1524                         if (i >= 0)
1525                                 langModule->encodingCO->setCurrentIndex(i);
1526                         else
1527                                 // unknown encoding. Set to default.
1528                                 default_enc = true;
1529                 }
1530         }
1531         langModule->defaultencodingRB->setChecked(default_enc);
1532         langModule->otherencodingRB->setChecked(!default_enc);
1533
1534         // numbering
1535         int const min_toclevel = textClass().min_toclevel();
1536         int const max_toclevel = textClass().max_toclevel();
1537         if (textClass().hasTocLevels()) {
1538                 numberingModule->setEnabled(true);
1539                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
1540                 numberingModule->depthSL->setMaximum(max_toclevel);
1541                 numberingModule->depthSL->setValue(params.secnumdepth);
1542                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
1543                 numberingModule->tocSL->setMaximum(max_toclevel);
1544                 numberingModule->tocSL->setValue(params.tocdepth);
1545                 updateNumbering();
1546         } else {
1547                 numberingModule->setEnabled(false);
1548                 numberingModule->tocTW->clear();
1549         }
1550
1551         // bullets
1552         bulletsModule->setBullet(0, params.user_defined_bullet(0));
1553         bulletsModule->setBullet(1, params.user_defined_bullet(1));
1554         bulletsModule->setBullet(2, params.user_defined_bullet(2));
1555         bulletsModule->setBullet(3, params.user_defined_bullet(3));
1556         bulletsModule->init();
1557
1558         // packages
1559         int nitem = findToken(tex_graphics, params.graphicsDriver);
1560         if (nitem >= 0)
1561                 latexModule->psdriverCO->setCurrentIndex(nitem);
1562         updateModuleInfo();
1563         
1564         mathsModule->amsCB->setChecked(
1565                 params.use_amsmath == BufferParams::package_on);
1566         mathsModule->amsautoCB->setChecked(
1567                 params.use_amsmath == BufferParams::package_auto);
1568
1569         mathsModule->esintCB->setChecked(
1570                 params.use_esint == BufferParams::package_on);
1571         mathsModule->esintautoCB->setChecked(
1572                 params.use_esint == BufferParams::package_auto);
1573
1574         switch (params.spacing().getSpace()) {
1575                 case Spacing::Other: nitem = 3; break;
1576                 case Spacing::Double: nitem = 2; break;
1577                 case Spacing::Onehalf: nitem = 1; break;
1578                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
1579         }
1580
1581         // text layout
1582         latexModule->classCO->setCurrentIndex(params.getBaseClass());
1583         
1584         updatePagestyle(textClass().opt_pagestyle(),
1585                                  params.pagestyle);
1586
1587         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
1588         if (params.spacing().getSpace() == Spacing::Other) {
1589                 textLayoutModule->lspacingLE->setText(
1590                         toqstr(params.spacing().getValueAsString()));
1591         }
1592         setLSpacing(nitem);
1593
1594         if (params.paragraph_separation == BufferParams::PARSEP_INDENT)
1595                 textLayoutModule->indentRB->setChecked(true);
1596         else
1597                 textLayoutModule->skipRB->setChecked(true);
1598
1599         int skip = 0;
1600         switch (params.getDefSkip().kind()) {
1601         case VSpace::SMALLSKIP:
1602                 skip = 0;
1603                 break;
1604         case VSpace::MEDSKIP:
1605                 skip = 1;
1606                 break;
1607         case VSpace::BIGSKIP:
1608                 skip = 2;
1609                 break;
1610         case VSpace::LENGTH:
1611         {
1612                 skip = 3;
1613                 string const length = params.getDefSkip().asLyXCommand();
1614                 lengthToWidgets(textLayoutModule->skipLE,
1615                         textLayoutModule->skipLengthCO,
1616                         length, defaultUnit);
1617                 break;
1618         }
1619         default:
1620                 skip = 0;
1621                 break;
1622         }
1623         textLayoutModule->skipCO->setCurrentIndex(skip);
1624         setSkip(skip);
1625
1626         textLayoutModule->twoColumnCB->setChecked(
1627                 params.columns == 2);
1628
1629         // break listings_params to multiple lines
1630         string lstparams =
1631                 InsetListingsParams(params.listings_params).separatedParams();
1632         textLayoutModule->listingsED->setPlainText(toqstr(lstparams));
1633
1634         if (!params.options.empty()) {
1635                 latexModule->optionsLE->setText(
1636                         toqstr(params.options));
1637         } else {
1638                 latexModule->optionsLE->setText(QString());
1639         }
1640
1641         floatModule->set(params.float_placement);
1642
1643         // Fonts
1644         updateFontsize(textClass().opt_fontsize(),
1645                         params.fontsize);
1646
1647         int n = findToken(tex_fonts_roman, params.fontsRoman);
1648         if (n >= 0) {
1649                 fontModule->fontsRomanCO->setCurrentIndex(n);
1650                 romanChanged(n);
1651         }
1652
1653         n = findToken(tex_fonts_sans, params.fontsSans);
1654         if (n >= 0)     {
1655                 fontModule->fontsSansCO->setCurrentIndex(n);
1656                 sansChanged(n);
1657         }
1658
1659         n = findToken(tex_fonts_monospaced, params.fontsTypewriter);
1660         if (n >= 0) {
1661                 fontModule->fontsTypewriterCO->setCurrentIndex(n);
1662                 ttChanged(n);
1663         }
1664
1665         fontModule->fontScCB->setChecked(params.fontsSC);
1666         fontModule->fontOsfCB->setChecked(params.fontsOSF);
1667         fontModule->scaleSansSB->setValue(params.fontsSansScale);
1668         fontModule->scaleTypewriterSB->setValue(params.fontsTypewriterScale);
1669         n = findToken(GuiDocument::fontfamilies, params.fontsDefaultFamily);
1670         if (n >= 0)
1671                 fontModule->fontsDefaultCO->setCurrentIndex(n);
1672
1673         // paper
1674         int const psize = params.papersize;
1675         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
1676         setCustomPapersize(psize);
1677
1678         bool const landscape =
1679                 params.orientation == ORIENTATION_LANDSCAPE;
1680         pageLayoutModule->landscapeRB->setChecked(landscape);
1681         pageLayoutModule->portraitRB->setChecked(!landscape);
1682
1683         pageLayoutModule->facingPagesCB->setChecked(
1684                 params.sides == TwoSides);
1685
1686
1687         lengthToWidgets(pageLayoutModule->paperwidthLE,
1688                 pageLayoutModule->paperwidthUnitCO, params.paperwidth, defaultUnit);
1689
1690         lengthToWidgets(pageLayoutModule->paperheightLE,
1691                 pageLayoutModule->paperheightUnitCO, params.paperheight, defaultUnit);
1692
1693         // margins
1694         Ui::MarginsUi * m = marginsModule;
1695
1696         setMargins(!params.use_geometry);
1697
1698         lengthToWidgets(m->topLE, m->topUnit,
1699                 params.topmargin, defaultUnit);
1700
1701         lengthToWidgets(m->bottomLE, m->bottomUnit,
1702                 params.bottommargin, defaultUnit);
1703
1704         lengthToWidgets(m->innerLE, m->innerUnit,
1705                 params.leftmargin, defaultUnit);
1706
1707         lengthToWidgets(m->outerLE, m->outerUnit,
1708                 params.rightmargin, defaultUnit);
1709
1710         lengthToWidgets(m->headheightLE, m->headheightUnit,
1711                 params.headheight, defaultUnit);
1712
1713         lengthToWidgets(m->headsepLE, m->headsepUnit,
1714                 params.headsep, defaultUnit);
1715
1716         lengthToWidgets(m->footskipLE, m->footskipUnit,
1717                 params.footskip, defaultUnit);
1718
1719         branchesModule->update(params);
1720
1721         // PDF support
1722         PDFOptions const & pdf = params.pdfoptions();
1723         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
1724         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
1725         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
1726         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
1727         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
1728
1729         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
1730         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
1731         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
1732
1733         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
1734
1735         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
1736         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
1737         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
1738         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
1739         pdfSupportModule->backrefCB->setChecked(pdf.backref);
1740         pdfSupportModule->pagebackrefCB->setChecked(pdf.pagebackref);
1741         pdfSupportModule->fullscreenCB->setChecked
1742                 (pdf.pagemode == pdf.pagemode_fullscreen);
1743
1744         pdfSupportModule->optionsLE->setText(
1745                 toqstr(pdf.quoted_options));
1746
1747         // embedded files
1748         updateEmbeddedFileList();
1749 }
1750
1751
1752 void GuiDocument::applyView()
1753 {
1754         apply(params());
1755 }
1756
1757
1758 void GuiDocument::saveDocDefault()
1759 {
1760         // we have to apply the params first
1761         applyView();
1762         saveAsDefault();
1763 }
1764
1765
1766 void GuiDocument::updateContents()
1767 {
1768         //update list of available modules
1769         QStringList strlist;
1770         vector<string> const modNames = getModuleNames();
1771         vector<string>::const_iterator it = modNames.begin();
1772         for (; it != modNames.end(); ++it)
1773                 strlist.push_back(toqstr(*it));
1774         available_model_.setStringList(strlist);
1775         //and selected ones, too
1776         QStringList strlist2;
1777         vector<string> const & selMods = getSelectedModules();
1778         it = selMods.begin();
1779         for (; it != selMods.end(); ++it)
1780                 strlist2.push_back(toqstr(*it));
1781         //FIXME It'd be nice to make sure here that the selected
1782         //modules are consistent: That required modules are actually
1783         //selected, and that we don't have conflicts. If so, we could
1784         //at least pop up a warning.
1785         selected_model_.setStringList(strlist2);
1786
1787         updateParams(bp_);
1788 }
1789
1790 void GuiDocument::useClassDefaults()
1791 {
1792         bp_.setBaseClass(latexModule->classCO->currentIndex());
1793         bp_.useClassDefaults();
1794         updateContents();
1795 }
1796
1797
1798 bool GuiDocument::isValid()
1799 {
1800         return validate_listings_params().empty();
1801 }
1802
1803
1804 char const * const GuiDocument::fontfamilies[5] = {
1805         "default", "rmdefault", "sfdefault", "ttdefault", ""
1806 };
1807
1808
1809 char const * GuiDocument::fontfamilies_gui[5] = {
1810         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
1811 };
1812
1813
1814 bool GuiDocument::initialiseParams(string const &)
1815 {
1816         bp_ = buffer().params();
1817         loadModuleNames();
1818         return true;
1819 }
1820
1821
1822 void GuiDocument::clearParams()
1823 {
1824         bp_ = BufferParams();
1825 }
1826
1827
1828 BufferId GuiDocument::id() const
1829 {
1830         return &buffer();
1831 }
1832
1833
1834 vector<string> const & GuiDocument::getModuleNames()
1835 {
1836         return moduleNames_;
1837 }
1838
1839
1840 vector<string> const & GuiDocument::getSelectedModules()
1841 {
1842         return params().getModules();
1843 }
1844
1845
1846 TextClass const & GuiDocument::textClass() const
1847 {
1848         return textclasslist[bp_.getBaseClass()];
1849 }
1850
1851
1852 static void dispatch_bufferparams(Dialog const & dialog,
1853         BufferParams const & bp, kb_action lfun)
1854 {
1855         ostringstream ss;
1856         ss << "\\begin_header\n";
1857         bp.writeFile(ss);
1858         ss << "\\end_header\n";
1859         dialog.dispatch(FuncRequest(lfun, ss.str()));
1860 }
1861
1862
1863 void GuiDocument::dispatchParams()
1864 {
1865         // This must come first so that a language change is correctly noticed
1866         setLanguage();
1867
1868         // Apply the BufferParams. Note that this will set the base class
1869         // and then update the buffer's layout.
1870         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
1871
1872         // Generate the colours requested by each new branch.
1873         BranchList & branchlist = params().branchlist();
1874         if (!branchlist.empty()) {
1875                 BranchList::const_iterator it = branchlist.begin();
1876                 BranchList::const_iterator const end = branchlist.end();
1877                 for (; it != end; ++it) {
1878                         docstring const & current_branch = it->getBranch();
1879                         Branch const * branch = branchlist.find(current_branch);
1880                         string const x11hexname = X11hexname(branch->getColor());
1881                         // display the new color
1882                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
1883                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
1884                 }
1885
1886                 // Open insets of selected branches, close deselected ones
1887                 dispatch(FuncRequest(LFUN_ALL_INSETS_TOGGLE,
1888                         "assign branch"));
1889         }
1890         // FIXME: If we used an LFUN, we would not need those two lines:
1891         bufferview()->processUpdateFlags(Update::Force | Update::FitCursor);
1892 }
1893
1894
1895 void GuiDocument::setLanguage() const
1896 {
1897         Language const * const newL = bp_.language;
1898         if (buffer().params().language == newL)
1899                 return;
1900
1901         string const & lang_name = newL->lang();
1902         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
1903 }
1904
1905
1906 void GuiDocument::saveAsDefault() const
1907 {
1908         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
1909 }
1910
1911
1912 bool GuiDocument::isFontAvailable(string const & font) const
1913 {
1914         if (font == "default" || font == "cmr"
1915             || font == "cmss" || font == "cmtt")
1916                 // these are standard
1917                 return true;
1918         if (font == "lmodern" || font == "lmss" || font == "lmtt")
1919                 return LaTeXFeatures::isAvailable("lmodern");
1920         if (font == "times" || font == "palatino"
1921                  || font == "helvet" || font == "courier")
1922                 return LaTeXFeatures::isAvailable("psnfss");
1923         if (font == "cmbr" || font == "cmtl")
1924                 return LaTeXFeatures::isAvailable("cmbright");
1925         if (font == "utopia")
1926                 return LaTeXFeatures::isAvailable("utopia")
1927                         || LaTeXFeatures::isAvailable("fourier");
1928         if (font == "beraserif" || font == "berasans"
1929                 || font == "beramono")
1930                 return LaTeXFeatures::isAvailable("bera");
1931         return LaTeXFeatures::isAvailable(font);
1932 }
1933
1934
1935 bool GuiDocument::providesOSF(string const & font) const
1936 {
1937         if (font == "cmr")
1938                 return isFontAvailable("eco");
1939         if (font == "palatino")
1940                 return isFontAvailable("mathpazo");
1941         return false;
1942 }
1943
1944
1945 bool GuiDocument::providesSC(string const & font) const
1946 {
1947         if (font == "palatino")
1948                 return isFontAvailable("mathpazo");
1949         if (font == "utopia")
1950                 return isFontAvailable("fourier");
1951         return false;
1952 }
1953
1954
1955 bool GuiDocument::providesScale(string const & font) const
1956 {
1957         return font == "helvet" || font == "luximono"
1958                 || font == "berasans"  || font == "beramono";
1959 }
1960
1961
1962 void GuiDocument::loadModuleNames ()
1963 {
1964         moduleNames_.clear();
1965         LyXModuleList::const_iterator it = moduleList.begin();
1966         for (; it != moduleList.end(); ++it)
1967                 moduleNames_.push_back(it->getName());
1968         if (!moduleNames_.empty())
1969                 sort(moduleNames_.begin(), moduleNames_.end());
1970 }
1971
1972
1973 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
1974
1975
1976 } // namespace frontend
1977 } // namespace lyx
1978
1979 #include "GuiDocument_moc.cpp"