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