]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiDocument.cpp
Spotted by Jim Rotmalm.
[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 "GuiIndices.h"
19 #include "GuiSelectionManager.h"
20 #include "LaTeXHighlighter.h"
21 #include "LengthCombo.h"
22 #include "PanelStack.h"
23 #include "Validator.h"
24
25 #include "LayoutFile.h"
26 #include "BranchList.h"
27 #include "buffer_funcs.h"
28 #include "Buffer.h"
29 #include "BufferParams.h"
30 #include "BufferView.h"
31 #include "Color.h"
32 #include "ColorCache.h"
33 #include "Encoding.h"
34 #include "FloatPlacement.h"
35 #include "Format.h"
36 #include "FuncRequest.h"
37 #include "HSpace.h"
38 #include "IndicesList.h"
39 #include "Language.h"
40 #include "LaTeXFeatures.h"
41 #include "Layout.h"
42 #include "LayoutModuleList.h"
43 #include "LyXRC.h"
44 #include "ModuleList.h"
45 #include "OutputParams.h"
46 #include "PDFOptions.h"
47 #include "qt_helpers.h"
48 #include "Spacing.h"
49 #include "TextClass.h"
50
51 #include "insets/InsetListingsParams.h"
52
53 #include "support/debug.h"
54 #include "support/FileName.h"
55 #include "support/filetools.h"
56 #include "support/gettext.h"
57 #include "support/lstrings.h"
58
59 #include "frontends/alert.h"
60
61 #include <QAbstractItemModel>
62 #include <QHeaderView>
63 #include <QColor>
64 #include <QColorDialog>
65 #include <QCloseEvent>
66 #include <QFontDatabase>
67 #include <QScrollBar>
68 #include <QTextCursor>
69
70 #include <sstream>
71 #include <vector>
72
73 #ifdef IN
74 #undef IN
75 #endif
76
77
78 // a style sheet for buttons
79 // this is for example used for the background color setting button
80 static inline QString colorButtonStyleSheet(QColor const & bgColor)
81 {
82         if (bgColor.isValid()) {
83                 QString rc = QLatin1String("background-color:");
84                 rc += bgColor.name();
85                 return rc;
86         }
87         return QString();
88 }
89
90
91 using namespace std;
92 using namespace lyx::support;
93
94
95 namespace {
96
97 char const * const tex_graphics[] =
98 {
99         "default", "dvialw", "dvilaser", "dvipdf", "dvipdfm", "dvipdfmx",
100         "dvips", "dvipsone", "dvitops", "dviwin", "dviwindo", "dvi2ps", "emtex",
101         "ln", "oztex", "pctexhp", "pctexps", "pctexwin", "pctex32", "pdftex",
102         "psprint", "pubps", "tcidvi", "textures", "truetex", "vtex", "xdvi",
103         "xetex", "none", ""
104 };
105
106
107 char const * const tex_graphics_gui[] =
108 {
109         N_("Default"), "dvialw", "DviLaser", "dvipdf", "DVIPDFM", "DVIPDFMx",
110         "Dvips", "DVIPSONE", "DVItoPS", "DVIWIN", "DVIWindo", "dvi2ps", "EmTeX",
111         "LN", "OzTeX", "pctexhp", "pctexps", "pctexwin", "PCTeX32", "pdfTeX",
112         "psprint", "pubps", "tcidvi", "Textures", "TrueTeX", "VTeX", "xdvi",
113         "XeTeX", N_("None"), ""
114 };
115
116
117 char const * const tex_fonts_roman[] =
118 {
119         "default", "cmr", "lmodern", "ae", "times", "palatino",
120         "charter", "newcent", "bookman", "utopia", "beraserif",
121         "ccfonts", "chancery", ""
122 };
123
124
125 char const * tex_fonts_roman_gui[] =
126 {
127         N_("Default"), N_("Computer Modern Roman"), N_("Latin Modern Roman"),
128         N_("AE (Almost European)"), N_("Times Roman"), N_("Palatino"),
129         N_("Bitstream Charter"), N_("New Century Schoolbook"), N_("Bookman"),
130         N_("Utopia"),  N_("Bera Serif"), N_("Concrete Roman"), N_("Zapf Chancery"),
131         ""
132 };
133
134
135 char const * const tex_fonts_sans[] =
136 {
137         "default", "cmss", "lmss", "helvet", "avant", "berasans", "cmbr", ""
138 };
139
140
141 char const * tex_fonts_sans_gui[] =
142 {
143         N_("Default"), N_("Computer Modern Sans"), N_("Latin Modern Sans"),
144         N_("Helvetica"), N_("Avant Garde"), N_("Bera Sans"), N_("CM Bright"), ""
145 };
146
147
148 char const * const tex_fonts_monospaced[] =
149 {
150         "default", "cmtt", "lmtt", "courier", "beramono", "luximono", "cmtl", ""
151 };
152
153
154 char const * tex_fonts_monospaced_gui[] =
155 {
156         N_("Default"), N_("Computer Modern Typewriter"),
157         N_("Latin Modern Typewriter"), N_("Courier"), N_("Bera Mono"),
158         N_("LuxiMono"), N_("CM Typewriter Light"), ""
159 };
160
161
162 char const * backref_opts[] =
163 {
164         "false", "section", "slide", "page", ""
165 };
166
167
168 char const * backref_opts_gui[] =
169 {
170         N_("Off"), N_("Section"), N_("Slide"), N_("Page"), ""
171 };
172
173
174 vector<pair<string, QString> > pagestyles;
175
176
177 } // anonymous namespace
178
179 namespace lyx {
180
181 RGBColor set_backgroundcolor;
182 bool is_backgroundcolor;
183 RGBColor set_fontcolor;
184 bool is_fontcolor;
185 RGBColor set_notefontcolor;
186 RGBColor set_boxbgcolor;
187
188 namespace {
189 // used when sorting the textclass list.
190 class less_textclass_avail_desc
191         : public binary_function<string, string, int>
192 {
193 public:
194         bool operator()(string const & lhs, string const & rhs) const
195         {
196                 // Ordering criteria:
197                 //   1. Availability of text class
198                 //   2. Description (lexicographic)
199                 LayoutFile const & tc1 = LayoutFileList::get()[lhs];
200                 LayoutFile const & tc2 = LayoutFileList::get()[rhs];
201                 int const order = compare_no_case(
202                         translateIfPossible(from_utf8(tc1.description())),
203                         translateIfPossible(from_utf8(tc2.description())));
204                 return (tc1.isTeXClassAvailable() && !tc2.isTeXClassAvailable()) ||
205                         (tc1.isTeXClassAvailable() == tc2.isTeXClassAvailable() && order < 0);
206         }
207 };
208
209 }
210
211 namespace frontend {
212 namespace {
213
214 vector<string> getRequiredList(string const & modName) 
215 {
216         LyXModule const * const mod = theModuleList[modName];
217         if (!mod)
218                 return vector<string>(); //empty such thing
219         return mod->getRequiredModules();
220 }
221
222
223 vector<string> getExcludedList(string const & modName)
224 {
225         LyXModule const * const mod = theModuleList[modName];
226         if (!mod)
227                 return vector<string>(); //empty such thing
228         return mod->getExcludedModules();
229 }
230
231
232 docstring getModuleDescription(string const & modName)
233 {
234         LyXModule const * const mod = theModuleList[modName];
235         if (!mod)
236                 return _("Module not found!");
237         // FIXME Unicode
238         return translateIfPossible(from_utf8(mod->getDescription()));
239 }
240
241
242 vector<string> getPackageList(string const & modName)
243 {
244         LyXModule const * const mod = theModuleList[modName];
245         if (!mod)
246                 return vector<string>(); //empty such thing
247         return mod->getPackageList();
248 }
249
250
251 bool isModuleAvailable(string const & modName)
252 {
253         LyXModule const * const mod = theModuleList[modName];
254         if (!mod)
255                 return false;
256         return mod->isAvailable();
257 }
258
259 } // anonymous namespace
260
261
262 /////////////////////////////////////////////////////////////////////
263 //
264 // ModuleSelectionManager
265 //
266 /////////////////////////////////////////////////////////////////////
267
268 /// SelectionManager for use with modules
269 class ModuleSelectionManager : public GuiSelectionManager 
270 {
271 public:
272         ///
273         ModuleSelectionManager(
274                 QTreeView * availableLV,
275                 QListView * selectedLV,
276                 QPushButton * addPB, 
277                 QPushButton * delPB, 
278                 QPushButton * upPB, 
279                 QPushButton * downPB,
280                 GuiIdListModel * availableModel,
281                 GuiIdListModel * selectedModel,
282                 GuiDocument const * container)
283         : GuiSelectionManager(availableLV, selectedLV, addPB, delPB,
284                                 upPB, downPB, availableModel, selectedModel), container_(container)
285                 {}
286         ///
287         void updateProvidedModules(LayoutModuleList const & pm) 
288                         { provided_modules_ = pm.list(); }
289         ///
290         void updateExcludedModules(LayoutModuleList const & em) 
291                         { excluded_modules_ = em.list(); }
292 private:
293         ///
294         virtual void updateAddPB();
295         ///
296         virtual void updateUpPB();
297         ///
298         virtual void updateDownPB();
299         ///
300         virtual void updateDelPB();
301         /// returns availableModel as a GuiIdListModel
302         GuiIdListModel * getAvailableModel() 
303         {
304                 return dynamic_cast<GuiIdListModel *>(availableModel);
305         }
306         /// returns selectedModel as a GuiIdListModel
307         GuiIdListModel * getSelectedModel() 
308         {
309                 return dynamic_cast<GuiIdListModel *>(selectedModel);
310         }
311         /// keeps a list of the modules the text class provides
312         list<string> provided_modules_;
313         /// similarly...
314         list<string> excluded_modules_;
315         /// 
316         GuiDocument const * container_;
317 };
318
319 void ModuleSelectionManager::updateAddPB() 
320 {
321         int const arows = availableModel->rowCount();
322         QModelIndexList const avail_sels = 
323                         availableLV->selectionModel()->selectedIndexes();
324
325         // disable if there aren't any modules (?), if none of them is chosen
326         // in the dialog, or if the chosen one is already selected for use.
327         if (arows == 0 || avail_sels.isEmpty() || isSelected(avail_sels.first())) {
328                 addPB->setEnabled(false);
329                 return;
330         }
331
332         QModelIndex const & idx = availableLV->selectionModel()->currentIndex();
333         string const modname = getAvailableModel()->getIDString(idx.row());
334
335         bool const enable = 
336                 container_->params().moduleCanBeAdded(modname);
337         addPB->setEnabled(enable);
338 }
339
340
341 void ModuleSelectionManager::updateDownPB()
342 {
343         int const srows = selectedModel->rowCount();
344         if (srows == 0) {
345                 downPB->setEnabled(false);
346                 return;
347         }
348         QModelIndex const & curidx = selectedLV->selectionModel()->currentIndex();
349         int const curRow = curidx.row();
350         if (curRow < 0 || curRow >= srows - 1) { // invalid or last item
351                 downPB->setEnabled(false);
352                 return;
353         }
354
355         // determine whether immediately succeding element requires this one
356         string const curmodname = getSelectedModel()->getIDString(curRow);
357         string const nextmodname = getSelectedModel()->getIDString(curRow + 1);
358
359         vector<string> reqs = getRequiredList(nextmodname);
360
361         // if it doesn't require anything....
362         if (reqs.empty()) {
363                 downPB->setEnabled(true);
364                 return;
365         }
366
367         // Enable it if this module isn't required.
368         // FIXME This should perhaps be more flexible and check whether, even 
369         // if the next one is required, there is also an earlier one that will do.
370         downPB->setEnabled(
371                         find(reqs.begin(), reqs.end(), curmodname) == reqs.end());
372 }
373
374 void ModuleSelectionManager::updateUpPB() 
375 {
376         int const srows = selectedModel->rowCount();
377         if (srows == 0) {
378                 upPB->setEnabled(false);
379                 return;
380         }
381
382         QModelIndex const & curIdx = selectedLV->selectionModel()->currentIndex();
383         int curRow = curIdx.row();
384         if (curRow <= 0 || curRow > srows - 1) { // first item or invalid
385                 upPB->setEnabled(false);
386                 return;
387         }
388         string const curmodname = getSelectedModel()->getIDString(curRow);
389
390         // determine whether immediately preceding element is required by this one
391         vector<string> reqs = getRequiredList(curmodname);
392
393         // if this one doesn't require anything....
394         if (reqs.empty()) {
395                 upPB->setEnabled(true);
396                 return;
397         }
398
399
400         // Enable it if the preceding module isn't required.
401         // NOTE This is less flexible than it might be. We could check whether, even 
402         // if the previous one is required, there is an earlier one that would do.
403         string const premod = getSelectedModel()->getIDString(curRow - 1);
404         upPB->setEnabled(find(reqs.begin(), reqs.end(), premod) == reqs.end());
405 }
406
407 void ModuleSelectionManager::updateDelPB() 
408 {
409         int const srows = selectedModel->rowCount();
410         if (srows == 0) {
411                 deletePB->setEnabled(false);
412                 return;
413         }
414
415         QModelIndex const & curidx = 
416                 selectedLV->selectionModel()->currentIndex();
417         int const curRow = curidx.row();
418         if (curRow < 0 || curRow >= srows) { // invalid index?
419                 deletePB->setEnabled(false);
420                 return;
421         }
422
423         string const curmodname = getSelectedModel()->getIDString(curRow);
424
425         // We're looking here for a reason NOT to enable the button. If we
426         // find one, we disable it and return. If we don't, we'll end up at
427         // the end of the function, and then we enable it.
428         for (int i = curRow + 1; i < srows; ++i) {
429                 string const thisMod = getSelectedModel()->getIDString(i);
430                 vector<string> reqs = getRequiredList(thisMod);
431                 //does this one require us?
432                 if (find(reqs.begin(), reqs.end(), curmodname) == reqs.end())
433                         //no...
434                         continue;
435
436                 // OK, so this module requires us
437                 // is there an EARLIER module that also satisfies the require?
438                 // NOTE We demand that it be earlier to keep the list of modules
439                 // consistent with the rule that a module must be proceeded by a
440                 // required module. There would be more flexible ways to proceed,
441                 // but that would be a lot more complicated, and the logic here is
442                 // already complicated. (That's why I've left the debugging code.)
443                 // lyxerr << "Testing " << thisMod << endl;
444                 bool foundone = false;
445                 for (int j = 0; j < curRow; ++j) {
446                         string const mod = getSelectedModel()->getIDString(j);
447                         // lyxerr << "In loop: Testing " << mod << endl;
448                         // do we satisfy the require? 
449                         if (find(reqs.begin(), reqs.end(), mod) != reqs.end()) {
450                                 // lyxerr << mod << " does the trick." << endl;
451                                 foundone = true;
452                                 break;
453                         }
454                 }
455                 // did we find a module to satisfy the require?
456                 if (!foundone) {
457                         // lyxerr << "No matching module found." << endl;
458                         deletePB->setEnabled(false);
459                         return;
460                 }
461         }
462         // lyxerr << "All's well that ends well." << endl;
463         deletePB->setEnabled(true);
464 }
465
466
467 /////////////////////////////////////////////////////////////////////
468 //
469 // PreambleModule
470 //
471 /////////////////////////////////////////////////////////////////////
472
473 PreambleModule::PreambleModule() : current_id_(0)
474 {
475         // This is not a memory leak. The object will be destroyed
476         // with this.
477         (void) new LaTeXHighlighter(preambleTE->document());
478         setFocusProxy(preambleTE);
479         connect(preambleTE, SIGNAL(textChanged()), this, SIGNAL(changed()));
480 }
481
482
483 void PreambleModule::update(BufferParams const & params, BufferId id)
484 {
485         QString preamble = toqstr(params.preamble);
486         // Nothing to do if the params and preamble are unchanged.
487         if (id == current_id_
488                 && preamble == preambleTE->document()->toPlainText())
489                 return;
490
491         QTextCursor cur = preambleTE->textCursor();
492         // Save the coords before switching to the new one.
493         preamble_coords_[current_id_] =
494                 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
495
496         // Save the params address for further use.
497         current_id_ = id;
498         preambleTE->document()->setPlainText(preamble);
499         Coords::const_iterator it = preamble_coords_.find(current_id_);
500         if (it == preamble_coords_.end())
501                 // First time we open this one.
502                 preamble_coords_[current_id_] = make_pair(0, 0);
503         else {
504                 // Restore saved coords.
505                 QTextCursor cur = preambleTE->textCursor();
506                 cur.setPosition(it->second.first);
507                 preambleTE->setTextCursor(cur);
508                 preambleTE->verticalScrollBar()->setValue(it->second.second);
509         }
510 }
511
512
513 void PreambleModule::apply(BufferParams & params)
514 {
515         params.preamble = fromqstr(preambleTE->document()->toPlainText());
516 }
517
518
519 void PreambleModule::closeEvent(QCloseEvent * e)
520 {
521         // Save the coords before closing.
522         QTextCursor cur = preambleTE->textCursor();
523         preamble_coords_[current_id_] =
524                 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
525         e->accept();
526 }
527
528
529 /////////////////////////////////////////////////////////////////////
530 //
531 // LocalLayout
532 //
533 /////////////////////////////////////////////////////////////////////
534
535
536 LocalLayout::LocalLayout() : current_id_(0), is_valid_(false)
537 {
538         connect(locallayoutTE, SIGNAL(textChanged()), this, SLOT(textChanged()));
539         connect(validatePB, SIGNAL(clicked()), this, SLOT(validatePressed()));
540 }
541
542
543 void LocalLayout::update(BufferParams const & params, BufferId id)
544 {
545         QString layout = toqstr(params.local_layout);
546         // Nothing to do if the params and preamble are unchanged.
547         if (id == current_id_
548                 && layout == locallayoutTE->document()->toPlainText())
549                 return;
550
551         // Save the params address for further use.
552         current_id_ = id;
553         locallayoutTE->document()->setPlainText(layout);
554         validate();
555 }
556
557
558 void LocalLayout::apply(BufferParams & params)
559 {
560         string const layout = fromqstr(locallayoutTE->document()->toPlainText());
561         params.local_layout = layout;
562 }
563
564
565 void LocalLayout::textChanged()
566 {
567         static const QString unknown = qt_("Press button to check validity...");
568
569         is_valid_ = false;
570         infoLB->setText(unknown);
571         validatePB->setEnabled(true);
572         changed();
573 }
574
575
576 void LocalLayout::validate() {
577         static const QString valid = qt_("Layout is valid!");
578         static const QString vtext =
579                 toqstr("<p style=\"font-weight: bold; \">") 
580                   + valid + toqstr("</p>");
581         static const QString invalid = qt_("Layout is invalid!");
582         static const QString ivtext =
583                 toqstr("<p style=\"color: #c00000; font-weight: bold; \">") 
584                   + invalid + toqstr("</p>");
585
586         string const layout = 
587                 fromqstr(locallayoutTE->document()->toPlainText().trimmed());
588         if (layout.empty()) {
589                 is_valid_ = true;
590                 infoLB->setText("");
591         } else {
592                 is_valid_ = TextClass::validate(layout);
593                 infoLB->setText(is_valid_ ? vtext : ivtext);
594         }
595         validatePB->setEnabled(false);
596 }
597
598
599 void LocalLayout::validatePressed() {
600         validate();
601         changed();
602 }
603
604
605 /////////////////////////////////////////////////////////////////////
606 //
607 // DocumentDialog
608 //
609 /////////////////////////////////////////////////////////////////////
610
611
612 GuiDocument::GuiDocument(GuiView & lv)
613         : GuiDialog(lv, "document", qt_("Document Settings"))
614 {
615         setupUi(this);
616
617         connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
618         connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
619         connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
620         connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore()));
621
622         connect(savePB, SIGNAL(clicked()), this, SLOT(saveDefaultClicked()));
623         connect(defaultPB, SIGNAL(clicked()), this, SLOT(useDefaultsClicked()));
624
625         // Manage the restore, ok, apply, restore and cancel/close buttons
626         bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
627         bc().setOK(okPB);
628         bc().setApply(applyPB);
629         bc().setCancel(closePB);
630         bc().setRestore(restorePB);
631
632
633         // text layout
634         textLayoutModule = new UiWidget<Ui::TextLayoutUi>;
635         connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
636                 this, SLOT(change_adaptor()));
637         connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
638                 this, SLOT(setLSpacing(int)));
639         connect(textLayoutModule->lspacingLE, SIGNAL(textChanged(const QString &)),
640                 this, SLOT(change_adaptor()));
641
642         connect(textLayoutModule->indentRB, SIGNAL(clicked()),
643                 this, SLOT(change_adaptor()));
644         connect(textLayoutModule->indentRB, SIGNAL(toggled(bool)),
645                 textLayoutModule->indentCO, SLOT(setEnabled(bool)));
646         connect(textLayoutModule->indentCO, SIGNAL(activated(int)),
647                 this, SLOT(change_adaptor()));
648         connect(textLayoutModule->indentCO, SIGNAL(activated(int)),
649                 this, SLOT(setIndent(int)));
650         connect(textLayoutModule->indentLE, SIGNAL(textChanged(const QString &)),
651                 this, SLOT(change_adaptor()));
652         connect(textLayoutModule->indentLengthCO, SIGNAL(activated(int)),
653                 this, SLOT(change_adaptor()));
654
655         connect(textLayoutModule->skipRB, SIGNAL(clicked()),
656                 this, SLOT(change_adaptor()));
657         connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
658                 textLayoutModule->skipCO, SLOT(setEnabled(bool)));
659         connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
660                 this, SLOT(change_adaptor()));
661         connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
662                 this, SLOT(setSkip(int)));
663         connect(textLayoutModule->skipLE, SIGNAL(textChanged(const QString &)),
664                 this, SLOT(change_adaptor()));
665         connect(textLayoutModule->skipLengthCO, SIGNAL(activated(int)),
666                 this, SLOT(change_adaptor()));
667
668         connect(textLayoutModule->indentRB, SIGNAL(toggled(bool)),
669                 this, SLOT(enableIndent(bool)));
670         connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
671                 this, SLOT(enableSkip(bool)));
672
673         connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
674                 this, SLOT(change_adaptor()));
675         connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
676                 this, SLOT(setColSep()));
677
678         textLayoutModule->lspacingLE->setValidator(new QDoubleValidator(
679                 textLayoutModule->lspacingLE));
680         textLayoutModule->indentLE->setValidator(unsignedLengthValidator(
681                 textLayoutModule->indentLE));
682         textLayoutModule->skipLE->setValidator(unsignedGlueLengthValidator(
683                 textLayoutModule->skipLE));
684
685         textLayoutModule->indentCO->addItem(qt_("Default"));
686         textLayoutModule->indentCO->addItem(qt_("Custom"));
687         textLayoutModule->skipCO->addItem(qt_("SmallSkip"));
688         textLayoutModule->skipCO->addItem(qt_("MedSkip"));
689         textLayoutModule->skipCO->addItem(qt_("BigSkip"));
690         textLayoutModule->skipCO->addItem(qt_("Custom"));
691         textLayoutModule->lspacingCO->insertItem(
692                 Spacing::Single, qt_("Single"));
693         textLayoutModule->lspacingCO->insertItem(
694                 Spacing::Onehalf, qt_("OneHalf"));
695         textLayoutModule->lspacingCO->insertItem(
696                 Spacing::Double, qt_("Double"));
697         textLayoutModule->lspacingCO->insertItem(
698                 Spacing::Other, qt_("Custom"));
699         // initialize the length validator
700         bc().addCheckedLineEdit(textLayoutModule->indentLE);
701         bc().addCheckedLineEdit(textLayoutModule->skipLE);
702
703
704         // master/child handling
705         masterChildModule = new UiWidget<Ui::MasterChildUi>;
706
707         connect(masterChildModule->childrenTW, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),
708                 this, SLOT(includeonlyClicked(QTreeWidgetItem *, int)));
709         connect(masterChildModule->includeonlyRB, SIGNAL(toggled(bool)),
710                 masterChildModule->childrenTW, SLOT(setEnabled(bool)));
711         connect(masterChildModule->includeonlyRB, SIGNAL(toggled(bool)),
712                 masterChildModule->maintainAuxCB, SLOT(setEnabled(bool)));
713         connect(masterChildModule->includeallRB, SIGNAL(clicked()),
714                 this, SLOT(change_adaptor()));
715         connect(masterChildModule->includeonlyRB, SIGNAL(clicked()),
716                 this, SLOT(change_adaptor()));
717         connect(masterChildModule->maintainAuxCB, SIGNAL(clicked()),
718                 this, SLOT(change_adaptor()));
719         masterChildModule->childrenTW->setColumnCount(2);
720         masterChildModule->childrenTW->headerItem()->setText(0, qt_("Child Document"));
721         masterChildModule->childrenTW->headerItem()->setText(1, qt_("Include to Output"));
722         masterChildModule->childrenTW->resizeColumnToContents(1);
723         masterChildModule->childrenTW->resizeColumnToContents(2);
724
725
726         // output
727         outputModule = new UiWidget<Ui::OutputUi>;
728
729         connect(outputModule->defaultFormatCO, SIGNAL(activated(int)),
730                 this, SLOT(change_adaptor()));
731         connect(outputModule->mathimgSB, SIGNAL(valueChanged(double)),
732                 this, SLOT(change_adaptor()));
733         connect(outputModule->strictCB, SIGNAL(stateChanged(int)),
734                 this, SLOT(change_adaptor()));
735         connect(outputModule->mathoutCB, SIGNAL(currentIndexChanged(int)),
736                 this, SLOT(change_adaptor()));
737
738         connect(outputModule->outputsyncCB, SIGNAL(clicked()),
739                 this, SLOT(change_adaptor()));
740         connect(outputModule->synccustomCB, SIGNAL(editTextChanged(QString)),
741                 this, SLOT(change_adaptor()));
742         outputModule->synccustomCB->addItem("");
743         outputModule->synccustomCB->addItem("\\synctex=1");
744         outputModule->synccustomCB->addItem("\\synctex=-1");
745         outputModule->synccustomCB->addItem("\\usepackage[active]{srcltx}");
746
747         // fonts
748         fontModule = new UiWidget<Ui::FontUi>;
749         connect(fontModule->osFontsCB, SIGNAL(clicked()),
750                 this, SLOT(change_adaptor()));
751         connect(fontModule->osFontsCB, SIGNAL(toggled(bool)),
752                 this, SLOT(osFontsChanged(bool)));
753         connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
754                 this, SLOT(change_adaptor()));
755         connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
756                 this, SLOT(romanChanged(int)));
757         connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
758                 this, SLOT(change_adaptor()));
759         connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
760                 this, SLOT(sansChanged(int)));
761         connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
762                 this, SLOT(change_adaptor()));
763         connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
764                 this, SLOT(ttChanged(int)));
765         connect(fontModule->fontsDefaultCO, SIGNAL(activated(int)),
766                 this, SLOT(change_adaptor()));
767         connect(fontModule->fontencCO, SIGNAL(activated(int)),
768                 this, SLOT(change_adaptor()));
769         connect(fontModule->fontencCO, SIGNAL(activated(int)),
770                 this, SLOT(fontencChanged(int)));
771         connect(fontModule->fontencLE, SIGNAL(textChanged(const QString &)),
772                 this, SLOT(change_adaptor()));
773         connect(fontModule->fontsizeCO, SIGNAL(activated(int)),
774                 this, SLOT(change_adaptor()));
775         connect(fontModule->cjkFontLE, SIGNAL(textChanged(const QString &)),
776                 this, SLOT(change_adaptor()));
777         connect(fontModule->scaleSansSB, SIGNAL(valueChanged(int)),
778                 this, SLOT(change_adaptor()));
779         connect(fontModule->scaleTypewriterSB, SIGNAL(valueChanged(int)),
780                 this, SLOT(change_adaptor()));
781         connect(fontModule->fontScCB, SIGNAL(clicked()),
782                 this, SLOT(change_adaptor()));
783         connect(fontModule->fontOsfCB, SIGNAL(clicked()),
784                 this, SLOT(change_adaptor()));
785
786         updateFontlist();
787
788         fontModule->fontsizeCO->addItem(qt_("Default"));
789         fontModule->fontsizeCO->addItem(qt_("10"));
790         fontModule->fontsizeCO->addItem(qt_("11"));
791         fontModule->fontsizeCO->addItem(qt_("12"));
792
793         fontModule->fontencCO->addItem(qt_("Default"));
794         fontModule->fontencCO->addItem(qt_("Custom"));
795         fontModule->fontencCO->addItem(qt_("None (no fontenc)"));
796
797         for (int n = 0; GuiDocument::fontfamilies_gui[n][0]; ++n)
798                 fontModule->fontsDefaultCO->addItem(
799                         qt_(GuiDocument::fontfamilies_gui[n]));
800
801
802         // page layout
803         pageLayoutModule = new UiWidget<Ui::PageLayoutUi>;
804         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
805                 this, SLOT(papersizeChanged(int)));
806         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
807                 this, SLOT(papersizeChanged(int)));
808         connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
809                 this, SLOT(change_adaptor()));
810         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
811                 this, SLOT(change_adaptor()));
812         connect(pageLayoutModule->paperheightLE, SIGNAL(textChanged(const QString &)),
813                 this, SLOT(change_adaptor()));
814         connect(pageLayoutModule->paperwidthLE, SIGNAL(textChanged(const QString &)),
815                 this, SLOT(change_adaptor()));
816         connect(pageLayoutModule->paperwidthUnitCO, SIGNAL(activated(int)),
817                 this, SLOT(change_adaptor()));
818         connect(pageLayoutModule->paperheightUnitCO, SIGNAL(activated(int)),
819                 this, SLOT(change_adaptor()));
820         connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
821                 this, SLOT(change_adaptor()));
822         connect(pageLayoutModule->landscapeRB, SIGNAL(clicked()),
823                 this, SLOT(change_adaptor()));
824         connect(pageLayoutModule->facingPagesCB, SIGNAL(clicked()),
825                 this, SLOT(change_adaptor()));
826         connect(pageLayoutModule->pagestyleCO, SIGNAL(activated(int)),
827                 this, SLOT(change_adaptor()));
828         
829         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
830         pageLayoutModule->pagestyleCO->addItem(qt_("empty"));
831         pageLayoutModule->pagestyleCO->addItem(qt_("plain"));
832         pageLayoutModule->pagestyleCO->addItem(qt_("headings"));
833         pageLayoutModule->pagestyleCO->addItem(qt_("fancy"));
834         bc().addCheckedLineEdit(pageLayoutModule->paperheightLE,
835                 pageLayoutModule->paperheightL);
836         bc().addCheckedLineEdit(pageLayoutModule->paperwidthLE,
837                 pageLayoutModule->paperwidthL);
838
839         QComboBox * cb = pageLayoutModule->papersizeCO;
840         cb->addItem(qt_("Default"));
841         cb->addItem(qt_("Custom"));
842         cb->addItem(qt_("US letter"));
843         cb->addItem(qt_("US legal"));
844         cb->addItem(qt_("US executive"));
845         cb->addItem(qt_("A0"));
846         cb->addItem(qt_("A1"));
847         cb->addItem(qt_("A2"));
848         cb->addItem(qt_("A3"));
849         cb->addItem(qt_("A4"));
850         cb->addItem(qt_("A5"));
851         cb->addItem(qt_("A6"));
852         cb->addItem(qt_("B0"));
853         cb->addItem(qt_("B1"));
854         cb->addItem(qt_("B2"));
855         cb->addItem(qt_("B3"));
856         cb->addItem(qt_("B4"));
857         cb->addItem(qt_("B5"));
858         cb->addItem(qt_("B6"));
859         cb->addItem(qt_("C0"));
860         cb->addItem(qt_("C1"));
861         cb->addItem(qt_("C2"));
862         cb->addItem(qt_("C3"));
863         cb->addItem(qt_("C4"));
864         cb->addItem(qt_("C5"));
865         cb->addItem(qt_("C6"));
866         cb->addItem(qt_("JIS B0"));
867         cb->addItem(qt_("JIS B1"));
868         cb->addItem(qt_("JIS B2"));
869         cb->addItem(qt_("JIS B3"));
870         cb->addItem(qt_("JIS B4"));
871         cb->addItem(qt_("JIS B5"));
872         cb->addItem(qt_("JIS B6"));
873         // remove the %-items from the unit choice
874         pageLayoutModule->paperwidthUnitCO->noPercents();
875         pageLayoutModule->paperheightUnitCO->noPercents();
876         pageLayoutModule->paperheightLE->setValidator(unsignedLengthValidator(
877                 pageLayoutModule->paperheightLE));
878         pageLayoutModule->paperwidthLE->setValidator(unsignedLengthValidator(
879                 pageLayoutModule->paperwidthLE));
880
881
882         // margins
883         marginsModule = new UiWidget<Ui::MarginsUi>;
884         connect(marginsModule->marginCB, SIGNAL(toggled(bool)),
885                 this, SLOT(setCustomMargins(bool)));
886         connect(marginsModule->marginCB, SIGNAL(clicked()),
887                 this, SLOT(change_adaptor()));
888         connect(marginsModule->topLE, SIGNAL(textChanged(QString)),
889                 this, SLOT(change_adaptor()));
890         connect(marginsModule->topUnit, SIGNAL(activated(int)),
891                 this, SLOT(change_adaptor()));
892         connect(marginsModule->bottomLE, SIGNAL(textChanged(QString)),
893                 this, SLOT(change_adaptor()));
894         connect(marginsModule->bottomUnit, SIGNAL(activated(int)),
895                 this, SLOT(change_adaptor()));
896         connect(marginsModule->innerLE, SIGNAL(textChanged(QString)),
897                 this, SLOT(change_adaptor()));
898         connect(marginsModule->innerUnit, SIGNAL(activated(int)),
899                 this, SLOT(change_adaptor()));
900         connect(marginsModule->outerLE, SIGNAL(textChanged(QString)),
901                 this, SLOT(change_adaptor()));
902         connect(marginsModule->outerUnit, SIGNAL(activated(int)),
903                 this, SLOT(change_adaptor()));
904         connect(marginsModule->headheightLE, SIGNAL(textChanged(QString)),
905                 this, SLOT(change_adaptor()));
906         connect(marginsModule->headheightUnit, SIGNAL(activated(int)),
907                 this, SLOT(change_adaptor()));
908         connect(marginsModule->headsepLE, SIGNAL(textChanged(QString)),
909                 this, SLOT(change_adaptor()));
910         connect(marginsModule->headsepUnit, SIGNAL(activated(int)),
911                 this, SLOT(change_adaptor()));
912         connect(marginsModule->footskipLE, SIGNAL(textChanged(QString)),
913                 this, SLOT(change_adaptor()));
914         connect(marginsModule->footskipUnit, SIGNAL(activated(int)),
915                 this, SLOT(change_adaptor()));
916         connect(marginsModule->columnsepLE, SIGNAL(textChanged(QString)),
917                 this, SLOT(change_adaptor()));
918         connect(marginsModule->columnsepUnit, SIGNAL(activated(int)),
919                 this, SLOT(change_adaptor()));
920         marginsModule->topLE->setValidator(unsignedLengthValidator(
921                 marginsModule->topLE));
922         marginsModule->bottomLE->setValidator(unsignedLengthValidator(
923                 marginsModule->bottomLE));
924         marginsModule->innerLE->setValidator(unsignedLengthValidator(
925                 marginsModule->innerLE));
926         marginsModule->outerLE->setValidator(unsignedLengthValidator(
927                 marginsModule->outerLE));
928         marginsModule->headsepLE->setValidator(unsignedLengthValidator(
929                 marginsModule->headsepLE));
930         marginsModule->headheightLE->setValidator(unsignedLengthValidator(
931                 marginsModule->headheightLE));
932         marginsModule->footskipLE->setValidator(unsignedLengthValidator(
933                 marginsModule->footskipLE));
934         marginsModule->columnsepLE->setValidator(unsignedLengthValidator(
935                 marginsModule->columnsepLE));
936
937         bc().addCheckedLineEdit(marginsModule->topLE,
938                 marginsModule->topL);
939         bc().addCheckedLineEdit(marginsModule->bottomLE,
940                 marginsModule->bottomL);
941         bc().addCheckedLineEdit(marginsModule->innerLE,
942                 marginsModule->innerL);
943         bc().addCheckedLineEdit(marginsModule->outerLE,
944                 marginsModule->outerL);
945         bc().addCheckedLineEdit(marginsModule->headsepLE,
946                 marginsModule->headsepL);
947         bc().addCheckedLineEdit(marginsModule->headheightLE,
948                 marginsModule->headheightL);
949         bc().addCheckedLineEdit(marginsModule->footskipLE,
950                 marginsModule->footskipL);
951         bc().addCheckedLineEdit(marginsModule->columnsepLE,
952                 marginsModule->columnsepL);
953
954
955         // language & quote
956         langModule = new UiWidget<Ui::LanguageUi>;
957         connect(langModule->languageCO, SIGNAL(activated(int)),
958                 this, SLOT(change_adaptor()));
959         connect(langModule->defaultencodingRB, SIGNAL(clicked()),
960                 this, SLOT(change_adaptor()));
961         connect(langModule->otherencodingRB, SIGNAL(clicked()),
962                 this, SLOT(change_adaptor()));
963         connect(langModule->encodingCO, SIGNAL(activated(int)),
964                 this, SLOT(change_adaptor()));
965         connect(langModule->quoteStyleCO, SIGNAL(activated(int)),
966                 this, SLOT(change_adaptor()));
967         connect(langModule->languagePackageCO, SIGNAL(activated(int)),
968                 this, SLOT(change_adaptor()));
969         connect(langModule->languagePackageED, SIGNAL(textChanged(QString)),
970                 this, SLOT(change_adaptor()));
971         connect(langModule->languagePackageCO, SIGNAL(currentIndexChanged(int)),
972                 this, SLOT(languagePackageChanged(int)));
973
974         QAbstractItemModel * language_model = guiApp->languageModel();
975         // FIXME: it would be nice if sorting was enabled/disabled via a checkbox.
976         language_model->sort(0);
977         langModule->languageCO->setModel(language_model);
978         langModule->languageCO->setModelColumn(0);
979
980         // Always put the default encoding in the first position.
981         langModule->encodingCO->addItem(qt_("Language Default (no inputenc)"));
982         QStringList encodinglist;
983         Encodings::const_iterator it = encodings.begin();
984         Encodings::const_iterator const end = encodings.end();
985         for (; it != end; ++it)
986                 encodinglist.append(qt_(it->guiName()));
987         encodinglist.sort();
988         langModule->encodingCO->addItems(encodinglist);
989
990         langModule->quoteStyleCO->addItem(qt_("``text''"));
991         langModule->quoteStyleCO->addItem(qt_("''text''"));
992         langModule->quoteStyleCO->addItem(qt_(",,text``"));
993         langModule->quoteStyleCO->addItem(qt_(",,text''"));
994         langModule->quoteStyleCO->addItem(qt_("<<text>>"));
995         langModule->quoteStyleCO->addItem(qt_(">>text<<"));
996
997         langModule->languagePackageCO->addItem(
998                 qt_("Default"), toqstr("default"));
999         langModule->languagePackageCO->addItem(
1000                 qt_("Automatic"), toqstr("auto"));
1001         langModule->languagePackageCO->addItem(
1002                 qt_("Always Babel"), toqstr("babel"));
1003         langModule->languagePackageCO->addItem(
1004                 qt_("Custom"), toqstr("custom"));
1005         langModule->languagePackageCO->addItem(
1006                 qt_("None[[language package]]"), toqstr("none"));
1007
1008
1009         // color
1010         colorModule = new UiWidget<Ui::ColorUi>;
1011         connect(colorModule->fontColorPB, SIGNAL(clicked()),
1012                 this, SLOT(changeFontColor()));
1013         connect(colorModule->delFontColorTB, SIGNAL(clicked()),
1014                 this, SLOT(deleteFontColor()));
1015         connect(colorModule->noteFontColorPB, SIGNAL(clicked()),
1016                 this, SLOT(changeNoteFontColor()));
1017         connect(colorModule->delNoteFontColorTB, SIGNAL(clicked()),
1018                 this, SLOT(deleteNoteFontColor()));
1019         connect(colorModule->backgroundPB, SIGNAL(clicked()),
1020                 this, SLOT(changeBackgroundColor()));
1021         connect(colorModule->delBackgroundTB, SIGNAL(clicked()),
1022                 this, SLOT(deleteBackgroundColor()));
1023         connect(colorModule->boxBackgroundPB, SIGNAL(clicked()),
1024                 this, SLOT(changeBoxBackgroundColor()));
1025         connect(colorModule->delBoxBackgroundTB, SIGNAL(clicked()),
1026                 this, SLOT(deleteBoxBackgroundColor()));
1027
1028
1029         // numbering
1030         numberingModule = new UiWidget<Ui::NumberingUi>;
1031         connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
1032                 this, SLOT(change_adaptor()));
1033         connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
1034                 this, SLOT(change_adaptor()));
1035         connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
1036                 this, SLOT(updateNumbering()));
1037         connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
1038                 this, SLOT(updateNumbering()));
1039         numberingModule->tocTW->setColumnCount(3);
1040         numberingModule->tocTW->headerItem()->setText(0, qt_("Example"));
1041         numberingModule->tocTW->headerItem()->setText(1, qt_("Numbered"));
1042         numberingModule->tocTW->headerItem()->setText(2, qt_("Appears in TOC"));
1043
1044
1045         // biblio
1046         biblioModule = new UiWidget<Ui::BiblioUi>;
1047         connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
1048                 biblioModule->citationStyleL, SLOT(setEnabled(bool)));
1049         connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
1050                 biblioModule->citeStyleCO, SLOT(setEnabled(bool)));
1051         connect(biblioModule->citeDefaultRB, SIGNAL(clicked()),
1052                 this, SLOT(change_adaptor()));
1053         connect(biblioModule->citeNatbibRB, SIGNAL(clicked()),
1054                 this, SLOT(change_adaptor()));
1055         connect(biblioModule->citeStyleCO, SIGNAL(activated(int)),
1056                 this, SLOT(change_adaptor()));
1057         connect(biblioModule->citeJurabibRB, SIGNAL(clicked()),
1058                 this, SLOT(change_adaptor()));
1059         connect(biblioModule->bibtopicCB, SIGNAL(clicked()),
1060                 this, SLOT(change_adaptor()));
1061         connect(biblioModule->bibtexCO, SIGNAL(activated(int)),
1062                 this, SLOT(bibtexChanged(int)));
1063         connect(biblioModule->bibtexOptionsED, SIGNAL(textChanged(QString)),
1064                 this, SLOT(change_adaptor()));
1065
1066         biblioModule->citeStyleCO->addItem(qt_("Author-year"));
1067         biblioModule->citeStyleCO->addItem(qt_("Numerical"));
1068         biblioModule->citeStyleCO->setCurrentIndex(0);
1069         
1070         biblioModule->bibtexCO->clear();
1071         biblioModule->bibtexCO->addItem(qt_("Default"), QString("default"));
1072         for (set<string>::const_iterator it = lyxrc.bibtex_alternatives.begin();
1073                              it != lyxrc.bibtex_alternatives.end(); ++it) {
1074                 QString const command = toqstr(*it).left(toqstr(*it).indexOf(" "));
1075                 biblioModule->bibtexCO->addItem(command, command);
1076         }
1077         
1078
1079         // indices
1080         indicesModule = new GuiIndices;
1081         connect(indicesModule, SIGNAL(changed()),
1082                 this, SLOT(change_adaptor()));
1083
1084
1085         // maths
1086         mathsModule = new UiWidget<Ui::MathsUi>;
1087         connect(mathsModule->amsautoCB, SIGNAL(toggled(bool)),
1088                 mathsModule->amsCB, SLOT(setDisabled(bool)));
1089         connect(mathsModule->esintautoCB, SIGNAL(toggled(bool)),
1090                 mathsModule->esintCB, SLOT(setDisabled(bool)));
1091         connect(mathsModule->mhchemautoCB, SIGNAL(toggled(bool)),
1092                 mathsModule->mhchemCB, SLOT(setDisabled(bool)));
1093         connect(mathsModule->mathdotsautoCB, SIGNAL(toggled(bool)),
1094                 mathsModule->mathdotsCB, SLOT(setDisabled(bool)));
1095         
1096         connect(mathsModule->amsCB, SIGNAL(clicked()),
1097                 this, SLOT(change_adaptor()));
1098         connect(mathsModule->amsautoCB, SIGNAL(clicked()),
1099                 this, SLOT(change_adaptor()));
1100         connect(mathsModule->esintCB, SIGNAL(clicked()),
1101                 this, SLOT(change_adaptor()));
1102         connect(mathsModule->esintautoCB, SIGNAL(clicked()),
1103                 this, SLOT(change_adaptor()));
1104         connect(mathsModule->mhchemCB, SIGNAL(clicked()),
1105                 this, SLOT(change_adaptor()));
1106         connect(mathsModule->mhchemautoCB, SIGNAL(clicked()),
1107                 this, SLOT(change_adaptor()));
1108         connect(mathsModule->mathdotsCB, SIGNAL(clicked()),
1109                 this, SLOT(change_adaptor()));
1110         connect(mathsModule->mathdotsautoCB, SIGNAL(clicked()),
1111                 this, SLOT(change_adaptor()));
1112         
1113
1114         // latex class
1115         latexModule = new UiWidget<Ui::LaTeXUi>;
1116         connect(latexModule->optionsLE, SIGNAL(textChanged(QString)),
1117                 this, SLOT(change_adaptor()));
1118         connect(latexModule->defaultOptionsCB, SIGNAL(clicked()),
1119                 this, SLOT(change_adaptor()));
1120         connect(latexModule->psdriverCO, SIGNAL(activated(int)),
1121                 this, SLOT(change_adaptor()));
1122         connect(latexModule->classCO, SIGNAL(activated(int)),
1123                 this, SLOT(classChanged()));
1124         connect(latexModule->classCO, SIGNAL(activated(int)),
1125                 this, SLOT(change_adaptor()));
1126         connect(latexModule->layoutPB, SIGNAL(clicked()),
1127                 this, SLOT(browseLayout()));
1128         connect(latexModule->layoutPB, SIGNAL(clicked()),
1129                 this, SLOT(change_adaptor()));
1130         connect(latexModule->childDocGB, SIGNAL(clicked()),
1131                 this, SLOT(change_adaptor()));
1132         connect(latexModule->childDocLE, SIGNAL(textChanged(QString)),
1133                 this, SLOT(change_adaptor()));
1134         connect(latexModule->childDocPB, SIGNAL(clicked()),
1135                 this, SLOT(browseMaster()));
1136         connect(latexModule->suppressDateCB, SIGNAL(clicked()),
1137                 this, SLOT(change_adaptor()));
1138         connect(latexModule->refstyleCB, SIGNAL(clicked()),
1139                 this, SLOT(change_adaptor()));
1140
1141         // postscript drivers
1142         for (int n = 0; tex_graphics[n][0]; ++n) {
1143                 QString enc = qt_(tex_graphics_gui[n]);
1144                 latexModule->psdriverCO->addItem(enc);
1145         }
1146         // latex classes
1147         latexModule->classCO->setModel(&classes_model_);
1148         LayoutFileList const & bcl = LayoutFileList::get();
1149         vector<LayoutFileIndex> classList = bcl.classList();
1150         sort(classList.begin(), classList.end(), less_textclass_avail_desc());
1151
1152         vector<LayoutFileIndex>::const_iterator cit  = classList.begin();
1153         vector<LayoutFileIndex>::const_iterator cen = classList.end();
1154         for (int i = 0; cit != cen; ++cit, ++i) {
1155                 LayoutFile const & tc = bcl[*cit];
1156                 docstring item = (tc.isTeXClassAvailable()) ?
1157                         from_utf8(tc.description()) :
1158                         bformat(_("Unavailable: %1$s"), from_utf8(tc.description()));
1159                 classes_model_.insertRow(i, toqstr(item), *cit);
1160         }
1161
1162
1163         // branches
1164         branchesModule = new GuiBranches;
1165         connect(branchesModule, SIGNAL(changed()),
1166                 this, SLOT(change_adaptor()));
1167         connect(branchesModule, SIGNAL(renameBranches(docstring const &, docstring const &)),
1168                 this, SLOT(branchesRename(docstring const &, docstring const &)));
1169         updateUnknownBranches();
1170
1171
1172         // preamble
1173         preambleModule = new PreambleModule;
1174         connect(preambleModule, SIGNAL(changed()),
1175                 this, SLOT(change_adaptor()));
1176         
1177         localLayout = new LocalLayout;
1178         connect(localLayout, SIGNAL(changed()),
1179                 this, SLOT(change_adaptor()));
1180
1181
1182         // bullets
1183         bulletsModule = new BulletsModule;
1184         connect(bulletsModule, SIGNAL(changed()),
1185                 this, SLOT(change_adaptor()));
1186
1187
1188         // Modules
1189         modulesModule = new UiWidget<Ui::ModulesUi>;
1190         modulesModule->availableLV->header()->setVisible(false);
1191         selectionManager =
1192                 new ModuleSelectionManager(modulesModule->availableLV,
1193                         modulesModule->selectedLV,
1194                         modulesModule->addPB, modulesModule->deletePB,
1195                         modulesModule->upPB, modulesModule->downPB,
1196                         availableModel(), selectedModel(), this);
1197         connect(selectionManager, SIGNAL(updateHook()),
1198                 this, SLOT(updateModuleInfo()));
1199         connect(selectionManager, SIGNAL(updateHook()),
1200                 this, SLOT(change_adaptor()));
1201         connect(selectionManager, SIGNAL(selectionChanged()),
1202                 this, SLOT(modulesChanged()));
1203
1204
1205         // PDF support
1206         pdfSupportModule = new UiWidget<Ui::PDFSupportUi>;
1207         connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
1208                 this, SLOT(change_adaptor()));
1209         connect(pdfSupportModule->titleLE, SIGNAL(textChanged(QString)),
1210                 this, SLOT(change_adaptor()));
1211         connect(pdfSupportModule->authorLE, SIGNAL(textChanged(QString)),
1212                 this, SLOT(change_adaptor()));
1213         connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(QString)),
1214                 this, SLOT(change_adaptor()));
1215         connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(QString)),
1216                 this, SLOT(change_adaptor()));
1217         connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
1218                 this, SLOT(change_adaptor()));
1219         connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
1220                 this, SLOT(change_adaptor()));
1221         connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
1222                 this, SLOT(change_adaptor()));
1223         connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
1224                 this, SLOT(change_adaptor()));
1225         connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
1226                 this, SLOT(change_adaptor()));
1227         connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
1228                 this, SLOT(change_adaptor()));
1229         connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
1230                 this, SLOT(change_adaptor()));
1231         connect(pdfSupportModule->backrefCO, SIGNAL(activated(int)),
1232                 this, SLOT(change_adaptor()));
1233         connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
1234                 this, SLOT(change_adaptor()));
1235         connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
1236                 this, SLOT(change_adaptor()));
1237         connect(pdfSupportModule->optionsLE, SIGNAL(textChanged(QString)),
1238                 this, SLOT(change_adaptor()));
1239
1240         for (int i = 0; backref_opts[i][0]; ++i)
1241                 pdfSupportModule->backrefCO->addItem(qt_(backref_opts_gui[i]));
1242
1243
1244         // float
1245         floatModule = new FloatPlacement;
1246         connect(floatModule, SIGNAL(changed()),
1247                 this, SLOT(change_adaptor()));
1248
1249
1250         // listings
1251         listingsModule = new UiWidget<Ui::ListingsSettingsUi>;
1252         connect(listingsModule->listingsED, SIGNAL(textChanged()),
1253                 this, SLOT(change_adaptor()));
1254         connect(listingsModule->bypassCB, SIGNAL(clicked()), 
1255                 this, SLOT(change_adaptor()));
1256         connect(listingsModule->bypassCB, SIGNAL(clicked()), 
1257                 this, SLOT(setListingsMessage()));
1258         connect(listingsModule->listingsED, SIGNAL(textChanged()),
1259                 this, SLOT(setListingsMessage()));
1260         listingsModule->listingsTB->setPlainText(
1261                 qt_("Input listings parameters below. Enter ? for a list of parameters."));
1262
1263
1264         // add the panels
1265         docPS->addPanel(latexModule, qt_("Document Class"));
1266         docPS->addPanel(masterChildModule, qt_("Child Documents"));
1267         docPS->addPanel(modulesModule, qt_("Modules"));
1268         docPS->addPanel(localLayout, qt_("Local Layout"));
1269         docPS->addPanel(fontModule, qt_("Fonts"));
1270         docPS->addPanel(textLayoutModule, qt_("Text Layout"));
1271         docPS->addPanel(pageLayoutModule, qt_("Page Layout"));
1272         docPS->addPanel(marginsModule, qt_("Page Margins"));
1273         docPS->addPanel(langModule, qt_("Language"));
1274         docPS->addPanel(colorModule, qt_("Colors"));
1275         docPS->addPanel(numberingModule, qt_("Numbering & TOC"));
1276         docPS->addPanel(biblioModule, qt_("Bibliography"));
1277         docPS->addPanel(indicesModule, qt_("Indexes"));
1278         docPS->addPanel(pdfSupportModule, qt_("PDF Properties"));
1279         docPS->addPanel(mathsModule, qt_("Math Options"));
1280         docPS->addPanel(floatModule, qt_("Float Placement"));
1281         docPS->addPanel(listingsModule, qt_("Listings"));
1282         docPS->addPanel(bulletsModule, qt_("Bullets"));
1283         docPS->addPanel(branchesModule, qt_("Branches"));
1284         docPS->addPanel(outputModule, qt_("Output"));
1285         docPS->addPanel(preambleModule, qt_("LaTeX Preamble"));
1286         docPS->setCurrentPanel(qt_("Document Class"));
1287 // FIXME: hack to work around resizing bug in Qt >= 4.2
1288 // bug verified with Qt 4.2.{0-3} (JSpitzm)
1289 #if QT_VERSION >= 0x040200
1290         docPS->updateGeometry();
1291 #endif
1292 }
1293
1294
1295 void GuiDocument::saveDefaultClicked()
1296 {
1297         saveDocDefault();
1298 }
1299
1300
1301 void GuiDocument::useDefaultsClicked()
1302 {
1303         useClassDefaults();
1304 }
1305
1306
1307 void GuiDocument::change_adaptor()
1308 {
1309         changed();
1310 }
1311
1312
1313 void GuiDocument::includeonlyClicked(QTreeWidgetItem * item, int)
1314 {
1315         if (item == 0)
1316                 return;
1317
1318         string child = fromqstr(item->text(0));
1319         if (child.empty())
1320                 return;
1321
1322         if (std::find(includeonlys_.begin(),
1323                       includeonlys_.end(), child) != includeonlys_.end())
1324                 includeonlys_.remove(child);
1325         else
1326                 includeonlys_.push_back(child);
1327         
1328         updateIncludeonlys();
1329         changed();
1330 }
1331
1332
1333 QString GuiDocument::validateListingsParameters()
1334 {
1335         // use a cache here to avoid repeated validation
1336         // of the same parameters
1337         static string param_cache;
1338         static QString msg_cache;
1339         
1340         if (listingsModule->bypassCB->isChecked())
1341                 return QString();
1342
1343         string params = fromqstr(listingsModule->listingsED->toPlainText());
1344         if (params != param_cache) {
1345                 param_cache = params;
1346                 msg_cache = toqstr(InsetListingsParams(params).validate());
1347         }
1348         return msg_cache;
1349 }
1350
1351
1352 void GuiDocument::setListingsMessage()
1353 {
1354         static bool isOK = true;
1355         QString msg = validateListingsParameters();
1356         if (msg.isEmpty()) {
1357                 if (isOK)
1358                         return;
1359                 isOK = true;
1360                 // listingsTB->setTextColor("black");
1361                 listingsModule->listingsTB->setPlainText(
1362                         qt_("Input listings parameters below. "
1363                 "Enter ? for a list of parameters."));
1364         } else {
1365                 isOK = false;
1366                 // listingsTB->setTextColor("red");
1367                 listingsModule->listingsTB->setPlainText(msg);
1368         }
1369 }
1370
1371
1372 void GuiDocument::setLSpacing(int item)
1373 {
1374         textLayoutModule->lspacingLE->setEnabled(item == 3);
1375 }
1376
1377
1378 void GuiDocument::setIndent(int item)
1379 {
1380         bool const enable = (item == 1);
1381         textLayoutModule->indentLE->setEnabled(enable);
1382         textLayoutModule->indentLengthCO->setEnabled(enable);
1383         textLayoutModule->skipLE->setEnabled(false);
1384         textLayoutModule->skipLengthCO->setEnabled(false);
1385         isValid();
1386 }
1387
1388
1389 void GuiDocument::enableIndent(bool indent)
1390 {
1391         textLayoutModule->skipLE->setEnabled(!indent);
1392         textLayoutModule->skipLengthCO->setEnabled(!indent);
1393         if (indent)
1394                 setIndent(textLayoutModule->indentCO->currentIndex());
1395 }
1396
1397
1398 void GuiDocument::setSkip(int item)
1399 {
1400         bool const enable = (item == 3);
1401         textLayoutModule->skipLE->setEnabled(enable);
1402         textLayoutModule->skipLengthCO->setEnabled(enable);
1403         isValid();
1404 }
1405
1406
1407 void GuiDocument::enableSkip(bool skip)
1408 {
1409         textLayoutModule->indentLE->setEnabled(!skip);
1410         textLayoutModule->indentLengthCO->setEnabled(!skip);
1411         if (skip)
1412                 setSkip(textLayoutModule->skipCO->currentIndex());
1413 }
1414
1415
1416 void GuiDocument::setMargins()
1417 {
1418         bool const extern_geometry =
1419                 documentClass().provides("geometry");
1420         marginsModule->marginCB->setEnabled(!extern_geometry);
1421         if (extern_geometry) {
1422                 marginsModule->marginCB->setChecked(false);
1423                 setCustomMargins(true);
1424         } else {
1425                 marginsModule->marginCB->setChecked(!bp_.use_geometry);
1426                 setCustomMargins(!bp_.use_geometry);
1427         }
1428 }
1429
1430
1431 void GuiDocument::papersizeChanged(int paper_size)
1432 {
1433         setCustomPapersize(paper_size == 1);
1434 }
1435
1436
1437 void GuiDocument::setCustomPapersize(bool custom)
1438 {
1439         pageLayoutModule->paperwidthL->setEnabled(custom);
1440         pageLayoutModule->paperwidthLE->setEnabled(custom);
1441         pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
1442         pageLayoutModule->paperheightL->setEnabled(custom);
1443         pageLayoutModule->paperheightLE->setEnabled(custom);
1444         pageLayoutModule->paperheightLE->setFocus();
1445         pageLayoutModule->paperheightUnitCO->setEnabled(custom);
1446 }
1447
1448
1449 void GuiDocument::setColSep()
1450 {
1451         setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
1452 }
1453
1454
1455 void GuiDocument::setCustomMargins(bool custom)
1456 {
1457         marginsModule->topL->setEnabled(!custom);
1458         marginsModule->topLE->setEnabled(!custom);
1459         marginsModule->topUnit->setEnabled(!custom);
1460
1461         marginsModule->bottomL->setEnabled(!custom);
1462         marginsModule->bottomLE->setEnabled(!custom);
1463         marginsModule->bottomUnit->setEnabled(!custom);
1464
1465         marginsModule->innerL->setEnabled(!custom);
1466         marginsModule->innerLE->setEnabled(!custom);
1467         marginsModule->innerUnit->setEnabled(!custom);
1468
1469         marginsModule->outerL->setEnabled(!custom);
1470         marginsModule->outerLE->setEnabled(!custom);
1471         marginsModule->outerUnit->setEnabled(!custom);
1472
1473         marginsModule->headheightL->setEnabled(!custom);
1474         marginsModule->headheightLE->setEnabled(!custom);
1475         marginsModule->headheightUnit->setEnabled(!custom);
1476
1477         marginsModule->headsepL->setEnabled(!custom);
1478         marginsModule->headsepLE->setEnabled(!custom);
1479         marginsModule->headsepUnit->setEnabled(!custom);
1480
1481         marginsModule->footskipL->setEnabled(!custom);
1482         marginsModule->footskipLE->setEnabled(!custom);
1483         marginsModule->footskipUnit->setEnabled(!custom);
1484
1485         bool const enableColSep = !custom && 
1486                         textLayoutModule->twoColumnCB->checkState() == Qt::Checked;
1487         marginsModule->columnsepL->setEnabled(enableColSep);
1488         marginsModule->columnsepLE->setEnabled(enableColSep);
1489         marginsModule->columnsepUnit->setEnabled(enableColSep);
1490 }
1491
1492
1493 void GuiDocument::changeBackgroundColor()
1494 {
1495         QColor const & newColor = QColorDialog::getColor(
1496                 rgb2qcolor(set_backgroundcolor), asQWidget());
1497         if (!newColor.isValid())
1498                 return;
1499         // set the button color and text
1500         colorModule->backgroundPB->setStyleSheet(
1501                 colorButtonStyleSheet(newColor));
1502         colorModule->backgroundPB->setText(toqstr("Change..."));
1503         // save color
1504         set_backgroundcolor = rgbFromHexName(fromqstr(newColor.name()));
1505         is_backgroundcolor = true;
1506         changed();
1507 }
1508
1509
1510 void GuiDocument::deleteBackgroundColor()
1511 {
1512         // set the button color back to default by setting an epmty StyleSheet
1513         colorModule->backgroundPB->setStyleSheet(QLatin1String(""));
1514         // change button text
1515         colorModule->backgroundPB->setText(toqstr("Default..."));
1516         // save default color (white)
1517         set_backgroundcolor = rgbFromHexName("#ffffff");
1518         is_backgroundcolor = false;
1519         changed();
1520 }
1521
1522
1523 void GuiDocument::changeFontColor()
1524 {
1525         QColor const & newColor = QColorDialog::getColor(
1526                 rgb2qcolor(set_fontcolor), asQWidget());
1527         if (!newColor.isValid())
1528                 return;
1529         // set the button color and text
1530         colorModule->fontColorPB->setStyleSheet(
1531                 colorButtonStyleSheet(newColor));
1532         colorModule->fontColorPB->setText(toqstr("Change..."));
1533         // save color
1534         set_fontcolor = rgbFromHexName(fromqstr(newColor.name()));
1535         is_fontcolor = true;
1536         changed();
1537 }
1538
1539
1540 void GuiDocument::deleteFontColor()
1541 {
1542         // set the button color back to default by setting an epmty StyleSheet
1543         colorModule->fontColorPB->setStyleSheet(QLatin1String(""));
1544         // change button text
1545         colorModule->fontColorPB->setText(toqstr("Default..."));
1546         // save default color (black)
1547         set_fontcolor = rgbFromHexName("#000000");
1548         is_fontcolor = false;
1549         changed();
1550 }
1551
1552
1553 void GuiDocument::changeNoteFontColor()
1554 {
1555         QColor const & newColor = QColorDialog::getColor(
1556                 rgb2qcolor(set_notefontcolor), asQWidget());
1557         if (!newColor.isValid())
1558                 return;
1559         // set the button color
1560         colorModule->noteFontColorPB->setStyleSheet(
1561                 colorButtonStyleSheet(newColor));
1562         // save color
1563         set_notefontcolor = rgbFromHexName(fromqstr(newColor.name()));
1564         changed();
1565 }
1566
1567
1568 void GuiDocument::deleteNoteFontColor()
1569 {
1570         // set the button color back to light gray
1571         colorModule->noteFontColorPB->setStyleSheet(
1572                 colorButtonStyleSheet(QColor(204, 204, 204, 255)));
1573         // save light gray as the set color
1574         set_notefontcolor = rgbFromHexName("#cccccc");
1575         changed();
1576 }
1577
1578
1579 void GuiDocument::changeBoxBackgroundColor()
1580 {
1581         QColor const & newColor = QColorDialog::getColor(
1582                 rgb2qcolor(set_boxbgcolor), asQWidget());
1583         if (!newColor.isValid())
1584                 return;
1585         // set the button color
1586         colorModule->boxBackgroundPB->setStyleSheet(
1587                 colorButtonStyleSheet(newColor));
1588         // save color
1589         set_boxbgcolor = rgbFromHexName(fromqstr(newColor.name()));
1590         changed();
1591 }
1592
1593
1594 void GuiDocument::deleteBoxBackgroundColor()
1595 {
1596         // set the button color back to red
1597         colorModule->boxBackgroundPB->setStyleSheet(
1598                 colorButtonStyleSheet(QColor(Qt::red)));
1599         // save red as the set color
1600         set_boxbgcolor = rgbFromHexName("#ff0000");
1601         changed();
1602 }
1603
1604
1605 void GuiDocument::osFontsChanged(bool nontexfonts)
1606 {
1607         bool const tex_fonts = !nontexfonts;
1608         updateFontlist();
1609         updateDefaultFormat();
1610         langModule->encodingCO->setEnabled(tex_fonts &&
1611                 !langModule->defaultencodingRB->isChecked());
1612         langModule->defaultencodingRB->setEnabled(tex_fonts);
1613         langModule->otherencodingRB->setEnabled(tex_fonts);
1614
1615         fontModule->fontsDefaultCO->setEnabled(tex_fonts);
1616         fontModule->fontsDefaultLA->setEnabled(tex_fonts);
1617         fontModule->cjkFontLE->setEnabled(tex_fonts);
1618         fontModule->cjkFontLA->setEnabled(tex_fonts);
1619         string font;
1620         if (tex_fonts)
1621                 font = tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1622         bool scaleable = providesScale(font);
1623         fontModule->scaleSansSB->setEnabled(scaleable);
1624         fontModule->scaleSansLA->setEnabled(scaleable);
1625         if (tex_fonts)
1626                 font = tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1627         scaleable = providesScale(font);
1628         fontModule->scaleTypewriterSB->setEnabled(scaleable);
1629         fontModule->scaleTypewriterLA->setEnabled(scaleable);
1630         if (tex_fonts)
1631                 font = tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1632         fontModule->fontScCB->setEnabled(providesSC(font));
1633         fontModule->fontOsfCB->setEnabled(providesOSF(font));
1634         
1635         fontModule->fontencLA->setEnabled(tex_fonts);
1636         fontModule->fontencCO->setEnabled(tex_fonts);
1637         if (!tex_fonts)
1638                 fontModule->fontencLE->setEnabled(false);
1639         else
1640                 fontencChanged(fontModule->fontencCO->currentIndex());
1641 }
1642
1643
1644 void GuiDocument::updateFontsize(string const & items, string const & sel)
1645 {
1646         fontModule->fontsizeCO->clear();
1647         fontModule->fontsizeCO->addItem(qt_("Default"));
1648
1649         for (int n = 0; !token(items,'|',n).empty(); ++n)
1650                 fontModule->fontsizeCO->
1651                         addItem(toqstr(token(items,'|',n)));
1652
1653         for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
1654                 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
1655                         fontModule->fontsizeCO->setCurrentIndex(n);
1656                         break;
1657                 }
1658         }
1659 }
1660
1661
1662 void GuiDocument::updateFontlist()
1663 {
1664         fontModule->fontsRomanCO->clear();
1665         fontModule->fontsSansCO->clear();
1666         fontModule->fontsTypewriterCO->clear();
1667
1668         // With XeTeX, we have access to all system fonts, but not the LaTeX fonts
1669         if (fontModule->osFontsCB->isChecked()) {
1670                 fontModule->fontsRomanCO->addItem(qt_("Default"));
1671                 fontModule->fontsSansCO->addItem(qt_("Default"));
1672                 fontModule->fontsTypewriterCO->addItem(qt_("Default"));
1673         
1674                 QFontDatabase fontdb;
1675                 QStringList families(fontdb.families());
1676                 for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
1677                         fontModule->fontsRomanCO->addItem(*it);
1678                         fontModule->fontsSansCO->addItem(*it);
1679                         fontModule->fontsTypewriterCO->addItem(*it);
1680                 }
1681                 return;
1682         }
1683
1684         for (int n = 0; tex_fonts_roman[n][0]; ++n) {
1685                 QString font = qt_(tex_fonts_roman_gui[n]);
1686                 if (!isFontAvailable(tex_fonts_roman[n]))
1687                         font += qt_(" (not installed)");
1688                 fontModule->fontsRomanCO->addItem(font);
1689         }
1690         for (int n = 0; tex_fonts_sans[n][0]; ++n) {
1691                 QString font = qt_(tex_fonts_sans_gui[n]);
1692                 if (!isFontAvailable(tex_fonts_sans[n]))
1693                         font += qt_(" (not installed)");
1694                 fontModule->fontsSansCO->addItem(font);
1695         }
1696         for (int n = 0; tex_fonts_monospaced[n][0]; ++n) {
1697                 QString font = qt_(tex_fonts_monospaced_gui[n]);
1698                 if (!isFontAvailable(tex_fonts_monospaced[n]))
1699                         font += qt_(" (not installed)");
1700                 fontModule->fontsTypewriterCO->addItem(font);
1701         }
1702 }
1703
1704
1705 void GuiDocument::fontencChanged(int item)
1706 {
1707         fontModule->fontencLE->setEnabled(item == 1);
1708 }
1709
1710
1711 void GuiDocument::romanChanged(int item)
1712 {
1713         if (fontModule->osFontsCB->isChecked())
1714                 return;
1715         string const font = tex_fonts_roman[item];
1716         fontModule->fontScCB->setEnabled(providesSC(font));
1717         fontModule->fontOsfCB->setEnabled(providesOSF(font));
1718 }
1719
1720
1721 void GuiDocument::sansChanged(int item)
1722 {
1723         if (fontModule->osFontsCB->isChecked())
1724                 return;
1725         string const font = tex_fonts_sans[item];
1726         bool scaleable = providesScale(font);
1727         fontModule->scaleSansSB->setEnabled(scaleable);
1728         fontModule->scaleSansLA->setEnabled(scaleable);
1729 }
1730
1731
1732 void GuiDocument::ttChanged(int item)
1733 {
1734         if (fontModule->osFontsCB->isChecked())
1735                 return;
1736         string const font = tex_fonts_monospaced[item];
1737         bool scaleable = providesScale(font);
1738         fontModule->scaleTypewriterSB->setEnabled(scaleable);
1739         fontModule->scaleTypewriterLA->setEnabled(scaleable);
1740 }
1741
1742
1743 void GuiDocument::updatePagestyle(string const & items, string const & sel)
1744 {
1745         pagestyles.clear();
1746         pageLayoutModule->pagestyleCO->clear();
1747         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1748
1749         for (int n = 0; !token(items, '|', n).empty(); ++n) {
1750                 string style = token(items, '|', n);
1751                 QString style_gui = qt_(style);
1752                 pagestyles.push_back(pair<string, QString>(style, style_gui));
1753                 pageLayoutModule->pagestyleCO->addItem(style_gui);
1754         }
1755
1756         if (sel == "default") {
1757                 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
1758                 return;
1759         }
1760
1761         int nn = 0;
1762
1763         for (size_t i = 0; i < pagestyles.size(); ++i)
1764                 if (pagestyles[i].first == sel)
1765                         nn = pageLayoutModule->pagestyleCO->findText(pagestyles[i].second);
1766
1767         if (nn > 0)
1768                 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
1769 }
1770
1771
1772 void GuiDocument::browseLayout()
1773 {
1774         QString const label1 = qt_("Layouts|#o#O");
1775         QString const dir1 = toqstr(lyxrc.document_path);
1776         QStringList const filter(qt_("LyX Layout (*.layout)"));
1777         QString file = browseRelFile(QString(), bufferFilePath(),
1778                 qt_("Local layout file"), filter, false,
1779                 label1, dir1);
1780
1781         if (!file.endsWith(".layout"))
1782                 return;
1783
1784         FileName layoutFile = support::makeAbsPath(fromqstr(file),
1785                 fromqstr(bufferFilePath()));
1786         
1787         int const ret = Alert::prompt(_("Local layout file"),
1788                 _("The layout file you have selected is a local layout\n"
1789                   "file, not one in the system or user directory. Your\n"
1790                   "document may not work with this layout if you do not\n"
1791                   "keep the layout file in the document directory."),
1792                   1, 1, _("&Set Layout"), _("&Cancel"));
1793         if (ret == 1)
1794                 return;
1795
1796         // load the layout file
1797         LayoutFileList & bcl = LayoutFileList::get();
1798         string classname = layoutFile.onlyFileName();
1799         // this will update an existing layout if that layout has been loaded before.
1800         LayoutFileIndex name = bcl.addLocalLayout(
1801                 classname.substr(0, classname.size() - 7),
1802                 layoutFile.onlyPath().absFileName());
1803
1804         if (name.empty()) {
1805                 Alert::error(_("Error"),
1806                         _("Unable to read local layout file."));                
1807                 return;
1808         }
1809
1810         // do not trigger classChanged if there is no change.
1811         if (latexModule->classCO->currentText() == toqstr(name))
1812                 return;
1813                 
1814         // add to combo box
1815         int idx = latexModule->classCO->findText(toqstr(name));
1816         if (idx == -1) {
1817                 classes_model_.insertRow(0, toqstr(name), name);
1818                 latexModule->classCO->setCurrentIndex(0);
1819         } else
1820                 latexModule->classCO->setCurrentIndex(idx);
1821         
1822         classChanged();
1823 }
1824
1825
1826 void GuiDocument::browseMaster()
1827 {
1828         QString const title = qt_("Select master document");
1829         QString const dir1 = toqstr(lyxrc.document_path);
1830         QString const old = latexModule->childDocLE->text();
1831         QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
1832         QStringList const filter(qt_("LyX Files (*.lyx)"));
1833         QString file = browseRelFile(old, docpath, title, filter, false,
1834                 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
1835
1836         if (!file.isEmpty())
1837                 latexModule->childDocLE->setText(file);
1838 }
1839
1840
1841 void GuiDocument::classChanged()
1842 {
1843         int idx = latexModule->classCO->currentIndex();
1844         if (idx < 0) 
1845                 return;
1846         string const classname = classes_model_.getIDString(idx);
1847
1848         // check whether the selected modules have changed.
1849         bool modules_changed = false;
1850         unsigned int const srows = selectedModel()->rowCount();
1851         if (srows != bp_.getModules().size())
1852                 modules_changed = true;
1853         else {
1854                 list<string>::const_iterator mit = bp_.getModules().begin();
1855                 list<string>::const_iterator men = bp_.getModules().end();
1856                 for (unsigned int i = 0; i < srows && mit != men; ++i, ++mit)
1857                         if (selectedModel()->getIDString(i) != *mit) {
1858                                 modules_changed = true;
1859                                 break;
1860                         }
1861         }
1862
1863         if (modules_changed || lyxrc.auto_reset_options) {
1864                 if (applyPB->isEnabled()) {
1865                         int const ret = Alert::prompt(_("Unapplied changes"),
1866                                         _("Some changes in the dialog were not yet applied.\n"
1867                                         "If you do not apply now, they will be lost after this action."),
1868                                         1, 1, _("&Apply"), _("&Dismiss"));
1869                         if (ret == 0)
1870                                 applyView();
1871                 }
1872         }
1873
1874         // We load the TextClass as soon as it is selected. This is
1875         // necessary so that other options in the dialog can be updated
1876         // according to the new class. Note, however, that, if you use 
1877         // the scroll wheel when sitting on the combo box, we'll load a 
1878         // lot of TextClass objects very quickly....
1879         if (!bp_.setBaseClass(classname)) {
1880                 Alert::error(_("Error"), _("Unable to set document class."));
1881                 return;
1882         }
1883         if (lyxrc.auto_reset_options)
1884                 bp_.useClassDefaults();
1885
1886         // With the introduction of modules came a distinction between the base 
1887         // class and the document class. The former corresponds to the main layout 
1888         // file; the latter is that plus the modules (or the document-specific layout,
1889         // or  whatever else there could be). Our parameters come from the document 
1890         // class. So when we set the base class, we also need to recreate the document 
1891         // class. Otherwise, we still have the old one.
1892         bp_.makeDocumentClass();
1893         paramsToDialog();
1894 }
1895
1896
1897 void GuiDocument::languagePackageChanged(int i)
1898 {
1899          langModule->languagePackageED->setEnabled(
1900                 langModule->languagePackageCO->itemData(i).toString() == "custom");
1901 }
1902
1903
1904 void GuiDocument::bibtexChanged(int n)
1905 {
1906         biblioModule->bibtexOptionsED->setEnabled(n != 0);
1907         changed();
1908 }
1909
1910
1911 namespace {
1912         // FIXME unicode 
1913         // both of these should take a vector<docstring>
1914         
1915         // This is an insanely complicated attempt to make this sort of thing
1916         // work with RTL languages.
1917         docstring formatStrVec(vector<string> const & v, docstring const & s) 
1918         {
1919                 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
1920                 if (v.size() == 0)
1921                         return docstring();
1922                 if (v.size() == 1) 
1923                         return translateIfPossible(from_utf8(v[0]));
1924                 if (v.size() == 2) {
1925                         docstring retval = _("%1$s and %2$s");
1926                         retval = subst(retval, _("and"), s);
1927                         return bformat(retval, translateIfPossible(from_utf8(v[0])),
1928                                        translateIfPossible(from_utf8(v[1])));
1929                 }
1930                 // The idea here is to format all but the last two items...
1931                 int const vSize = v.size();
1932                 docstring t2 = _("%1$s, %2$s");
1933                 docstring retval = translateIfPossible(from_utf8(v[0]));
1934                 for (int i = 1; i < vSize - 2; ++i)
1935                         retval = bformat(t2, retval, translateIfPossible(from_utf8(v[i]))); 
1936                 //...and then to  plug them, and the last two, into this schema
1937                 docstring t = _("%1$s, %2$s, and %3$s");
1938                 t = subst(t, _("and"), s);
1939                 return bformat(t, retval, translateIfPossible(from_utf8(v[vSize - 2])),
1940                                translateIfPossible(from_utf8(v[vSize - 1])));
1941         }
1942         
1943         vector<string> idsToNames(vector<string> const & idList)
1944         {
1945                 vector<string> retval;
1946                 vector<string>::const_iterator it  = idList.begin();
1947                 vector<string>::const_iterator end = idList.end();
1948                 for (; it != end; ++it) {
1949                         LyXModule const * const mod = theModuleList[*it];
1950                         if (!mod)
1951                                 retval.push_back(to_utf8(bformat(_("%1$s (unavailable)"), 
1952                                                 translateIfPossible(from_utf8(*it)))));
1953                         else
1954                                 retval.push_back(mod->getName());
1955                 }
1956                 return retval;
1957         }
1958 } // end anonymous namespace
1959
1960
1961 void GuiDocument::modulesToParams(BufferParams & bp)
1962 {
1963         // update list of loaded modules
1964         bp.clearLayoutModules();
1965         int const srows = modules_sel_model_.rowCount();
1966         for (int i = 0; i < srows; ++i)
1967                 bp.addLayoutModule(modules_sel_model_.getIDString(i));
1968
1969         // update the list of removed modules
1970         bp.clearRemovedModules();
1971         LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
1972         list<string>::const_iterator rit = reqmods.begin();
1973         list<string>::const_iterator ren = reqmods.end();
1974
1975         // check each of the default modules
1976         for (; rit != ren; rit++) {
1977                 list<string>::const_iterator mit = bp.getModules().begin();
1978                 list<string>::const_iterator men = bp.getModules().end();
1979                 bool found = false;
1980                 for (; mit != men; mit++) {
1981                         if (*rit == *mit) {
1982                                 found = true;
1983                                 break;
1984                         }
1985                 }
1986                 if (!found) {
1987                         // the module isn't present so must have been removed by the user
1988                         bp.addRemovedModule(*rit);
1989                 }
1990         }
1991 }
1992
1993 void GuiDocument::modulesChanged()
1994 {
1995         modulesToParams(bp_);
1996         bp_.makeDocumentClass();
1997         paramsToDialog();
1998 }
1999
2000
2001 void GuiDocument::updateModuleInfo()
2002 {
2003         selectionManager->update();
2004         
2005         //Module description
2006         bool const focus_on_selected = selectionManager->selectedFocused();
2007         QAbstractItemView * lv;
2008         if (focus_on_selected)
2009                 lv = modulesModule->selectedLV;
2010         else
2011                 lv= modulesModule->availableLV;
2012         if (lv->selectionModel()->selectedIndexes().isEmpty()) {
2013                 modulesModule->infoML->document()->clear();
2014                 return;
2015         }
2016         QModelIndex const & idx = lv->selectionModel()->currentIndex();
2017         GuiIdListModel const & id_model = 
2018                         focus_on_selected  ? modules_sel_model_ : modules_av_model_;
2019         string const modName = id_model.getIDString(idx.row());
2020         docstring desc = getModuleDescription(modName);
2021
2022         LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
2023         if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
2024                 if (!desc.empty())
2025                         desc += "\n";
2026                 desc += _("Module provided by document class.");
2027         }
2028
2029         vector<string> pkglist = getPackageList(modName);
2030         docstring pkgdesc = formatStrVec(pkglist, _("and"));
2031         if (!pkgdesc.empty()) {
2032                 if (!desc.empty())
2033                         desc += "\n";
2034                 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
2035         }
2036
2037         pkglist = getRequiredList(modName);
2038         if (!pkglist.empty()) {
2039                 vector<string> const reqdescs = idsToNames(pkglist);
2040                 pkgdesc = formatStrVec(reqdescs, _("or"));
2041                 if (!desc.empty())
2042                         desc += "\n";
2043                 desc += bformat(_("Modules required: %1$s."), pkgdesc);
2044         }
2045
2046         pkglist = getExcludedList(modName);
2047         if (!pkglist.empty()) {
2048                 vector<string> const reqdescs = idsToNames(pkglist);
2049                 pkgdesc = formatStrVec(reqdescs, _( "and"));
2050                 if (!desc.empty())
2051                         desc += "\n";
2052                 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
2053         }
2054
2055         if (!isModuleAvailable(modName)) {
2056                 if (!desc.empty())
2057                         desc += "\n";
2058                 desc += _("WARNING: Some required packages are unavailable!");
2059         }
2060
2061         modulesModule->infoML->document()->setPlainText(toqstr(desc));
2062 }
2063
2064
2065 void GuiDocument::updateNumbering()
2066 {
2067         DocumentClass const & tclass = documentClass();
2068
2069         numberingModule->tocTW->setUpdatesEnabled(false);
2070         numberingModule->tocTW->clear();
2071
2072         int const depth = numberingModule->depthSL->value();
2073         int const toc = numberingModule->tocSL->value();
2074         QString const no = qt_("No");
2075         QString const yes = qt_("Yes");
2076         QTreeWidgetItem * item = 0;
2077
2078         DocumentClass::const_iterator lit = tclass.begin();
2079         DocumentClass::const_iterator len = tclass.end();
2080         for (; lit != len; ++lit) {
2081                 int const toclevel = lit->toclevel;
2082                 if (toclevel != Layout::NOT_IN_TOC && lit->labeltype == LABEL_COUNTER) {
2083                         item = new QTreeWidgetItem(numberingModule->tocTW);
2084                         item->setText(0, toqstr(translateIfPossible(lit->name())));
2085                         item->setText(1, (toclevel <= depth) ? yes : no);
2086                         item->setText(2, (toclevel <= toc) ? yes : no);
2087                 }
2088         }
2089
2090         numberingModule->tocTW->setUpdatesEnabled(true);
2091         numberingModule->tocTW->update();
2092 }
2093
2094
2095 void GuiDocument::updateDefaultFormat()
2096 {
2097         if (!bufferview())
2098                 return;
2099         // make a copy in order to consider unapplied changes
2100         Buffer * tmpbuf = buffer().clone();
2101         tmpbuf->params().useNonTeXFonts =
2102                 fontModule->osFontsCB->isChecked();
2103         int idx = latexModule->classCO->currentIndex();
2104         if (idx >= 0) {
2105                 string const classname = classes_model_.getIDString(idx);
2106                 tmpbuf->params().setBaseClass(classname);
2107                 tmpbuf->params().makeDocumentClass();
2108         }
2109         outputModule->defaultFormatCO->blockSignals(true);
2110         outputModule->defaultFormatCO->clear();
2111         outputModule->defaultFormatCO->addItem(qt_("Default"),
2112                                 QVariant(QString("default")));
2113         typedef vector<Format const *> Formats;
2114         Formats formats = tmpbuf->exportableFormats(true);
2115         Formats::const_iterator cit = formats.begin();
2116         Formats::const_iterator end = formats.end();
2117         for (; cit != end; ++cit)
2118                 outputModule->defaultFormatCO->addItem(qt_((*cit)->prettyname()),
2119                                 QVariant(toqstr((*cit)->name())));
2120         outputModule->defaultFormatCO->blockSignals(false);
2121         // delete the copy
2122         delete tmpbuf;
2123 }
2124
2125
2126 bool GuiDocument::isChildIncluded(string const & child)
2127 {
2128         if (includeonlys_.empty())
2129                 return false;
2130         return (std::find(includeonlys_.begin(),
2131                           includeonlys_.end(), child) != includeonlys_.end());
2132 }
2133
2134
2135 void GuiDocument::applyView()
2136 {
2137         // preamble
2138         preambleModule->apply(bp_);
2139         localLayout->apply(bp_);
2140
2141         // date
2142         bp_.suppress_date = latexModule->suppressDateCB->isChecked();
2143         bp_.use_refstyle  = latexModule->refstyleCB->isChecked();
2144
2145         // biblio
2146         bp_.setCiteEngine(ENGINE_BASIC);
2147
2148         if (biblioModule->citeNatbibRB->isChecked()) {
2149                 bool const use_numerical_citations =
2150                         biblioModule->citeStyleCO->currentIndex();
2151                 if (use_numerical_citations)
2152                         bp_.setCiteEngine(ENGINE_NATBIB_NUMERICAL);
2153                 else
2154                         bp_.setCiteEngine(ENGINE_NATBIB_AUTHORYEAR);
2155
2156         } else if (biblioModule->citeJurabibRB->isChecked())
2157                 bp_.setCiteEngine(ENGINE_JURABIB);
2158
2159         bp_.use_bibtopic =
2160                 biblioModule->bibtopicCB->isChecked();
2161
2162         string const bibtex_command =
2163                 fromqstr(biblioModule->bibtexCO->itemData(
2164                         biblioModule->bibtexCO->currentIndex()).toString());
2165         string const bibtex_options =
2166                 fromqstr(biblioModule->bibtexOptionsED->text());
2167         if (bibtex_command == "default" || bibtex_options.empty())
2168                 bp_.bibtex_command = bibtex_command;
2169         else
2170                 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
2171
2172         // Indices
2173         indicesModule->apply(bp_);
2174
2175         // language & quotes
2176         if (langModule->defaultencodingRB->isChecked()) {
2177                 bp_.inputenc = "auto";
2178         } else {
2179                 int i = langModule->encodingCO->currentIndex();
2180                 if (i == 0)
2181                         bp_.inputenc = "default";
2182                 else {
2183                         QString const enc_gui =
2184                                 langModule->encodingCO->currentText();
2185                         Encodings::const_iterator it = encodings.begin();
2186                         Encodings::const_iterator const end = encodings.end();
2187                         bool found = false;
2188                         for (; it != end; ++it) {
2189                                 if (qt_(it->guiName()) == enc_gui) {
2190                                         bp_.inputenc = it->latexName();
2191                                         found = true;
2192                                         break;
2193                                 }
2194                         }
2195                         if (!found) {
2196                                 // should not happen
2197                                 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
2198                                 bp_.inputenc = "default";
2199                         }
2200                 }
2201         }
2202
2203         InsetQuotes::QuoteLanguage lga = InsetQuotes::EnglishQuotes;
2204         switch (langModule->quoteStyleCO->currentIndex()) {
2205         case 0:
2206                 lga = InsetQuotes::EnglishQuotes;
2207                 break;
2208         case 1:
2209                 lga = InsetQuotes::SwedishQuotes;
2210                 break;
2211         case 2:
2212                 lga = InsetQuotes::GermanQuotes;
2213                 break;
2214         case 3:
2215                 lga = InsetQuotes::PolishQuotes;
2216                 break;
2217         case 4:
2218                 lga = InsetQuotes::FrenchQuotes;
2219                 break;
2220         case 5:
2221                 lga = InsetQuotes::DanishQuotes;
2222                 break;
2223         }
2224         bp_.quotes_language = lga;
2225
2226         QString const lang = langModule->languageCO->itemData(
2227                 langModule->languageCO->currentIndex()).toString();
2228         bp_.language = lyx::languages.getLanguage(fromqstr(lang));
2229         
2230         QString const pack = langModule->languagePackageCO->itemData(
2231                 langModule->languagePackageCO->currentIndex()).toString();
2232         if (pack == "custom")
2233                 bp_.lang_package =
2234                         fromqstr(langModule->languagePackageED->text());
2235         else
2236                 bp_.lang_package = fromqstr(pack);
2237
2238         //color
2239         bp_.backgroundcolor = set_backgroundcolor;
2240         bp_.isbackgroundcolor = is_backgroundcolor;
2241         bp_.fontcolor = set_fontcolor;
2242         bp_.isfontcolor = is_fontcolor;
2243         bp_.notefontcolor = set_notefontcolor;
2244         bp_.boxbgcolor = set_boxbgcolor;
2245
2246         // numbering
2247         if (bp_.documentClass().hasTocLevels()) {
2248                 bp_.tocdepth = numberingModule->tocSL->value();
2249                 bp_.secnumdepth = numberingModule->depthSL->value();
2250         }
2251
2252         // bullets
2253         bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
2254         bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
2255         bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
2256         bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
2257
2258         // packages
2259         bp_.graphics_driver =
2260                 tex_graphics[latexModule->psdriverCO->currentIndex()];
2261         
2262         // text layout
2263         int idx = latexModule->classCO->currentIndex();
2264         if (idx >= 0) {
2265                 string const classname = classes_model_.getIDString(idx);
2266                 bp_.setBaseClass(classname);
2267         }
2268
2269         // Modules
2270         modulesToParams(bp_);
2271
2272         // Math
2273         if (mathsModule->amsautoCB->isChecked())
2274                 bp_.use_amsmath = BufferParams::package_auto;
2275         else {
2276                 if (mathsModule->amsCB->isChecked())
2277                         bp_.use_amsmath = BufferParams::package_on;
2278                 else
2279                         bp_.use_amsmath = BufferParams::package_off;
2280         }
2281         if (mathsModule->esintautoCB->isChecked())
2282                 bp_.use_esint = BufferParams::package_auto;
2283         else {
2284                 if (mathsModule->esintCB->isChecked())
2285                         bp_.use_esint = BufferParams::package_on;
2286                 else
2287                         bp_.use_esint = BufferParams::package_off;
2288         }
2289         if (mathsModule->mhchemautoCB->isChecked())
2290                 bp_.use_mhchem = BufferParams::package_auto;
2291         else {
2292                 if (mathsModule->mhchemCB->isChecked())
2293                         bp_.use_mhchem = BufferParams::package_on;
2294                 else
2295                         bp_.use_mhchem = BufferParams::package_off;
2296         }
2297         if (mathsModule->mathdotsautoCB->isChecked())
2298                 bp_.use_mathdots = BufferParams::package_auto;
2299         else {
2300                 if (mathsModule->mathdotsCB->isChecked())
2301                         bp_.use_mathdots = BufferParams::package_on;
2302                 else
2303                         bp_.use_mathdots = BufferParams::package_off;
2304         }
2305         
2306         // Page Layout
2307         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
2308                 bp_.pagestyle = "default";
2309         else {
2310                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
2311                 for (size_t i = 0; i != pagestyles.size(); ++i)
2312                         if (pagestyles[i].second == style_gui)
2313                                 bp_.pagestyle = pagestyles[i].first;
2314         }
2315
2316         // Text Layout
2317         switch (textLayoutModule->lspacingCO->currentIndex()) {
2318         case 0:
2319                 bp_.spacing().set(Spacing::Single);
2320                 break;
2321         case 1:
2322                 bp_.spacing().set(Spacing::Onehalf);
2323                 break;
2324         case 2:
2325                 bp_.spacing().set(Spacing::Double);
2326                 break;
2327         case 3: {
2328                 string s = widgetToDoubleStr(textLayoutModule->lspacingLE);
2329                 if (s.empty())
2330                         bp_.spacing().set(Spacing::Single);
2331                 else
2332                         bp_.spacing().set(Spacing::Other, s);
2333                 break;
2334                 }
2335         }
2336
2337         if (textLayoutModule->twoColumnCB->isChecked())
2338                 bp_.columns = 2;
2339         else
2340                 bp_.columns = 1;
2341
2342         if (textLayoutModule->indentRB->isChecked()) {
2343                 // if paragraphs are separated by an indentation
2344                 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
2345                 switch (textLayoutModule->indentCO->currentIndex()) {
2346                 case 0:
2347                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2348                         break;
2349                 case 1: {
2350                         HSpace indent = HSpace(
2351                                 widgetsToLength(textLayoutModule->indentLE,
2352                                 textLayoutModule->indentLengthCO)
2353                                 );
2354                         bp_.setIndentation(indent);
2355                         break;
2356                         }
2357                 default:
2358                         // this should never happen
2359                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2360                         break;
2361                 }
2362         } else {
2363                 // if paragraphs are separated by a skip
2364                 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
2365                 switch (textLayoutModule->skipCO->currentIndex()) {
2366                 case 0:
2367                         bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
2368                         break;
2369                 case 1:
2370                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2371                         break;
2372                 case 2:
2373                         bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
2374                         break;
2375                 case 3:
2376                         {
2377                         VSpace vs = VSpace(
2378                                 widgetsToLength(textLayoutModule->skipLE,
2379                                 textLayoutModule->skipLengthCO)
2380                                 );
2381                         bp_.setDefSkip(vs);
2382                         break;
2383                         }
2384                 default:
2385                         // this should never happen
2386                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2387                         break;
2388                 }
2389         }
2390
2391         bp_.options =
2392                 fromqstr(latexModule->optionsLE->text());
2393
2394         bp_.use_default_options =
2395                 latexModule->defaultOptionsCB->isChecked();
2396
2397         if (latexModule->childDocGB->isChecked())
2398                 bp_.master =
2399                         fromqstr(latexModule->childDocLE->text());
2400         else
2401                 bp_.master = string();
2402
2403         // Master/Child
2404         bp_.clearIncludedChildren();
2405         if (masterChildModule->includeonlyRB->isChecked()) {
2406                 list<string>::const_iterator it = includeonlys_.begin();
2407                 for (; it != includeonlys_.end() ; ++it) {
2408                         bp_.addIncludedChildren(*it);
2409                 }
2410         }
2411         bp_.maintain_unincluded_children =
2412                 masterChildModule->maintainAuxCB->isChecked();
2413
2414         // Float Placement
2415         bp_.float_placement = floatModule->get();
2416
2417         // Listings
2418         // text should have passed validation
2419         bp_.listings_params =
2420                 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
2421
2422         // output
2423         bp_.default_output_format = fromqstr(outputModule->defaultFormatCO->itemData(
2424                 outputModule->defaultFormatCO->currentIndex()).toString());
2425
2426         bool const nontexfonts = fontModule->osFontsCB->isChecked();
2427         bp_.useNonTeXFonts = nontexfonts;
2428
2429         bp_.output_sync = outputModule->outputsyncCB->isChecked();
2430         bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
2431
2432         int mathfmt = outputModule->mathoutCB->currentIndex();
2433         if (mathfmt == -1)
2434                 mathfmt = 0;
2435         BufferParams::MathOutput const mo =
2436                 static_cast<BufferParams::MathOutput>(mathfmt);
2437         bp_.html_math_output = mo;
2438         bp_.html_be_strict = outputModule->strictCB->isChecked();
2439         bp_.html_math_img_scale = outputModule->mathimgSB->value();
2440
2441         // fonts
2442         if (nontexfonts) {
2443                 if (fontModule->fontsRomanCO->currentIndex() == 0)
2444                         bp_.fonts_roman = "default";
2445                 else
2446                         bp_.fonts_roman =
2447                                 fromqstr(fontModule->fontsRomanCO->currentText());
2448         
2449                 if (fontModule->fontsSansCO->currentIndex() == 0)
2450                         bp_.fonts_sans = "default";
2451                 else
2452                         bp_.fonts_sans =
2453                                 fromqstr(fontModule->fontsSansCO->currentText());
2454         
2455                 if (fontModule->fontsTypewriterCO->currentIndex() == 0)
2456                         bp_.fonts_typewriter = "default";
2457                 else
2458                         bp_.fonts_typewriter =
2459                                 fromqstr(fontModule->fontsTypewriterCO->currentText());
2460         } else {
2461                 bp_.fonts_roman =
2462                         tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
2463         
2464                 bp_.fonts_sans =
2465                         tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
2466         
2467                 bp_.fonts_typewriter =
2468                         tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
2469         }
2470
2471         if (fontModule->fontencCO->currentIndex() == 0)
2472                 bp_.fontenc = "global";
2473         else if (fontModule->fontencCO->currentIndex() == 1)
2474                 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
2475         else if (fontModule->fontencCO->currentIndex() == 2)
2476                 bp_.fontenc = "default";
2477
2478         bp_.fonts_cjk =
2479                 fromqstr(fontModule->cjkFontLE->text());
2480
2481         bp_.fonts_sans_scale = fontModule->scaleSansSB->value();
2482
2483         bp_.fonts_typewriter_scale = fontModule->scaleTypewriterSB->value();
2484
2485         bp_.fonts_expert_sc = fontModule->fontScCB->isChecked();
2486
2487         bp_.fonts_old_figures = fontModule->fontOsfCB->isChecked();
2488
2489         if (nontexfonts)
2490                 bp_.fonts_default_family = "default";
2491         else
2492                 bp_.fonts_default_family = GuiDocument::fontfamilies[
2493                         fontModule->fontsDefaultCO->currentIndex()];
2494
2495         if (fontModule->fontsizeCO->currentIndex() == 0)
2496                 bp_.fontsize = "default";
2497         else
2498                 bp_.fontsize =
2499                         fromqstr(fontModule->fontsizeCO->currentText());
2500
2501         // paper
2502         bp_.papersize = PAPER_SIZE(
2503                 pageLayoutModule->papersizeCO->currentIndex());
2504
2505         bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
2506                 pageLayoutModule->paperwidthUnitCO);
2507
2508         bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
2509                 pageLayoutModule->paperheightUnitCO);
2510
2511         if (pageLayoutModule->facingPagesCB->isChecked())
2512                 bp_.sides = TwoSides;
2513         else
2514                 bp_.sides = OneSide;
2515
2516         if (pageLayoutModule->landscapeRB->isChecked())
2517                 bp_.orientation = ORIENTATION_LANDSCAPE;
2518         else
2519                 bp_.orientation = ORIENTATION_PORTRAIT;
2520
2521         // margins
2522         bp_.use_geometry = !marginsModule->marginCB->isChecked();
2523
2524         Ui::MarginsUi const * m = marginsModule;
2525
2526         bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
2527         bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
2528         bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
2529         bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
2530         bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
2531         bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
2532         bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
2533         bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
2534
2535         // branches
2536         branchesModule->apply(bp_);
2537
2538         // PDF support
2539         PDFOptions & pdf = bp_.pdfoptions();
2540         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
2541         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
2542         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
2543         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
2544         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
2545
2546         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
2547         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
2548         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
2549         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
2550
2551         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
2552         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
2553         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
2554         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
2555         pdf.backref =
2556                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
2557         if (pdfSupportModule->fullscreenCB->isChecked())
2558                 pdf.pagemode = pdf.pagemode_fullscreen;
2559         else
2560                 pdf.pagemode.clear();
2561         pdf.quoted_options = pdf.quoted_options_check(
2562                                 fromqstr(pdfSupportModule->optionsLE->text()));
2563 }
2564
2565
2566 void GuiDocument::paramsToDialog()
2567 {
2568         // set the default unit
2569         Length::UNIT const defaultUnit = Length::defaultUnit();
2570
2571         // preamble
2572         preambleModule->update(bp_, id());
2573         localLayout->update(bp_, id());
2574
2575         // date
2576         latexModule->suppressDateCB->setChecked(bp_.suppress_date);
2577         latexModule->refstyleCB->setChecked(bp_.use_refstyle);
2578
2579         // biblio
2580         biblioModule->citeDefaultRB->setChecked(
2581                 bp_.citeEngine() == ENGINE_BASIC);
2582
2583         biblioModule->citeNatbibRB->setChecked(
2584                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL ||
2585                 bp_.citeEngine() == ENGINE_NATBIB_AUTHORYEAR);
2586
2587         biblioModule->citeStyleCO->setCurrentIndex(
2588                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL);
2589
2590         biblioModule->citeJurabibRB->setChecked(
2591                 bp_.citeEngine() == ENGINE_JURABIB);
2592
2593         biblioModule->bibtopicCB->setChecked(
2594                 bp_.use_bibtopic);
2595
2596         string command;
2597         string options =
2598                 split(bp_.bibtex_command, command, ' ');
2599
2600         int const bpos = biblioModule->bibtexCO->findData(toqstr(command));
2601         if (bpos != -1) {
2602                 biblioModule->bibtexCO->setCurrentIndex(bpos);
2603                 biblioModule->bibtexOptionsED->setText(toqstr(options).trimmed());
2604         } else {
2605                 biblioModule->bibtexCO->setCurrentIndex(0);
2606                 biblioModule->bibtexOptionsED->clear();
2607         }
2608         biblioModule->bibtexOptionsED->setEnabled(
2609                 biblioModule->bibtexCO->currentIndex() != 0);
2610
2611         // indices
2612         indicesModule->update(bp_);
2613
2614         // language & quotes
2615         int const pos = langModule->languageCO->findData(toqstr(
2616                 bp_.language->lang()));
2617         langModule->languageCO->setCurrentIndex(pos);
2618
2619         langModule->quoteStyleCO->setCurrentIndex(
2620                 bp_.quotes_language);
2621
2622         bool default_enc = true;
2623         if (bp_.inputenc != "auto") {
2624                 default_enc = false;
2625                 if (bp_.inputenc == "default") {
2626                         langModule->encodingCO->setCurrentIndex(0);
2627                 } else {
2628                         string enc_gui;
2629                         Encodings::const_iterator it = encodings.begin();
2630                         Encodings::const_iterator const end = encodings.end();
2631                         for (; it != end; ++it) {
2632                                 if (it->latexName() == bp_.inputenc) {
2633                                         enc_gui = it->guiName();
2634                                         break;
2635                                 }
2636                         }
2637                         int const i = langModule->encodingCO->findText(
2638                                         qt_(enc_gui));
2639                         if (i >= 0)
2640                                 langModule->encodingCO->setCurrentIndex(i);
2641                         else
2642                                 // unknown encoding. Set to default.
2643                                 default_enc = true;
2644                 }
2645         }
2646         langModule->defaultencodingRB->setChecked(default_enc);
2647         langModule->otherencodingRB->setChecked(!default_enc);
2648
2649         int const p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
2650         if (p == -1) {
2651                 langModule->languagePackageCO->setCurrentIndex(
2652                           langModule->languagePackageCO->findData("custom"));
2653                 langModule->languagePackageED->setText(toqstr(bp_.lang_package));
2654         } else {
2655                 langModule->languagePackageCO->setCurrentIndex(p);
2656                 langModule->languagePackageED->clear();
2657         }
2658
2659         //color
2660         if (bp_.isfontcolor) {
2661                 colorModule->fontColorPB->setStyleSheet(
2662                         colorButtonStyleSheet(rgb2qcolor(bp_.fontcolor)));
2663         }
2664         set_fontcolor = bp_.fontcolor;
2665         is_fontcolor = bp_.isfontcolor;
2666
2667         colorModule->noteFontColorPB->setStyleSheet(
2668                 colorButtonStyleSheet(rgb2qcolor(bp_.notefontcolor)));
2669         set_notefontcolor = bp_.notefontcolor;
2670
2671         if (bp_.isbackgroundcolor) {
2672                 colorModule->backgroundPB->setStyleSheet(
2673                         colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
2674         }
2675         set_backgroundcolor = bp_.backgroundcolor;
2676         is_backgroundcolor = bp_.isbackgroundcolor;
2677
2678         colorModule->boxBackgroundPB->setStyleSheet(
2679                 colorButtonStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
2680         set_boxbgcolor = bp_.boxbgcolor;
2681
2682         // numbering
2683         int const min_toclevel = documentClass().min_toclevel();
2684         int const max_toclevel = documentClass().max_toclevel();
2685         if (documentClass().hasTocLevels()) {
2686                 numberingModule->setEnabled(true);
2687                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
2688                 numberingModule->depthSL->setMaximum(max_toclevel);
2689                 numberingModule->depthSL->setValue(bp_.secnumdepth);
2690                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
2691                 numberingModule->tocSL->setMaximum(max_toclevel);
2692                 numberingModule->tocSL->setValue(bp_.tocdepth);
2693                 updateNumbering();
2694         } else {
2695                 numberingModule->setEnabled(false);
2696                 numberingModule->tocTW->clear();
2697         }
2698
2699         // bullets
2700         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
2701         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
2702         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
2703         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
2704         bulletsModule->init();
2705
2706         // packages
2707         int nitem = findToken(tex_graphics, bp_.graphics_driver);
2708         if (nitem >= 0)
2709                 latexModule->psdriverCO->setCurrentIndex(nitem);
2710         updateModuleInfo();
2711         
2712         mathsModule->amsCB->setChecked(
2713                 bp_.use_amsmath == BufferParams::package_on);
2714         mathsModule->amsautoCB->setChecked(
2715                 bp_.use_amsmath == BufferParams::package_auto);
2716
2717         mathsModule->esintCB->setChecked(
2718                 bp_.use_esint == BufferParams::package_on);
2719         mathsModule->esintautoCB->setChecked(
2720                 bp_.use_esint == BufferParams::package_auto);
2721
2722         mathsModule->mhchemCB->setChecked(
2723                 bp_.use_mhchem == BufferParams::package_on);
2724         mathsModule->mhchemautoCB->setChecked(
2725                 bp_.use_mhchem == BufferParams::package_auto);
2726
2727         mathsModule->mathdotsCB->setChecked(
2728                 bp_.use_mathdots == BufferParams::package_on);
2729         mathsModule->mathdotsautoCB->setChecked(
2730                 bp_.use_mathdots == BufferParams::package_auto);
2731
2732         switch (bp_.spacing().getSpace()) {
2733                 case Spacing::Other: nitem = 3; break;
2734                 case Spacing::Double: nitem = 2; break;
2735                 case Spacing::Onehalf: nitem = 1; break;
2736                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
2737         }
2738
2739         // text layout
2740         string const & layoutID = bp_.baseClassID();
2741         setLayoutComboByIDString(layoutID);
2742
2743         updatePagestyle(documentClass().opt_pagestyle(),
2744                                  bp_.pagestyle);
2745
2746         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
2747         if (bp_.spacing().getSpace() == Spacing::Other) {
2748                 doubleToWidget(textLayoutModule->lspacingLE,
2749                         bp_.spacing().getValueAsString());
2750         }
2751         setLSpacing(nitem);
2752
2753         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
2754                 textLayoutModule->indentRB->setChecked(true);
2755                 string indentation = bp_.getIndentation().asLyXCommand();
2756                 int indent = 0;
2757                 if (indentation != "default") {
2758                         lengthToWidgets(textLayoutModule->indentLE,
2759                         textLayoutModule->indentLengthCO,
2760                         indentation, defaultUnit);
2761                         indent = 1;
2762                 }
2763                 textLayoutModule->indentCO->setCurrentIndex(indent);
2764                 setIndent(indent);
2765         } else {
2766                 textLayoutModule->skipRB->setChecked(true);
2767                 int skip = 0;
2768                 switch (bp_.getDefSkip().kind()) {
2769                 case VSpace::SMALLSKIP:
2770                         skip = 0;
2771                         break;
2772                 case VSpace::MEDSKIP:
2773                         skip = 1;
2774                         break;
2775                 case VSpace::BIGSKIP:
2776                         skip = 2;
2777                         break;
2778                 case VSpace::LENGTH:
2779                         {
2780                         skip = 3;
2781                         string const length = bp_.getDefSkip().asLyXCommand();
2782                         lengthToWidgets(textLayoutModule->skipLE,
2783                                 textLayoutModule->skipLengthCO,
2784                                 length, defaultUnit);
2785                         break;
2786                         }
2787                 default:
2788                         skip = 0;
2789                         break;
2790                 }
2791                 textLayoutModule->skipCO->setCurrentIndex(skip);
2792                 setSkip(skip);
2793         }
2794
2795         textLayoutModule->twoColumnCB->setChecked(
2796                 bp_.columns == 2);
2797
2798         if (!bp_.options.empty()) {
2799                 latexModule->optionsLE->setText(
2800                         toqstr(bp_.options));
2801         } else {
2802                 latexModule->optionsLE->setText(QString());
2803         }
2804
2805         // latex
2806         latexModule->defaultOptionsCB->setChecked(
2807                         bp_.use_default_options);
2808         updateSelectedModules();
2809         selectionManager->updateProvidedModules(
2810                         bp_.baseClass()->providedModules());
2811         selectionManager->updateExcludedModules(
2812                         bp_.baseClass()->excludedModules());
2813
2814         if (!documentClass().options().empty()) {
2815                 latexModule->defaultOptionsLE->setText(
2816                         toqstr(documentClass().options()));
2817         } else {
2818                 latexModule->defaultOptionsLE->setText(
2819                         toqstr(_("[No options predefined]")));
2820         }
2821
2822         latexModule->defaultOptionsLE->setEnabled(
2823                 bp_.use_default_options
2824                 && !documentClass().options().empty());
2825
2826         latexModule->defaultOptionsCB->setEnabled(
2827                 !documentClass().options().empty());
2828
2829         if (!bp_.master.empty()) {
2830                 latexModule->childDocGB->setChecked(true);
2831                 latexModule->childDocLE->setText(
2832                         toqstr(bp_.master));
2833         } else {
2834                 latexModule->childDocLE->setText(QString());
2835                 latexModule->childDocGB->setChecked(false);
2836         }
2837
2838         // Master/Child
2839         if (!bufferview() || !buffer().hasChildren()) {
2840                 masterChildModule->childrenTW->clear();
2841                 includeonlys_.clear();
2842                 docPS->showPanel(qt_("Child Documents"), false);
2843                 if (docPS->isCurrentPanel(qt_("Child Documents")))
2844                         docPS->setCurrentPanel(qt_("Document Class"));
2845         } else {
2846                 docPS->showPanel(qt_("Child Documents"), true);
2847                 masterChildModule->setEnabled(true);
2848                 includeonlys_ = bp_.getIncludedChildren();
2849                 updateIncludeonlys();
2850         }
2851         masterChildModule->maintainAuxCB->setChecked(
2852                 bp_.maintain_unincluded_children);
2853
2854         // Float Settings
2855         floatModule->set(bp_.float_placement);
2856
2857         // ListingsSettings
2858         // break listings_params to multiple lines
2859         string lstparams =
2860                 InsetListingsParams(bp_.listings_params).separatedParams();
2861         listingsModule->listingsED->setPlainText(toqstr(lstparams));
2862
2863         // Output
2864         // update combobox with formats
2865         updateDefaultFormat();
2866         int index = outputModule->defaultFormatCO->findData(toqstr(
2867                 bp_.default_output_format));
2868         // set to default if format is not found 
2869         if (index == -1)
2870                 index = 0;
2871         outputModule->defaultFormatCO->setCurrentIndex(index);
2872         fontModule->osFontsCB->setEnabled(bp_.baseClass()->outputType() == lyx::LATEX);
2873         fontModule->osFontsCB->setChecked(
2874                 bp_.baseClass()->outputType() == lyx::LATEX && bp_.useNonTeXFonts);
2875
2876         outputModule->outputsyncCB->setChecked(bp_.output_sync);
2877         outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
2878
2879         outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
2880         outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
2881         outputModule->strictCB->setChecked(bp_.html_be_strict);
2882
2883         // Fonts
2884         updateFontsize(documentClass().opt_fontsize(),
2885                         bp_.fontsize);
2886
2887         if (bp_.useNonTeXFonts) {
2888                 fontModule->fontencLA->setEnabled(false);
2889                 fontModule->fontencCO->setEnabled(false);
2890                 fontModule->fontencLE->setEnabled(false);
2891                 for (int i = 0; i < fontModule->fontsRomanCO->count(); ++i) {
2892                         if (fontModule->fontsRomanCO->itemText(i) == toqstr(bp_.fonts_roman)) {
2893                                 fontModule->fontsRomanCO->setCurrentIndex(i);
2894                                 break;
2895                         }
2896                 }
2897                 
2898                 for (int i = 0; i < fontModule->fontsSansCO->count(); ++i) {
2899                         if (fontModule->fontsSansCO->itemText(i) == toqstr(bp_.fonts_sans)) {
2900                                 fontModule->fontsSansCO->setCurrentIndex(i);
2901                                 break;
2902                         }
2903                 }
2904                 for (int i = 0; i < fontModule->fontsTypewriterCO->count(); ++i) {
2905                         if (fontModule->fontsTypewriterCO->itemText(i) == 
2906                                 toqstr(bp_.fonts_typewriter)) {
2907                                 fontModule->fontsTypewriterCO->setCurrentIndex(i);
2908                                 break;
2909                         }
2910                 }
2911         } else {
2912                 fontModule->fontencLA->setEnabled(true);
2913                 fontModule->fontencCO->setEnabled(true);
2914                 fontModule->fontencLE->setEnabled(true);
2915                 int n = findToken(tex_fonts_roman, bp_.fonts_roman);
2916                 if (n >= 0) {
2917                         fontModule->fontsRomanCO->setCurrentIndex(n);
2918                         romanChanged(n);
2919                 }
2920         
2921                 n = findToken(tex_fonts_sans, bp_.fonts_sans);
2922                 if (n >= 0) {
2923                         fontModule->fontsSansCO->setCurrentIndex(n);
2924                         sansChanged(n);
2925                 }
2926         
2927                 n = findToken(tex_fonts_monospaced, bp_.fonts_typewriter);
2928                 if (n >= 0) {
2929                         fontModule->fontsTypewriterCO->setCurrentIndex(n);
2930                         ttChanged(n);
2931                 }
2932         }
2933
2934         if (!bp_.fonts_cjk.empty())
2935                 fontModule->cjkFontLE->setText(
2936                         toqstr(bp_.fonts_cjk));
2937         else
2938                 fontModule->cjkFontLE->setText(QString());
2939
2940         fontModule->fontScCB->setChecked(bp_.fonts_expert_sc);
2941         fontModule->fontOsfCB->setChecked(bp_.fonts_old_figures);
2942         fontModule->scaleSansSB->setValue(bp_.fonts_sans_scale);
2943         fontModule->scaleTypewriterSB->setValue(bp_.fonts_typewriter_scale);
2944         
2945         int nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
2946         if (nn >= 0)
2947                 fontModule->fontsDefaultCO->setCurrentIndex(nn);
2948
2949         if (bp_.fontenc == "global") {
2950                 fontModule->fontencCO->setCurrentIndex(0);
2951                 fontModule->fontencLE->setEnabled(false);
2952         } else if (bp_.fontenc == "default") {
2953                 fontModule->fontencCO->setCurrentIndex(2);
2954                 fontModule->fontencLE->setEnabled(false);
2955         } else {
2956                 fontModule->fontencCO->setCurrentIndex(1);
2957                 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
2958         }
2959
2960         // paper
2961         bool const extern_geometry =
2962                 documentClass().provides("geometry");
2963         int const psize = bp_.papersize;
2964         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
2965         setCustomPapersize(!extern_geometry && psize == 1);
2966         pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
2967
2968         bool const landscape =
2969                 bp_.orientation == ORIENTATION_LANDSCAPE;
2970         pageLayoutModule->landscapeRB->setChecked(landscape);
2971         pageLayoutModule->portraitRB->setChecked(!landscape);
2972         pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
2973         pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
2974
2975         pageLayoutModule->facingPagesCB->setChecked(
2976                 bp_.sides == TwoSides);
2977
2978         lengthToWidgets(pageLayoutModule->paperwidthLE,
2979                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, defaultUnit);
2980         lengthToWidgets(pageLayoutModule->paperheightLE,
2981                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, defaultUnit);
2982
2983         // margins
2984         Ui::MarginsUi * m = marginsModule;
2985
2986         setMargins();
2987
2988         lengthToWidgets(m->topLE, m->topUnit,
2989                 bp_.topmargin, defaultUnit);
2990
2991         lengthToWidgets(m->bottomLE, m->bottomUnit,
2992                 bp_.bottommargin, defaultUnit);
2993
2994         lengthToWidgets(m->innerLE, m->innerUnit,
2995                 bp_.leftmargin, defaultUnit);
2996
2997         lengthToWidgets(m->outerLE, m->outerUnit,
2998                 bp_.rightmargin, defaultUnit);
2999
3000         lengthToWidgets(m->headheightLE, m->headheightUnit,
3001                 bp_.headheight, defaultUnit);
3002
3003         lengthToWidgets(m->headsepLE, m->headsepUnit,
3004                 bp_.headsep, defaultUnit);
3005
3006         lengthToWidgets(m->footskipLE, m->footskipUnit,
3007                 bp_.footskip, defaultUnit);
3008
3009         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
3010                 bp_.columnsep, defaultUnit);
3011
3012         // branches
3013         updateUnknownBranches();
3014         branchesModule->update(bp_);
3015
3016         // PDF support
3017         PDFOptions const & pdf = bp_.pdfoptions();
3018         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
3019         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
3020         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
3021         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
3022         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
3023
3024         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
3025         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
3026         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
3027
3028         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
3029
3030         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
3031         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
3032         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
3033         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
3034
3035         nn = findToken(backref_opts, pdf.backref);
3036         if (nn >= 0)
3037                 pdfSupportModule->backrefCO->setCurrentIndex(nn);
3038
3039         pdfSupportModule->fullscreenCB->setChecked
3040                 (pdf.pagemode == pdf.pagemode_fullscreen);
3041
3042         pdfSupportModule->optionsLE->setText(
3043                 toqstr(pdf.quoted_options));
3044
3045         // Make sure that the bc is in the INITIAL state
3046         if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
3047                 bc().restore();
3048
3049         // clear changed branches cache
3050         changedBranches_.clear();
3051 }
3052
3053
3054 void GuiDocument::saveDocDefault()
3055 {
3056         // we have to apply the params first
3057         applyView();
3058         saveAsDefault();
3059 }
3060
3061
3062 void GuiDocument::updateAvailableModules() 
3063 {
3064         modules_av_model_.clear();
3065         list<modInfoStruct> const & modInfoList = getModuleInfo();
3066         list<modInfoStruct>::const_iterator mit = modInfoList.begin();
3067         list<modInfoStruct>::const_iterator men = modInfoList.end();
3068         for (int i = 0; mit != men; ++mit, ++i)
3069                 modules_av_model_.insertRow(i, mit->name, mit->id, 
3070                                 mit->description);
3071 }
3072
3073
3074 void GuiDocument::updateSelectedModules() 
3075 {
3076         modules_sel_model_.clear();
3077         list<modInfoStruct> const selModList = getSelectedModules();
3078         list<modInfoStruct>::const_iterator mit = selModList.begin();
3079         list<modInfoStruct>::const_iterator men = selModList.end();
3080         for (int i = 0; mit != men; ++mit, ++i)
3081                 modules_sel_model_.insertRow(i, mit->name, mit->id, 
3082                                 mit->description);
3083 }
3084
3085
3086 void GuiDocument::updateIncludeonlys()
3087 {
3088         masterChildModule->childrenTW->clear();
3089         QString const no = qt_("No");
3090         QString const yes = qt_("Yes");
3091
3092         if (includeonlys_.empty()) {
3093                 masterChildModule->includeallRB->setChecked(true);
3094                 masterChildModule->childrenTW->setEnabled(false);
3095                 masterChildModule->maintainAuxCB->setEnabled(false);
3096         } else {
3097                 masterChildModule->includeonlyRB->setChecked(true);
3098                 masterChildModule->childrenTW->setEnabled(true);
3099                 masterChildModule->maintainAuxCB->setEnabled(true);
3100         }
3101         QTreeWidgetItem * item = 0;
3102         ListOfBuffers children = buffer().getChildren();
3103         ListOfBuffers::const_iterator it  = children.begin();
3104         ListOfBuffers::const_iterator end = children.end();
3105         bool has_unincluded = false;
3106         bool all_unincluded = true;
3107         for (; it != end; ++it) {
3108                 item = new QTreeWidgetItem(masterChildModule->childrenTW);
3109                 // FIXME Unicode
3110                 string const name =
3111                         to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
3112                                                         from_utf8(buffer().filePath())));
3113                 item->setText(0, toqstr(name));
3114                 item->setText(1, isChildIncluded(name) ? yes : no);
3115                 if (!isChildIncluded(name))
3116                         has_unincluded = true;
3117                 else
3118                         all_unincluded = false;
3119         }
3120         // Both if all childs are included and if none is included
3121         // is equal to "include all" (i.e., ommit \includeonly).
3122         // Thus, reset the GUI.
3123         if (!has_unincluded || all_unincluded) {
3124                 masterChildModule->includeallRB->setChecked(true);
3125                 masterChildModule->childrenTW->setEnabled(false);
3126                 includeonlys_.clear();
3127         }
3128         // If all are included, we need to update again.
3129         if (!has_unincluded)
3130                 updateIncludeonlys();
3131 }
3132
3133
3134 void GuiDocument::updateContents()
3135 {
3136         // Nothing to do here as the document settings is not cursor dependant.
3137         return;
3138 }
3139
3140
3141 void GuiDocument::useClassDefaults()
3142 {
3143         if (applyPB->isEnabled()) {
3144                 int const ret = Alert::prompt(_("Unapplied changes"),
3145                                 _("Some changes in the dialog were not yet applied.\n"
3146                                   "If you do not apply now, they will be lost after this action."),
3147                                 1, 1, _("&Apply"), _("&Dismiss"));
3148                 if (ret == 0)
3149                         applyView();
3150         }
3151
3152         int idx = latexModule->classCO->currentIndex();
3153         string const classname = classes_model_.getIDString(idx);
3154         if (!bp_.setBaseClass(classname)) {
3155                 Alert::error(_("Error"), _("Unable to set document class."));
3156                 return;
3157         }
3158         bp_.useClassDefaults();
3159         paramsToDialog();
3160 }
3161
3162
3163 void GuiDocument::setLayoutComboByIDString(string const & idString)
3164 {
3165         int idx = classes_model_.findIDString(idString);
3166         if (idx < 0)
3167                 Alert::warning(_("Can't set layout!"), 
3168                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
3169         else 
3170                 latexModule->classCO->setCurrentIndex(idx);
3171 }
3172
3173
3174 bool GuiDocument::isValid()
3175 {
3176         return 
3177                 validateListingsParameters().isEmpty() &&
3178                 localLayout->isValid() &&
3179                 (
3180                         // if we're asking for skips between paragraphs
3181                         !textLayoutModule->skipRB->isChecked() ||
3182                         // then either we haven't chosen custom
3183                         textLayoutModule->skipCO->currentIndex() != 3 || 
3184                         // or else a length has been given
3185                         !textLayoutModule->skipLE->text().isEmpty()
3186                 ) && 
3187                 (
3188                         // if we're asking for indentation
3189                         !textLayoutModule->indentRB->isChecked() || 
3190                         // then either we haven't chosen custom
3191                         textLayoutModule->indentCO->currentIndex() != 1 || 
3192                         // or else a length has been given
3193                         !textLayoutModule->indentLE->text().isEmpty()
3194                 );
3195 }
3196
3197
3198 char const * const GuiDocument::fontfamilies[5] = {
3199         "default", "rmdefault", "sfdefault", "ttdefault", ""
3200 };
3201
3202
3203 char const * GuiDocument::fontfamilies_gui[5] = {
3204         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
3205 };
3206
3207
3208 bool GuiDocument::initialiseParams(string const &)
3209 {
3210         BufferView const * view = bufferview();
3211         if (!view) {
3212                 bp_ = BufferParams();
3213                 paramsToDialog();
3214                 return true;
3215         }
3216         bp_ = view->buffer().params();
3217         loadModuleInfo();
3218         updateAvailableModules();
3219         //FIXME It'd be nice to make sure here that the selected
3220         //modules are consistent: That required modules are actually
3221         //selected, and that we don't have conflicts. If so, we could
3222         //at least pop up a warning.
3223         paramsToDialog();
3224         return true;
3225 }
3226
3227
3228 void GuiDocument::clearParams()
3229 {
3230         bp_ = BufferParams();
3231 }
3232
3233
3234 BufferId GuiDocument::id() const
3235 {
3236         BufferView const * const view = bufferview();
3237         return view? &view->buffer() : 0;
3238 }
3239
3240
3241 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
3242 {
3243         return moduleNames_;
3244 }
3245
3246
3247 list<GuiDocument::modInfoStruct> const 
3248                 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
3249 {
3250         LayoutModuleList::const_iterator it =  mods.begin();
3251         LayoutModuleList::const_iterator end = mods.end();
3252         list<modInfoStruct> mInfo;
3253         for (; it != end; ++it) {
3254                 modInfoStruct m;
3255                 m.id = *it;
3256                 LyXModule const * const mod = theModuleList[*it];
3257                 if (mod)
3258                         // FIXME Unicode
3259                         m.name = toqstr(translateIfPossible(from_utf8(mod->getName())));
3260                 else 
3261                         m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
3262                 mInfo.push_back(m);
3263         }
3264         return mInfo;
3265 }
3266
3267
3268 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
3269 {
3270         return makeModuleInfo(params().getModules());
3271 }
3272
3273
3274 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
3275 {
3276         return makeModuleInfo(params().baseClass()->providedModules());
3277 }
3278
3279
3280 DocumentClass const & GuiDocument::documentClass() const
3281 {
3282         return bp_.documentClass();
3283 }
3284
3285
3286 static void dispatch_bufferparams(Dialog const & dialog,
3287         BufferParams const & bp, FuncCode lfun)
3288 {
3289         ostringstream ss;
3290         ss << "\\begin_header\n";
3291         bp.writeFile(ss);
3292         ss << "\\end_header\n";
3293         dialog.dispatch(FuncRequest(lfun, ss.str()));
3294 }
3295
3296
3297 void GuiDocument::dispatchParams()
3298 {
3299         // This must come first so that a language change is correctly noticed
3300         setLanguage();
3301
3302         // Apply the BufferParams. Note that this will set the base class
3303         // and then update the buffer's layout.
3304         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
3305
3306         if (!params().master.empty()) {
3307                 FileName const master_file = support::makeAbsPath(params().master,
3308                            support::onlyPath(buffer().absFileName()));
3309                 if (isLyXFileName(master_file.absFileName())) {
3310                         Buffer * master = checkAndLoadLyXFile(master_file);
3311                         if (master) {
3312                                 if (master->isChild(const_cast<Buffer *>(&buffer())))
3313                                         const_cast<Buffer &>(buffer()).setParent(master);
3314                                 else
3315                                         Alert::warning(_("Assigned master does not include this file"), 
3316                                                 bformat(_("You must include this file in the document\n"
3317                                                           "'%1$s' in order to use the master document\n"
3318                                                           "feature."), from_utf8(params().master)));
3319                         } else
3320                                 Alert::warning(_("Could not load master"), 
3321                                                 bformat(_("The master document '%1$s'\n"
3322                                                            "could not be loaded."),
3323                                                            from_utf8(params().master)));
3324                 }
3325         }
3326
3327         // Generate the colours requested by each new branch.
3328         BranchList & branchlist = params().branchlist();
3329         if (!branchlist.empty()) {
3330                 BranchList::const_iterator it = branchlist.begin();
3331                 BranchList::const_iterator const end = branchlist.end();
3332                 for (; it != end; ++it) {
3333                         docstring const & current_branch = it->branch();
3334                         Branch const * branch = branchlist.find(current_branch);
3335                         string const x11hexname = X11hexname(branch->color());
3336                         // display the new color
3337                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
3338                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
3339                 }
3340
3341                 // Open insets of selected branches, close deselected ones
3342                 dispatch(FuncRequest(LFUN_INSET_FORALL,
3343                         "Branch inset-toggle assign"));
3344         }
3345         // rename branches in the document
3346         executeBranchRenaming();
3347         // and clear changed branches cache
3348         changedBranches_.clear();
3349         
3350         // Generate the colours requested by indices.
3351         IndicesList & indiceslist = params().indiceslist();
3352         if (!indiceslist.empty()) {
3353                 IndicesList::const_iterator it = indiceslist.begin();
3354                 IndicesList::const_iterator const end = indiceslist.end();
3355                 for (; it != end; ++it) {
3356                         docstring const & current_index = it->shortcut();
3357                         Index const * index = indiceslist.findShortcut(current_index);
3358                         string const x11hexname = X11hexname(index->color());
3359                         // display the new color
3360                         docstring const str = current_index + ' ' + from_ascii(x11hexname);
3361                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
3362                 }
3363         }
3364         // FIXME LFUN
3365         // If we used an LFUN, we would not need these two lines:
3366         BufferView * bv = const_cast<BufferView *>(bufferview());
3367         bv->processUpdateFlags(Update::Force | Update::FitCursor);
3368 }
3369
3370
3371 void GuiDocument::setLanguage() const
3372 {
3373         Language const * const newL = bp_.language;
3374         if (buffer().params().language == newL)
3375                 return;
3376
3377         string const & lang_name = newL->lang();
3378         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
3379 }
3380
3381
3382 void GuiDocument::saveAsDefault() const
3383 {
3384         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
3385 }
3386
3387
3388 bool GuiDocument::isFontAvailable(string const & font) const
3389 {
3390         if (font == "default" || font == "cmr"
3391             || font == "cmss" || font == "cmtt")
3392                 // these are standard
3393                 return true;
3394         if (font == "lmodern" || font == "lmss" || font == "lmtt")
3395                 return LaTeXFeatures::isAvailable("lmodern");
3396         if (font == "times" || font == "palatino"
3397                  || font == "helvet" || font == "courier")
3398                 return LaTeXFeatures::isAvailable("psnfss");
3399         if (font == "cmbr" || font == "cmtl")
3400                 return LaTeXFeatures::isAvailable("cmbright");
3401         if (font == "utopia")
3402                 return LaTeXFeatures::isAvailable("utopia")
3403                         || LaTeXFeatures::isAvailable("fourier");
3404         if (font == "beraserif" || font == "berasans"
3405                 || font == "beramono")
3406                 return LaTeXFeatures::isAvailable("bera");
3407         return LaTeXFeatures::isAvailable(font);
3408 }
3409
3410
3411 bool GuiDocument::providesOSF(string const & font) const
3412 {
3413         if (fontModule->osFontsCB->isChecked())
3414                 // FIXME: we should check if the fonts really
3415                 // have OSF support. But how?
3416                 return true;
3417         if (font == "cmr")
3418                 return isFontAvailable("eco");
3419         if (font == "palatino")
3420                 return isFontAvailable("mathpazo");
3421         return false;
3422 }
3423
3424
3425 bool GuiDocument::providesSC(string const & font) const
3426 {
3427         if (fontModule->osFontsCB->isChecked())
3428                 return false;
3429         if (font == "palatino")
3430                 return isFontAvailable("mathpazo");
3431         if (font == "utopia")
3432                 return isFontAvailable("fourier");
3433         return false;
3434 }
3435
3436
3437 bool GuiDocument::providesScale(string const & font) const
3438 {
3439         if (fontModule->osFontsCB->isChecked())
3440                 return true;
3441         return font == "helvet" || font == "luximono"
3442                 || font == "berasans"  || font == "beramono";
3443 }
3444
3445
3446 void GuiDocument::loadModuleInfo()
3447 {
3448         moduleNames_.clear();
3449         LyXModuleList::const_iterator it  = theModuleList.begin();
3450         LyXModuleList::const_iterator end = theModuleList.end();
3451         for (; it != end; ++it) {
3452                 modInfoStruct m;
3453                 m.id = it->getID();
3454                 // FIXME Unicode
3455                 m.name = toqstr(translateIfPossible(from_utf8(it->getName())));
3456                 // this is supposed to give us the first sentence of the description
3457                 // FIXME Unicode
3458                 QString desc =
3459                         toqstr(translateIfPossible(from_utf8(it->getDescription())));
3460                 int const pos = desc.indexOf(".");
3461                 if (pos > 0)
3462                         desc.truncate(pos + 1);
3463                 m.description = desc;
3464                 moduleNames_.push_back(m);
3465         }
3466 }
3467
3468
3469 void GuiDocument::updateUnknownBranches()
3470 {
3471         if (!bufferview())
3472                 return;
3473         list<docstring> used_branches;
3474         buffer().getUsedBranches(used_branches);
3475         list<docstring>::const_iterator it = used_branches.begin();
3476         QStringList unknown_branches;
3477         for (; it != used_branches.end() ; ++it) {
3478                 if (!buffer().params().branchlist().find(*it))
3479                         unknown_branches.append(toqstr(*it));
3480         }
3481         branchesModule->setUnknownBranches(unknown_branches);
3482 }
3483
3484
3485 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
3486 {
3487         map<docstring, docstring>::iterator it = changedBranches_.begin();
3488         for (; it != changedBranches_.end() ; ++it) {
3489                 if (it->second == oldname) {
3490                         // branch has already been renamed
3491                         it->second = newname;
3492                         return;
3493                 }
3494         }
3495         // store new name
3496         changedBranches_[oldname] = newname;
3497 }
3498
3499
3500 void GuiDocument::executeBranchRenaming() const
3501 {
3502         map<docstring, docstring>::const_iterator it = changedBranches_.begin();
3503         for (; it != changedBranches_.end() ; ++it) {
3504                 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
3505                 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
3506         }
3507 }
3508
3509
3510 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
3511
3512
3513 } // namespace frontend
3514 } // namespace lyx
3515
3516 #include "moc_GuiDocument.cpp"