]> git.lyx.org Git - features.git/blob - src/frontends/qt4/GuiDocument.cpp
* Per-document setting for bibtex and makeindex.
[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 (vector<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         if (bibtex_command == "default")
1748                 bp_.bibtex_command = bibtex_command;
1749         else
1750                 bp_.bibtex_command = bibtex_command + " "
1751                         + fromqstr(biblioModule->bibtexOptionsED->text());
1752
1753         // Indices
1754         indicesModule->apply(bp_);
1755
1756         // language & quotes
1757         if (langModule->defaultencodingRB->isChecked()) {
1758                 bp_.inputenc = "auto";
1759         } else {
1760                 int i = langModule->encodingCO->currentIndex();
1761                 if (i == 0)
1762                         bp_.inputenc = "default";
1763                 else {
1764                         QString const enc_gui =
1765                                 langModule->encodingCO->currentText();
1766                         Encodings::const_iterator it = encodings.begin();
1767                         Encodings::const_iterator const end = encodings.end();
1768                         bool found = false;
1769                         for (; it != end; ++it) {
1770                                 if (qt_(it->guiName()) == enc_gui) {
1771                                         bp_.inputenc = it->latexName();
1772                                         found = true;
1773                                         break;
1774                                 }
1775                         }
1776                         if (!found) {
1777                                 // should not happen
1778                                 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
1779                                 bp_.inputenc = "default";
1780                         }
1781                 }
1782         }
1783
1784         InsetQuotes::QuoteLanguage lga = InsetQuotes::EnglishQuotes;
1785         switch (langModule->quoteStyleCO->currentIndex()) {
1786         case 0:
1787                 lga = InsetQuotes::EnglishQuotes;
1788                 break;
1789         case 1:
1790                 lga = InsetQuotes::SwedishQuotes;
1791                 break;
1792         case 2:
1793                 lga = InsetQuotes::GermanQuotes;
1794                 break;
1795         case 3:
1796                 lga = InsetQuotes::PolishQuotes;
1797                 break;
1798         case 4:
1799                 lga = InsetQuotes::FrenchQuotes;
1800                 break;
1801         case 5:
1802                 lga = InsetQuotes::DanishQuotes;
1803                 break;
1804         }
1805         bp_.quotes_language = lga;
1806
1807         QString const lang = langModule->languageCO->itemData(
1808                 langModule->languageCO->currentIndex()).toString();
1809         bp_.language = languages.getLanguage(fromqstr(lang));
1810
1811         // numbering
1812         if (bp_.documentClass().hasTocLevels()) {
1813                 bp_.tocdepth = numberingModule->tocSL->value();
1814                 bp_.secnumdepth = numberingModule->depthSL->value();
1815         }
1816
1817         // bullets
1818         bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
1819         bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
1820         bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
1821         bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
1822
1823         // packages
1824         bp_.graphicsDriver =
1825                 tex_graphics[latexModule->psdriverCO->currentIndex()];
1826         
1827         // text layout
1828         int idx = latexModule->classCO->currentIndex();
1829         if (idx >= 0) {
1830                 string const classname = classes_model_.getIDString(idx);
1831                 bp_.setBaseClass(classname);
1832         }
1833
1834         // Modules
1835         modulesToParams(bp_);
1836
1837         if (mathsModule->amsautoCB->isChecked()) {
1838                 bp_.use_amsmath = BufferParams::package_auto;
1839         } else {
1840                 if (mathsModule->amsCB->isChecked())
1841                         bp_.use_amsmath = BufferParams::package_on;
1842                 else
1843                         bp_.use_amsmath = BufferParams::package_off;
1844         }
1845
1846         if (mathsModule->esintautoCB->isChecked())
1847                 bp_.use_esint = BufferParams::package_auto;
1848         else {
1849                 if (mathsModule->esintCB->isChecked())
1850                         bp_.use_esint = BufferParams::package_on;
1851                 else
1852                         bp_.use_esint = BufferParams::package_off;
1853         }
1854
1855         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
1856                 bp_.pagestyle = "default";
1857         else {
1858                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
1859                 for (size_t i = 0; i != pagestyles.size(); ++i)
1860                         if (pagestyles[i].second == style_gui)
1861                                 bp_.pagestyle = pagestyles[i].first;
1862         }
1863
1864         switch (textLayoutModule->lspacingCO->currentIndex()) {
1865         case 0:
1866                 bp_.spacing().set(Spacing::Single);
1867                 break;
1868         case 1:
1869                 bp_.spacing().set(Spacing::Onehalf);
1870                 break;
1871         case 2:
1872                 bp_.spacing().set(Spacing::Double);
1873                 break;
1874         case 3:
1875                 bp_.spacing().set(Spacing::Other,
1876                         fromqstr(textLayoutModule->lspacingLE->text()));
1877                 break;
1878         }
1879
1880         if (textLayoutModule->twoColumnCB->isChecked())
1881                 bp_.columns = 2;
1882         else
1883                 bp_.columns = 1;
1884
1885         // text should have passed validation
1886         bp_.listings_params =
1887                 InsetListingsParams(fromqstr(textLayoutModule->listingsED->toPlainText())).params();
1888
1889         if (textLayoutModule->indentRB->isChecked())
1890                 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
1891         else
1892                 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
1893
1894         switch (textLayoutModule->skipCO->currentIndex()) {
1895         case 0:
1896                 bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
1897                 break;
1898         case 1:
1899                 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
1900                 break;
1901         case 2:
1902                 bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
1903                 break;
1904         case 3:
1905         {
1906                 VSpace vs = VSpace(
1907                         widgetsToLength(textLayoutModule->skipLE,
1908                                 textLayoutModule->skipLengthCO)
1909                         );
1910                 bp_.setDefSkip(vs);
1911                 break;
1912         }
1913         default:
1914                 // DocumentDefskipCB assures that this never happens
1915                 // so Assert then !!!  - jbl
1916                 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
1917                 break;
1918         }
1919
1920         bp_.options =
1921                 fromqstr(latexModule->optionsLE->text());
1922
1923         bp_.use_default_options =
1924                 latexModule->defaultOptionsCB->isChecked();
1925
1926         if (latexModule->childDocGB->isChecked())
1927                 bp_.master =
1928                         fromqstr(latexModule->childDocLE->text());
1929         else
1930                 bp_.master = string();
1931
1932         bp_.float_placement = floatModule->get();
1933
1934         // output
1935         bp_.defaultOutputFormat = fromqstr(outputModule->defaultFormatCO->itemData(
1936                 outputModule->defaultFormatCO->currentIndex()).toString());
1937
1938         bool const xetex = outputModule->xetexCB->isChecked();
1939         bp_.useXetex = xetex;
1940
1941         // fonts
1942         if (xetex) {
1943                 if (fontModule->fontsRomanCO->currentIndex() == 0)
1944                         bp_.fontsRoman = "default";
1945                 else
1946                         bp_.fontsRoman =
1947                                 fromqstr(fontModule->fontsRomanCO->currentText());
1948         
1949                 if (fontModule->fontsSansCO->currentIndex() == 0)
1950                         bp_.fontsSans = "default";
1951                 else
1952                         bp_.fontsSans =
1953                                 fromqstr(fontModule->fontsSansCO->currentText());
1954         
1955                 if (fontModule->fontsTypewriterCO->currentIndex() == 0)
1956                         bp_.fontsTypewriter = "default";
1957                 else
1958                         bp_.fontsTypewriter =
1959                                 fromqstr(fontModule->fontsTypewriterCO->currentText());
1960         } else {
1961                 bp_.fontsRoman =
1962                         tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1963         
1964                 bp_.fontsSans =
1965                         tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1966         
1967                 bp_.fontsTypewriter =
1968                         tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1969         }
1970
1971         bp_.fontsCJK =
1972                 fromqstr(fontModule->cjkFontLE->text());
1973
1974         bp_.fontsSansScale = fontModule->scaleSansSB->value();
1975
1976         bp_.fontsTypewriterScale = fontModule->scaleTypewriterSB->value();
1977
1978         bp_.fontsSC = fontModule->fontScCB->isChecked();
1979
1980         bp_.fontsOSF = fontModule->fontOsfCB->isChecked();
1981
1982         if (xetex)
1983                 bp_.fontsDefaultFamily = "default";
1984         else
1985                 bp_.fontsDefaultFamily = GuiDocument::fontfamilies[
1986                         fontModule->fontsDefaultCO->currentIndex()];
1987
1988         if (fontModule->fontsizeCO->currentIndex() == 0)
1989                 bp_.fontsize = "default";
1990         else
1991                 bp_.fontsize =
1992                         fromqstr(fontModule->fontsizeCO->currentText());
1993
1994         // paper
1995         bp_.papersize = PAPER_SIZE(
1996                 pageLayoutModule->papersizeCO->currentIndex());
1997
1998         // custom, A3, B3 and B4 paper sizes need geometry
1999         int psize = pageLayoutModule->papersizeCO->currentIndex();
2000         bool geom_papersize = (psize == 1 || psize == 5 || psize == 8 || psize == 9);
2001
2002         bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
2003                 pageLayoutModule->paperwidthUnitCO);
2004
2005         bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
2006                 pageLayoutModule->paperheightUnitCO);
2007
2008         if (pageLayoutModule->facingPagesCB->isChecked())
2009                 bp_.sides = TwoSides;
2010         else
2011                 bp_.sides = OneSide;
2012
2013         if (pageLayoutModule->landscapeRB->isChecked())
2014                 bp_.orientation = ORIENTATION_LANDSCAPE;
2015         else
2016                 bp_.orientation = ORIENTATION_PORTRAIT;
2017
2018         bp_.backgroundcolor = set_backgroundcolor;
2019
2020         // margins
2021         bp_.use_geometry = !marginsModule->marginCB->isChecked()
2022                 || geom_papersize;
2023
2024         Ui::MarginsUi const * m = marginsModule;
2025
2026         bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
2027         bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
2028         bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
2029         bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
2030         bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
2031         bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
2032         bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
2033         bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
2034
2035         branchesModule->apply(bp_);
2036
2037         // PDF support
2038         PDFOptions & pdf = bp_.pdfoptions();
2039         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
2040         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
2041         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
2042         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
2043         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
2044
2045         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
2046         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
2047         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
2048         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
2049
2050         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
2051         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
2052         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
2053         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
2054         pdf.backref =
2055                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
2056         if (pdfSupportModule->fullscreenCB->isChecked())
2057                 pdf.pagemode = pdf.pagemode_fullscreen;
2058         else
2059                 pdf.pagemode.clear();
2060         pdf.quoted_options = pdf.quoted_options_check(
2061                                 fromqstr(pdfSupportModule->optionsLE->text()));
2062 }
2063
2064
2065 void GuiDocument::paramsToDialog()
2066 {
2067         // set the default unit
2068         Length::UNIT const defaultUnit = Length::defaultUnit();
2069
2070         // preamble
2071         preambleModule->update(bp_, id());
2072
2073         // biblio
2074         biblioModule->citeDefaultRB->setChecked(
2075                 bp_.citeEngine() == ENGINE_BASIC);
2076
2077         biblioModule->citeNatbibRB->setChecked(
2078                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL ||
2079                 bp_.citeEngine() == ENGINE_NATBIB_AUTHORYEAR);
2080
2081         biblioModule->citeStyleCO->setCurrentIndex(
2082                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL);
2083
2084         biblioModule->citeJurabibRB->setChecked(
2085                 bp_.citeEngine() == ENGINE_JURABIB);
2086
2087         biblioModule->bibtopicCB->setChecked(
2088                 bp_.use_bibtopic);
2089
2090         string command;
2091         string options =
2092                 split(bp_.bibtex_command, command, ' ');
2093
2094         int const bpos = biblioModule->bibtexCO->findData(toqstr(command));
2095         if (bpos != -1) {
2096                 biblioModule->bibtexCO->setCurrentIndex(bpos);
2097                 biblioModule->bibtexOptionsED->setText(toqstr(options).trimmed());
2098         } else {
2099                 biblioModule->bibtexCO->setCurrentIndex(0);
2100                 biblioModule->bibtexOptionsED->clear();
2101         }
2102         biblioModule->bibtexOptionsED->setEnabled(
2103                 biblioModule->bibtexCO->currentIndex() != 0);
2104
2105         // indices
2106         indicesModule->update(bp_);
2107
2108         // language & quotes
2109         int const pos = langModule->languageCO->findData(toqstr(
2110                 bp_.language->lang()));
2111         langModule->languageCO->setCurrentIndex(pos);
2112
2113         langModule->quoteStyleCO->setCurrentIndex(
2114                 bp_.quotes_language);
2115
2116         bool default_enc = true;
2117         if (bp_.inputenc != "auto") {
2118                 default_enc = false;
2119                 if (bp_.inputenc == "default") {
2120                         langModule->encodingCO->setCurrentIndex(0);
2121                 } else {
2122                         string enc_gui;
2123                         Encodings::const_iterator it = encodings.begin();
2124                         Encodings::const_iterator const end = encodings.end();
2125                         for (; it != end; ++it) {
2126                                 if (it->latexName() == bp_.inputenc) {
2127                                         enc_gui = it->guiName();
2128                                         break;
2129                                 }
2130                         }
2131                         int const i = langModule->encodingCO->findText(
2132                                         qt_(enc_gui));
2133                         if (i >= 0)
2134                                 langModule->encodingCO->setCurrentIndex(i);
2135                         else
2136                                 // unknown encoding. Set to default.
2137                                 default_enc = true;
2138                 }
2139         }
2140         langModule->defaultencodingRB->setChecked(default_enc);
2141         langModule->otherencodingRB->setChecked(!default_enc);
2142
2143         // numbering
2144         int const min_toclevel = documentClass().min_toclevel();
2145         int const max_toclevel = documentClass().max_toclevel();
2146         if (documentClass().hasTocLevels()) {
2147                 numberingModule->setEnabled(true);
2148                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
2149                 numberingModule->depthSL->setMaximum(max_toclevel);
2150                 numberingModule->depthSL->setValue(bp_.secnumdepth);
2151                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
2152                 numberingModule->tocSL->setMaximum(max_toclevel);
2153                 numberingModule->tocSL->setValue(bp_.tocdepth);
2154                 updateNumbering();
2155         } else {
2156                 numberingModule->setEnabled(false);
2157                 numberingModule->tocTW->clear();
2158         }
2159
2160         // bullets
2161         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
2162         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
2163         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
2164         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
2165         bulletsModule->init();
2166
2167         // packages
2168         int nitem = findToken(tex_graphics, bp_.graphicsDriver);
2169         if (nitem >= 0)
2170                 latexModule->psdriverCO->setCurrentIndex(nitem);
2171         updateModuleInfo();
2172         
2173         mathsModule->amsCB->setChecked(
2174                 bp_.use_amsmath == BufferParams::package_on);
2175         mathsModule->amsautoCB->setChecked(
2176                 bp_.use_amsmath == BufferParams::package_auto);
2177
2178         mathsModule->esintCB->setChecked(
2179                 bp_.use_esint == BufferParams::package_on);
2180         mathsModule->esintautoCB->setChecked(
2181                 bp_.use_esint == BufferParams::package_auto);
2182
2183         switch (bp_.spacing().getSpace()) {
2184                 case Spacing::Other: nitem = 3; break;
2185                 case Spacing::Double: nitem = 2; break;
2186                 case Spacing::Onehalf: nitem = 1; break;
2187                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
2188         }
2189
2190         // text layout
2191         string const & layoutID = bp_.baseClassID();
2192         setLayoutComboByIDString(layoutID);
2193
2194         updatePagestyle(documentClass().opt_pagestyle(),
2195                                  bp_.pagestyle);
2196
2197         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
2198         if (bp_.spacing().getSpace() == Spacing::Other) {
2199                 textLayoutModule->lspacingLE->setText(
2200                         toqstr(bp_.spacing().getValueAsString()));
2201         }
2202         setLSpacing(nitem);
2203
2204         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation)
2205                 textLayoutModule->indentRB->setChecked(true);
2206         else
2207                 textLayoutModule->skipRB->setChecked(true);
2208
2209         int skip = 0;
2210         switch (bp_.getDefSkip().kind()) {
2211         case VSpace::SMALLSKIP:
2212                 skip = 0;
2213                 break;
2214         case VSpace::MEDSKIP:
2215                 skip = 1;
2216                 break;
2217         case VSpace::BIGSKIP:
2218                 skip = 2;
2219                 break;
2220         case VSpace::LENGTH:
2221         {
2222                 skip = 3;
2223                 string const length = bp_.getDefSkip().asLyXCommand();
2224                 lengthToWidgets(textLayoutModule->skipLE,
2225                         textLayoutModule->skipLengthCO,
2226                         length, defaultUnit);
2227                 break;
2228         }
2229         default:
2230                 skip = 0;
2231                 break;
2232         }
2233         textLayoutModule->skipCO->setCurrentIndex(skip);
2234         setSkip(skip);
2235
2236         textLayoutModule->twoColumnCB->setChecked(
2237                 bp_.columns == 2);
2238
2239         // break listings_params to multiple lines
2240         string lstparams =
2241                 InsetListingsParams(bp_.listings_params).separatedParams();
2242         textLayoutModule->listingsED->setPlainText(toqstr(lstparams));
2243
2244         if (!bp_.options.empty()) {
2245                 latexModule->optionsLE->setText(
2246                         toqstr(bp_.options));
2247         } else {
2248                 latexModule->optionsLE->setText(QString());
2249         }
2250
2251         // latex
2252         latexModule->defaultOptionsCB->setChecked(
2253                         bp_.use_default_options);
2254         updateSelectedModules();
2255         selectionManager->updateProvidedModules(
2256                         bp_.baseClass()->providedModules());
2257         selectionManager->updateExcludedModules(
2258                         bp_.baseClass()->excludedModules());
2259
2260         if (!documentClass().options().empty()) {
2261                 latexModule->defaultOptionsLE->setText(
2262                         toqstr(documentClass().options()));
2263         } else {
2264                 latexModule->defaultOptionsLE->setText(
2265                         toqstr(_("[No options predefined]")));
2266         }
2267
2268         latexModule->defaultOptionsLE->setEnabled(
2269                 bp_.use_default_options
2270                 && !documentClass().options().empty());
2271
2272         latexModule->defaultOptionsCB->setEnabled(
2273                 !documentClass().options().empty());
2274
2275         if (!bp_.master.empty()) {
2276                 latexModule->childDocGB->setChecked(true);
2277                 latexModule->childDocLE->setText(
2278                         toqstr(bp_.master));
2279         } else {
2280                 latexModule->childDocLE->setText(QString());
2281                 latexModule->childDocGB->setChecked(false);
2282         }
2283
2284         floatModule->set(bp_.float_placement);
2285
2286         // Output
2287         // update combobox with formats
2288         updateDefaultFormat();
2289         int index = outputModule->defaultFormatCO->findData(toqstr(
2290                 bp_.defaultOutputFormat));
2291         // set to default if format is not found 
2292         if (index == -1)
2293                 index = 0;
2294         outputModule->defaultFormatCO->setCurrentIndex(index);
2295         outputModule->xetexCB->setEnabled(bp_.baseClass()->outputType() == lyx::LATEX);
2296         outputModule->xetexCB->setChecked(
2297                 bp_.baseClass()->outputType() == lyx::LATEX && bp_.useXetex);
2298
2299         // Fonts
2300         updateFontsize(documentClass().opt_fontsize(),
2301                         bp_.fontsize);
2302
2303         if (bp_.useXetex) {
2304                 for (int i = 0; i < fontModule->fontsRomanCO->count(); ++i) {
2305                         if (fontModule->fontsRomanCO->itemText(i) == toqstr(bp_.fontsRoman)) {
2306                                 fontModule->fontsRomanCO->setCurrentIndex(i);
2307                                 return;
2308                         }
2309                 }
2310                 
2311                 for (int i = 0; i < fontModule->fontsSansCO->count(); ++i) {
2312                         if (fontModule->fontsSansCO->itemText(i) == toqstr(bp_.fontsSans)) {
2313                                 fontModule->fontsSansCO->setCurrentIndex(i);
2314                                 return;
2315                         }
2316                 }
2317                 for (int i = 0; i < fontModule->fontsTypewriterCO->count(); ++i) {
2318                         if (fontModule->fontsTypewriterCO->itemText(i) == 
2319                                 toqstr(bp_.fontsTypewriter)) {
2320                                 fontModule->fontsTypewriterCO->setCurrentIndex(i);
2321                                 return;
2322                         }
2323                 }
2324         } else {
2325                 int n = findToken(tex_fonts_roman, bp_.fontsRoman);
2326                 if (n >= 0) {
2327                         fontModule->fontsRomanCO->setCurrentIndex(n);
2328                         romanChanged(n);
2329                 }
2330         
2331                 n = findToken(tex_fonts_sans, bp_.fontsSans);
2332                 if (n >= 0) {
2333                         fontModule->fontsSansCO->setCurrentIndex(n);
2334                         sansChanged(n);
2335                 }
2336         
2337                 n = findToken(tex_fonts_monospaced, bp_.fontsTypewriter);
2338                 if (n >= 0) {
2339                         fontModule->fontsTypewriterCO->setCurrentIndex(n);
2340                         ttChanged(n);
2341                 }
2342         }
2343
2344         if (!bp_.fontsCJK.empty())
2345                 fontModule->cjkFontLE->setText(
2346                         toqstr(bp_.fontsCJK));
2347         else
2348                 fontModule->cjkFontLE->setText(QString());
2349
2350         fontModule->fontScCB->setChecked(bp_.fontsSC);
2351         fontModule->fontOsfCB->setChecked(bp_.fontsOSF);
2352         fontModule->scaleSansSB->setValue(bp_.fontsSansScale);
2353         fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale);
2354
2355         int nn = findToken(GuiDocument::fontfamilies, bp_.fontsDefaultFamily);
2356         if (nn >= 0)
2357                 fontModule->fontsDefaultCO->setCurrentIndex(nn);
2358
2359         // paper
2360         bool const extern_geometry =
2361                 documentClass().provides("geometry");
2362         int const psize = bp_.papersize;
2363         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
2364         setCustomPapersize(!extern_geometry && psize);
2365         pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
2366
2367         bool const landscape =
2368                 bp_.orientation == ORIENTATION_LANDSCAPE;
2369         pageLayoutModule->landscapeRB->setChecked(landscape);
2370         pageLayoutModule->portraitRB->setChecked(!landscape);
2371         pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
2372         pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
2373
2374         pageLayoutModule->facingPagesCB->setChecked(
2375                 bp_.sides == TwoSides);
2376
2377         pageLayoutModule->backgroundPB->setStyleSheet(
2378                 colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
2379         set_backgroundcolor = bp_.backgroundcolor;
2380
2381         lengthToWidgets(pageLayoutModule->paperwidthLE,
2382                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, defaultUnit);
2383         lengthToWidgets(pageLayoutModule->paperheightLE,
2384                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, defaultUnit);
2385
2386         // margins
2387         Ui::MarginsUi * m = marginsModule;
2388
2389         setMargins(!bp_.use_geometry);
2390
2391         lengthToWidgets(m->topLE, m->topUnit,
2392                 bp_.topmargin, defaultUnit);
2393
2394         lengthToWidgets(m->bottomLE, m->bottomUnit,
2395                 bp_.bottommargin, defaultUnit);
2396
2397         lengthToWidgets(m->innerLE, m->innerUnit,
2398                 bp_.leftmargin, defaultUnit);
2399
2400         lengthToWidgets(m->outerLE, m->outerUnit,
2401                 bp_.rightmargin, defaultUnit);
2402
2403         lengthToWidgets(m->headheightLE, m->headheightUnit,
2404                 bp_.headheight, defaultUnit);
2405
2406         lengthToWidgets(m->headsepLE, m->headsepUnit,
2407                 bp_.headsep, defaultUnit);
2408
2409         lengthToWidgets(m->footskipLE, m->footskipUnit,
2410                 bp_.footskip, defaultUnit);
2411
2412         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
2413                 bp_.columnsep, defaultUnit);
2414
2415         branchesModule->update(bp_);
2416
2417         // PDF support
2418         PDFOptions const & pdf = bp_.pdfoptions();
2419         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
2420         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
2421         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
2422         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
2423         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
2424
2425         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
2426         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
2427         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
2428
2429         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
2430
2431         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
2432         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
2433         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
2434         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
2435
2436         nn = findToken(backref_opts, pdf.backref);
2437         if (nn >= 0)
2438                 pdfSupportModule->backrefCO->setCurrentIndex(nn);
2439
2440         pdfSupportModule->fullscreenCB->setChecked
2441                 (pdf.pagemode == pdf.pagemode_fullscreen);
2442
2443         pdfSupportModule->optionsLE->setText(
2444                 toqstr(pdf.quoted_options));
2445
2446         // Make sure that the bc is in the INITIAL state
2447         if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
2448                 bc().restore();
2449 }
2450
2451
2452 void GuiDocument::saveDocDefault()
2453 {
2454         // we have to apply the params first
2455         applyView();
2456         saveAsDefault();
2457 }
2458
2459
2460 void GuiDocument::updateAvailableModules() 
2461 {
2462         modules_av_model_.clear();
2463         list<modInfoStruct> const & modInfoList = getModuleInfo();
2464         list<modInfoStruct>::const_iterator mit = modInfoList.begin();
2465         list<modInfoStruct>::const_iterator men = modInfoList.end();
2466         for (int i = 0; mit != men; ++mit, ++i)
2467                 modules_av_model_.insertRow(i, mit->name, mit->id, 
2468                                 mit->description);
2469 }
2470
2471
2472 void GuiDocument::updateSelectedModules() 
2473 {
2474         modules_sel_model_.clear();
2475         list<modInfoStruct> const selModList = getSelectedModules();
2476         list<modInfoStruct>::const_iterator mit = selModList.begin();
2477         list<modInfoStruct>::const_iterator men = selModList.end();
2478         for (int i = 0; mit != men; ++mit, ++i)
2479                 modules_sel_model_.insertRow(i, mit->name, mit->id, 
2480                                 mit->description);
2481 }
2482
2483
2484 void GuiDocument::updateContents()
2485 {
2486         // Nothing to do here as the document settings is not cursor dependant.
2487         return;
2488 }
2489
2490
2491 void GuiDocument::useClassDefaults()
2492 {
2493         if (applyPB->isEnabled()) {
2494                 int const ret = Alert::prompt(_("Unapplied changes"),
2495                                 _("Some changes in the dialog were not yet applied.\n"
2496                                   "If you do not apply now, they will be lost after this action."),
2497                                 1, 1, _("&Apply"), _("&Dismiss"));
2498                 if (ret == 0)
2499                         applyView();
2500         }
2501
2502         int idx = latexModule->classCO->currentIndex();
2503         string const classname = classes_model_.getIDString(idx);
2504         if (!bp_.setBaseClass(classname)) {
2505                 Alert::error(_("Error"), _("Unable to set document class."));
2506                 return;
2507         }
2508         bp_.useClassDefaults();
2509         paramsToDialog();
2510 }
2511
2512
2513 void GuiDocument::setLayoutComboByIDString(string const & idString)
2514 {
2515         int idx = classes_model_.findIDString(idString);
2516         if (idx < 0)
2517                 Alert::warning(_("Can't set layout!"), 
2518                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
2519         else 
2520                 latexModule->classCO->setCurrentIndex(idx);
2521 }
2522
2523
2524 bool GuiDocument::isValid()
2525 {
2526         return validateListingsParameters().isEmpty()
2527                 && (textLayoutModule->skipCO->currentIndex() != 3
2528                         || !textLayoutModule->skipLE->text().isEmpty());
2529 }
2530
2531
2532 char const * const GuiDocument::fontfamilies[5] = {
2533         "default", "rmdefault", "sfdefault", "ttdefault", ""
2534 };
2535
2536
2537 char const * GuiDocument::fontfamilies_gui[5] = {
2538         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
2539 };
2540
2541
2542 bool GuiDocument::initialiseParams(string const &)
2543 {
2544         BufferView const * view = bufferview();
2545         if (!view) {
2546                 bp_ = BufferParams();
2547                 paramsToDialog();
2548                 return true;
2549         }
2550         bp_ = view->buffer().params();
2551         loadModuleInfo();
2552         updateAvailableModules();
2553         //FIXME It'd be nice to make sure here that the selected
2554         //modules are consistent: That required modules are actually
2555         //selected, and that we don't have conflicts. If so, we could
2556         //at least pop up a warning.
2557         paramsToDialog();
2558         return true;
2559 }
2560
2561
2562 void GuiDocument::clearParams()
2563 {
2564         bp_ = BufferParams();
2565 }
2566
2567
2568 BufferId GuiDocument::id() const
2569 {
2570         BufferView const * const view = bufferview();
2571         return view? &view->buffer() : 0;
2572 }
2573
2574
2575 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
2576 {
2577         return moduleNames_;
2578 }
2579
2580
2581 list<GuiDocument::modInfoStruct> const 
2582                 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
2583 {
2584         LayoutModuleList::const_iterator it =  mods.begin();
2585         LayoutModuleList::const_iterator end = mods.end();
2586         list<modInfoStruct> mInfo;
2587         for (; it != end; ++it) {
2588                 modInfoStruct m;
2589                 m.id = *it;
2590                 LyXModule * mod = moduleList[*it];
2591                 if (mod)
2592                         // FIXME Unicode
2593                         m.name = toqstr(translateIfPossible(from_utf8(mod->getName())));
2594                 else 
2595                         m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
2596                 mInfo.push_back(m);
2597         }
2598         return mInfo;
2599 }
2600
2601
2602 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
2603 {
2604         return makeModuleInfo(params().getModules());
2605 }
2606
2607
2608 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
2609 {
2610         return makeModuleInfo(params().baseClass()->providedModules());
2611 }
2612
2613
2614 DocumentClass const & GuiDocument::documentClass() const
2615 {
2616         return bp_.documentClass();
2617 }
2618
2619
2620 static void dispatch_bufferparams(Dialog const & dialog,
2621         BufferParams const & bp, FuncCode lfun)
2622 {
2623         ostringstream ss;
2624         ss << "\\begin_header\n";
2625         bp.writeFile(ss);
2626         ss << "\\end_header\n";
2627         dialog.dispatch(FuncRequest(lfun, ss.str()));
2628 }
2629
2630
2631 void GuiDocument::dispatchParams()
2632 {
2633         // This must come first so that a language change is correctly noticed
2634         setLanguage();
2635
2636         // Apply the BufferParams. Note that this will set the base class
2637         // and then update the buffer's layout.
2638         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
2639
2640         if (!params().master.empty()) {
2641                 FileName const master_file = support::makeAbsPath(params().master,
2642                            support::onlyPath(buffer().absFileName()));
2643                 if (isLyXFilename(master_file.absFilename())) {
2644                         Buffer * master = checkAndLoadLyXFile(master_file);
2645                         if (master) {
2646                                 if (master->isChild(const_cast<Buffer *>(&buffer())))
2647                                         const_cast<Buffer &>(buffer()).setParent(master);
2648                                 else
2649                                         Alert::warning(_("Assigned master does not include this file"), 
2650                                                 bformat(_("You must include this file in the document\n"
2651                                                           "'%1$s' in order to use the master document\n"
2652                                                           "feature."), from_utf8(params().master)));
2653                         } else
2654                                 Alert::warning(_("Could not load master"), 
2655                                                 bformat(_("The master document '%1$s'\n"
2656                                                            "could not be loaded."),
2657                                                            from_utf8(params().master)));
2658                 }
2659         }
2660
2661         // Generate the colours requested by each new branch.
2662         BranchList & branchlist = params().branchlist();
2663         if (!branchlist.empty()) {
2664                 BranchList::const_iterator it = branchlist.begin();
2665                 BranchList::const_iterator const end = branchlist.end();
2666                 for (; it != end; ++it) {
2667                         docstring const & current_branch = it->branch();
2668                         Branch const * branch = branchlist.find(current_branch);
2669                         string const x11hexname = X11hexname(branch->color());
2670                         // display the new color
2671                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
2672                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
2673                 }
2674
2675                 // Open insets of selected branches, close deselected ones
2676                 dispatch(FuncRequest(LFUN_ALL_INSETS_TOGGLE,
2677                         "assign branch"));
2678         }
2679         // Generate the colours requested by indices.
2680         IndicesList & indiceslist = params().indiceslist();
2681         if (!indiceslist.empty()) {
2682                 IndicesList::const_iterator it = indiceslist.begin();
2683                 IndicesList::const_iterator const end = indiceslist.end();
2684                 for (; it != end; ++it) {
2685                         docstring const & current_index = it->index();
2686                         Index const * index = indiceslist.find(current_index);
2687                         string const x11hexname = X11hexname(index->color());
2688                         // display the new color
2689                         docstring const str = current_index + ' ' + from_ascii(x11hexname);
2690                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
2691                 }
2692         }
2693         // FIXME: If we used an LFUN, we would not need those two lines:
2694         BufferView * bv = const_cast<BufferView *>(bufferview());
2695         bv->processUpdateFlags(Update::Force | Update::FitCursor);
2696 }
2697
2698
2699 void GuiDocument::setLanguage() const
2700 {
2701         Language const * const newL = bp_.language;
2702         if (buffer().params().language == newL)
2703                 return;
2704
2705         string const & lang_name = newL->lang();
2706         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
2707 }
2708
2709
2710 void GuiDocument::saveAsDefault() const
2711 {
2712         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
2713 }
2714
2715
2716 bool GuiDocument::isFontAvailable(string const & font) const
2717 {
2718         if (font == "default" || font == "cmr"
2719             || font == "cmss" || font == "cmtt")
2720                 // these are standard
2721                 return true;
2722         if (font == "lmodern" || font == "lmss" || font == "lmtt")
2723                 return LaTeXFeatures::isAvailable("lmodern");
2724         if (font == "times" || font == "palatino"
2725                  || font == "helvet" || font == "courier")
2726                 return LaTeXFeatures::isAvailable("psnfss");
2727         if (font == "cmbr" || font == "cmtl")
2728                 return LaTeXFeatures::isAvailable("cmbright");
2729         if (font == "utopia")
2730                 return LaTeXFeatures::isAvailable("utopia")
2731                         || LaTeXFeatures::isAvailable("fourier");
2732         if (font == "beraserif" || font == "berasans"
2733                 || font == "beramono")
2734                 return LaTeXFeatures::isAvailable("bera");
2735         return LaTeXFeatures::isAvailable(font);
2736 }
2737
2738
2739 bool GuiDocument::providesOSF(string const & font) const
2740 {
2741         if (outputModule->xetexCB->isChecked())
2742                 // FIXME: we should check if the fonts really
2743                 // have OSF support. But how?
2744                 return true;
2745         if (font == "cmr")
2746                 return isFontAvailable("eco");
2747         if (font == "palatino")
2748                 return isFontAvailable("mathpazo");
2749         return false;
2750 }
2751
2752
2753 bool GuiDocument::providesSC(string const & font) const
2754 {
2755         if (outputModule->xetexCB->isChecked())
2756                 return false;
2757         if (font == "palatino")
2758                 return isFontAvailable("mathpazo");
2759         if (font == "utopia")
2760                 return isFontAvailable("fourier");
2761         return false;
2762 }
2763
2764
2765 bool GuiDocument::providesScale(string const & font) const
2766 {
2767         if (outputModule->xetexCB->isChecked())
2768                 return true;
2769         return font == "helvet" || font == "luximono"
2770                 || font == "berasans"  || font == "beramono";
2771 }
2772
2773
2774 void GuiDocument::loadModuleInfo()
2775 {
2776         moduleNames_.clear();
2777         LyXModuleList::const_iterator it  = moduleList.begin();
2778         LyXModuleList::const_iterator end = moduleList.end();
2779         for (; it != end; ++it) {
2780                 modInfoStruct m;
2781                 m.id = it->getID();
2782                 // FIXME Unicode
2783                 m.name = toqstr(translateIfPossible(from_utf8(it->getName())));
2784                 // this is supposed to give us the first sentence of the description
2785                 // FIXME Unicode
2786                 QString desc =
2787                         toqstr(translateIfPossible(from_utf8(it->getDescription())));
2788                 int const pos = desc.indexOf(".");
2789                 if (pos > 0)
2790                         desc.truncate(pos + 1);
2791                 m.description = desc;
2792                 moduleNames_.push_back(m);
2793         }
2794 }
2795
2796
2797 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
2798
2799
2800 } // namespace frontend
2801 } // namespace lyx
2802
2803 #include "moc_GuiDocument.cpp"