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