]> git.lyx.org Git - features.git/blob - src/frontends/qt4/GuiDocument.cpp
Fix doubling of bibtex and index alternatives everytime preferences are saved.
[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         connect(biblioModule->bibtexCO, SIGNAL(activated(int)),
863                 this, SLOT(bibtexChanged(int)));
864         connect(biblioModule->bibtexOptionsED, SIGNAL(textChanged(QString)),
865                 this, SLOT(change_adaptor()));
866         // biblio
867         biblioModule->citeStyleCO->addItem(qt_("Author-year"));
868         biblioModule->citeStyleCO->addItem(qt_("Numerical"));
869         biblioModule->citeStyleCO->setCurrentIndex(0);
870         
871         biblioModule->bibtexCO->clear();
872
873         biblioModule->bibtexCO->addItem(qt_("Default"), QString("default"));
874         for (set<string>::const_iterator it = lyxrc.bibtex_alternatives.begin();
875                              it != lyxrc.bibtex_alternatives.end(); ++it) {
876                 QString const command = toqstr(*it).left(toqstr(*it).indexOf(" "));
877                 biblioModule->bibtexCO->addItem(command, command);
878         }
879
880         // indices
881         indicesModule = new GuiIndices;
882         connect(indicesModule, SIGNAL(changed()),
883                 this, SLOT(change_adaptor()));
884
885
886         mathsModule = new UiWidget<Ui::MathsUi>;
887         connect(mathsModule->amsautoCB, SIGNAL(toggled(bool)),
888                 mathsModule->amsCB, SLOT(setDisabled(bool)));
889         connect(mathsModule->esintautoCB, SIGNAL(toggled(bool)),
890                 mathsModule->esintCB, SLOT(setDisabled(bool)));
891         // maths
892         connect(mathsModule->amsCB, SIGNAL(clicked()),
893                 this, SLOT(change_adaptor()));
894         connect(mathsModule->amsautoCB, SIGNAL(clicked()),
895                 this, SLOT(change_adaptor()));
896         connect(mathsModule->esintCB, SIGNAL(clicked()),
897                 this, SLOT(change_adaptor()));
898         connect(mathsModule->esintautoCB, SIGNAL(clicked()),
899                 this, SLOT(change_adaptor()));
900
901         latexModule = new UiWidget<Ui::LaTeXUi>;
902         // latex class
903         connect(latexModule->optionsLE, SIGNAL(textChanged(QString)),
904                 this, SLOT(change_adaptor()));
905         connect(latexModule->defaultOptionsCB, SIGNAL(clicked()),
906                 this, SLOT(change_adaptor()));
907         connect(latexModule->psdriverCO, SIGNAL(activated(int)),
908                 this, SLOT(change_adaptor()));
909         connect(latexModule->classCO, SIGNAL(activated(int)),
910                 this, SLOT(classChanged()));
911         connect(latexModule->classCO, SIGNAL(activated(int)),
912                 this, SLOT(change_adaptor()));
913         connect(latexModule->layoutPB, SIGNAL(clicked()),
914                 this, SLOT(browseLayout()));
915         connect(latexModule->layoutPB, SIGNAL(clicked()),
916                 this, SLOT(change_adaptor()));
917         connect(latexModule->childDocGB, SIGNAL(clicked()),
918                 this, SLOT(change_adaptor()));
919         connect(latexModule->childDocLE, SIGNAL(textChanged(QString)),
920                 this, SLOT(change_adaptor()));
921         connect(latexModule->childDocPB, SIGNAL(clicked()),
922                 this, SLOT(browseMaster()));
923
924         // postscript drivers
925         for (int n = 0; tex_graphics[n][0]; ++n) {
926                 QString enc = qt_(tex_graphics_gui[n]);
927                 latexModule->psdriverCO->addItem(enc);
928         }
929         // latex classes
930         latexModule->classCO->setModel(&classes_model_);
931         LayoutFileList const & bcl = LayoutFileList::get();
932         vector<LayoutFileIndex> classList = bcl.classList();
933         sort(classList.begin(), classList.end(), less_textclass_avail_desc());
934
935         vector<LayoutFileIndex>::const_iterator cit  = classList.begin();
936         vector<LayoutFileIndex>::const_iterator cen = classList.end();
937         for (int i = 0; cit != cen; ++cit, ++i) {
938                 LayoutFile const & tc = bcl[*cit];
939                 docstring item = (tc.isTeXClassAvailable()) ?
940                         from_utf8(tc.description()) :
941                         bformat(_("Unavailable: %1$s"), from_utf8(tc.description()));
942                 classes_model_.insertRow(i, toqstr(item), *cit);
943         }
944
945         // branches
946         branchesModule = new GuiBranches;
947         connect(branchesModule, SIGNAL(changed()),
948                 this, SLOT(change_adaptor()));
949
950         // preamble
951         preambleModule = new PreambleModule;
952         connect(preambleModule, SIGNAL(changed()),
953                 this, SLOT(change_adaptor()));
954
955         // bullets
956         bulletsModule = new BulletsModule;
957         connect(bulletsModule, SIGNAL(changed()),
958                 this, SLOT(change_adaptor()));
959
960         // Modules
961         modulesModule = new UiWidget<Ui::ModulesUi>;
962
963         selectionManager =
964                 new ModuleSelectionManager(modulesModule->availableLV,
965                         modulesModule->selectedLV,
966                         modulesModule->addPB, modulesModule->deletePB,
967                         modulesModule->upPB, modulesModule->downPB,
968                         availableModel(), selectedModel(), this);
969         connect(selectionManager, SIGNAL(updateHook()),
970                 this, SLOT(updateModuleInfo()));
971         connect(selectionManager, SIGNAL(updateHook()),
972                 this, SLOT(change_adaptor()));
973         connect(selectionManager, SIGNAL(selectionChanged()),
974                 this, SLOT(modulesChanged()));
975
976         // PDF support
977         pdfSupportModule = new UiWidget<Ui::PDFSupportUi>;
978
979         connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
980                 this, SLOT(change_adaptor()));
981         connect(pdfSupportModule->titleLE, SIGNAL(textChanged(QString)),
982                 this, SLOT(change_adaptor()));
983         connect(pdfSupportModule->authorLE, SIGNAL(textChanged(QString)),
984                 this, SLOT(change_adaptor()));
985         connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(QString)),
986                 this, SLOT(change_adaptor()));
987         connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(QString)),
988                 this, SLOT(change_adaptor()));
989         connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
990                 this, SLOT(change_adaptor()));
991         connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
992                 this, SLOT(change_adaptor()));
993         connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
994                 this, SLOT(change_adaptor()));
995         connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
996                 this, SLOT(change_adaptor()));
997         connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
998                 this, SLOT(change_adaptor()));
999         connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
1000                 this, SLOT(change_adaptor()));
1001         connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
1002                 this, SLOT(change_adaptor()));
1003         connect(pdfSupportModule->backrefCO, SIGNAL(activated(int)),
1004                 this, SLOT(change_adaptor()));
1005         connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
1006                 this, SLOT(change_adaptor()));
1007         connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
1008                 this, SLOT(change_adaptor()));
1009         connect(pdfSupportModule->optionsLE, SIGNAL(textChanged(QString)),
1010                 this, SLOT(change_adaptor()));
1011
1012         for (int i = 0; backref_opts[i][0]; ++i)
1013                 pdfSupportModule->backrefCO->addItem(qt_(backref_opts_gui[i]));
1014
1015         // float
1016         floatModule = new FloatPlacement;
1017         connect(floatModule, SIGNAL(changed()),
1018                 this, SLOT(change_adaptor()));
1019
1020         docPS->addPanel(latexModule, qt_("Document Class"));
1021         docPS->addPanel(modulesModule, qt_("Modules"));
1022         docPS->addPanel(fontModule, qt_("Fonts"));
1023         docPS->addPanel(textLayoutModule, qt_("Text Layout"));
1024         docPS->addPanel(pageLayoutModule, qt_("Page Layout"));
1025         docPS->addPanel(marginsModule, qt_("Page Margins"));
1026         docPS->addPanel(langModule, qt_("Language"));
1027         docPS->addPanel(numberingModule, qt_("Numbering & TOC"));
1028         docPS->addPanel(biblioModule, qt_("Bibliography"));
1029         docPS->addPanel(indicesModule, qt_("Indexes"));
1030         docPS->addPanel(pdfSupportModule, qt_("PDF Properties"));
1031         docPS->addPanel(mathsModule, qt_("Math Options"));
1032         docPS->addPanel(floatModule, qt_("Float Placement"));
1033         docPS->addPanel(bulletsModule, qt_("Bullets"));
1034         docPS->addPanel(branchesModule, qt_("Branches"));
1035         docPS->addPanel(outputModule, qt_("Output"));
1036         docPS->addPanel(preambleModule, qt_("LaTeX Preamble"));
1037         docPS->setCurrentPanel(qt_("Document Class"));
1038 // FIXME: hack to work around resizing bug in Qt >= 4.2
1039 // bug verified with Qt 4.2.{0-3} (JSpitzm)
1040 #if QT_VERSION >= 0x040200
1041         docPS->updateGeometry();
1042 #endif
1043 }
1044
1045
1046 void GuiDocument::showPreamble()
1047 {
1048         docPS->setCurrentPanel(qt_("LaTeX Preamble"));
1049 }
1050
1051
1052 void GuiDocument::saveDefaultClicked()
1053 {
1054         saveDocDefault();
1055 }
1056
1057
1058 void GuiDocument::useDefaultsClicked()
1059 {
1060         useClassDefaults();
1061 }
1062
1063
1064 void GuiDocument::change_adaptor()
1065 {
1066         changed();
1067 }
1068
1069
1070 QString GuiDocument::validateListingsParameters()
1071 {
1072         // use a cache here to avoid repeated validation
1073         // of the same parameters
1074         static string param_cache;
1075         static QString msg_cache;
1076         
1077         if (textLayoutModule->bypassCB->isChecked())
1078                 return QString();
1079
1080         string params = fromqstr(textLayoutModule->listingsED->toPlainText());
1081         if (params != param_cache) {
1082                 param_cache = params;
1083                 msg_cache = toqstr(InsetListingsParams(params).validate());
1084         }
1085         return msg_cache;
1086 }
1087
1088
1089 void GuiDocument::setListingsMessage()
1090 {
1091         static bool isOK = true;
1092         QString msg = validateListingsParameters();
1093         if (msg.isEmpty()) {
1094                 if (isOK)
1095                         return;
1096                 isOK = true;
1097                 // listingsTB->setTextColor("black");
1098                 textLayoutModule->listingsTB->setPlainText(
1099                         qt_("Input listings parameters on the right. "
1100                 "Enter ? for a list of parameters."));
1101         } else {
1102                 isOK = false;
1103                 // listingsTB->setTextColor("red");
1104                 textLayoutModule->listingsTB->setPlainText(msg);
1105         }
1106 }
1107
1108
1109 void GuiDocument::setLSpacing(int item)
1110 {
1111         textLayoutModule->lspacingLE->setEnabled(item == 3);
1112 }
1113
1114
1115 void GuiDocument::setSkip(int item)
1116 {
1117         bool const enable = (item == 3);
1118         textLayoutModule->skipLE->setEnabled(enable);
1119         textLayoutModule->skipLengthCO->setEnabled(enable);
1120 }
1121
1122
1123 void GuiDocument::enableSkip(bool skip)
1124 {
1125         textLayoutModule->skipCO->setEnabled(skip);
1126         textLayoutModule->skipLE->setEnabled(skip);
1127         textLayoutModule->skipLengthCO->setEnabled(skip);
1128         if (skip)
1129                 setSkip(textLayoutModule->skipCO->currentIndex());
1130 }
1131
1132
1133 void GuiDocument::portraitChanged()
1134 {
1135         setMargins(pageLayoutModule->papersizeCO->currentIndex());
1136 }
1137
1138
1139 void GuiDocument::setMargins(bool custom)
1140 {
1141         bool const extern_geometry =
1142                 documentClass().provides("geometry");
1143         marginsModule->marginCB->setEnabled(!extern_geometry);
1144         if (extern_geometry) {
1145                 marginsModule->marginCB->setChecked(false);
1146                 setCustomMargins(true);
1147                 return;
1148         }
1149         marginsModule->marginCB->setChecked(custom);
1150         setCustomMargins(custom);
1151 }
1152
1153
1154 void GuiDocument::setCustomPapersize(int papersize)
1155 {
1156         bool const custom = (papersize == 1);
1157
1158         pageLayoutModule->paperwidthL->setEnabled(custom);
1159         pageLayoutModule->paperwidthLE->setEnabled(custom);
1160         pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
1161         pageLayoutModule->paperheightL->setEnabled(custom);
1162         pageLayoutModule->paperheightLE->setEnabled(custom);
1163         pageLayoutModule->paperheightLE->setFocus();
1164         pageLayoutModule->paperheightUnitCO->setEnabled(custom);
1165 }
1166
1167
1168 void GuiDocument::setColSep()
1169 {
1170         setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
1171 }
1172
1173
1174 void GuiDocument::setCustomMargins(bool custom)
1175 {
1176         marginsModule->topL->setEnabled(!custom);
1177         marginsModule->topLE->setEnabled(!custom);
1178         marginsModule->topUnit->setEnabled(!custom);
1179
1180         marginsModule->bottomL->setEnabled(!custom);
1181         marginsModule->bottomLE->setEnabled(!custom);
1182         marginsModule->bottomUnit->setEnabled(!custom);
1183
1184         marginsModule->innerL->setEnabled(!custom);
1185         marginsModule->innerLE->setEnabled(!custom);
1186         marginsModule->innerUnit->setEnabled(!custom);
1187
1188         marginsModule->outerL->setEnabled(!custom);
1189         marginsModule->outerLE->setEnabled(!custom);
1190         marginsModule->outerUnit->setEnabled(!custom);
1191
1192         marginsModule->headheightL->setEnabled(!custom);
1193         marginsModule->headheightLE->setEnabled(!custom);
1194         marginsModule->headheightUnit->setEnabled(!custom);
1195
1196         marginsModule->headsepL->setEnabled(!custom);
1197         marginsModule->headsepLE->setEnabled(!custom);
1198         marginsModule->headsepUnit->setEnabled(!custom);
1199
1200         marginsModule->footskipL->setEnabled(!custom);
1201         marginsModule->footskipLE->setEnabled(!custom);
1202         marginsModule->footskipUnit->setEnabled(!custom);
1203
1204         bool const enableColSep = !custom && 
1205                         textLayoutModule->twoColumnCB->checkState() == Qt::Checked;
1206         marginsModule->columnsepL->setEnabled(enableColSep);
1207         marginsModule->columnsepLE->setEnabled(enableColSep);
1208         marginsModule->columnsepUnit->setEnabled(enableColSep);
1209 }
1210
1211 void GuiDocument::changeBackgroundColor()
1212 {
1213         QColor const & newColor = QColorDialog::getColor(
1214                 rgb2qcolor(set_backgroundcolor), asQWidget());
1215         if (!newColor.isValid())
1216                 return;
1217         // set the button color
1218         pageLayoutModule->backgroundPB->setStyleSheet(
1219                 colorButtonStyleSheet(newColor));
1220         // save color
1221         set_backgroundcolor = rgbFromHexName(fromqstr(newColor.name()));
1222         changed();
1223 }
1224
1225
1226 void GuiDocument::deleteBackgroundColor()
1227 {
1228         // set the button color back to white
1229         pageLayoutModule->backgroundPB->setStyleSheet(
1230                 colorButtonStyleSheet(QColor(Qt::white)));
1231         // save white as the set color
1232         set_backgroundcolor = rgbFromHexName("#ffffff");
1233         changed();
1234 }
1235
1236
1237 void GuiDocument::xetexChanged(bool xetex)
1238 {
1239         updateFontlist();
1240         updateDefaultFormat();
1241         langModule->encodingCO->setEnabled(!xetex &&
1242                 !langModule->defaultencodingRB->isChecked());
1243         langModule->defaultencodingRB->setEnabled(!xetex);
1244         langModule->otherencodingRB->setEnabled(!xetex);
1245
1246         fontModule->fontsDefaultCO->setEnabled(!xetex);
1247         fontModule->fontsDefaultLA->setEnabled(!xetex);
1248         fontModule->cjkFontLE->setEnabled(!xetex);
1249         fontModule->cjkFontLA->setEnabled(!xetex);
1250         string font;
1251         if (!xetex)
1252                 font = tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1253         bool scaleable = providesScale(font);
1254         fontModule->scaleSansSB->setEnabled(scaleable);
1255         fontModule->scaleSansLA->setEnabled(scaleable);
1256         if (!xetex)
1257                 font = tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1258         scaleable = providesScale(font);
1259         fontModule->scaleTypewriterSB->setEnabled(scaleable);
1260         fontModule->scaleTypewriterLA->setEnabled(scaleable);
1261         if (!xetex)
1262                 font = tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1263         fontModule->fontScCB->setEnabled(providesSC(font));
1264         fontModule->fontOsfCB->setEnabled(providesOSF(font));
1265 }
1266
1267
1268 void GuiDocument::updateFontsize(string const & items, string const & sel)
1269 {
1270         fontModule->fontsizeCO->clear();
1271         fontModule->fontsizeCO->addItem(qt_("Default"));
1272
1273         for (int n = 0; !token(items,'|',n).empty(); ++n)
1274                 fontModule->fontsizeCO->
1275                         addItem(toqstr(token(items,'|',n)));
1276
1277         for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
1278                 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
1279                         fontModule->fontsizeCO->setCurrentIndex(n);
1280                         break;
1281                 }
1282         }
1283 }
1284
1285
1286 void GuiDocument::updateFontlist()
1287 {
1288         fontModule->fontsRomanCO->clear();
1289         fontModule->fontsSansCO->clear();
1290         fontModule->fontsTypewriterCO->clear();
1291
1292         // With XeTeX, we have access to all system fonts, but not the LaTeX fonts
1293         if (outputModule->xetexCB->isChecked()) {
1294                 fontModule->fontsRomanCO->addItem(qt_("Default"));
1295                 fontModule->fontsSansCO->addItem(qt_("Default"));
1296                 fontModule->fontsTypewriterCO->addItem(qt_("Default"));
1297         
1298                 QFontDatabase fontdb;
1299                 QStringList families(fontdb.families());
1300                 for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
1301                         fontModule->fontsRomanCO->addItem(*it);
1302                         fontModule->fontsSansCO->addItem(*it);
1303                         fontModule->fontsTypewriterCO->addItem(*it);
1304                 }
1305                 return;
1306         }
1307
1308         for (int n = 0; tex_fonts_roman[n][0]; ++n) {
1309                 QString font = qt_(tex_fonts_roman_gui[n]);
1310                 if (!isFontAvailable(tex_fonts_roman[n]))
1311                         font += qt_(" (not installed)");
1312                 fontModule->fontsRomanCO->addItem(font);
1313         }
1314         for (int n = 0; tex_fonts_sans[n][0]; ++n) {
1315                 QString font = qt_(tex_fonts_sans_gui[n]);
1316                 if (!isFontAvailable(tex_fonts_sans[n]))
1317                         font += qt_(" (not installed)");
1318                 fontModule->fontsSansCO->addItem(font);
1319         }
1320         for (int n = 0; tex_fonts_monospaced[n][0]; ++n) {
1321                 QString font = qt_(tex_fonts_monospaced_gui[n]);
1322                 if (!isFontAvailable(tex_fonts_monospaced[n]))
1323                         font += qt_(" (not installed)");
1324                 fontModule->fontsTypewriterCO->addItem(font);
1325         }
1326 }
1327
1328
1329 void GuiDocument::romanChanged(int item)
1330 {
1331         if (outputModule->xetexCB->isChecked())
1332                 return;
1333         string const font = tex_fonts_roman[item];
1334         fontModule->fontScCB->setEnabled(providesSC(font));
1335         fontModule->fontOsfCB->setEnabled(providesOSF(font));
1336 }
1337
1338
1339 void GuiDocument::sansChanged(int item)
1340 {
1341         if (outputModule->xetexCB->isChecked())
1342                 return;
1343         string const font = tex_fonts_sans[item];
1344         bool scaleable = providesScale(font);
1345         fontModule->scaleSansSB->setEnabled(scaleable);
1346         fontModule->scaleSansLA->setEnabled(scaleable);
1347 }
1348
1349
1350 void GuiDocument::ttChanged(int item)
1351 {
1352         if (outputModule->xetexCB->isChecked())
1353                 return;
1354         string const font = tex_fonts_monospaced[item];
1355         bool scaleable = providesScale(font);
1356         fontModule->scaleTypewriterSB->setEnabled(scaleable);
1357         fontModule->scaleTypewriterLA->setEnabled(scaleable);
1358 }
1359
1360
1361 void GuiDocument::updatePagestyle(string const & items, string const & sel)
1362 {
1363         pagestyles.clear();
1364         pageLayoutModule->pagestyleCO->clear();
1365         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1366
1367         for (int n = 0; !token(items, '|', n).empty(); ++n) {
1368                 string style = token(items, '|', n);
1369                 QString style_gui = qt_(style);
1370                 pagestyles.push_back(pair<string, QString>(style, style_gui));
1371                 pageLayoutModule->pagestyleCO->addItem(style_gui);
1372         }
1373
1374         if (sel == "default") {
1375                 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
1376                 return;
1377         }
1378
1379         int nn = 0;
1380
1381         for (size_t i = 0; i < pagestyles.size(); ++i)
1382                 if (pagestyles[i].first == sel)
1383                         nn = pageLayoutModule->pagestyleCO->findText(pagestyles[i].second);
1384
1385         if (nn > 0)
1386                 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
1387 }
1388
1389
1390 void GuiDocument::browseLayout()
1391 {
1392         QString const label1 = qt_("Layouts|#o#O");
1393         QString const dir1 = toqstr(lyxrc.document_path);
1394         QStringList const filter(qt_("LyX Layout (*.layout)"));
1395         QString file = browseRelFile(QString(), bufferFilepath(),
1396                 qt_("Local layout file"), filter, false,
1397                 label1, dir1);
1398
1399         if (!file.endsWith(".layout"))
1400                 return;
1401
1402         FileName layoutFile = support::makeAbsPath(fromqstr(file),
1403                 fromqstr(bufferFilepath()));
1404         
1405         int const ret = Alert::prompt(_("Local layout file"),
1406                 _("The layout file you have selected is a local layout\n"
1407                   "file, not one in the system or user directory. Your\n"
1408                   "document may not work with this layout if you do not\n"
1409                   "keep the layout file in the document directory."),
1410                   1, 1, _("&Set Layout"), _("&Cancel"));
1411         if (ret == 1)
1412                 return;
1413
1414         // load the layout file
1415         LayoutFileList & bcl = LayoutFileList::get();
1416         string classname = layoutFile.onlyFileName();
1417         // this will update an existing layout if that layout has been loaded before.
1418         LayoutFileIndex name = bcl.addLocalLayout(
1419                 classname.substr(0, classname.size() - 7),
1420                 layoutFile.onlyPath().absFilename());
1421
1422         if (name.empty()) {
1423                 Alert::error(_("Error"),
1424                         _("Unable to read local layout file."));                
1425                 return;
1426         }
1427
1428         // do not trigger classChanged if there is no change.
1429         if (latexModule->classCO->currentText() == toqstr(name))
1430                 return;
1431                 
1432         // add to combo box
1433         int idx = latexModule->classCO->findText(toqstr(name));
1434         if (idx == -1) {
1435                 classes_model_.insertRow(0, toqstr(name), name);
1436                 latexModule->classCO->setCurrentIndex(0);
1437         } else
1438                 latexModule->classCO->setCurrentIndex(idx);
1439         
1440         classChanged();
1441 }
1442
1443
1444 void GuiDocument::browseMaster()
1445 {
1446         QString const title = qt_("Select master document");
1447         QString const dir1 = toqstr(lyxrc.document_path);
1448         QString const old = latexModule->childDocLE->text();
1449         QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
1450         QStringList const filter(qt_("LyX Files (*.lyx)"));
1451         QString file = browseRelFile(old, docpath, title, filter, false,
1452                 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
1453
1454         latexModule->childDocLE->setText(file);
1455 }
1456
1457
1458 void GuiDocument::classChanged()
1459 {
1460         int idx = latexModule->classCO->currentIndex();
1461         if (idx < 0) 
1462                 return;
1463         string const classname = classes_model_.getIDString(idx);
1464
1465         // check whether the selected modules have changed.
1466         bool modules_changed = false;
1467         unsigned int const srows = selectedModel()->rowCount();
1468         if (srows != bp_.getModules().size())
1469                 modules_changed = true;
1470         else {
1471                 list<string>::const_iterator mit = bp_.getModules().begin();
1472                 list<string>::const_iterator men = bp_.getModules().end();
1473                 for (unsigned int i = 0; i < srows && mit != men; ++i, ++mit)
1474                         if (selectedModel()->getIDString(i) != *mit) {
1475                                 modules_changed = true;
1476                                 break;
1477                         }
1478         }
1479
1480         if (modules_changed || lyxrc.auto_reset_options) {
1481                 if (applyPB->isEnabled()) {
1482                         int const ret = Alert::prompt(_("Unapplied changes"),
1483                                         _("Some changes in the dialog were not yet applied.\n"
1484                                         "If you do not apply now, they will be lost after this action."),
1485                                         1, 1, _("&Apply"), _("&Dismiss"));
1486                         if (ret == 0)
1487                                 applyView();
1488                 }
1489         }
1490
1491         // We load the TextClass as soon as it is selected. This is
1492         // necessary so that other options in the dialog can be updated
1493         // according to the new class. Note, however, that, if you use 
1494         // the scroll wheel when sitting on the combo box, we'll load a 
1495         // lot of TextClass objects very quickly....
1496         if (!bp_.setBaseClass(classname)) {
1497                 Alert::error(_("Error"), _("Unable to set document class."));
1498                 return;
1499         }
1500         if (lyxrc.auto_reset_options)
1501                 bp_.useClassDefaults();
1502
1503         // With the introduction of modules came a distinction between the base 
1504         // class and the document class. The former corresponds to the main layout 
1505         // file; the latter is that plus the modules (or the document-specific layout,
1506         // or  whatever else there could be). Our parameters come from the document 
1507         // class. So when we set the base class, we also need to recreate the document 
1508         // class. Otherwise, we still have the old one.
1509         bp_.makeDocumentClass();
1510         paramsToDialog();
1511 }
1512
1513
1514 void GuiDocument::bibtexChanged(int n)
1515 {
1516         biblioModule->bibtexOptionsED->setEnabled(n != 0);
1517         changed();
1518 }
1519
1520
1521 namespace {
1522         // This is an insanely complicated attempt to make this sort of thing
1523         // work with RTL languages.
1524         docstring formatStrVec(vector<string> const & v, docstring const & s) 
1525         {
1526                 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
1527                 if (v.size() == 0)
1528                         return docstring();
1529                 if (v.size() == 1) 
1530                         return from_utf8(v[0]);
1531                 if (v.size() == 2) {
1532                         docstring retval = _("%1$s and %2$s");
1533                         retval = subst(retval, _("and"), s);
1534                         return bformat(retval, from_utf8(v[0]), from_utf8(v[1]));
1535                 }
1536                 // The idea here is to format all but the last two items...
1537                 int const vSize = v.size();
1538                 docstring t2 = _("%1$s, %2$s");
1539                 docstring retval = from_utf8(v[0]);
1540                 for (int i = 1; i < vSize - 2; ++i)
1541                         retval = bformat(t2, retval, from_utf8(v[i])); 
1542                 //...and then to  plug them, and the last two, into this schema
1543                 docstring t = _("%1$s, %2$s, and %3$s");
1544                 t = subst(t, _("and"), s);
1545                 return bformat(t, retval, from_utf8(v[vSize - 2]), from_utf8(v[vSize - 1]));
1546         }
1547         
1548         vector<string> idsToNames(vector<string> const & idList)
1549         {
1550                 vector<string> retval;
1551                 vector<string>::const_iterator it  = idList.begin();
1552                 vector<string>::const_iterator end = idList.end();
1553                 for (; it != end; ++it) {
1554                         LyXModule const * const mod = moduleList[*it];
1555                         if (!mod)
1556                                 retval.push_back(*it + " (Unavailable)");
1557                         else
1558                                 retval.push_back(mod->getName());
1559                 }
1560                 return retval;
1561         }
1562 }
1563
1564
1565 void GuiDocument::modulesToParams(BufferParams & bp)
1566 {
1567         // update list of loaded modules
1568         bp.clearLayoutModules();
1569         int const srows = modules_sel_model_.rowCount();
1570         for (int i = 0; i < srows; ++i)
1571                 bp.addLayoutModule(modules_sel_model_.getIDString(i));
1572
1573         // update the list of removed modules
1574         bp.clearRemovedModules();
1575         LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
1576         list<string>::const_iterator rit = reqmods.begin();
1577         list<string>::const_iterator ren = reqmods.end();
1578
1579         // check each of the default modules
1580         for (; rit != ren; rit++) {
1581                 list<string>::const_iterator mit = bp.getModules().begin();
1582                 list<string>::const_iterator men = bp.getModules().end();
1583                 bool found = false;
1584                 for (; mit != men; mit++) {
1585                         if (*rit == *mit) {
1586                                 found = true;
1587                                 break;
1588                         }
1589                 }
1590                 if (!found) {
1591                         // the module isn't present so must have been removed by the user
1592                         bp.addRemovedModule(*rit);
1593                 }
1594         }
1595 }
1596
1597 void GuiDocument::modulesChanged()
1598 {
1599         modulesToParams(bp_);
1600         bp_.makeDocumentClass();
1601         paramsToDialog();
1602 }
1603
1604
1605 void GuiDocument::updateModuleInfo()
1606 {
1607         selectionManager->update();
1608         
1609         //Module description
1610         bool const focus_on_selected = selectionManager->selectedFocused();
1611         QListView const * const lv = 
1612                         focus_on_selected ? modulesModule->selectedLV : modulesModule->availableLV;
1613         if (lv->selectionModel()->selectedIndexes().isEmpty()) {
1614                 modulesModule->infoML->document()->clear();
1615                 return;
1616         }
1617         QModelIndex const & idx = lv->selectionModel()->currentIndex();
1618         GuiIdListModel const & id_model = 
1619                         focus_on_selected  ? modules_sel_model_ : modules_av_model_;
1620         string const modName = id_model.getIDString(idx.row());
1621         docstring desc = getModuleDescription(modName);
1622
1623         LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
1624         if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
1625                 if (!desc.empty())
1626                         desc += "\n";
1627                 desc += _("Module provided by document class.");
1628         }
1629
1630         vector<string> pkglist = getPackageList(modName);
1631         docstring pkgdesc = formatStrVec(pkglist, _("and"));
1632         if (!pkgdesc.empty()) {
1633                 if (!desc.empty())
1634                         desc += "\n";
1635                 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
1636         }
1637
1638         pkglist = getRequiredList(modName);
1639         if (!pkglist.empty()) {
1640                 vector<string> const reqdescs = idsToNames(pkglist);
1641                 pkgdesc = formatStrVec(reqdescs, _("or"));
1642                 if (!desc.empty())
1643                         desc += "\n";
1644                 desc += bformat(_("Module required: %1$s."), pkgdesc);
1645         }
1646
1647         pkglist = getExcludedList(modName);
1648         if (!pkglist.empty()) {
1649                 vector<string> const reqdescs = idsToNames(pkglist);
1650                 pkgdesc = formatStrVec(reqdescs, _( "and"));
1651                 if (!desc.empty())
1652                         desc += "\n";
1653                 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
1654         }
1655
1656         if (!isModuleAvailable(modName)) {
1657                 if (!desc.empty())
1658                         desc += "\n";
1659                 desc += _("WARNING: Some required packages are unavailable!");
1660         }
1661
1662         modulesModule->infoML->document()->setPlainText(toqstr(desc));
1663 }
1664
1665
1666 void GuiDocument::updateNumbering()
1667 {
1668         DocumentClass const & tclass = documentClass();
1669
1670         numberingModule->tocTW->setUpdatesEnabled(false);
1671         numberingModule->tocTW->clear();
1672
1673         int const depth = numberingModule->depthSL->value();
1674         int const toc = numberingModule->tocSL->value();
1675         QString const no = qt_("No");
1676         QString const yes = qt_("Yes");
1677         QTreeWidgetItem * item = 0;
1678
1679         DocumentClass::const_iterator lit = tclass.begin();
1680         DocumentClass::const_iterator len = tclass.end();
1681         for (; lit != len; ++lit) {
1682                 int const toclevel = lit->toclevel;
1683                 if (toclevel != Layout::NOT_IN_TOC && lit->labeltype == LABEL_COUNTER) {
1684                         item = new QTreeWidgetItem(numberingModule->tocTW);
1685                         item->setText(0, toqstr(translateIfPossible(lit->name())));
1686                         item->setText(1, (toclevel <= depth) ? yes : no);
1687                         item->setText(2, (toclevel <= toc) ? yes : no);
1688                 }
1689         }
1690
1691         numberingModule->tocTW->setUpdatesEnabled(true);
1692         numberingModule->tocTW->update();
1693 }
1694
1695
1696 void GuiDocument::updateDefaultFormat()
1697 {
1698         // make a copy in order to consider unapplied changes
1699         Buffer * tmpbuf = const_cast<Buffer *>(&buffer());
1700         tmpbuf->params().useXetex = outputModule->xetexCB->isChecked();
1701         int idx = latexModule->classCO->currentIndex();
1702         if (idx >= 0) {
1703                 string const classname = classes_model_.getIDString(idx);
1704                 tmpbuf->params().setBaseClass(classname);
1705                 tmpbuf->params().makeDocumentClass();
1706         }
1707         outputModule->defaultFormatCO->blockSignals(true);
1708         outputModule->defaultFormatCO->clear();
1709         outputModule->defaultFormatCO->addItem(qt_("Default"),
1710                                 QVariant(QString("default")));
1711         typedef vector<Format const *> Formats;
1712         Formats formats = tmpbuf->exportableFormats(true);
1713         Formats::const_iterator cit = formats.begin();
1714         Formats::const_iterator end = formats.end();
1715         for (; cit != end; ++cit)
1716                 outputModule->defaultFormatCO->addItem(qt_((*cit)->prettyname()),
1717                                 QVariant(toqstr((*cit)->name())));
1718         outputModule->defaultFormatCO->blockSignals(false);
1719 }
1720
1721
1722 void GuiDocument::applyView()
1723 {
1724         // preamble
1725         preambleModule->apply(bp_);
1726
1727         // biblio
1728         bp_.setCiteEngine(ENGINE_BASIC);
1729
1730         if (biblioModule->citeNatbibRB->isChecked()) {
1731                 bool const use_numerical_citations =
1732                         biblioModule->citeStyleCO->currentIndex();
1733                 if (use_numerical_citations)
1734                         bp_.setCiteEngine(ENGINE_NATBIB_NUMERICAL);
1735                 else
1736                         bp_.setCiteEngine(ENGINE_NATBIB_AUTHORYEAR);
1737
1738         } else if (biblioModule->citeJurabibRB->isChecked())
1739                 bp_.setCiteEngine(ENGINE_JURABIB);
1740
1741         bp_.use_bibtopic =
1742                 biblioModule->bibtopicCB->isChecked();
1743
1744         string const bibtex_command =
1745                 fromqstr(biblioModule->bibtexCO->itemData(
1746                         biblioModule->bibtexCO->currentIndex()).toString());
1747         string const bibtex_options =
1748                 fromqstr(biblioModule->bibtexOptionsED->text());
1749         if (bibtex_command == "default" || bibtex_options.empty())
1750                 bp_.bibtex_command = bibtex_command;
1751         else
1752                 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
1753
1754         // Indices
1755         indicesModule->apply(bp_);
1756
1757         // language & quotes
1758         if (langModule->defaultencodingRB->isChecked()) {
1759                 bp_.inputenc = "auto";
1760         } else {
1761                 int i = langModule->encodingCO->currentIndex();
1762                 if (i == 0)
1763                         bp_.inputenc = "default";
1764                 else {
1765                         QString const enc_gui =
1766                                 langModule->encodingCO->currentText();
1767                         Encodings::const_iterator it = encodings.begin();
1768                         Encodings::const_iterator const end = encodings.end();
1769                         bool found = false;
1770                         for (; it != end; ++it) {
1771                                 if (qt_(it->guiName()) == enc_gui) {
1772                                         bp_.inputenc = it->latexName();
1773                                         found = true;
1774                                         break;
1775                                 }
1776                         }
1777                         if (!found) {
1778                                 // should not happen
1779                                 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
1780                                 bp_.inputenc = "default";
1781                         }
1782                 }
1783         }
1784
1785         InsetQuotes::QuoteLanguage lga = InsetQuotes::EnglishQuotes;
1786         switch (langModule->quoteStyleCO->currentIndex()) {
1787         case 0:
1788                 lga = InsetQuotes::EnglishQuotes;
1789                 break;
1790         case 1:
1791                 lga = InsetQuotes::SwedishQuotes;
1792                 break;
1793         case 2:
1794                 lga = InsetQuotes::GermanQuotes;
1795                 break;
1796         case 3:
1797                 lga = InsetQuotes::PolishQuotes;
1798                 break;
1799         case 4:
1800                 lga = InsetQuotes::FrenchQuotes;
1801                 break;
1802         case 5:
1803                 lga = InsetQuotes::DanishQuotes;
1804                 break;
1805         }
1806         bp_.quotes_language = lga;
1807
1808         QString const lang = langModule->languageCO->itemData(
1809                 langModule->languageCO->currentIndex()).toString();
1810         bp_.language = languages.getLanguage(fromqstr(lang));
1811
1812         // numbering
1813         if (bp_.documentClass().hasTocLevels()) {
1814                 bp_.tocdepth = numberingModule->tocSL->value();
1815                 bp_.secnumdepth = numberingModule->depthSL->value();
1816         }
1817
1818         // bullets
1819         bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
1820         bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
1821         bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
1822         bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
1823
1824         // packages
1825         bp_.graphicsDriver =
1826                 tex_graphics[latexModule->psdriverCO->currentIndex()];
1827         
1828         // text layout
1829         int idx = latexModule->classCO->currentIndex();
1830         if (idx >= 0) {
1831                 string const classname = classes_model_.getIDString(idx);
1832                 bp_.setBaseClass(classname);
1833         }
1834
1835         // Modules
1836         modulesToParams(bp_);
1837
1838         if (mathsModule->amsautoCB->isChecked()) {
1839                 bp_.use_amsmath = BufferParams::package_auto;
1840         } else {
1841                 if (mathsModule->amsCB->isChecked())
1842                         bp_.use_amsmath = BufferParams::package_on;
1843                 else
1844                         bp_.use_amsmath = BufferParams::package_off;
1845         }
1846
1847         if (mathsModule->esintautoCB->isChecked())
1848                 bp_.use_esint = BufferParams::package_auto;
1849         else {
1850                 if (mathsModule->esintCB->isChecked())
1851                         bp_.use_esint = BufferParams::package_on;
1852                 else
1853                         bp_.use_esint = BufferParams::package_off;
1854         }
1855
1856         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
1857                 bp_.pagestyle = "default";
1858         else {
1859                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
1860                 for (size_t i = 0; i != pagestyles.size(); ++i)
1861                         if (pagestyles[i].second == style_gui)
1862                                 bp_.pagestyle = pagestyles[i].first;
1863         }
1864
1865         switch (textLayoutModule->lspacingCO->currentIndex()) {
1866         case 0:
1867                 bp_.spacing().set(Spacing::Single);
1868                 break;
1869         case 1:
1870                 bp_.spacing().set(Spacing::Onehalf);
1871                 break;
1872         case 2:
1873                 bp_.spacing().set(Spacing::Double);
1874                 break;
1875         case 3:
1876                 bp_.spacing().set(Spacing::Other,
1877                         fromqstr(textLayoutModule->lspacingLE->text()));
1878                 break;
1879         }
1880
1881         if (textLayoutModule->twoColumnCB->isChecked())
1882                 bp_.columns = 2;
1883         else
1884                 bp_.columns = 1;
1885
1886         // text should have passed validation
1887         bp_.listings_params =
1888                 InsetListingsParams(fromqstr(textLayoutModule->listingsED->toPlainText())).params();
1889
1890         if (textLayoutModule->indentRB->isChecked())
1891                 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
1892         else
1893                 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
1894
1895         switch (textLayoutModule->skipCO->currentIndex()) {
1896         case 0:
1897                 bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
1898                 break;
1899         case 1:
1900                 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
1901                 break;
1902         case 2:
1903                 bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
1904                 break;
1905         case 3:
1906         {
1907                 VSpace vs = VSpace(
1908                         widgetsToLength(textLayoutModule->skipLE,
1909                                 textLayoutModule->skipLengthCO)
1910                         );
1911                 bp_.setDefSkip(vs);
1912                 break;
1913         }
1914         default:
1915                 // DocumentDefskipCB assures that this never happens
1916                 // so Assert then !!!  - jbl
1917                 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
1918                 break;
1919         }
1920
1921         bp_.options =
1922                 fromqstr(latexModule->optionsLE->text());
1923
1924         bp_.use_default_options =
1925                 latexModule->defaultOptionsCB->isChecked();
1926
1927         if (latexModule->childDocGB->isChecked())
1928                 bp_.master =
1929                         fromqstr(latexModule->childDocLE->text());
1930         else
1931                 bp_.master = string();
1932
1933         bp_.float_placement = floatModule->get();
1934
1935         // output
1936         bp_.defaultOutputFormat = fromqstr(outputModule->defaultFormatCO->itemData(
1937                 outputModule->defaultFormatCO->currentIndex()).toString());
1938
1939         bool const xetex = outputModule->xetexCB->isChecked();
1940         bp_.useXetex = xetex;
1941
1942         // fonts
1943         if (xetex) {
1944                 if (fontModule->fontsRomanCO->currentIndex() == 0)
1945                         bp_.fontsRoman = "default";
1946                 else
1947                         bp_.fontsRoman =
1948                                 fromqstr(fontModule->fontsRomanCO->currentText());
1949         
1950                 if (fontModule->fontsSansCO->currentIndex() == 0)
1951                         bp_.fontsSans = "default";
1952                 else
1953                         bp_.fontsSans =
1954                                 fromqstr(fontModule->fontsSansCO->currentText());
1955         
1956                 if (fontModule->fontsTypewriterCO->currentIndex() == 0)
1957                         bp_.fontsTypewriter = "default";
1958                 else
1959                         bp_.fontsTypewriter =
1960                                 fromqstr(fontModule->fontsTypewriterCO->currentText());
1961         } else {
1962                 bp_.fontsRoman =
1963                         tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1964         
1965                 bp_.fontsSans =
1966                         tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1967         
1968                 bp_.fontsTypewriter =
1969                         tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1970         }
1971
1972         bp_.fontsCJK =
1973                 fromqstr(fontModule->cjkFontLE->text());
1974
1975         bp_.fontsSansScale = fontModule->scaleSansSB->value();
1976
1977         bp_.fontsTypewriterScale = fontModule->scaleTypewriterSB->value();
1978
1979         bp_.fontsSC = fontModule->fontScCB->isChecked();
1980
1981         bp_.fontsOSF = fontModule->fontOsfCB->isChecked();
1982
1983         if (xetex)
1984                 bp_.fontsDefaultFamily = "default";
1985         else
1986                 bp_.fontsDefaultFamily = GuiDocument::fontfamilies[
1987                         fontModule->fontsDefaultCO->currentIndex()];
1988
1989         if (fontModule->fontsizeCO->currentIndex() == 0)
1990                 bp_.fontsize = "default";
1991         else
1992                 bp_.fontsize =
1993                         fromqstr(fontModule->fontsizeCO->currentText());
1994
1995         // paper
1996         bp_.papersize = PAPER_SIZE(
1997                 pageLayoutModule->papersizeCO->currentIndex());
1998
1999         // custom, A3, B3 and B4 paper sizes need geometry
2000         int psize = pageLayoutModule->papersizeCO->currentIndex();
2001         bool geom_papersize = (psize == 1 || psize == 5 || psize == 8 || psize == 9);
2002
2003         bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
2004                 pageLayoutModule->paperwidthUnitCO);
2005
2006         bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
2007                 pageLayoutModule->paperheightUnitCO);
2008
2009         if (pageLayoutModule->facingPagesCB->isChecked())
2010                 bp_.sides = TwoSides;
2011         else
2012                 bp_.sides = OneSide;
2013
2014         if (pageLayoutModule->landscapeRB->isChecked())
2015                 bp_.orientation = ORIENTATION_LANDSCAPE;
2016         else
2017                 bp_.orientation = ORIENTATION_PORTRAIT;
2018
2019         bp_.backgroundcolor = set_backgroundcolor;
2020
2021         // margins
2022         bp_.use_geometry = !marginsModule->marginCB->isChecked()
2023                 || geom_papersize;
2024
2025         Ui::MarginsUi const * m = marginsModule;
2026
2027         bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
2028         bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
2029         bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
2030         bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
2031         bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
2032         bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
2033         bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
2034         bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
2035
2036         branchesModule->apply(bp_);
2037
2038         // PDF support
2039         PDFOptions & pdf = bp_.pdfoptions();
2040         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
2041         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
2042         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
2043         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
2044         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
2045
2046         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
2047         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
2048         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
2049         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
2050
2051         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
2052         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
2053         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
2054         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
2055         pdf.backref =
2056                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
2057         if (pdfSupportModule->fullscreenCB->isChecked())
2058                 pdf.pagemode = pdf.pagemode_fullscreen;
2059         else
2060                 pdf.pagemode.clear();
2061         pdf.quoted_options = pdf.quoted_options_check(
2062                                 fromqstr(pdfSupportModule->optionsLE->text()));
2063 }
2064
2065
2066 void GuiDocument::paramsToDialog()
2067 {
2068         // set the default unit
2069         Length::UNIT const defaultUnit = Length::defaultUnit();
2070
2071         // preamble
2072         preambleModule->update(bp_, id());
2073
2074         // biblio
2075         biblioModule->citeDefaultRB->setChecked(
2076                 bp_.citeEngine() == ENGINE_BASIC);
2077
2078         biblioModule->citeNatbibRB->setChecked(
2079                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL ||
2080                 bp_.citeEngine() == ENGINE_NATBIB_AUTHORYEAR);
2081
2082         biblioModule->citeStyleCO->setCurrentIndex(
2083                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL);
2084
2085         biblioModule->citeJurabibRB->setChecked(
2086                 bp_.citeEngine() == ENGINE_JURABIB);
2087
2088         biblioModule->bibtopicCB->setChecked(
2089                 bp_.use_bibtopic);
2090
2091         string command;
2092         string options =
2093                 split(bp_.bibtex_command, command, ' ');
2094
2095         int const bpos = biblioModule->bibtexCO->findData(toqstr(command));
2096         if (bpos != -1) {
2097                 biblioModule->bibtexCO->setCurrentIndex(bpos);
2098                 biblioModule->bibtexOptionsED->setText(toqstr(options).trimmed());
2099         } else {
2100                 biblioModule->bibtexCO->setCurrentIndex(0);
2101                 biblioModule->bibtexOptionsED->clear();
2102         }
2103         biblioModule->bibtexOptionsED->setEnabled(
2104                 biblioModule->bibtexCO->currentIndex() != 0);
2105
2106         // indices
2107         indicesModule->update(bp_);
2108
2109         // language & quotes
2110         int const pos = langModule->languageCO->findData(toqstr(
2111                 bp_.language->lang()));
2112         langModule->languageCO->setCurrentIndex(pos);
2113
2114         langModule->quoteStyleCO->setCurrentIndex(
2115                 bp_.quotes_language);
2116
2117         bool default_enc = true;
2118         if (bp_.inputenc != "auto") {
2119                 default_enc = false;
2120                 if (bp_.inputenc == "default") {
2121                         langModule->encodingCO->setCurrentIndex(0);
2122                 } else {
2123                         string enc_gui;
2124                         Encodings::const_iterator it = encodings.begin();
2125                         Encodings::const_iterator const end = encodings.end();
2126                         for (; it != end; ++it) {
2127                                 if (it->latexName() == bp_.inputenc) {
2128                                         enc_gui = it->guiName();
2129                                         break;
2130                                 }
2131                         }
2132                         int const i = langModule->encodingCO->findText(
2133                                         qt_(enc_gui));
2134                         if (i >= 0)
2135                                 langModule->encodingCO->setCurrentIndex(i);
2136                         else
2137                                 // unknown encoding. Set to default.
2138                                 default_enc = true;
2139                 }
2140         }
2141         langModule->defaultencodingRB->setChecked(default_enc);
2142         langModule->otherencodingRB->setChecked(!default_enc);
2143
2144         // numbering
2145         int const min_toclevel = documentClass().min_toclevel();
2146         int const max_toclevel = documentClass().max_toclevel();
2147         if (documentClass().hasTocLevels()) {
2148                 numberingModule->setEnabled(true);
2149                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
2150                 numberingModule->depthSL->setMaximum(max_toclevel);
2151                 numberingModule->depthSL->setValue(bp_.secnumdepth);
2152                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
2153                 numberingModule->tocSL->setMaximum(max_toclevel);
2154                 numberingModule->tocSL->setValue(bp_.tocdepth);
2155                 updateNumbering();
2156         } else {
2157                 numberingModule->setEnabled(false);
2158                 numberingModule->tocTW->clear();
2159         }
2160
2161         // bullets
2162         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
2163         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
2164         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
2165         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
2166         bulletsModule->init();
2167
2168         // packages
2169         int nitem = findToken(tex_graphics, bp_.graphicsDriver);
2170         if (nitem >= 0)
2171                 latexModule->psdriverCO->setCurrentIndex(nitem);
2172         updateModuleInfo();
2173         
2174         mathsModule->amsCB->setChecked(
2175                 bp_.use_amsmath == BufferParams::package_on);
2176         mathsModule->amsautoCB->setChecked(
2177                 bp_.use_amsmath == BufferParams::package_auto);
2178
2179         mathsModule->esintCB->setChecked(
2180                 bp_.use_esint == BufferParams::package_on);
2181         mathsModule->esintautoCB->setChecked(
2182                 bp_.use_esint == BufferParams::package_auto);
2183
2184         switch (bp_.spacing().getSpace()) {
2185                 case Spacing::Other: nitem = 3; break;
2186                 case Spacing::Double: nitem = 2; break;
2187                 case Spacing::Onehalf: nitem = 1; break;
2188                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
2189         }
2190
2191         // text layout
2192         string const & layoutID = bp_.baseClassID();
2193         setLayoutComboByIDString(layoutID);
2194
2195         updatePagestyle(documentClass().opt_pagestyle(),
2196                                  bp_.pagestyle);
2197
2198         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
2199         if (bp_.spacing().getSpace() == Spacing::Other) {
2200                 textLayoutModule->lspacingLE->setText(
2201                         toqstr(bp_.spacing().getValueAsString()));
2202         }
2203         setLSpacing(nitem);
2204
2205         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation)
2206                 textLayoutModule->indentRB->setChecked(true);
2207         else
2208                 textLayoutModule->skipRB->setChecked(true);
2209
2210         int skip = 0;
2211         switch (bp_.getDefSkip().kind()) {
2212         case VSpace::SMALLSKIP:
2213                 skip = 0;
2214                 break;
2215         case VSpace::MEDSKIP:
2216                 skip = 1;
2217                 break;
2218         case VSpace::BIGSKIP:
2219                 skip = 2;
2220                 break;
2221         case VSpace::LENGTH:
2222         {
2223                 skip = 3;
2224                 string const length = bp_.getDefSkip().asLyXCommand();
2225                 lengthToWidgets(textLayoutModule->skipLE,
2226                         textLayoutModule->skipLengthCO,
2227                         length, defaultUnit);
2228                 break;
2229         }
2230         default:
2231                 skip = 0;
2232                 break;
2233         }
2234         textLayoutModule->skipCO->setCurrentIndex(skip);
2235         setSkip(skip);
2236
2237         textLayoutModule->twoColumnCB->setChecked(
2238                 bp_.columns == 2);
2239
2240         // break listings_params to multiple lines
2241         string lstparams =
2242                 InsetListingsParams(bp_.listings_params).separatedParams();
2243         textLayoutModule->listingsED->setPlainText(toqstr(lstparams));
2244
2245         if (!bp_.options.empty()) {
2246                 latexModule->optionsLE->setText(
2247                         toqstr(bp_.options));
2248         } else {
2249                 latexModule->optionsLE->setText(QString());
2250         }
2251
2252         // latex
2253         latexModule->defaultOptionsCB->setChecked(
2254                         bp_.use_default_options);
2255         updateSelectedModules();
2256         selectionManager->updateProvidedModules(
2257                         bp_.baseClass()->providedModules());
2258         selectionManager->updateExcludedModules(
2259                         bp_.baseClass()->excludedModules());
2260
2261         if (!documentClass().options().empty()) {
2262                 latexModule->defaultOptionsLE->setText(
2263                         toqstr(documentClass().options()));
2264         } else {
2265                 latexModule->defaultOptionsLE->setText(
2266                         toqstr(_("[No options predefined]")));
2267         }
2268
2269         latexModule->defaultOptionsLE->setEnabled(
2270                 bp_.use_default_options
2271                 && !documentClass().options().empty());
2272
2273         latexModule->defaultOptionsCB->setEnabled(
2274                 !documentClass().options().empty());
2275
2276         if (!bp_.master.empty()) {
2277                 latexModule->childDocGB->setChecked(true);
2278                 latexModule->childDocLE->setText(
2279                         toqstr(bp_.master));
2280         } else {
2281                 latexModule->childDocLE->setText(QString());
2282                 latexModule->childDocGB->setChecked(false);
2283         }
2284
2285         floatModule->set(bp_.float_placement);
2286
2287         // Output
2288         // update combobox with formats
2289         updateDefaultFormat();
2290         int index = outputModule->defaultFormatCO->findData(toqstr(
2291                 bp_.defaultOutputFormat));
2292         // set to default if format is not found 
2293         if (index == -1)
2294                 index = 0;
2295         outputModule->defaultFormatCO->setCurrentIndex(index);
2296         outputModule->xetexCB->setEnabled(bp_.baseClass()->outputType() == lyx::LATEX);
2297         outputModule->xetexCB->setChecked(
2298                 bp_.baseClass()->outputType() == lyx::LATEX && bp_.useXetex);
2299
2300         // Fonts
2301         updateFontsize(documentClass().opt_fontsize(),
2302                         bp_.fontsize);
2303
2304         if (bp_.useXetex) {
2305                 for (int i = 0; i < fontModule->fontsRomanCO->count(); ++i) {
2306                         if (fontModule->fontsRomanCO->itemText(i) == toqstr(bp_.fontsRoman)) {
2307                                 fontModule->fontsRomanCO->setCurrentIndex(i);
2308                                 return;
2309                         }
2310                 }
2311                 
2312                 for (int i = 0; i < fontModule->fontsSansCO->count(); ++i) {
2313                         if (fontModule->fontsSansCO->itemText(i) == toqstr(bp_.fontsSans)) {
2314                                 fontModule->fontsSansCO->setCurrentIndex(i);
2315                                 return;
2316                         }
2317                 }
2318                 for (int i = 0; i < fontModule->fontsTypewriterCO->count(); ++i) {
2319                         if (fontModule->fontsTypewriterCO->itemText(i) == 
2320                                 toqstr(bp_.fontsTypewriter)) {
2321                                 fontModule->fontsTypewriterCO->setCurrentIndex(i);
2322                                 return;
2323                         }
2324                 }
2325         } else {
2326                 int n = findToken(tex_fonts_roman, bp_.fontsRoman);
2327                 if (n >= 0) {
2328                         fontModule->fontsRomanCO->setCurrentIndex(n);
2329                         romanChanged(n);
2330                 }
2331         
2332                 n = findToken(tex_fonts_sans, bp_.fontsSans);
2333                 if (n >= 0) {
2334                         fontModule->fontsSansCO->setCurrentIndex(n);
2335                         sansChanged(n);
2336                 }
2337         
2338                 n = findToken(tex_fonts_monospaced, bp_.fontsTypewriter);
2339                 if (n >= 0) {
2340                         fontModule->fontsTypewriterCO->setCurrentIndex(n);
2341                         ttChanged(n);
2342                 }
2343         }
2344
2345         if (!bp_.fontsCJK.empty())
2346                 fontModule->cjkFontLE->setText(
2347                         toqstr(bp_.fontsCJK));
2348         else
2349                 fontModule->cjkFontLE->setText(QString());
2350
2351         fontModule->fontScCB->setChecked(bp_.fontsSC);
2352         fontModule->fontOsfCB->setChecked(bp_.fontsOSF);
2353         fontModule->scaleSansSB->setValue(bp_.fontsSansScale);
2354         fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale);
2355
2356         int nn = findToken(GuiDocument::fontfamilies, bp_.fontsDefaultFamily);
2357         if (nn >= 0)
2358                 fontModule->fontsDefaultCO->setCurrentIndex(nn);
2359
2360         // paper
2361         bool const extern_geometry =
2362                 documentClass().provides("geometry");
2363         int const psize = bp_.papersize;
2364         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
2365         setCustomPapersize(!extern_geometry && psize);
2366         pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
2367
2368         bool const landscape =
2369                 bp_.orientation == ORIENTATION_LANDSCAPE;
2370         pageLayoutModule->landscapeRB->setChecked(landscape);
2371         pageLayoutModule->portraitRB->setChecked(!landscape);
2372         pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
2373         pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
2374
2375         pageLayoutModule->facingPagesCB->setChecked(
2376                 bp_.sides == TwoSides);
2377
2378         pageLayoutModule->backgroundPB->setStyleSheet(
2379                 colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
2380         set_backgroundcolor = bp_.backgroundcolor;
2381
2382         lengthToWidgets(pageLayoutModule->paperwidthLE,
2383                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, defaultUnit);
2384         lengthToWidgets(pageLayoutModule->paperheightLE,
2385                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, defaultUnit);
2386
2387         // margins
2388         Ui::MarginsUi * m = marginsModule;
2389
2390         setMargins(!bp_.use_geometry);
2391
2392         lengthToWidgets(m->topLE, m->topUnit,
2393                 bp_.topmargin, defaultUnit);
2394
2395         lengthToWidgets(m->bottomLE, m->bottomUnit,
2396                 bp_.bottommargin, defaultUnit);
2397
2398         lengthToWidgets(m->innerLE, m->innerUnit,
2399                 bp_.leftmargin, defaultUnit);
2400
2401         lengthToWidgets(m->outerLE, m->outerUnit,
2402                 bp_.rightmargin, defaultUnit);
2403
2404         lengthToWidgets(m->headheightLE, m->headheightUnit,
2405                 bp_.headheight, defaultUnit);
2406
2407         lengthToWidgets(m->headsepLE, m->headsepUnit,
2408                 bp_.headsep, defaultUnit);
2409
2410         lengthToWidgets(m->footskipLE, m->footskipUnit,
2411                 bp_.footskip, defaultUnit);
2412
2413         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
2414                 bp_.columnsep, defaultUnit);
2415
2416         branchesModule->update(bp_);
2417
2418         // PDF support
2419         PDFOptions const & pdf = bp_.pdfoptions();
2420         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
2421         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
2422         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
2423         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
2424         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
2425
2426         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
2427         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
2428         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
2429
2430         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
2431
2432         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
2433         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
2434         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
2435         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
2436
2437         nn = findToken(backref_opts, pdf.backref);
2438         if (nn >= 0)
2439                 pdfSupportModule->backrefCO->setCurrentIndex(nn);
2440
2441         pdfSupportModule->fullscreenCB->setChecked
2442                 (pdf.pagemode == pdf.pagemode_fullscreen);
2443
2444         pdfSupportModule->optionsLE->setText(
2445                 toqstr(pdf.quoted_options));
2446
2447         // Make sure that the bc is in the INITIAL state
2448         if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
2449                 bc().restore();
2450 }
2451
2452
2453 void GuiDocument::saveDocDefault()
2454 {
2455         // we have to apply the params first
2456         applyView();
2457         saveAsDefault();
2458 }
2459
2460
2461 void GuiDocument::updateAvailableModules() 
2462 {
2463         modules_av_model_.clear();
2464         list<modInfoStruct> const & modInfoList = getModuleInfo();
2465         list<modInfoStruct>::const_iterator mit = modInfoList.begin();
2466         list<modInfoStruct>::const_iterator men = modInfoList.end();
2467         for (int i = 0; mit != men; ++mit, ++i)
2468                 modules_av_model_.insertRow(i, mit->name, mit->id, 
2469                                 mit->description);
2470 }
2471
2472
2473 void GuiDocument::updateSelectedModules() 
2474 {
2475         modules_sel_model_.clear();
2476         list<modInfoStruct> const selModList = getSelectedModules();
2477         list<modInfoStruct>::const_iterator mit = selModList.begin();
2478         list<modInfoStruct>::const_iterator men = selModList.end();
2479         for (int i = 0; mit != men; ++mit, ++i)
2480                 modules_sel_model_.insertRow(i, mit->name, mit->id, 
2481                                 mit->description);
2482 }
2483
2484
2485 void GuiDocument::updateContents()
2486 {
2487         // Nothing to do here as the document settings is not cursor dependant.
2488         return;
2489 }
2490
2491
2492 void GuiDocument::useClassDefaults()
2493 {
2494         if (applyPB->isEnabled()) {
2495                 int const ret = Alert::prompt(_("Unapplied changes"),
2496                                 _("Some changes in the dialog were not yet applied.\n"
2497                                   "If you do not apply now, they will be lost after this action."),
2498                                 1, 1, _("&Apply"), _("&Dismiss"));
2499                 if (ret == 0)
2500                         applyView();
2501         }
2502
2503         int idx = latexModule->classCO->currentIndex();
2504         string const classname = classes_model_.getIDString(idx);
2505         if (!bp_.setBaseClass(classname)) {
2506                 Alert::error(_("Error"), _("Unable to set document class."));
2507                 return;
2508         }
2509         bp_.useClassDefaults();
2510         paramsToDialog();
2511 }
2512
2513
2514 void GuiDocument::setLayoutComboByIDString(string const & idString)
2515 {
2516         int idx = classes_model_.findIDString(idString);
2517         if (idx < 0)
2518                 Alert::warning(_("Can't set layout!"), 
2519                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
2520         else 
2521                 latexModule->classCO->setCurrentIndex(idx);
2522 }
2523
2524
2525 bool GuiDocument::isValid()
2526 {
2527         return validateListingsParameters().isEmpty()
2528                 && (textLayoutModule->skipCO->currentIndex() != 3
2529                         || !textLayoutModule->skipLE->text().isEmpty());
2530 }
2531
2532
2533 char const * const GuiDocument::fontfamilies[5] = {
2534         "default", "rmdefault", "sfdefault", "ttdefault", ""
2535 };
2536
2537
2538 char const * GuiDocument::fontfamilies_gui[5] = {
2539         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
2540 };
2541
2542
2543 bool GuiDocument::initialiseParams(string const &)
2544 {
2545         BufferView const * view = bufferview();
2546         if (!view) {
2547                 bp_ = BufferParams();
2548                 paramsToDialog();
2549                 return true;
2550         }
2551         bp_ = view->buffer().params();
2552         loadModuleInfo();
2553         updateAvailableModules();
2554         //FIXME It'd be nice to make sure here that the selected
2555         //modules are consistent: That required modules are actually
2556         //selected, and that we don't have conflicts. If so, we could
2557         //at least pop up a warning.
2558         paramsToDialog();
2559         return true;
2560 }
2561
2562
2563 void GuiDocument::clearParams()
2564 {
2565         bp_ = BufferParams();
2566 }
2567
2568
2569 BufferId GuiDocument::id() const
2570 {
2571         BufferView const * const view = bufferview();
2572         return view? &view->buffer() : 0;
2573 }
2574
2575
2576 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
2577 {
2578         return moduleNames_;
2579 }
2580
2581
2582 list<GuiDocument::modInfoStruct> const 
2583                 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
2584 {
2585         LayoutModuleList::const_iterator it =  mods.begin();
2586         LayoutModuleList::const_iterator end = mods.end();
2587         list<modInfoStruct> mInfo;
2588         for (; it != end; ++it) {
2589                 modInfoStruct m;
2590                 m.id = *it;
2591                 LyXModule * mod = moduleList[*it];
2592                 if (mod)
2593                         // FIXME Unicode
2594                         m.name = toqstr(translateIfPossible(from_utf8(mod->getName())));
2595                 else 
2596                         m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
2597                 mInfo.push_back(m);
2598         }
2599         return mInfo;
2600 }
2601
2602
2603 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
2604 {
2605         return makeModuleInfo(params().getModules());
2606 }
2607
2608
2609 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
2610 {
2611         return makeModuleInfo(params().baseClass()->providedModules());
2612 }
2613
2614
2615 DocumentClass const & GuiDocument::documentClass() const
2616 {
2617         return bp_.documentClass();
2618 }
2619
2620
2621 static void dispatch_bufferparams(Dialog const & dialog,
2622         BufferParams const & bp, FuncCode lfun)
2623 {
2624         ostringstream ss;
2625         ss << "\\begin_header\n";
2626         bp.writeFile(ss);
2627         ss << "\\end_header\n";
2628         dialog.dispatch(FuncRequest(lfun, ss.str()));
2629 }
2630
2631
2632 void GuiDocument::dispatchParams()
2633 {
2634         // This must come first so that a language change is correctly noticed
2635         setLanguage();
2636
2637         // Apply the BufferParams. Note that this will set the base class
2638         // and then update the buffer's layout.
2639         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
2640
2641         if (!params().master.empty()) {
2642                 FileName const master_file = support::makeAbsPath(params().master,
2643                            support::onlyPath(buffer().absFileName()));
2644                 if (isLyXFilename(master_file.absFilename())) {
2645                         Buffer * master = checkAndLoadLyXFile(master_file);
2646                         if (master) {
2647                                 if (master->isChild(const_cast<Buffer *>(&buffer())))
2648                                         const_cast<Buffer &>(buffer()).setParent(master);
2649                                 else
2650                                         Alert::warning(_("Assigned master does not include this file"), 
2651                                                 bformat(_("You must include this file in the document\n"
2652                                                           "'%1$s' in order to use the master document\n"
2653                                                           "feature."), from_utf8(params().master)));
2654                         } else
2655                                 Alert::warning(_("Could not load master"), 
2656                                                 bformat(_("The master document '%1$s'\n"
2657                                                            "could not be loaded."),
2658                                                            from_utf8(params().master)));
2659                 }
2660         }
2661
2662         // Generate the colours requested by each new branch.
2663         BranchList & branchlist = params().branchlist();
2664         if (!branchlist.empty()) {
2665                 BranchList::const_iterator it = branchlist.begin();
2666                 BranchList::const_iterator const end = branchlist.end();
2667                 for (; it != end; ++it) {
2668                         docstring const & current_branch = it->branch();
2669                         Branch const * branch = branchlist.find(current_branch);
2670                         string const x11hexname = X11hexname(branch->color());
2671                         // display the new color
2672                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
2673                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
2674                 }
2675
2676                 // Open insets of selected branches, close deselected ones
2677                 dispatch(FuncRequest(LFUN_ALL_INSETS_TOGGLE,
2678                         "assign branch"));
2679         }
2680         // Generate the colours requested by indices.
2681         IndicesList & indiceslist = params().indiceslist();
2682         if (!indiceslist.empty()) {
2683                 IndicesList::const_iterator it = indiceslist.begin();
2684                 IndicesList::const_iterator const end = indiceslist.end();
2685                 for (; it != end; ++it) {
2686                         docstring const & current_index = it->index();
2687                         Index const * index = indiceslist.find(current_index);
2688                         string const x11hexname = X11hexname(index->color());
2689                         // display the new color
2690                         docstring const str = current_index + ' ' + from_ascii(x11hexname);
2691                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
2692                 }
2693         }
2694         // FIXME: If we used an LFUN, we would not need those two lines:
2695         BufferView * bv = const_cast<BufferView *>(bufferview());
2696         bv->processUpdateFlags(Update::Force | Update::FitCursor);
2697 }
2698
2699
2700 void GuiDocument::setLanguage() const
2701 {
2702         Language const * const newL = bp_.language;
2703         if (buffer().params().language == newL)
2704                 return;
2705
2706         string const & lang_name = newL->lang();
2707         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
2708 }
2709
2710
2711 void GuiDocument::saveAsDefault() const
2712 {
2713         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
2714 }
2715
2716
2717 bool GuiDocument::isFontAvailable(string const & font) const
2718 {
2719         if (font == "default" || font == "cmr"
2720             || font == "cmss" || font == "cmtt")
2721                 // these are standard
2722                 return true;
2723         if (font == "lmodern" || font == "lmss" || font == "lmtt")
2724                 return LaTeXFeatures::isAvailable("lmodern");
2725         if (font == "times" || font == "palatino"
2726                  || font == "helvet" || font == "courier")
2727                 return LaTeXFeatures::isAvailable("psnfss");
2728         if (font == "cmbr" || font == "cmtl")
2729                 return LaTeXFeatures::isAvailable("cmbright");
2730         if (font == "utopia")
2731                 return LaTeXFeatures::isAvailable("utopia")
2732                         || LaTeXFeatures::isAvailable("fourier");
2733         if (font == "beraserif" || font == "berasans"
2734                 || font == "beramono")
2735                 return LaTeXFeatures::isAvailable("bera");
2736         return LaTeXFeatures::isAvailable(font);
2737 }
2738
2739
2740 bool GuiDocument::providesOSF(string const & font) const
2741 {
2742         if (outputModule->xetexCB->isChecked())
2743                 // FIXME: we should check if the fonts really
2744                 // have OSF support. But how?
2745                 return true;
2746         if (font == "cmr")
2747                 return isFontAvailable("eco");
2748         if (font == "palatino")
2749                 return isFontAvailable("mathpazo");
2750         return false;
2751 }
2752
2753
2754 bool GuiDocument::providesSC(string const & font) const
2755 {
2756         if (outputModule->xetexCB->isChecked())
2757                 return false;
2758         if (font == "palatino")
2759                 return isFontAvailable("mathpazo");
2760         if (font == "utopia")
2761                 return isFontAvailable("fourier");
2762         return false;
2763 }
2764
2765
2766 bool GuiDocument::providesScale(string const & font) const
2767 {
2768         if (outputModule->xetexCB->isChecked())
2769                 return true;
2770         return font == "helvet" || font == "luximono"
2771                 || font == "berasans"  || font == "beramono";
2772 }
2773
2774
2775 void GuiDocument::loadModuleInfo()
2776 {
2777         moduleNames_.clear();
2778         LyXModuleList::const_iterator it  = moduleList.begin();
2779         LyXModuleList::const_iterator end = moduleList.end();
2780         for (; it != end; ++it) {
2781                 modInfoStruct m;
2782                 m.id = it->getID();
2783                 // FIXME Unicode
2784                 m.name = toqstr(translateIfPossible(from_utf8(it->getName())));
2785                 // this is supposed to give us the first sentence of the description
2786                 // FIXME Unicode
2787                 QString desc =
2788                         toqstr(translateIfPossible(from_utf8(it->getDescription())));
2789                 int const pos = desc.indexOf(".");
2790                 if (pos > 0)
2791                         desc.truncate(pos + 1);
2792                 m.description = desc;
2793                 moduleNames_.push_back(m);
2794         }
2795 }
2796
2797
2798 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
2799
2800
2801 } // namespace frontend
2802 } // namespace lyx
2803
2804 #include "moc_GuiDocument.cpp"