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