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