]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiDocument.cpp
This is the last of a series of patches that merges the layout modules development...
[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         connect(langModule->defaultencodingCB, SIGNAL(toggled(bool)),
469                 langModule->encodingL, SLOT(setDisabled(bool)));
470         connect(langModule->defaultencodingCB, SIGNAL(toggled(bool)),
471                 langModule->encodingCO, SLOT(setDisabled(bool)));
472         // language & quote
473         connect(langModule->languageCO, SIGNAL(activated(int)),
474                 this, SLOT(change_adaptor()));
475         connect(langModule->defaultencodingCB, SIGNAL(clicked()),
476                 this, SLOT(change_adaptor()));
477         connect(langModule->encodingCO, SIGNAL(activated(int)),
478                 this, SLOT(change_adaptor()));
479         connect(langModule->quoteStyleCO, SIGNAL(activated(int)),
480                 this, SLOT(change_adaptor()));
481         // language & quotes
482         vector<LanguagePair> const langs = getLanguageData(false);
483         vector<LanguagePair>::const_iterator lit  = langs.begin();
484         vector<LanguagePair>::const_iterator lend = langs.end();
485         for (; lit != lend; ++lit) {
486                 langModule->languageCO->addItem(toqstr(lit->first));
487         }
488
489         // Always put the default encoding in the first position.
490         // It is special because the displayed text is translated.
491         langModule->encodingCO->addItem(qt_("LaTeX default"));
492         Encodings::const_iterator it = encodings.begin();
493         Encodings::const_iterator const end = encodings.end();
494         for (; it != end; ++it)
495                 langModule->encodingCO->addItem(toqstr(it->latexName()));
496
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         langModule->quoteStyleCO->addItem(qt_("<<text>>"));
502         langModule->quoteStyleCO->addItem(qt_(">>text<<"));
503
504
505
506         numberingModule = new UiWidget<Ui::NumberingUi>;
507         // numbering
508         connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
509                 this, SLOT(change_adaptor()));
510         connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
511                 this, SLOT(change_adaptor()));
512         connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
513                 this, SLOT(updateNumbering()));
514         connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
515                 this, SLOT(updateNumbering()));
516         numberingModule->tocTW->setColumnCount(3);
517         numberingModule->tocTW->headerItem()->setText(0, qt_("Example"));
518         numberingModule->tocTW->headerItem()->setText(1, qt_("Numbered"));
519         numberingModule->tocTW->headerItem()->setText(2, qt_("Appears in TOC"));
520
521
522         biblioModule = new UiWidget<Ui::BiblioUi>;
523         connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
524                 biblioModule->citationStyleL, SLOT(setEnabled(bool)));
525         connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
526                 biblioModule->citeStyleCO, SLOT(setEnabled(bool)));
527         // biblio
528         connect(biblioModule->citeDefaultRB, SIGNAL(clicked()),
529                 this, SLOT(change_adaptor()));
530         connect(biblioModule->citeNatbibRB, SIGNAL(clicked()),
531                 this, SLOT(change_adaptor()));
532         connect(biblioModule->citeStyleCO, SIGNAL(activated(int)),
533                 this, SLOT(change_adaptor()));
534         connect(biblioModule->citeJurabibRB, SIGNAL(clicked()),
535                 this, SLOT(change_adaptor()));
536         connect(biblioModule->bibtopicCB, SIGNAL(clicked()),
537                 this, SLOT(change_adaptor()));
538         // biblio
539         biblioModule->citeStyleCO->addItem(qt_("Author-year"));
540         biblioModule->citeStyleCO->addItem(qt_("Numerical"));
541         biblioModule->citeStyleCO->setCurrentIndex(0);
542
543
544         mathsModule = new UiWidget<Ui::MathsUi>;
545         connect(mathsModule->amsautoCB, SIGNAL(toggled(bool)),
546                 mathsModule->amsCB, SLOT(setDisabled(bool)));
547         connect(mathsModule->esintautoCB, SIGNAL(toggled(bool)),
548                 mathsModule->esintCB, SLOT(setDisabled(bool)));
549         // maths
550         connect(mathsModule->amsCB, SIGNAL(clicked()),
551                 this, SLOT(change_adaptor()));
552         connect(mathsModule->amsautoCB, SIGNAL(clicked()),
553                 this, SLOT(change_adaptor()));
554         connect(mathsModule->esintCB, SIGNAL(clicked()),
555                 this, SLOT(change_adaptor()));
556         connect(mathsModule->esintautoCB, SIGNAL(clicked()),
557                 this, SLOT(change_adaptor()));
558
559         latexModule = new UiWidget<Ui::LaTeXUi>;
560         // latex class
561         connect(latexModule->classCO, SIGNAL(activated(int)),
562                 this, SLOT(change_adaptor()));
563         connect(latexModule->optionsLE, SIGNAL(textChanged(const QString &)),
564                 this, SLOT(change_adaptor()));
565         connect(latexModule->psdriverCO, SIGNAL(activated(int)),
566                 this, SLOT(change_adaptor()));
567         connect(latexModule->classCO, SIGNAL(activated(int)),
568                 this, SLOT(classChanged()));
569         
570         selectionManager = 
571                 new GuiSelectionManager(latexModule->availableLV, latexModule->selectedLV, 
572                         latexModule->addPB, latexModule->deletePB, 
573                         latexModule->upPB, latexModule->downPB, 
574                         availableModel(), selectedModel());
575         connect(selectionManager, SIGNAL(updateHook()),
576                 this, SLOT(updateModuleInfo()));
577         connect(selectionManager, SIGNAL(updateHook()),
578                 this, SLOT(change_adaptor()));
579         
580         // postscript drivers
581         for (int n = 0; tex_graphics[n][0]; ++n) {
582                 QString enc = qt_(tex_graphics_gui[n]);
583                 latexModule->psdriverCO->addItem(enc);
584         }
585         // latex classes
586         //FIXME This seems too involved with the kernel. Some of this
587         //should be moved to the controller---which should perhaps just
588         //give us a list of entries or something of the sort.
589         for (TextClassList::const_iterator cit = textclasslist.begin();
590              cit != textclasslist.end(); ++cit) {
591                 if (cit->isTeXClassAvailable()) {
592                         latexModule->classCO->addItem(toqstr(cit->description()));
593                 } else {
594                         docstring item =
595                                 bformat(_("Unavailable: %1$s"), from_utf8(cit->description()));
596                         latexModule->classCO->addItem(toqstr(item));
597                 }
598         }
599
600         // branches
601         branchesModule = new GuiBranches;
602         connect(branchesModule, SIGNAL(changed()),
603                 this, SLOT(change_adaptor()));
604
605         // preamble
606         preambleModule = new PreambleModule;
607         connect(preambleModule, SIGNAL(changed()),
608                 this, SLOT(change_adaptor()));
609
610         // bullets
611         bulletsModule = new BulletsModule;
612         connect(bulletsModule, SIGNAL(changed()),
613                 this, SLOT(change_adaptor()));
614
615
616         // float
617         floatModule = new FloatPlacement;
618         connect(floatModule, SIGNAL(changed()),
619                 this, SLOT(change_adaptor()));
620
621         docPS->addPanel(latexModule, _("Document Class"));
622         docPS->addPanel(fontModule, _("Fonts"));
623         docPS->addPanel(textLayoutModule, _("Text Layout"));
624         docPS->addPanel(pageLayoutModule, _("Page Layout"));
625         docPS->addPanel(marginsModule, _("Page Margins"));
626         docPS->addPanel(langModule, _("Language"));
627         docPS->addPanel(numberingModule, _("Numbering & TOC"));
628         docPS->addPanel(biblioModule, _("Bibliography"));
629         docPS->addPanel(mathsModule, _("Math Options"));
630         docPS->addPanel(floatModule, _("Float Placement"));
631         docPS->addPanel(bulletsModule, _("Bullets"));
632         docPS->addPanel(branchesModule, _("Branches"));
633         docPS->addPanel(preambleModule, _("LaTeX Preamble"));
634         docPS->setCurrentPanel(_("Document Class"));
635 // FIXME: hack to work around resizing bug in Qt >= 4.2
636 // bug verified with Qt 4.2.{0-3} (JSpitzm)
637 #if QT_VERSION >= 0x040200
638         docPS->updateGeometry();
639 #endif
640 }
641
642
643 ControlDocument & GuiDocumentDialog::controller()
644 {
645         return static_cast<ControlDocument &>(GuiDialog::controller());
646 }
647
648
649 void GuiDocumentDialog::showPreamble()
650 {
651         docPS->setCurrentPanel(_("LaTeX Preamble"));
652 }
653
654
655 void GuiDocumentDialog::saveDefaultClicked()
656 {
657         saveDocDefault();
658 }
659
660
661 void GuiDocumentDialog::useDefaultsClicked()
662 {
663         useClassDefaults();
664 }
665
666
667 void GuiDocumentDialog::change_adaptor()
668 {
669         changed();
670 }
671
672
673 docstring GuiDocumentDialog::validate_listings_params()
674 {
675         // use a cache here to avoid repeated validation
676         // of the same parameters
677         static string param_cache = string();
678         static docstring msg_cache = docstring();
679         
680         if (textLayoutModule->bypassCB->isChecked())
681                 return docstring();
682
683         string params = fromqstr(textLayoutModule->listingsED->toPlainText());
684         if (params != param_cache) {
685                 param_cache = params;
686                 msg_cache = InsetListingsParams(params).validate();
687         }
688         return msg_cache;
689 }
690
691
692 void GuiDocumentDialog::set_listings_msg()
693 {
694         static bool isOK = true;
695         docstring msg = validate_listings_params();
696         if (msg.empty()) {
697                 if (isOK)
698                         return;
699                 isOK = true;
700                 // listingsTB->setTextColor("black");
701                 textLayoutModule->listingsTB->setPlainText(
702                         qt_("Input listings parameters on the right. Enter ? for a list of parameters."));
703         } else {
704                 isOK = false;
705                 // listingsTB->setTextColor("red");
706                 textLayoutModule->listingsTB->setPlainText(toqstr(msg));
707         }
708 }
709
710
711 void GuiDocumentDialog::closeEvent(QCloseEvent * e)
712 {
713         slotClose();
714         e->accept();
715 }
716
717
718 void GuiDocumentDialog::setLSpacing(int item)
719 {
720         textLayoutModule->lspacingLE->setEnabled(item == 3);
721 }
722
723
724 void GuiDocumentDialog::setSkip(int item)
725 {
726         bool const enable = (item == 3);
727         textLayoutModule->skipLE->setEnabled(enable);
728         textLayoutModule->skipLengthCO->setEnabled(enable);
729 }
730
731
732 void GuiDocumentDialog::enableSkip(bool skip)
733 {
734         textLayoutModule->skipCO->setEnabled(skip);
735         textLayoutModule->skipLE->setEnabled(skip);
736         textLayoutModule->skipLengthCO->setEnabled(skip);
737         if (skip)
738                 setSkip(textLayoutModule->skipCO->currentIndex());
739 }
740
741 void GuiDocumentDialog::portraitChanged()
742 {
743         setMargins(pageLayoutModule->papersizeCO->currentIndex());
744 }
745
746 void GuiDocumentDialog::setMargins(bool custom)
747 {
748         marginsModule->marginCB->setChecked(custom);
749         setCustomMargins(custom);
750 }
751
752
753 void GuiDocumentDialog::setCustomPapersize(int papersize)
754 {
755         bool const custom = (papersize == 1);
756
757         pageLayoutModule->paperwidthL->setEnabled(custom);
758         pageLayoutModule->paperwidthLE->setEnabled(custom);
759         pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
760         pageLayoutModule->paperheightL->setEnabled(custom);
761         pageLayoutModule->paperheightLE->setEnabled(custom);
762         pageLayoutModule->paperheightLE->setFocus();
763         pageLayoutModule->paperheightUnitCO->setEnabled(custom);
764 }
765
766
767 void GuiDocumentDialog::setCustomMargins(bool custom)
768 {
769         marginsModule->topL->setEnabled(!custom);
770         marginsModule->topLE->setEnabled(!custom);
771         marginsModule->topUnit->setEnabled(!custom);
772
773         marginsModule->bottomL->setEnabled(!custom);
774         marginsModule->bottomLE->setEnabled(!custom);
775         marginsModule->bottomUnit->setEnabled(!custom);
776
777         marginsModule->innerL->setEnabled(!custom);
778         marginsModule->innerLE->setEnabled(!custom);
779         marginsModule->innerUnit->setEnabled(!custom);
780
781         marginsModule->outerL->setEnabled(!custom);
782         marginsModule->outerLE->setEnabled(!custom);
783         marginsModule->outerUnit->setEnabled(!custom);
784
785         marginsModule->headheightL->setEnabled(!custom);
786         marginsModule->headheightLE->setEnabled(!custom);
787         marginsModule->headheightUnit->setEnabled(!custom);
788
789         marginsModule->headsepL->setEnabled(!custom);
790         marginsModule->headsepLE->setEnabled(!custom);
791         marginsModule->headsepUnit->setEnabled(!custom);
792
793         marginsModule->footskipL->setEnabled(!custom);
794         marginsModule->footskipLE->setEnabled(!custom);
795         marginsModule->footskipUnit->setEnabled(!custom);
796 }
797
798
799 void GuiDocumentDialog::updateFontsize(string const & items, string const & sel)
800 {
801         fontModule->fontsizeCO->clear();
802         fontModule->fontsizeCO->addItem(qt_("Default"));
803
804         for (int n = 0; !token(items,'|',n).empty(); ++n)
805                 fontModule->fontsizeCO->
806                         addItem(toqstr(token(items,'|',n)));
807
808         for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
809                 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
810                         fontModule->fontsizeCO->setCurrentIndex(n);
811                         break;
812                 }
813         }
814 }
815
816
817 void GuiDocumentDialog::romanChanged(int item)
818 {
819         string const font = tex_fonts_roman[item];
820         fontModule->fontScCB->setEnabled(controller().providesSC(font));
821         fontModule->fontOsfCB->setEnabled(controller().providesOSF(font));
822 }
823
824
825 void GuiDocumentDialog::sansChanged(int item)
826 {
827         string const font = tex_fonts_sans[item];
828         bool scaleable = controller().providesScale(font);
829         fontModule->scaleSansSB->setEnabled(scaleable);
830         fontModule->scaleSansLA->setEnabled(scaleable);
831 }
832
833
834 void GuiDocumentDialog::ttChanged(int item)
835 {
836         string const font = tex_fonts_monospaced[item];
837         bool scaleable = controller().providesScale(font);
838         fontModule->scaleTypewriterSB->setEnabled(scaleable);
839         fontModule->scaleTypewriterLA->setEnabled(scaleable);
840 }
841
842
843 void GuiDocumentDialog::updatePagestyle(string const & items, string const & sel)
844 {
845         pagestyles.clear();
846         pageLayoutModule->pagestyleCO->clear();
847         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
848
849         for (int n = 0; !token(items,'|',n).empty(); ++n) {
850                 string style = token(items, '|', n);
851                 docstring style_gui = _(style);
852                 pagestyles.push_back(pair<string, docstring>(style, style_gui));
853                 pageLayoutModule->pagestyleCO->addItem(toqstr(style_gui));
854         }
855
856         if (sel == "default") {
857                 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
858                 return;
859         }
860
861         int nn = 0;
862
863         for (size_t i = 0; i < pagestyles.size(); ++i)
864                 if (pagestyles[i].first == sel)
865                         nn = pageLayoutModule->pagestyleCO->findText(
866                                         toqstr(pagestyles[i].second));
867
868         if (nn > 0)
869                 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
870 }
871
872
873 void GuiDocumentDialog::classChanged()
874 {
875         BufferParams & params = controller().params();
876         textclass_type const tc = latexModule->classCO->currentIndex();
877         params.setJustBaseClass(tc);
878         if (lyxrc.auto_reset_options)
879                 params.useClassDefaults();
880         updateContents();
881 }
882
883
884 void GuiDocumentDialog::updateModuleInfo()
885 {
886         selectionManager->update();
887         //Module description
888         QListView const * const lv = selectionManager->selectedFocused() ?
889                                      latexModule->selectedLV :
890                         latexModule->availableLV;
891         if (lv->selectionModel()->selectedIndexes().isEmpty())
892                 latexModule->infoML->document()->clear();
893         else {
894                 QModelIndex const idx = lv->selectionModel()->currentIndex();
895                 string const modName = fromqstr(idx.data().toString());
896                 string desc = controller().getModuleDescription(modName);
897                 vector<string> pkgList = controller().getPackageList(modName);
898                 string pkgdesc;
899                 //this mess formats the package list as "pkg1, pkg2, and pkg3"
900                 int const pkgListSize = pkgList.size();
901                 for (int i = 0; i < pkgListSize; ++i) {
902                         if (i == 1) {
903                                 if (i == pkgListSize - 1) //last element
904                                         pkgdesc += " and ";
905                                 else
906                                         pkgdesc += ", ";
907                         } else if (i > 1) {
908                                 if (i == pkgListSize - 1) //last element
909                                         pkgdesc += ", and ";
910                                 else
911                                         pkgdesc += ", ";
912                         }
913                         pkgdesc += pkgList[i];
914                 }
915                 if (!pkgdesc.empty())
916                         desc += " Requires " + pkgdesc + ".";
917                 latexModule->infoML->document()->setPlainText(toqstr(desc));
918         }
919 }
920
921
922 void GuiDocumentDialog::updateNumbering()
923 {
924         TextClass const & tclass = controller().params().getTextClass();
925
926         numberingModule->tocTW->setUpdatesEnabled(false);
927         numberingModule->tocTW->clear();
928
929         int const depth = numberingModule->depthSL->value();
930         int const toc = numberingModule->tocSL->value();
931         QString const no = qt_("No");
932         QString const yes = qt_("Yes");
933         TextClass::const_iterator end = tclass.end();
934         TextClass::const_iterator cit = tclass.begin();
935         QTreeWidgetItem * item = 0;
936         for ( ; cit != end ; ++cit) {
937                 int const toclevel = (*cit)->toclevel;
938                 if (toclevel != Layout::NOT_IN_TOC
939                     && (*cit)->labeltype == LABEL_COUNTER) {
940                         item = new QTreeWidgetItem(numberingModule->tocTW);
941                         item->setText(0, toqstr(translateIfPossible((*cit)->name())));
942                         item->setText(1, (toclevel <= depth) ? yes : no);
943                         item->setText(2, (toclevel <= toc) ? yes : no);
944                 }
945         }
946
947         numberingModule->tocTW->setUpdatesEnabled(true);
948         numberingModule->tocTW->update();
949 }
950
951 void GuiDocumentDialog::apply(BufferParams & params)
952 {
953         // preamble
954         preambleModule->apply(params);
955
956         // biblio
957         params.setCiteEngine(biblio::ENGINE_BASIC);
958
959         if (biblioModule->citeNatbibRB->isChecked()) {
960                 bool const use_numerical_citations =
961                         biblioModule->citeStyleCO->currentIndex();
962                 if (use_numerical_citations)
963                         params.setCiteEngine(biblio::ENGINE_NATBIB_NUMERICAL);
964                 else
965                         params.setCiteEngine(biblio::ENGINE_NATBIB_AUTHORYEAR);
966
967         } else if (biblioModule->citeJurabibRB->isChecked())
968                 params.setCiteEngine(biblio::ENGINE_JURABIB);
969
970         params.use_bibtopic =
971                 biblioModule->bibtopicCB->isChecked();
972
973         // language & quotes
974         if (langModule->defaultencodingCB->isChecked()) {
975                 params.inputenc = "auto";
976         } else {
977                 int i = langModule->encodingCO->currentIndex();
978                 if (i == 0)
979                         params.inputenc = "default";
980                 else
981                         params.inputenc =
982                                 fromqstr(langModule->encodingCO->currentText());
983         }
984
985         InsetQuotes::quote_language lga = InsetQuotes::EnglishQ;
986         switch (langModule->quoteStyleCO->currentIndex()) {
987         case 0:
988                 lga = InsetQuotes::EnglishQ;
989                 break;
990         case 1:
991                 lga = InsetQuotes::SwedishQ;
992                 break;
993         case 2:
994                 lga = InsetQuotes::GermanQ;
995                 break;
996         case 3:
997                 lga = InsetQuotes::PolishQ;
998                 break;
999         case 4:
1000                 lga = InsetQuotes::FrenchQ;
1001                 break;
1002         case 5:
1003                 lga = InsetQuotes::DanishQ;
1004                 break;
1005         }
1006         params.quotes_language = lga;
1007
1008         int const pos = langModule->languageCO->currentIndex();
1009         params.language = lyx::languages.getLanguage(lang_[pos]);
1010
1011         // numbering
1012         if (params.getTextClass().hasTocLevels()) {
1013                 params.tocdepth = numberingModule->tocSL->value();
1014                 params.secnumdepth = numberingModule->depthSL->value();
1015         }
1016
1017         // bullets
1018         params.user_defined_bullet(0) = bulletsModule->getBullet(0);
1019         params.user_defined_bullet(1) = bulletsModule->getBullet(1);
1020         params.user_defined_bullet(2) = bulletsModule->getBullet(2);
1021         params.user_defined_bullet(3) = bulletsModule->getBullet(3);
1022
1023         // packages
1024         params.graphicsDriver =
1025                 tex_graphics[latexModule->psdriverCO->currentIndex()];
1026         
1027         // Modules
1028         params.clearLayoutModules();
1029         QStringList const selMods = selectedModel()->stringList();
1030         for (int i = 0; i != selMods.size(); ++i)
1031                 params.addLayoutModule(lyx::fromqstr(selMods[i]));
1032
1033
1034         if (mathsModule->amsautoCB->isChecked()) {
1035                 params.use_amsmath = BufferParams::package_auto;
1036         } else {
1037                 if (mathsModule->amsCB->isChecked())
1038                         params.use_amsmath = BufferParams::package_on;
1039                 else
1040                         params.use_amsmath = BufferParams::package_off;
1041         }
1042
1043         if (mathsModule->esintautoCB->isChecked())
1044                 params.use_esint = BufferParams::package_auto;
1045         else {
1046                 if (mathsModule->esintCB->isChecked())
1047                         params.use_esint = BufferParams::package_on;
1048                 else
1049                         params.use_esint = BufferParams::package_off;
1050         }
1051
1052         // text layout
1053         params.setJustBaseClass(latexModule->classCO->currentIndex());
1054
1055         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
1056                 params.pagestyle = "default";
1057         else {
1058                 docstring style_gui =
1059                         qstring_to_ucs4(pageLayoutModule->pagestyleCO->currentText());
1060                 for (size_t i = 0; i < pagestyles.size(); ++i)
1061                         if (pagestyles[i].second == style_gui)
1062                                 params.pagestyle = pagestyles[i].first;
1063         }
1064
1065         switch (textLayoutModule->lspacingCO->currentIndex()) {
1066         case 0:
1067                 params.spacing().set(Spacing::Single);
1068                 break;
1069         case 1:
1070                 params.spacing().set(Spacing::Onehalf);
1071                 break;
1072         case 2:
1073                 params.spacing().set(Spacing::Double);
1074                 break;
1075         case 3:
1076                 params.spacing().set(Spacing::Other,
1077                         fromqstr(textLayoutModule->lspacingLE->text()));
1078                 break;
1079         }
1080
1081         if (textLayoutModule->twoColumnCB->isChecked())
1082                 params.columns = 2;
1083         else
1084                 params.columns = 1;
1085
1086         // text should have passed validation
1087         params.listings_params =
1088                 InsetListingsParams(fromqstr(textLayoutModule->listingsED->toPlainText())).params();
1089
1090         if (textLayoutModule->indentRB->isChecked())
1091                 params.paragraph_separation = BufferParams::PARSEP_INDENT;
1092         else
1093                 params.paragraph_separation = BufferParams::PARSEP_SKIP;
1094
1095         switch (textLayoutModule->skipCO->currentIndex()) {
1096         case 0:
1097                 params.setDefSkip(VSpace(VSpace::SMALLSKIP));
1098                 break;
1099         case 1:
1100                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
1101                 break;
1102         case 2:
1103                 params.setDefSkip(VSpace(VSpace::BIGSKIP));
1104                 break;
1105         case 3:
1106         {
1107                 VSpace vs = VSpace(
1108                         widgetsToLength(textLayoutModule->skipLE,
1109                                 textLayoutModule->skipLengthCO)
1110                         );
1111                 params.setDefSkip(vs);
1112                 break;
1113         }
1114         default:
1115                 // DocumentDefskipCB assures that this never happens
1116                 // so Assert then !!!  - jbl
1117                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
1118                 break;
1119         }
1120
1121         params.options =
1122                 fromqstr(latexModule->optionsLE->text());
1123
1124         params.float_placement = floatModule->get();
1125
1126         // fonts
1127         params.fontsRoman =
1128                 tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1129
1130         params.fontsSans =
1131                 tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1132
1133         params.fontsTypewriter =
1134                 tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1135
1136         params.fontsSansScale = fontModule->scaleSansSB->value();
1137
1138         params.fontsTypewriterScale = fontModule->scaleTypewriterSB->value();
1139
1140         params.fontsSC = fontModule->fontScCB->isChecked();
1141
1142         params.fontsOSF = fontModule->fontOsfCB->isChecked();
1143
1144         params.fontsDefaultFamily = ControlDocument::fontfamilies[
1145                 fontModule->fontsDefaultCO->currentIndex()];
1146
1147         if (fontModule->fontsizeCO->currentIndex() == 0)
1148                 params.fontsize = "default";
1149         else
1150                 params.fontsize =
1151                         fromqstr(fontModule->fontsizeCO->currentText());
1152
1153         // paper
1154         params.papersize = PAPER_SIZE(
1155                 pageLayoutModule->papersizeCO->currentIndex());
1156
1157         // custom, A3, B3 and B4 paper sizes need geometry
1158         int psize = pageLayoutModule->papersizeCO->currentIndex();
1159         bool geom_papersize = (psize == 1 || psize == 5 || psize == 8 || psize == 9);
1160
1161         params.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
1162                 pageLayoutModule->paperwidthUnitCO);
1163
1164         params.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
1165                 pageLayoutModule->paperheightUnitCO);
1166
1167         if (pageLayoutModule->facingPagesCB->isChecked())
1168                 params.sides = TextClass::TwoSides;
1169         else
1170                 params.sides = TextClass::OneSide;
1171
1172         if (pageLayoutModule->landscapeRB->isChecked())
1173                 params.orientation = ORIENTATION_LANDSCAPE;
1174         else
1175                 params.orientation = ORIENTATION_PORTRAIT;
1176
1177         // margins
1178         params.use_geometry =
1179                 (!marginsModule->marginCB->isChecked()
1180                 || geom_papersize);
1181
1182         Ui::MarginsUi const * m(marginsModule);
1183
1184         params.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
1185
1186         params.topmargin = widgetsToLength(m->topLE, m->topUnit);
1187
1188         params.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
1189
1190         params.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
1191
1192         params.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
1193
1194         params.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
1195
1196         params.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
1197
1198         branchesModule->apply(params);
1199 }
1200
1201
1202 /** Return the position of val in the vector if found.
1203     If not found, return 0.
1204  */
1205 template<class A>
1206 static size_t findPos(std::vector<A> const & vec, A const & val)
1207 {
1208         typename std::vector<A>::const_iterator it =
1209                 std::find(vec.begin(), vec.end(), val);
1210         if (it == vec.end())
1211                 return 0;
1212         return distance(vec.begin(), it);
1213 }
1214
1215
1216 void GuiDocumentDialog::updateParams()
1217 {
1218         BufferParams const & params = controller().params();
1219         updateParams(params);
1220 }
1221
1222
1223 void GuiDocumentDialog::updateParams(BufferParams const & params)
1224 {
1225         // set the default unit
1226         // FIXME: move to controller
1227         Length::UNIT defaultUnit = Length::CM;
1228         switch (lyxrc.default_papersize) {
1229                 case PAPER_DEFAULT: break;
1230
1231                 case PAPER_USLETTER:
1232                 case PAPER_USLEGAL:
1233                 case PAPER_USEXECUTIVE:
1234                         defaultUnit = Length::IN;
1235                         break;
1236
1237                 case PAPER_A3:
1238                 case PAPER_A4:
1239                 case PAPER_A5:
1240                 case PAPER_B3:
1241                 case PAPER_B4:
1242                 case PAPER_B5:
1243                         defaultUnit = Length::CM;
1244                         break;
1245                 case PAPER_CUSTOM:
1246                         break;
1247         }
1248
1249         // preamble
1250         preambleModule->update(params, controller().id());
1251
1252         // biblio
1253         biblioModule->citeDefaultRB->setChecked(
1254                 params.getEngine() == biblio::ENGINE_BASIC);
1255
1256         biblioModule->citeNatbibRB->setChecked(
1257                 params.getEngine() == biblio::ENGINE_NATBIB_NUMERICAL ||
1258                 params.getEngine() == biblio::ENGINE_NATBIB_AUTHORYEAR);
1259
1260         biblioModule->citeStyleCO->setCurrentIndex(
1261                 params.getEngine() == biblio::ENGINE_NATBIB_NUMERICAL);
1262
1263         biblioModule->citeJurabibRB->setChecked(
1264                 params.getEngine() == biblio::ENGINE_JURABIB);
1265
1266         biblioModule->bibtopicCB->setChecked(
1267                 params.use_bibtopic);
1268
1269         // language & quotes
1270         int const pos = int(findPos(lang_,
1271                                     params.language->lang()));
1272         langModule->languageCO->setCurrentIndex(pos);
1273
1274         langModule->quoteStyleCO->setCurrentIndex(
1275                 params.quotes_language);
1276
1277         langModule->defaultencodingCB->setChecked(true);
1278
1279         if (params.inputenc != "auto") {
1280                 langModule->defaultencodingCB->setChecked(false);
1281                 if (params.inputenc == "default") {
1282                         langModule->encodingCO->setCurrentIndex(0);
1283                 } else {
1284                         int const i = langModule->encodingCO->findText(
1285                                         toqstr(params.inputenc));
1286                         if (i >= 0)
1287                                 langModule->encodingCO->setCurrentIndex(i);
1288                         else
1289                                 // unknown encoding. Set to default.
1290                                 langModule->defaultencodingCB->setChecked(true);
1291                 }
1292         }
1293
1294         // numbering
1295         int const min_toclevel = controller().textClass().min_toclevel();
1296         int const max_toclevel = controller().textClass().max_toclevel();
1297         if (controller().textClass().hasTocLevels()) {
1298                 numberingModule->setEnabled(true);
1299                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
1300                 numberingModule->depthSL->setMaximum(max_toclevel);
1301                 numberingModule->depthSL->setValue(params.secnumdepth);
1302                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
1303                 numberingModule->tocSL->setMaximum(max_toclevel);
1304                 numberingModule->tocSL->setValue(params.tocdepth);
1305                 updateNumbering();
1306         } else {
1307                 numberingModule->setEnabled(false);
1308                 numberingModule->tocTW->clear();
1309         }
1310
1311         // bullets
1312         bulletsModule->setBullet(0, params.user_defined_bullet(0));
1313         bulletsModule->setBullet(1, params.user_defined_bullet(1));
1314         bulletsModule->setBullet(2, params.user_defined_bullet(2));
1315         bulletsModule->setBullet(3, params.user_defined_bullet(3));
1316         bulletsModule->init();
1317
1318         // packages
1319         int nitem = findToken(tex_graphics, params.graphicsDriver);
1320         if (nitem >= 0)
1321                 latexModule->psdriverCO->setCurrentIndex(nitem);
1322         updateModuleInfo();
1323         
1324         mathsModule->amsCB->setChecked(
1325                 params.use_amsmath == BufferParams::package_on);
1326         mathsModule->amsautoCB->setChecked(
1327                 params.use_amsmath == BufferParams::package_auto);
1328
1329         mathsModule->esintCB->setChecked(
1330                 params.use_esint == BufferParams::package_on);
1331         mathsModule->esintautoCB->setChecked(
1332                 params.use_esint == BufferParams::package_auto);
1333
1334         switch (params.spacing().getSpace()) {
1335                 case Spacing::Other: nitem = 3; break;
1336                 case Spacing::Double: nitem = 2; break;
1337                 case Spacing::Onehalf: nitem = 1; break;
1338                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
1339         }
1340
1341         // text layout
1342         latexModule->classCO->setCurrentIndex(params.getBaseClass());
1343         
1344         updatePagestyle(controller().textClass().opt_pagestyle(),
1345                                  params.pagestyle);
1346
1347         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
1348         if (params.spacing().getSpace() == Spacing::Other) {
1349                 textLayoutModule->lspacingLE->setText(
1350                         toqstr(params.spacing().getValueAsString()));
1351         }
1352         setLSpacing(nitem);
1353
1354         if (params.paragraph_separation == BufferParams::PARSEP_INDENT)
1355                 textLayoutModule->indentRB->setChecked(true);
1356         else
1357                 textLayoutModule->skipRB->setChecked(true);
1358
1359         int skip = 0;
1360         switch (params.getDefSkip().kind()) {
1361         case VSpace::SMALLSKIP:
1362                 skip = 0;
1363                 break;
1364         case VSpace::MEDSKIP:
1365                 skip = 1;
1366                 break;
1367         case VSpace::BIGSKIP:
1368                 skip = 2;
1369                 break;
1370         case VSpace::LENGTH:
1371         {
1372                 skip = 3;
1373                 string const length = params.getDefSkip().asLyXCommand();
1374                 lengthToWidgets(textLayoutModule->skipLE,
1375                         textLayoutModule->skipLengthCO,
1376                         length, defaultUnit);
1377                 break;
1378         }
1379         default:
1380                 skip = 0;
1381                 break;
1382         }
1383         textLayoutModule->skipCO->setCurrentIndex(skip);
1384         setSkip(skip);
1385
1386         textLayoutModule->twoColumnCB->setChecked(
1387                 params.columns == 2);
1388
1389         // break listings_params to multiple lines
1390         string lstparams =
1391                 InsetListingsParams(params.listings_params).separatedParams();
1392         textLayoutModule->listingsED->setPlainText(toqstr(lstparams));
1393
1394         if (!params.options.empty()) {
1395                 latexModule->optionsLE->setText(
1396                         toqstr(params.options));
1397         } else {
1398                 latexModule->optionsLE->setText(QString());
1399         }
1400
1401         floatModule->set(params.float_placement);
1402
1403         // Fonts
1404         updateFontsize(controller().textClass().opt_fontsize(),
1405                         params.fontsize);
1406
1407         int n = findToken(tex_fonts_roman, params.fontsRoman);
1408         if (n >= 0) {
1409                 fontModule->fontsRomanCO->setCurrentIndex(n);
1410                 romanChanged(n);
1411         }
1412
1413         n = findToken(tex_fonts_sans, params.fontsSans);
1414         if (n >= 0)     {
1415                 fontModule->fontsSansCO->setCurrentIndex(n);
1416                 sansChanged(n);
1417         }
1418
1419         n = findToken(tex_fonts_monospaced, params.fontsTypewriter);
1420         if (n >= 0) {
1421                 fontModule->fontsTypewriterCO->setCurrentIndex(n);
1422                 ttChanged(n);
1423         }
1424
1425         fontModule->fontScCB->setChecked(params.fontsSC);
1426         fontModule->fontOsfCB->setChecked(params.fontsOSF);
1427         fontModule->scaleSansSB->setValue(params.fontsSansScale);
1428         fontModule->scaleTypewriterSB->setValue(params.fontsTypewriterScale);
1429         n = findToken(ControlDocument::fontfamilies, params.fontsDefaultFamily);
1430         if (n >= 0)
1431                 fontModule->fontsDefaultCO->setCurrentIndex(n);
1432
1433         // paper
1434         int const psize = params.papersize;
1435         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
1436         setCustomPapersize(psize);
1437
1438         bool const landscape =
1439                 params.orientation == ORIENTATION_LANDSCAPE;
1440         pageLayoutModule->landscapeRB->setChecked(landscape);
1441         pageLayoutModule->portraitRB->setChecked(!landscape);
1442
1443         pageLayoutModule->facingPagesCB->setChecked(
1444                 params.sides == TextClass::TwoSides);
1445
1446
1447         lengthToWidgets(pageLayoutModule->paperwidthLE,
1448                 pageLayoutModule->paperwidthUnitCO, params.paperwidth, defaultUnit);
1449
1450         lengthToWidgets(pageLayoutModule->paperheightLE,
1451                 pageLayoutModule->paperheightUnitCO, params.paperheight, defaultUnit);
1452
1453         // margins
1454         Ui::MarginsUi * m = marginsModule;
1455
1456         setMargins(!params.use_geometry);
1457
1458         lengthToWidgets(m->topLE, m->topUnit,
1459                 params.topmargin, defaultUnit);
1460
1461         lengthToWidgets(m->bottomLE, m->bottomUnit,
1462                 params.bottommargin, defaultUnit);
1463
1464         lengthToWidgets(m->innerLE, m->innerUnit,
1465                 params.leftmargin, defaultUnit);
1466
1467         lengthToWidgets(m->outerLE, m->outerUnit,
1468                 params.rightmargin, defaultUnit);
1469
1470         lengthToWidgets(m->headheightLE, m->headheightUnit,
1471                 params.headheight, defaultUnit);
1472
1473         lengthToWidgets(m->headsepLE, m->headsepUnit,
1474                 params.headsep, defaultUnit);
1475
1476         lengthToWidgets(m->footskipLE, m->footskipUnit,
1477                 params.footskip, defaultUnit);
1478
1479         branchesModule->update(params);
1480 }
1481
1482
1483 void GuiDocumentDialog::applyView()
1484 {
1485         apply(controller().params());
1486 }
1487
1488
1489 void GuiDocumentDialog::saveDocDefault()
1490 {
1491         // we have to apply the params first
1492         applyView();
1493         controller().saveAsDefault();
1494 }
1495
1496
1497 void GuiDocumentDialog::updateContents()
1498 {
1499         //update list of available modules
1500         QStringList strlist;
1501         vector<string> const modNames = controller().getModuleNames();
1502         vector<string>::const_iterator it = modNames.begin();
1503         for (; it != modNames.end(); ++it)
1504                 strlist.push_back(toqstr(*it));
1505         available_model_.setStringList(strlist);
1506         //and selected ones, too
1507         QStringList strlist2;
1508         vector<string> const & selMods = controller().getSelectedModules();
1509         it = selMods.begin();
1510         for (; it != selMods.end(); ++it)
1511                 strlist2.push_back(toqstr(*it));
1512         selected_model_.setStringList(strlist2);
1513
1514         updateParams(controller().params());
1515 }
1516
1517 void GuiDocumentDialog::useClassDefaults()
1518 {
1519         BufferParams & params = controller().params();
1520
1521         params.setJustBaseClass(latexModule->classCO->currentIndex());
1522         params.useClassDefaults();
1523         updateContents();
1524 }
1525
1526
1527 bool GuiDocumentDialog::isValid()
1528 {
1529         return validate_listings_params().empty();
1530 }
1531
1532
1533 } // namespace frontend
1534 } // namespace lyx
1535
1536 #include "GuiDocument_moc.cpp"