]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiDocument.cpp
Substack support for XHTML.
[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         if (!LaTeXFeatures::isAvailable("fontspec"))
802                 fontModule->osFontsCB->setToolTip(
803                         qt_("Use OpenType and TrueType fonts directly (requires XeTeX or LuaTeX)\n"
804                             "You need to install the package \"fontspec\" to use this feature"));
805
806
807         // page layout
808         pageLayoutModule = new UiWidget<Ui::PageLayoutUi>;
809         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
810                 this, SLOT(papersizeChanged(int)));
811         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
812                 this, SLOT(papersizeChanged(int)));
813         connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
814                 this, SLOT(change_adaptor()));
815         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
816                 this, SLOT(change_adaptor()));
817         connect(pageLayoutModule->paperheightLE, SIGNAL(textChanged(const QString &)),
818                 this, SLOT(change_adaptor()));
819         connect(pageLayoutModule->paperwidthLE, SIGNAL(textChanged(const QString &)),
820                 this, SLOT(change_adaptor()));
821         connect(pageLayoutModule->paperwidthUnitCO, SIGNAL(activated(int)),
822                 this, SLOT(change_adaptor()));
823         connect(pageLayoutModule->paperheightUnitCO, SIGNAL(activated(int)),
824                 this, SLOT(change_adaptor()));
825         connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
826                 this, SLOT(change_adaptor()));
827         connect(pageLayoutModule->landscapeRB, SIGNAL(clicked()),
828                 this, SLOT(change_adaptor()));
829         connect(pageLayoutModule->facingPagesCB, SIGNAL(clicked()),
830                 this, SLOT(change_adaptor()));
831         connect(pageLayoutModule->pagestyleCO, SIGNAL(activated(int)),
832                 this, SLOT(change_adaptor()));
833         
834         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
835         pageLayoutModule->pagestyleCO->addItem(qt_("empty"));
836         pageLayoutModule->pagestyleCO->addItem(qt_("plain"));
837         pageLayoutModule->pagestyleCO->addItem(qt_("headings"));
838         pageLayoutModule->pagestyleCO->addItem(qt_("fancy"));
839         bc().addCheckedLineEdit(pageLayoutModule->paperheightLE,
840                 pageLayoutModule->paperheightL);
841         bc().addCheckedLineEdit(pageLayoutModule->paperwidthLE,
842                 pageLayoutModule->paperwidthL);
843
844         QComboBox * cb = pageLayoutModule->papersizeCO;
845         cb->addItem(qt_("Default"));
846         cb->addItem(qt_("Custom"));
847         cb->addItem(qt_("US letter"));
848         cb->addItem(qt_("US legal"));
849         cb->addItem(qt_("US executive"));
850         cb->addItem(qt_("A0"));
851         cb->addItem(qt_("A1"));
852         cb->addItem(qt_("A2"));
853         cb->addItem(qt_("A3"));
854         cb->addItem(qt_("A4"));
855         cb->addItem(qt_("A5"));
856         cb->addItem(qt_("A6"));
857         cb->addItem(qt_("B0"));
858         cb->addItem(qt_("B1"));
859         cb->addItem(qt_("B2"));
860         cb->addItem(qt_("B3"));
861         cb->addItem(qt_("B4"));
862         cb->addItem(qt_("B5"));
863         cb->addItem(qt_("B6"));
864         cb->addItem(qt_("C0"));
865         cb->addItem(qt_("C1"));
866         cb->addItem(qt_("C2"));
867         cb->addItem(qt_("C3"));
868         cb->addItem(qt_("C4"));
869         cb->addItem(qt_("C5"));
870         cb->addItem(qt_("C6"));
871         cb->addItem(qt_("JIS B0"));
872         cb->addItem(qt_("JIS B1"));
873         cb->addItem(qt_("JIS B2"));
874         cb->addItem(qt_("JIS B3"));
875         cb->addItem(qt_("JIS B4"));
876         cb->addItem(qt_("JIS B5"));
877         cb->addItem(qt_("JIS B6"));
878         // remove the %-items from the unit choice
879         pageLayoutModule->paperwidthUnitCO->noPercents();
880         pageLayoutModule->paperheightUnitCO->noPercents();
881         pageLayoutModule->paperheightLE->setValidator(unsignedLengthValidator(
882                 pageLayoutModule->paperheightLE));
883         pageLayoutModule->paperwidthLE->setValidator(unsignedLengthValidator(
884                 pageLayoutModule->paperwidthLE));
885
886
887         // margins
888         marginsModule = new UiWidget<Ui::MarginsUi>;
889         connect(marginsModule->marginCB, SIGNAL(toggled(bool)),
890                 this, SLOT(setCustomMargins(bool)));
891         connect(marginsModule->marginCB, SIGNAL(clicked()),
892                 this, SLOT(change_adaptor()));
893         connect(marginsModule->topLE, SIGNAL(textChanged(QString)),
894                 this, SLOT(change_adaptor()));
895         connect(marginsModule->topUnit, SIGNAL(activated(int)),
896                 this, SLOT(change_adaptor()));
897         connect(marginsModule->bottomLE, SIGNAL(textChanged(QString)),
898                 this, SLOT(change_adaptor()));
899         connect(marginsModule->bottomUnit, SIGNAL(activated(int)),
900                 this, SLOT(change_adaptor()));
901         connect(marginsModule->innerLE, SIGNAL(textChanged(QString)),
902                 this, SLOT(change_adaptor()));
903         connect(marginsModule->innerUnit, SIGNAL(activated(int)),
904                 this, SLOT(change_adaptor()));
905         connect(marginsModule->outerLE, SIGNAL(textChanged(QString)),
906                 this, SLOT(change_adaptor()));
907         connect(marginsModule->outerUnit, SIGNAL(activated(int)),
908                 this, SLOT(change_adaptor()));
909         connect(marginsModule->headheightLE, SIGNAL(textChanged(QString)),
910                 this, SLOT(change_adaptor()));
911         connect(marginsModule->headheightUnit, SIGNAL(activated(int)),
912                 this, SLOT(change_adaptor()));
913         connect(marginsModule->headsepLE, SIGNAL(textChanged(QString)),
914                 this, SLOT(change_adaptor()));
915         connect(marginsModule->headsepUnit, SIGNAL(activated(int)),
916                 this, SLOT(change_adaptor()));
917         connect(marginsModule->footskipLE, SIGNAL(textChanged(QString)),
918                 this, SLOT(change_adaptor()));
919         connect(marginsModule->footskipUnit, SIGNAL(activated(int)),
920                 this, SLOT(change_adaptor()));
921         connect(marginsModule->columnsepLE, SIGNAL(textChanged(QString)),
922                 this, SLOT(change_adaptor()));
923         connect(marginsModule->columnsepUnit, SIGNAL(activated(int)),
924                 this, SLOT(change_adaptor()));
925         marginsModule->topLE->setValidator(unsignedLengthValidator(
926                 marginsModule->topLE));
927         marginsModule->bottomLE->setValidator(unsignedLengthValidator(
928                 marginsModule->bottomLE));
929         marginsModule->innerLE->setValidator(unsignedLengthValidator(
930                 marginsModule->innerLE));
931         marginsModule->outerLE->setValidator(unsignedLengthValidator(
932                 marginsModule->outerLE));
933         marginsModule->headsepLE->setValidator(unsignedLengthValidator(
934                 marginsModule->headsepLE));
935         marginsModule->headheightLE->setValidator(unsignedLengthValidator(
936                 marginsModule->headheightLE));
937         marginsModule->footskipLE->setValidator(unsignedLengthValidator(
938                 marginsModule->footskipLE));
939         marginsModule->columnsepLE->setValidator(unsignedLengthValidator(
940                 marginsModule->columnsepLE));
941
942         bc().addCheckedLineEdit(marginsModule->topLE,
943                 marginsModule->topL);
944         bc().addCheckedLineEdit(marginsModule->bottomLE,
945                 marginsModule->bottomL);
946         bc().addCheckedLineEdit(marginsModule->innerLE,
947                 marginsModule->innerL);
948         bc().addCheckedLineEdit(marginsModule->outerLE,
949                 marginsModule->outerL);
950         bc().addCheckedLineEdit(marginsModule->headsepLE,
951                 marginsModule->headsepL);
952         bc().addCheckedLineEdit(marginsModule->headheightLE,
953                 marginsModule->headheightL);
954         bc().addCheckedLineEdit(marginsModule->footskipLE,
955                 marginsModule->footskipL);
956         bc().addCheckedLineEdit(marginsModule->columnsepLE,
957                 marginsModule->columnsepL);
958
959
960         // language & quote
961         langModule = new UiWidget<Ui::LanguageUi>;
962         connect(langModule->languageCO, SIGNAL(activated(int)),
963                 this, SLOT(change_adaptor()));
964         connect(langModule->defaultencodingRB, SIGNAL(clicked()),
965                 this, SLOT(change_adaptor()));
966         connect(langModule->otherencodingRB, SIGNAL(clicked()),
967                 this, SLOT(change_adaptor()));
968         connect(langModule->encodingCO, SIGNAL(activated(int)),
969                 this, SLOT(change_adaptor()));
970         connect(langModule->quoteStyleCO, SIGNAL(activated(int)),
971                 this, SLOT(change_adaptor()));
972         connect(langModule->languagePackageCO, SIGNAL(activated(int)),
973                 this, SLOT(change_adaptor()));
974         connect(langModule->languagePackageED, SIGNAL(textChanged(QString)),
975                 this, SLOT(change_adaptor()));
976         connect(langModule->languagePackageCO, SIGNAL(currentIndexChanged(int)),
977                 this, SLOT(languagePackageChanged(int)));
978
979         QAbstractItemModel * language_model = guiApp->languageModel();
980         // FIXME: it would be nice if sorting was enabled/disabled via a checkbox.
981         language_model->sort(0);
982         langModule->languageCO->setModel(language_model);
983         langModule->languageCO->setModelColumn(0);
984
985         // Always put the default encoding in the first position.
986         langModule->encodingCO->addItem(qt_("Language Default (no inputenc)"));
987         QStringList encodinglist;
988         Encodings::const_iterator it = encodings.begin();
989         Encodings::const_iterator const end = encodings.end();
990         for (; it != end; ++it)
991                 encodinglist.append(qt_(it->guiName()));
992         encodinglist.sort();
993         langModule->encodingCO->addItems(encodinglist);
994
995         langModule->quoteStyleCO->addItem(qt_("``text''"));
996         langModule->quoteStyleCO->addItem(qt_("''text''"));
997         langModule->quoteStyleCO->addItem(qt_(",,text``"));
998         langModule->quoteStyleCO->addItem(qt_(",,text''"));
999         langModule->quoteStyleCO->addItem(qt_("<<text>>"));
1000         langModule->quoteStyleCO->addItem(qt_(">>text<<"));
1001
1002         langModule->languagePackageCO->addItem(
1003                 qt_("Default"), toqstr("default"));
1004         langModule->languagePackageCO->addItem(
1005                 qt_("Automatic"), toqstr("auto"));
1006         langModule->languagePackageCO->addItem(
1007                 qt_("Always Babel"), toqstr("babel"));
1008         langModule->languagePackageCO->addItem(
1009                 qt_("Custom"), toqstr("custom"));
1010         langModule->languagePackageCO->addItem(
1011                 qt_("None[[language package]]"), toqstr("none"));
1012
1013
1014         // color
1015         colorModule = new UiWidget<Ui::ColorUi>;
1016         connect(colorModule->fontColorPB, SIGNAL(clicked()),
1017                 this, SLOT(changeFontColor()));
1018         connect(colorModule->delFontColorTB, SIGNAL(clicked()),
1019                 this, SLOT(deleteFontColor()));
1020         connect(colorModule->noteFontColorPB, SIGNAL(clicked()),
1021                 this, SLOT(changeNoteFontColor()));
1022         connect(colorModule->delNoteFontColorTB, SIGNAL(clicked()),
1023                 this, SLOT(deleteNoteFontColor()));
1024         connect(colorModule->backgroundPB, SIGNAL(clicked()),
1025                 this, SLOT(changeBackgroundColor()));
1026         connect(colorModule->delBackgroundTB, SIGNAL(clicked()),
1027                 this, SLOT(deleteBackgroundColor()));
1028         connect(colorModule->boxBackgroundPB, SIGNAL(clicked()),
1029                 this, SLOT(changeBoxBackgroundColor()));
1030         connect(colorModule->delBoxBackgroundTB, SIGNAL(clicked()),
1031                 this, SLOT(deleteBoxBackgroundColor()));
1032
1033
1034         // numbering
1035         numberingModule = new UiWidget<Ui::NumberingUi>;
1036         connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
1037                 this, SLOT(change_adaptor()));
1038         connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
1039                 this, SLOT(change_adaptor()));
1040         connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
1041                 this, SLOT(updateNumbering()));
1042         connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
1043                 this, SLOT(updateNumbering()));
1044         numberingModule->tocTW->setColumnCount(3);
1045         numberingModule->tocTW->headerItem()->setText(0, qt_("Example"));
1046         numberingModule->tocTW->headerItem()->setText(1, qt_("Numbered"));
1047         numberingModule->tocTW->headerItem()->setText(2, qt_("Appears in TOC"));
1048         numberingModule->tocTW->header()->setResizeMode(QHeaderView::ResizeToContents);
1049
1050
1051         // biblio
1052         biblioModule = new UiWidget<Ui::BiblioUi>;
1053         connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
1054                 biblioModule->citationStyleL, SLOT(setEnabled(bool)));
1055         connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
1056                 biblioModule->citeStyleCO, SLOT(setEnabled(bool)));
1057         connect(biblioModule->citeDefaultRB, SIGNAL(clicked()),
1058                 this, SLOT(change_adaptor()));
1059         connect(biblioModule->citeNatbibRB, SIGNAL(clicked()),
1060                 this, SLOT(change_adaptor()));
1061         connect(biblioModule->citeStyleCO, SIGNAL(activated(int)),
1062                 this, SLOT(change_adaptor()));
1063         connect(biblioModule->citeJurabibRB, SIGNAL(clicked()),
1064                 this, SLOT(change_adaptor()));
1065         connect(biblioModule->bibtopicCB, SIGNAL(clicked()),
1066                 this, SLOT(change_adaptor()));
1067         connect(biblioModule->bibtexCO, SIGNAL(activated(int)),
1068                 this, SLOT(bibtexChanged(int)));
1069         connect(biblioModule->bibtexOptionsED, SIGNAL(textChanged(QString)),
1070                 this, SLOT(change_adaptor()));
1071
1072         biblioModule->citeStyleCO->addItem(qt_("Author-year"));
1073         biblioModule->citeStyleCO->addItem(qt_("Numerical"));
1074         biblioModule->citeStyleCO->setCurrentIndex(0);
1075
1076         // NOTE: we do not provide "custom" here for security reasons!
1077         biblioModule->bibtexCO->clear();
1078         biblioModule->bibtexCO->addItem(qt_("Default"), QString("default"));
1079         for (set<string>::const_iterator it = lyxrc.bibtex_alternatives.begin();
1080                              it != lyxrc.bibtex_alternatives.end(); ++it) {
1081                 QString const command = toqstr(*it).left(toqstr(*it).indexOf(" "));
1082                 biblioModule->bibtexCO->addItem(command, command);
1083         }
1084
1085
1086         // indices
1087         indicesModule = new GuiIndices;
1088         connect(indicesModule, SIGNAL(changed()),
1089                 this, SLOT(change_adaptor()));
1090
1091
1092         // maths
1093         mathsModule = new UiWidget<Ui::MathsUi>;
1094         connect(mathsModule->amsautoCB, SIGNAL(toggled(bool)),
1095                 mathsModule->amsCB, SLOT(setDisabled(bool)));
1096         connect(mathsModule->esintautoCB, SIGNAL(toggled(bool)),
1097                 mathsModule->esintCB, SLOT(setDisabled(bool)));
1098         connect(mathsModule->mhchemautoCB, SIGNAL(toggled(bool)),
1099                 mathsModule->mhchemCB, SLOT(setDisabled(bool)));
1100         connect(mathsModule->mathdotsautoCB, SIGNAL(toggled(bool)),
1101                 mathsModule->mathdotsCB, SLOT(setDisabled(bool)));
1102         
1103         connect(mathsModule->amsCB, SIGNAL(clicked()),
1104                 this, SLOT(change_adaptor()));
1105         connect(mathsModule->amsautoCB, SIGNAL(clicked()),
1106                 this, SLOT(change_adaptor()));
1107         connect(mathsModule->esintCB, SIGNAL(clicked()),
1108                 this, SLOT(change_adaptor()));
1109         connect(mathsModule->esintautoCB, SIGNAL(clicked()),
1110                 this, SLOT(change_adaptor()));
1111         connect(mathsModule->mhchemCB, SIGNAL(clicked()),
1112                 this, SLOT(change_adaptor()));
1113         connect(mathsModule->mhchemautoCB, SIGNAL(clicked()),
1114                 this, SLOT(change_adaptor()));
1115         connect(mathsModule->mathdotsCB, SIGNAL(clicked()),
1116                 this, SLOT(change_adaptor()));
1117         connect(mathsModule->mathdotsautoCB, SIGNAL(clicked()),
1118                 this, SLOT(change_adaptor()));
1119         
1120
1121         // latex class
1122         latexModule = new UiWidget<Ui::LaTeXUi>;
1123         connect(latexModule->optionsLE, SIGNAL(textChanged(QString)),
1124                 this, SLOT(change_adaptor()));
1125         connect(latexModule->defaultOptionsCB, SIGNAL(clicked()),
1126                 this, SLOT(change_adaptor()));
1127         connect(latexModule->psdriverCO, SIGNAL(activated(int)),
1128                 this, SLOT(change_adaptor()));
1129         connect(latexModule->classCO, SIGNAL(activated(int)),
1130                 this, SLOT(classChanged()));
1131         connect(latexModule->classCO, SIGNAL(activated(int)),
1132                 this, SLOT(change_adaptor()));
1133         connect(latexModule->layoutPB, SIGNAL(clicked()),
1134                 this, SLOT(browseLayout()));
1135         connect(latexModule->layoutPB, SIGNAL(clicked()),
1136                 this, SLOT(change_adaptor()));
1137         connect(latexModule->childDocGB, SIGNAL(clicked()),
1138                 this, SLOT(change_adaptor()));
1139         connect(latexModule->childDocLE, SIGNAL(textChanged(QString)),
1140                 this, SLOT(change_adaptor()));
1141         connect(latexModule->childDocPB, SIGNAL(clicked()),
1142                 this, SLOT(browseMaster()));
1143         connect(latexModule->suppressDateCB, SIGNAL(clicked()),
1144                 this, SLOT(change_adaptor()));
1145         connect(latexModule->refstyleCB, SIGNAL(clicked()),
1146                 this, SLOT(change_adaptor()));
1147
1148         // postscript drivers
1149         for (int n = 0; tex_graphics[n][0]; ++n) {
1150                 QString enc = qt_(tex_graphics_gui[n]);
1151                 latexModule->psdriverCO->addItem(enc);
1152         }
1153         // latex classes
1154         latexModule->classCO->setModel(&classes_model_);
1155         LayoutFileList const & bcl = LayoutFileList::get();
1156         vector<LayoutFileIndex> classList = bcl.classList();
1157         sort(classList.begin(), classList.end(), less_textclass_avail_desc());
1158
1159         vector<LayoutFileIndex>::const_iterator cit  = classList.begin();
1160         vector<LayoutFileIndex>::const_iterator cen = classList.end();
1161         for (int i = 0; cit != cen; ++cit, ++i) {
1162                 LayoutFile const & tc = bcl[*cit];
1163                 docstring item = (tc.isTeXClassAvailable()) ?
1164                         from_utf8(tc.description()) :
1165                         bformat(_("Unavailable: %1$s"), from_utf8(tc.description()));
1166                 classes_model_.insertRow(i, toqstr(item), *cit);
1167         }
1168
1169
1170         // branches
1171         branchesModule = new GuiBranches;
1172         connect(branchesModule, SIGNAL(changed()),
1173                 this, SLOT(change_adaptor()));
1174         connect(branchesModule, SIGNAL(renameBranches(docstring const &, docstring const &)),
1175                 this, SLOT(branchesRename(docstring const &, docstring const &)));
1176         updateUnknownBranches();
1177
1178
1179         // preamble
1180         preambleModule = new PreambleModule;
1181         connect(preambleModule, SIGNAL(changed()),
1182                 this, SLOT(change_adaptor()));
1183         
1184         localLayout = new LocalLayout;
1185         connect(localLayout, SIGNAL(changed()),
1186                 this, SLOT(change_adaptor()));
1187
1188
1189         // bullets
1190         bulletsModule = new BulletsModule;
1191         connect(bulletsModule, SIGNAL(changed()),
1192                 this, SLOT(change_adaptor()));
1193
1194
1195         // Modules
1196         modulesModule = new UiWidget<Ui::ModulesUi>;
1197         modulesModule->availableLV->header()->setVisible(false);
1198         modulesModule->availableLV->header()->setResizeMode(QHeaderView::ResizeToContents);
1199         modulesModule->availableLV->header()->setStretchLastSection(false);
1200         selectionManager =
1201                 new ModuleSelectionManager(modulesModule->availableLV,
1202                         modulesModule->selectedLV,
1203                         modulesModule->addPB, modulesModule->deletePB,
1204                         modulesModule->upPB, modulesModule->downPB,
1205                         availableModel(), selectedModel(), this);
1206         connect(selectionManager, SIGNAL(updateHook()),
1207                 this, SLOT(updateModuleInfo()));
1208         connect(selectionManager, SIGNAL(updateHook()),
1209                 this, SLOT(change_adaptor()));
1210         connect(selectionManager, SIGNAL(selectionChanged()),
1211                 this, SLOT(modulesChanged()));
1212
1213
1214         // PDF support
1215         pdfSupportModule = new UiWidget<Ui::PDFSupportUi>;
1216         connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
1217                 this, SLOT(change_adaptor()));
1218         connect(pdfSupportModule->titleLE, SIGNAL(textChanged(QString)),
1219                 this, SLOT(change_adaptor()));
1220         connect(pdfSupportModule->authorLE, SIGNAL(textChanged(QString)),
1221                 this, SLOT(change_adaptor()));
1222         connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(QString)),
1223                 this, SLOT(change_adaptor()));
1224         connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(QString)),
1225                 this, SLOT(change_adaptor()));
1226         connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
1227                 this, SLOT(change_adaptor()));
1228         connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
1229                 this, SLOT(change_adaptor()));
1230         connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
1231                 this, SLOT(change_adaptor()));
1232         connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
1233                 this, SLOT(change_adaptor()));
1234         connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
1235                 this, SLOT(change_adaptor()));
1236         connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
1237                 this, SLOT(change_adaptor()));
1238         connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
1239                 this, SLOT(change_adaptor()));
1240         connect(pdfSupportModule->backrefCO, SIGNAL(activated(int)),
1241                 this, SLOT(change_adaptor()));
1242         connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
1243                 this, SLOT(change_adaptor()));
1244         connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
1245                 this, SLOT(change_adaptor()));
1246         connect(pdfSupportModule->optionsLE, SIGNAL(textChanged(QString)),
1247                 this, SLOT(change_adaptor()));
1248
1249         for (int i = 0; backref_opts[i][0]; ++i)
1250                 pdfSupportModule->backrefCO->addItem(qt_(backref_opts_gui[i]));
1251
1252
1253         // float
1254         floatModule = new FloatPlacement;
1255         connect(floatModule, SIGNAL(changed()),
1256                 this, SLOT(change_adaptor()));
1257
1258
1259         // listings
1260         listingsModule = new UiWidget<Ui::ListingsSettingsUi>;
1261         connect(listingsModule->listingsED, SIGNAL(textChanged()),
1262                 this, SLOT(change_adaptor()));
1263         connect(listingsModule->bypassCB, SIGNAL(clicked()), 
1264                 this, SLOT(change_adaptor()));
1265         connect(listingsModule->bypassCB, SIGNAL(clicked()), 
1266                 this, SLOT(setListingsMessage()));
1267         connect(listingsModule->listingsED, SIGNAL(textChanged()),
1268                 this, SLOT(setListingsMessage()));
1269         listingsModule->listingsTB->setPlainText(
1270                 qt_("Input listings parameters below. Enter ? for a list of parameters."));
1271
1272
1273         // add the panels
1274         docPS->addPanel(latexModule, qt_("Document Class"));
1275         docPS->addPanel(masterChildModule, qt_("Child Documents"));
1276         docPS->addPanel(modulesModule, qt_("Modules"));
1277         docPS->addPanel(localLayout, qt_("Local Layout"));
1278         docPS->addPanel(fontModule, qt_("Fonts"));
1279         docPS->addPanel(textLayoutModule, qt_("Text Layout"));
1280         docPS->addPanel(pageLayoutModule, qt_("Page Layout"));
1281         docPS->addPanel(marginsModule, qt_("Page Margins"));
1282         docPS->addPanel(langModule, qt_("Language"));
1283         docPS->addPanel(colorModule, qt_("Colors"));
1284         docPS->addPanel(numberingModule, qt_("Numbering & TOC"));
1285         docPS->addPanel(biblioModule, qt_("Bibliography"));
1286         docPS->addPanel(indicesModule, qt_("Indexes"));
1287         docPS->addPanel(pdfSupportModule, qt_("PDF Properties"));
1288         docPS->addPanel(mathsModule, qt_("Math Options"));
1289         docPS->addPanel(floatModule, qt_("Float Placement"));
1290         docPS->addPanel(listingsModule, qt_("Listings"));
1291         docPS->addPanel(bulletsModule, qt_("Bullets"));
1292         docPS->addPanel(branchesModule, qt_("Branches"));
1293         docPS->addPanel(outputModule, qt_("Output"));
1294         docPS->addPanel(preambleModule, qt_("LaTeX Preamble"));
1295         docPS->setCurrentPanel(qt_("Document Class"));
1296 // FIXME: hack to work around resizing bug in Qt >= 4.2
1297 // bug verified with Qt 4.2.{0-3} (JSpitzm)
1298 #if QT_VERSION >= 0x040200
1299         docPS->updateGeometry();
1300 #endif
1301 }
1302
1303
1304 void GuiDocument::saveDefaultClicked()
1305 {
1306         saveDocDefault();
1307 }
1308
1309
1310 void GuiDocument::useDefaultsClicked()
1311 {
1312         useClassDefaults();
1313 }
1314
1315
1316 void GuiDocument::change_adaptor()
1317 {
1318         changed();
1319 }
1320
1321
1322 void GuiDocument::includeonlyClicked(QTreeWidgetItem * item, int)
1323 {
1324         if (item == 0)
1325                 return;
1326
1327         string child = fromqstr(item->text(0));
1328         if (child.empty())
1329                 return;
1330
1331         if (std::find(includeonlys_.begin(),
1332                       includeonlys_.end(), child) != includeonlys_.end())
1333                 includeonlys_.remove(child);
1334         else
1335                 includeonlys_.push_back(child);
1336         
1337         updateIncludeonlys();
1338         changed();
1339 }
1340
1341
1342 QString GuiDocument::validateListingsParameters()
1343 {
1344         // use a cache here to avoid repeated validation
1345         // of the same parameters
1346         static string param_cache;
1347         static QString msg_cache;
1348         
1349         if (listingsModule->bypassCB->isChecked())
1350                 return QString();
1351
1352         string params = fromqstr(listingsModule->listingsED->toPlainText());
1353         if (params != param_cache) {
1354                 param_cache = params;
1355                 msg_cache = toqstr(InsetListingsParams(params).validate());
1356         }
1357         return msg_cache;
1358 }
1359
1360
1361 void GuiDocument::setListingsMessage()
1362 {
1363         static bool isOK = true;
1364         QString msg = validateListingsParameters();
1365         if (msg.isEmpty()) {
1366                 if (isOK)
1367                         return;
1368                 isOK = true;
1369                 // listingsTB->setTextColor("black");
1370                 listingsModule->listingsTB->setPlainText(
1371                         qt_("Input listings parameters below. "
1372                 "Enter ? for a list of parameters."));
1373         } else {
1374                 isOK = false;
1375                 // listingsTB->setTextColor("red");
1376                 listingsModule->listingsTB->setPlainText(msg);
1377         }
1378 }
1379
1380
1381 void GuiDocument::setLSpacing(int item)
1382 {
1383         textLayoutModule->lspacingLE->setEnabled(item == 3);
1384 }
1385
1386
1387 void GuiDocument::setIndent(int item)
1388 {
1389         bool const enable = (item == 1);
1390         textLayoutModule->indentLE->setEnabled(enable);
1391         textLayoutModule->indentLengthCO->setEnabled(enable);
1392         textLayoutModule->skipLE->setEnabled(false);
1393         textLayoutModule->skipLengthCO->setEnabled(false);
1394         isValid();
1395 }
1396
1397
1398 void GuiDocument::enableIndent(bool indent)
1399 {
1400         textLayoutModule->skipLE->setEnabled(!indent);
1401         textLayoutModule->skipLengthCO->setEnabled(!indent);
1402         if (indent)
1403                 setIndent(textLayoutModule->indentCO->currentIndex());
1404 }
1405
1406
1407 void GuiDocument::setSkip(int item)
1408 {
1409         bool const enable = (item == 3);
1410         textLayoutModule->skipLE->setEnabled(enable);
1411         textLayoutModule->skipLengthCO->setEnabled(enable);
1412         isValid();
1413 }
1414
1415
1416 void GuiDocument::enableSkip(bool skip)
1417 {
1418         textLayoutModule->indentLE->setEnabled(!skip);
1419         textLayoutModule->indentLengthCO->setEnabled(!skip);
1420         if (skip)
1421                 setSkip(textLayoutModule->skipCO->currentIndex());
1422 }
1423
1424
1425 void GuiDocument::setMargins()
1426 {
1427         bool const extern_geometry =
1428                 documentClass().provides("geometry");
1429         marginsModule->marginCB->setEnabled(!extern_geometry);
1430         if (extern_geometry) {
1431                 marginsModule->marginCB->setChecked(false);
1432                 setCustomMargins(true);
1433         } else {
1434                 marginsModule->marginCB->setChecked(!bp_.use_geometry);
1435                 setCustomMargins(!bp_.use_geometry);
1436         }
1437 }
1438
1439
1440 void GuiDocument::papersizeChanged(int paper_size)
1441 {
1442         setCustomPapersize(paper_size == 1);
1443 }
1444
1445
1446 void GuiDocument::setCustomPapersize(bool custom)
1447 {
1448         pageLayoutModule->paperwidthL->setEnabled(custom);
1449         pageLayoutModule->paperwidthLE->setEnabled(custom);
1450         pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
1451         pageLayoutModule->paperheightL->setEnabled(custom);
1452         pageLayoutModule->paperheightLE->setEnabled(custom);
1453         pageLayoutModule->paperheightLE->setFocus();
1454         pageLayoutModule->paperheightUnitCO->setEnabled(custom);
1455 }
1456
1457
1458 void GuiDocument::setColSep()
1459 {
1460         setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
1461 }
1462
1463
1464 void GuiDocument::setCustomMargins(bool custom)
1465 {
1466         marginsModule->topL->setEnabled(!custom);
1467         marginsModule->topLE->setEnabled(!custom);
1468         marginsModule->topUnit->setEnabled(!custom);
1469
1470         marginsModule->bottomL->setEnabled(!custom);
1471         marginsModule->bottomLE->setEnabled(!custom);
1472         marginsModule->bottomUnit->setEnabled(!custom);
1473
1474         marginsModule->innerL->setEnabled(!custom);
1475         marginsModule->innerLE->setEnabled(!custom);
1476         marginsModule->innerUnit->setEnabled(!custom);
1477
1478         marginsModule->outerL->setEnabled(!custom);
1479         marginsModule->outerLE->setEnabled(!custom);
1480         marginsModule->outerUnit->setEnabled(!custom);
1481
1482         marginsModule->headheightL->setEnabled(!custom);
1483         marginsModule->headheightLE->setEnabled(!custom);
1484         marginsModule->headheightUnit->setEnabled(!custom);
1485
1486         marginsModule->headsepL->setEnabled(!custom);
1487         marginsModule->headsepLE->setEnabled(!custom);
1488         marginsModule->headsepUnit->setEnabled(!custom);
1489
1490         marginsModule->footskipL->setEnabled(!custom);
1491         marginsModule->footskipLE->setEnabled(!custom);
1492         marginsModule->footskipUnit->setEnabled(!custom);
1493
1494         bool const enableColSep = !custom && 
1495                         textLayoutModule->twoColumnCB->checkState() == Qt::Checked;
1496         marginsModule->columnsepL->setEnabled(enableColSep);
1497         marginsModule->columnsepLE->setEnabled(enableColSep);
1498         marginsModule->columnsepUnit->setEnabled(enableColSep);
1499 }
1500
1501
1502 void GuiDocument::changeBackgroundColor()
1503 {
1504         QColor const & newColor = QColorDialog::getColor(
1505                 rgb2qcolor(set_backgroundcolor), asQWidget());
1506         if (!newColor.isValid())
1507                 return;
1508         // set the button color and text
1509         colorModule->backgroundPB->setStyleSheet(
1510                 colorButtonStyleSheet(newColor));
1511         colorModule->backgroundPB->setText(qt_("&Change..."));
1512         // save color
1513         set_backgroundcolor = rgbFromHexName(fromqstr(newColor.name()));
1514         is_backgroundcolor = true;
1515         changed();
1516 }
1517
1518
1519 void GuiDocument::deleteBackgroundColor()
1520 {
1521         // set the button color back to default by setting an empty StyleSheet
1522         colorModule->backgroundPB->setStyleSheet(QLatin1String(""));
1523         // change button text
1524         colorModule->backgroundPB->setText(qt_("&Default..."));
1525         // save default color (white)
1526         set_backgroundcolor = rgbFromHexName("#ffffff");
1527         is_backgroundcolor = false;
1528         changed();
1529 }
1530
1531
1532 void GuiDocument::changeFontColor()
1533 {
1534         QColor const & newColor = QColorDialog::getColor(
1535                 rgb2qcolor(set_fontcolor), asQWidget());
1536         if (!newColor.isValid())
1537                 return;
1538         // set the button color and text
1539         colorModule->fontColorPB->setStyleSheet(
1540                 colorButtonStyleSheet(newColor));
1541         colorModule->fontColorPB->setText(qt_("&Change..."));
1542         // save color
1543         set_fontcolor = rgbFromHexName(fromqstr(newColor.name()));
1544         is_fontcolor = true;
1545         changed();
1546 }
1547
1548
1549 void GuiDocument::deleteFontColor()
1550 {
1551         // set the button color back to default by setting an empty StyleSheet
1552         colorModule->fontColorPB->setStyleSheet(QLatin1String(""));
1553         // change button text
1554         colorModule->fontColorPB->setText(qt_("&Default..."));
1555         // save default color (black)
1556         set_fontcolor = rgbFromHexName("#000000");
1557         is_fontcolor = false;
1558         changed();
1559 }
1560
1561
1562 void GuiDocument::changeNoteFontColor()
1563 {
1564         QColor const & newColor = QColorDialog::getColor(
1565                 rgb2qcolor(set_notefontcolor), asQWidget());
1566         if (!newColor.isValid())
1567                 return;
1568         // set the button color
1569         colorModule->noteFontColorPB->setStyleSheet(
1570                 colorButtonStyleSheet(newColor));
1571         // save color
1572         set_notefontcolor = rgbFromHexName(fromqstr(newColor.name()));
1573         changed();
1574 }
1575
1576
1577 void GuiDocument::deleteNoteFontColor()
1578 {
1579         // set the button color back to pref
1580         theApp()->getRgbColor(Color_greyedouttext, set_notefontcolor);
1581         colorModule->noteFontColorPB->setStyleSheet(
1582                 colorButtonStyleSheet(rgb2qcolor(set_notefontcolor)));
1583         changed();
1584 }
1585
1586
1587 void GuiDocument::changeBoxBackgroundColor()
1588 {
1589         QColor const & newColor = QColorDialog::getColor(
1590                 rgb2qcolor(set_boxbgcolor), asQWidget());
1591         if (!newColor.isValid())
1592                 return;
1593         // set the button color
1594         colorModule->boxBackgroundPB->setStyleSheet(
1595                 colorButtonStyleSheet(newColor));
1596         // save color
1597         set_boxbgcolor = rgbFromHexName(fromqstr(newColor.name()));
1598         changed();
1599 }
1600
1601
1602 void GuiDocument::deleteBoxBackgroundColor()
1603 {
1604         // set the button color back to pref
1605         theApp()->getRgbColor(Color_shadedbg, set_boxbgcolor);
1606         colorModule->boxBackgroundPB->setStyleSheet(
1607                 colorButtonStyleSheet(rgb2qcolor(set_boxbgcolor)));
1608         changed();
1609 }
1610
1611
1612 void GuiDocument::osFontsChanged(bool nontexfonts)
1613 {
1614         bool const tex_fonts = !nontexfonts;
1615         updateFontlist();
1616         updateDefaultFormat();
1617         langModule->encodingCO->setEnabled(tex_fonts &&
1618                 !langModule->defaultencodingRB->isChecked());
1619         langModule->defaultencodingRB->setEnabled(tex_fonts);
1620         langModule->otherencodingRB->setEnabled(tex_fonts);
1621
1622         fontModule->fontsDefaultCO->setEnabled(tex_fonts);
1623         fontModule->fontsDefaultLA->setEnabled(tex_fonts);
1624         fontModule->cjkFontLE->setEnabled(tex_fonts);
1625         fontModule->cjkFontLA->setEnabled(tex_fonts);
1626         string font;
1627         if (tex_fonts)
1628                 font = tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1629         bool scaleable = providesScale(font);
1630         fontModule->scaleSansSB->setEnabled(scaleable);
1631         fontModule->scaleSansLA->setEnabled(scaleable);
1632         if (tex_fonts)
1633                 font = tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1634         scaleable = providesScale(font);
1635         fontModule->scaleTypewriterSB->setEnabled(scaleable);
1636         fontModule->scaleTypewriterLA->setEnabled(scaleable);
1637         if (tex_fonts)
1638                 font = tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1639         fontModule->fontScCB->setEnabled(providesSC(font));
1640         fontModule->fontOsfCB->setEnabled(providesOSF(font));
1641         
1642         fontModule->fontencLA->setEnabled(tex_fonts);
1643         fontModule->fontencCO->setEnabled(tex_fonts);
1644         if (!tex_fonts)
1645                 fontModule->fontencLE->setEnabled(false);
1646         else
1647                 fontencChanged(fontModule->fontencCO->currentIndex());
1648 }
1649
1650
1651 void GuiDocument::updateFontsize(string const & items, string const & sel)
1652 {
1653         fontModule->fontsizeCO->clear();
1654         fontModule->fontsizeCO->addItem(qt_("Default"));
1655
1656         for (int n = 0; !token(items,'|',n).empty(); ++n)
1657                 fontModule->fontsizeCO->
1658                         addItem(toqstr(token(items,'|',n)));
1659
1660         for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
1661                 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
1662                         fontModule->fontsizeCO->setCurrentIndex(n);
1663                         break;
1664                 }
1665         }
1666 }
1667
1668
1669 void GuiDocument::updateFontlist()
1670 {
1671         fontModule->fontsRomanCO->clear();
1672         fontModule->fontsSansCO->clear();
1673         fontModule->fontsTypewriterCO->clear();
1674
1675         // With XeTeX, we have access to all system fonts, but not the LaTeX fonts
1676         if (fontModule->osFontsCB->isChecked()) {
1677                 fontModule->fontsRomanCO->addItem(qt_("Default"));
1678                 fontModule->fontsSansCO->addItem(qt_("Default"));
1679                 fontModule->fontsTypewriterCO->addItem(qt_("Default"));
1680         
1681                 QFontDatabase fontdb;
1682                 QStringList families(fontdb.families());
1683                 for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
1684                         fontModule->fontsRomanCO->addItem(*it);
1685                         fontModule->fontsSansCO->addItem(*it);
1686                         fontModule->fontsTypewriterCO->addItem(*it);
1687                 }
1688                 return;
1689         }
1690
1691         for (int n = 0; tex_fonts_roman[n][0]; ++n) {
1692                 QString font = qt_(tex_fonts_roman_gui[n]);
1693                 if (!isFontAvailable(tex_fonts_roman[n]))
1694                         font += qt_(" (not installed)");
1695                 fontModule->fontsRomanCO->addItem(font);
1696         }
1697         for (int n = 0; tex_fonts_sans[n][0]; ++n) {
1698                 QString font = qt_(tex_fonts_sans_gui[n]);
1699                 if (!isFontAvailable(tex_fonts_sans[n]))
1700                         font += qt_(" (not installed)");
1701                 fontModule->fontsSansCO->addItem(font);
1702         }
1703         for (int n = 0; tex_fonts_monospaced[n][0]; ++n) {
1704                 QString font = qt_(tex_fonts_monospaced_gui[n]);
1705                 if (!isFontAvailable(tex_fonts_monospaced[n]))
1706                         font += qt_(" (not installed)");
1707                 fontModule->fontsTypewriterCO->addItem(font);
1708         }
1709 }
1710
1711
1712 void GuiDocument::fontencChanged(int item)
1713 {
1714         fontModule->fontencLE->setEnabled(item == 1);
1715 }
1716
1717
1718 void GuiDocument::romanChanged(int item)
1719 {
1720         if (fontModule->osFontsCB->isChecked())
1721                 return;
1722         string const font = tex_fonts_roman[item];
1723         fontModule->fontScCB->setEnabled(providesSC(font));
1724         fontModule->fontOsfCB->setEnabled(providesOSF(font));
1725 }
1726
1727
1728 void GuiDocument::sansChanged(int item)
1729 {
1730         if (fontModule->osFontsCB->isChecked())
1731                 return;
1732         string const font = tex_fonts_sans[item];
1733         bool scaleable = providesScale(font);
1734         fontModule->scaleSansSB->setEnabled(scaleable);
1735         fontModule->scaleSansLA->setEnabled(scaleable);
1736 }
1737
1738
1739 void GuiDocument::ttChanged(int item)
1740 {
1741         if (fontModule->osFontsCB->isChecked())
1742                 return;
1743         string const font = tex_fonts_monospaced[item];
1744         bool scaleable = providesScale(font);
1745         fontModule->scaleTypewriterSB->setEnabled(scaleable);
1746         fontModule->scaleTypewriterLA->setEnabled(scaleable);
1747 }
1748
1749
1750 void GuiDocument::updatePagestyle(string const & items, string const & sel)
1751 {
1752         pagestyles.clear();
1753         pageLayoutModule->pagestyleCO->clear();
1754         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1755
1756         for (int n = 0; !token(items, '|', n).empty(); ++n) {
1757                 string style = token(items, '|', n);
1758                 QString style_gui = qt_(style);
1759                 pagestyles.push_back(pair<string, QString>(style, style_gui));
1760                 pageLayoutModule->pagestyleCO->addItem(style_gui);
1761         }
1762
1763         if (sel == "default") {
1764                 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
1765                 return;
1766         }
1767
1768         int nn = 0;
1769
1770         for (size_t i = 0; i < pagestyles.size(); ++i)
1771                 if (pagestyles[i].first == sel)
1772                         nn = pageLayoutModule->pagestyleCO->findText(pagestyles[i].second);
1773
1774         if (nn > 0)
1775                 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
1776 }
1777
1778
1779 void GuiDocument::browseLayout()
1780 {
1781         QString const label1 = qt_("Layouts|#o#O");
1782         QString const dir1 = toqstr(lyxrc.document_path);
1783         QStringList const filter(qt_("LyX Layout (*.layout)"));
1784         QString file = browseRelFile(QString(), bufferFilePath(),
1785                 qt_("Local layout file"), filter, false,
1786                 label1, dir1);
1787
1788         if (!file.endsWith(".layout"))
1789                 return;
1790
1791         FileName layoutFile = support::makeAbsPath(fromqstr(file),
1792                 fromqstr(bufferFilePath()));
1793         
1794         int const ret = Alert::prompt(_("Local layout file"),
1795                 _("The layout file you have selected is a local layout\n"
1796                   "file, not one in the system or user directory. Your\n"
1797                   "document may not work with this layout if you do not\n"
1798                   "keep the layout file in the document directory."),
1799                   1, 1, _("&Set Layout"), _("&Cancel"));
1800         if (ret == 1)
1801                 return;
1802
1803         // load the layout file
1804         LayoutFileList & bcl = LayoutFileList::get();
1805         string classname = layoutFile.onlyFileName();
1806         // this will update an existing layout if that layout has been loaded before.
1807         LayoutFileIndex name = bcl.addLocalLayout(
1808                 classname.substr(0, classname.size() - 7),
1809                 layoutFile.onlyPath().absFileName());
1810
1811         if (name.empty()) {
1812                 Alert::error(_("Error"),
1813                         _("Unable to read local layout file."));                
1814                 return;
1815         }
1816
1817         // do not trigger classChanged if there is no change.
1818         if (latexModule->classCO->currentText() == toqstr(name))
1819                 return;
1820                 
1821         // add to combo box
1822         int idx = latexModule->classCO->findText(toqstr(name));
1823         if (idx == -1) {
1824                 classes_model_.insertRow(0, toqstr(name), name);
1825                 latexModule->classCO->setCurrentIndex(0);
1826         } else
1827                 latexModule->classCO->setCurrentIndex(idx);
1828         
1829         classChanged();
1830 }
1831
1832
1833 void GuiDocument::browseMaster()
1834 {
1835         QString const title = qt_("Select master document");
1836         QString const dir1 = toqstr(lyxrc.document_path);
1837         QString const old = latexModule->childDocLE->text();
1838         QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
1839         QStringList const filter(qt_("LyX Files (*.lyx)"));
1840         QString file = browseRelFile(old, docpath, title, filter, false,
1841                 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
1842
1843         if (!file.isEmpty())
1844                 latexModule->childDocLE->setText(file);
1845 }
1846
1847
1848 void GuiDocument::classChanged()
1849 {
1850         int idx = latexModule->classCO->currentIndex();
1851         if (idx < 0) 
1852                 return;
1853         string const classname = classes_model_.getIDString(idx);
1854
1855         // check whether the selected modules have changed.
1856         bool modules_changed = false;
1857         unsigned int const srows = selectedModel()->rowCount();
1858         if (srows != bp_.getModules().size())
1859                 modules_changed = true;
1860         else {
1861                 list<string>::const_iterator mit = bp_.getModules().begin();
1862                 list<string>::const_iterator men = bp_.getModules().end();
1863                 for (unsigned int i = 0; i < srows && mit != men; ++i, ++mit)
1864                         if (selectedModel()->getIDString(i) != *mit) {
1865                                 modules_changed = true;
1866                                 break;
1867                         }
1868         }
1869
1870         if (modules_changed || lyxrc.auto_reset_options) {
1871                 if (applyPB->isEnabled()) {
1872                         int const ret = Alert::prompt(_("Unapplied changes"),
1873                                         _("Some changes in the dialog were not yet applied.\n"
1874                                         "If you do not apply now, they will be lost after this action."),
1875                                         1, 1, _("&Apply"), _("&Dismiss"));
1876                         if (ret == 0)
1877                                 applyView();
1878                 }
1879         }
1880
1881         // We load the TextClass as soon as it is selected. This is
1882         // necessary so that other options in the dialog can be updated
1883         // according to the new class. Note, however, that, if you use 
1884         // the scroll wheel when sitting on the combo box, we'll load a 
1885         // lot of TextClass objects very quickly....
1886         if (!bp_.setBaseClass(classname)) {
1887                 Alert::error(_("Error"), _("Unable to set document class."));
1888                 return;
1889         }
1890         if (lyxrc.auto_reset_options)
1891                 bp_.useClassDefaults();
1892
1893         // With the introduction of modules came a distinction between the base 
1894         // class and the document class. The former corresponds to the main layout 
1895         // file; the latter is that plus the modules (or the document-specific layout,
1896         // or  whatever else there could be). Our parameters come from the document 
1897         // class. So when we set the base class, we also need to recreate the document 
1898         // class. Otherwise, we still have the old one.
1899         bp_.makeDocumentClass();
1900         paramsToDialog();
1901 }
1902
1903
1904 void GuiDocument::languagePackageChanged(int i)
1905 {
1906          langModule->languagePackageED->setEnabled(
1907                 langModule->languagePackageCO->itemData(i).toString() == "custom");
1908 }
1909
1910
1911 void GuiDocument::bibtexChanged(int n)
1912 {
1913         biblioModule->bibtexOptionsED->setEnabled(
1914                 biblioModule->bibtexCO->itemData(n).toString() != "default");
1915         changed();
1916 }
1917
1918
1919 namespace {
1920         // FIXME unicode 
1921         // both of these should take a vector<docstring>
1922         
1923         // This is an insanely complicated attempt to make this sort of thing
1924         // work with RTL languages.
1925         docstring formatStrVec(vector<string> const & v, docstring const & s) 
1926         {
1927                 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
1928                 if (v.size() == 0)
1929                         return docstring();
1930                 if (v.size() == 1) 
1931                         return translateIfPossible(from_utf8(v[0]));
1932                 if (v.size() == 2) {
1933                         docstring retval = _("%1$s and %2$s");
1934                         retval = subst(retval, _("and"), s);
1935                         return bformat(retval, translateIfPossible(from_utf8(v[0])),
1936                                        translateIfPossible(from_utf8(v[1])));
1937                 }
1938                 // The idea here is to format all but the last two items...
1939                 int const vSize = v.size();
1940                 docstring t2 = _("%1$s, %2$s");
1941                 docstring retval = translateIfPossible(from_utf8(v[0]));
1942                 for (int i = 1; i < vSize - 2; ++i)
1943                         retval = bformat(t2, retval, translateIfPossible(from_utf8(v[i]))); 
1944                 //...and then to  plug them, and the last two, into this schema
1945                 docstring t = _("%1$s, %2$s, and %3$s");
1946                 t = subst(t, _("and"), s);
1947                 return bformat(t, retval, translateIfPossible(from_utf8(v[vSize - 2])),
1948                                translateIfPossible(from_utf8(v[vSize - 1])));
1949         }
1950         
1951         vector<string> idsToNames(vector<string> const & idList)
1952         {
1953                 vector<string> retval;
1954                 vector<string>::const_iterator it  = idList.begin();
1955                 vector<string>::const_iterator end = idList.end();
1956                 for (; it != end; ++it) {
1957                         LyXModule const * const mod = theModuleList[*it];
1958                         if (!mod)
1959                                 retval.push_back(to_utf8(bformat(_("%1$s (unavailable)"), 
1960                                                 translateIfPossible(from_utf8(*it)))));
1961                         else
1962                                 retval.push_back(mod->getName());
1963                 }
1964                 return retval;
1965         }
1966 } // end anonymous namespace
1967
1968
1969 void GuiDocument::modulesToParams(BufferParams & bp)
1970 {
1971         // update list of loaded modules
1972         bp.clearLayoutModules();
1973         int const srows = modules_sel_model_.rowCount();
1974         for (int i = 0; i < srows; ++i)
1975                 bp.addLayoutModule(modules_sel_model_.getIDString(i));
1976
1977         // update the list of removed modules
1978         bp.clearRemovedModules();
1979         LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
1980         list<string>::const_iterator rit = reqmods.begin();
1981         list<string>::const_iterator ren = reqmods.end();
1982
1983         // check each of the default modules
1984         for (; rit != ren; rit++) {
1985                 list<string>::const_iterator mit = bp.getModules().begin();
1986                 list<string>::const_iterator men = bp.getModules().end();
1987                 bool found = false;
1988                 for (; mit != men; mit++) {
1989                         if (*rit == *mit) {
1990                                 found = true;
1991                                 break;
1992                         }
1993                 }
1994                 if (!found) {
1995                         // the module isn't present so must have been removed by the user
1996                         bp.addRemovedModule(*rit);
1997                 }
1998         }
1999 }
2000
2001 void GuiDocument::modulesChanged()
2002 {
2003         modulesToParams(bp_);
2004         bp_.makeDocumentClass();
2005         paramsToDialog();
2006 }
2007
2008
2009 void GuiDocument::updateModuleInfo()
2010 {
2011         selectionManager->update();
2012         
2013         //Module description
2014         bool const focus_on_selected = selectionManager->selectedFocused();
2015         QAbstractItemView * lv;
2016         if (focus_on_selected)
2017                 lv = modulesModule->selectedLV;
2018         else
2019                 lv= modulesModule->availableLV;
2020         if (lv->selectionModel()->selectedIndexes().isEmpty()) {
2021                 modulesModule->infoML->document()->clear();
2022                 return;
2023         }
2024         QModelIndex const & idx = lv->selectionModel()->currentIndex();
2025         GuiIdListModel const & id_model = 
2026                         focus_on_selected  ? modules_sel_model_ : modules_av_model_;
2027         string const modName = id_model.getIDString(idx.row());
2028         docstring desc = getModuleDescription(modName);
2029
2030         LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
2031         if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
2032                 if (!desc.empty())
2033                         desc += "\n";
2034                 desc += _("Module provided by document class.");
2035         }
2036
2037         vector<string> pkglist = getPackageList(modName);
2038         docstring pkgdesc = formatStrVec(pkglist, _("and"));
2039         if (!pkgdesc.empty()) {
2040                 if (!desc.empty())
2041                         desc += "\n";
2042                 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
2043         }
2044
2045         pkglist = getRequiredList(modName);
2046         if (!pkglist.empty()) {
2047                 vector<string> const reqdescs = idsToNames(pkglist);
2048                 pkgdesc = formatStrVec(reqdescs, _("or"));
2049                 if (!desc.empty())
2050                         desc += "\n";
2051                 desc += bformat(_("Modules required: %1$s."), pkgdesc);
2052         }
2053
2054         pkglist = getExcludedList(modName);
2055         if (!pkglist.empty()) {
2056                 vector<string> const reqdescs = idsToNames(pkglist);
2057                 pkgdesc = formatStrVec(reqdescs, _( "and"));
2058                 if (!desc.empty())
2059                         desc += "\n";
2060                 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
2061         }
2062
2063         if (!isModuleAvailable(modName)) {
2064                 if (!desc.empty())
2065                         desc += "\n";
2066                 desc += _("WARNING: Some required packages are unavailable!");
2067         }
2068
2069         modulesModule->infoML->document()->setPlainText(toqstr(desc));
2070 }
2071
2072
2073 void GuiDocument::updateNumbering()
2074 {
2075         DocumentClass const & tclass = documentClass();
2076
2077         numberingModule->tocTW->setUpdatesEnabled(false);
2078         numberingModule->tocTW->clear();
2079
2080         int const depth = numberingModule->depthSL->value();
2081         int const toc = numberingModule->tocSL->value();
2082         QString const no = qt_("No");
2083         QString const yes = qt_("Yes");
2084         QTreeWidgetItem * item = 0;
2085
2086         DocumentClass::const_iterator lit = tclass.begin();
2087         DocumentClass::const_iterator len = tclass.end();
2088         for (; lit != len; ++lit) {
2089                 int const toclevel = lit->toclevel;
2090                 if (toclevel != Layout::NOT_IN_TOC && lit->labeltype == LABEL_COUNTER) {
2091                         item = new QTreeWidgetItem(numberingModule->tocTW);
2092                         item->setText(0, toqstr(translateIfPossible(lit->name())));
2093                         item->setText(1, (toclevel <= depth) ? yes : no);
2094                         item->setText(2, (toclevel <= toc) ? yes : no);
2095                 }
2096         }
2097
2098         numberingModule->tocTW->setUpdatesEnabled(true);
2099         numberingModule->tocTW->update();
2100 }
2101
2102
2103 void GuiDocument::updateDefaultFormat()
2104 {
2105         if (!bufferview())
2106                 return;
2107         // make a copy in order to consider unapplied changes
2108         Buffer * tmpbuf = buffer().clone();
2109         tmpbuf->params().useNonTeXFonts =
2110                 fontModule->osFontsCB->isChecked();
2111         int idx = latexModule->classCO->currentIndex();
2112         if (idx >= 0) {
2113                 string const classname = classes_model_.getIDString(idx);
2114                 tmpbuf->params().setBaseClass(classname);
2115                 tmpbuf->params().makeDocumentClass();
2116         }
2117         outputModule->defaultFormatCO->blockSignals(true);
2118         outputModule->defaultFormatCO->clear();
2119         outputModule->defaultFormatCO->addItem(qt_("Default"),
2120                                 QVariant(QString("default")));
2121         typedef vector<Format const *> Formats;
2122         Formats formats = tmpbuf->exportableFormats(true);
2123         Formats::const_iterator cit = formats.begin();
2124         Formats::const_iterator end = formats.end();
2125         for (; cit != end; ++cit)
2126                 outputModule->defaultFormatCO->addItem(qt_((*cit)->prettyname()),
2127                                 QVariant(toqstr((*cit)->name())));
2128         outputModule->defaultFormatCO->blockSignals(false);
2129         // delete the copy
2130         delete tmpbuf;
2131 }
2132
2133
2134 bool GuiDocument::isChildIncluded(string const & child)
2135 {
2136         if (includeonlys_.empty())
2137                 return false;
2138         return (std::find(includeonlys_.begin(),
2139                           includeonlys_.end(), child) != includeonlys_.end());
2140 }
2141
2142
2143 void GuiDocument::applyView()
2144 {
2145         // preamble
2146         preambleModule->apply(bp_);
2147         localLayout->apply(bp_);
2148
2149         // date
2150         bp_.suppress_date = latexModule->suppressDateCB->isChecked();
2151         bp_.use_refstyle  = latexModule->refstyleCB->isChecked();
2152
2153         // biblio
2154         bp_.setCiteEngine(ENGINE_BASIC);
2155
2156         if (biblioModule->citeNatbibRB->isChecked()) {
2157                 bool const use_numerical_citations =
2158                         biblioModule->citeStyleCO->currentIndex();
2159                 if (use_numerical_citations)
2160                         bp_.setCiteEngine(ENGINE_NATBIB_NUMERICAL);
2161                 else
2162                         bp_.setCiteEngine(ENGINE_NATBIB_AUTHORYEAR);
2163
2164         } else if (biblioModule->citeJurabibRB->isChecked())
2165                 bp_.setCiteEngine(ENGINE_JURABIB);
2166
2167         bp_.use_bibtopic =
2168                 biblioModule->bibtopicCB->isChecked();
2169
2170         string const bibtex_command =
2171                 fromqstr(biblioModule->bibtexCO->itemData(
2172                         biblioModule->bibtexCO->currentIndex()).toString());
2173         string const bibtex_options =
2174                 fromqstr(biblioModule->bibtexOptionsED->text());
2175         if (bibtex_command == "default" || bibtex_options.empty())
2176                 bp_.bibtex_command = bibtex_command;
2177         else
2178                 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
2179
2180         // Indices
2181         indicesModule->apply(bp_);
2182
2183         // language & quotes
2184         if (langModule->defaultencodingRB->isChecked()) {
2185                 bp_.inputenc = "auto";
2186         } else {
2187                 int i = langModule->encodingCO->currentIndex();
2188                 if (i == 0)
2189                         bp_.inputenc = "default";
2190                 else {
2191                         QString const enc_gui =
2192                                 langModule->encodingCO->currentText();
2193                         Encodings::const_iterator it = encodings.begin();
2194                         Encodings::const_iterator const end = encodings.end();
2195                         bool found = false;
2196                         for (; it != end; ++it) {
2197                                 if (qt_(it->guiName()) == enc_gui) {
2198                                         bp_.inputenc = it->latexName();
2199                                         found = true;
2200                                         break;
2201                                 }
2202                         }
2203                         if (!found) {
2204                                 // should not happen
2205                                 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
2206                                 bp_.inputenc = "default";
2207                         }
2208                 }
2209         }
2210
2211         InsetQuotes::QuoteLanguage lga = InsetQuotes::EnglishQuotes;
2212         switch (langModule->quoteStyleCO->currentIndex()) {
2213         case 0:
2214                 lga = InsetQuotes::EnglishQuotes;
2215                 break;
2216         case 1:
2217                 lga = InsetQuotes::SwedishQuotes;
2218                 break;
2219         case 2:
2220                 lga = InsetQuotes::GermanQuotes;
2221                 break;
2222         case 3:
2223                 lga = InsetQuotes::PolishQuotes;
2224                 break;
2225         case 4:
2226                 lga = InsetQuotes::FrenchQuotes;
2227                 break;
2228         case 5:
2229                 lga = InsetQuotes::DanishQuotes;
2230                 break;
2231         }
2232         bp_.quotes_language = lga;
2233
2234         QString const lang = langModule->languageCO->itemData(
2235                 langModule->languageCO->currentIndex()).toString();
2236         bp_.language = lyx::languages.getLanguage(fromqstr(lang));
2237         
2238         QString const pack = langModule->languagePackageCO->itemData(
2239                 langModule->languagePackageCO->currentIndex()).toString();
2240         if (pack == "custom")
2241                 bp_.lang_package =
2242                         fromqstr(langModule->languagePackageED->text());
2243         else
2244                 bp_.lang_package = fromqstr(pack);
2245
2246         //color
2247         bp_.backgroundcolor = set_backgroundcolor;
2248         bp_.isbackgroundcolor = is_backgroundcolor;
2249         bp_.fontcolor = set_fontcolor;
2250         bp_.isfontcolor = is_fontcolor;
2251         bp_.notefontcolor = set_notefontcolor;
2252         bp_.boxbgcolor = set_boxbgcolor;
2253
2254         // numbering
2255         if (bp_.documentClass().hasTocLevels()) {
2256                 bp_.tocdepth = numberingModule->tocSL->value();
2257                 bp_.secnumdepth = numberingModule->depthSL->value();
2258         }
2259
2260         // bullets
2261         bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
2262         bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
2263         bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
2264         bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
2265
2266         // packages
2267         bp_.graphics_driver =
2268                 tex_graphics[latexModule->psdriverCO->currentIndex()];
2269         
2270         // text layout
2271         int idx = latexModule->classCO->currentIndex();
2272         if (idx >= 0) {
2273                 string const classname = classes_model_.getIDString(idx);
2274                 bp_.setBaseClass(classname);
2275         }
2276
2277         // Modules
2278         modulesToParams(bp_);
2279
2280         // Math
2281         if (mathsModule->amsautoCB->isChecked())
2282                 bp_.use_amsmath = BufferParams::package_auto;
2283         else {
2284                 if (mathsModule->amsCB->isChecked())
2285                         bp_.use_amsmath = BufferParams::package_on;
2286                 else
2287                         bp_.use_amsmath = BufferParams::package_off;
2288         }
2289         if (mathsModule->esintautoCB->isChecked())
2290                 bp_.use_esint = BufferParams::package_auto;
2291         else {
2292                 if (mathsModule->esintCB->isChecked())
2293                         bp_.use_esint = BufferParams::package_on;
2294                 else
2295                         bp_.use_esint = BufferParams::package_off;
2296         }
2297         if (mathsModule->mhchemautoCB->isChecked())
2298                 bp_.use_mhchem = BufferParams::package_auto;
2299         else {
2300                 if (mathsModule->mhchemCB->isChecked())
2301                         bp_.use_mhchem = BufferParams::package_on;
2302                 else
2303                         bp_.use_mhchem = BufferParams::package_off;
2304         }
2305         if (mathsModule->mathdotsautoCB->isChecked())
2306                 bp_.use_mathdots = BufferParams::package_auto;
2307         else {
2308                 if (mathsModule->mathdotsCB->isChecked())
2309                         bp_.use_mathdots = BufferParams::package_on;
2310                 else
2311                         bp_.use_mathdots = BufferParams::package_off;
2312         }
2313         
2314         // Page Layout
2315         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
2316                 bp_.pagestyle = "default";
2317         else {
2318                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
2319                 for (size_t i = 0; i != pagestyles.size(); ++i)
2320                         if (pagestyles[i].second == style_gui)
2321                                 bp_.pagestyle = pagestyles[i].first;
2322         }
2323
2324         // Text Layout
2325         switch (textLayoutModule->lspacingCO->currentIndex()) {
2326         case 0:
2327                 bp_.spacing().set(Spacing::Single);
2328                 break;
2329         case 1:
2330                 bp_.spacing().set(Spacing::Onehalf);
2331                 break;
2332         case 2:
2333                 bp_.spacing().set(Spacing::Double);
2334                 break;
2335         case 3: {
2336                 string s = widgetToDoubleStr(textLayoutModule->lspacingLE);
2337                 if (s.empty())
2338                         bp_.spacing().set(Spacing::Single);
2339                 else
2340                         bp_.spacing().set(Spacing::Other, s);
2341                 break;
2342                 }
2343         }
2344
2345         if (textLayoutModule->twoColumnCB->isChecked())
2346                 bp_.columns = 2;
2347         else
2348                 bp_.columns = 1;
2349
2350         if (textLayoutModule->indentRB->isChecked()) {
2351                 // if paragraphs are separated by an indentation
2352                 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
2353                 switch (textLayoutModule->indentCO->currentIndex()) {
2354                 case 0:
2355                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2356                         break;
2357                 case 1: {
2358                         HSpace indent = HSpace(
2359                                 widgetsToLength(textLayoutModule->indentLE,
2360                                 textLayoutModule->indentLengthCO)
2361                                 );
2362                         bp_.setIndentation(indent);
2363                         break;
2364                         }
2365                 default:
2366                         // this should never happen
2367                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2368                         break;
2369                 }
2370         } else {
2371                 // if paragraphs are separated by a skip
2372                 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
2373                 switch (textLayoutModule->skipCO->currentIndex()) {
2374                 case 0:
2375                         bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
2376                         break;
2377                 case 1:
2378                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2379                         break;
2380                 case 2:
2381                         bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
2382                         break;
2383                 case 3:
2384                         {
2385                         VSpace vs = VSpace(
2386                                 widgetsToLength(textLayoutModule->skipLE,
2387                                 textLayoutModule->skipLengthCO)
2388                                 );
2389                         bp_.setDefSkip(vs);
2390                         break;
2391                         }
2392                 default:
2393                         // this should never happen
2394                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2395                         break;
2396                 }
2397         }
2398
2399         bp_.options =
2400                 fromqstr(latexModule->optionsLE->text());
2401
2402         bp_.use_default_options =
2403                 latexModule->defaultOptionsCB->isChecked();
2404
2405         if (latexModule->childDocGB->isChecked())
2406                 bp_.master =
2407                         fromqstr(latexModule->childDocLE->text());
2408         else
2409                 bp_.master = string();
2410
2411         // Master/Child
2412         bp_.clearIncludedChildren();
2413         if (masterChildModule->includeonlyRB->isChecked()) {
2414                 list<string>::const_iterator it = includeonlys_.begin();
2415                 for (; it != includeonlys_.end() ; ++it) {
2416                         bp_.addIncludedChildren(*it);
2417                 }
2418         }
2419         bp_.maintain_unincluded_children =
2420                 masterChildModule->maintainAuxCB->isChecked();
2421
2422         // Float Placement
2423         bp_.float_placement = floatModule->get();
2424
2425         // Listings
2426         // text should have passed validation
2427         bp_.listings_params =
2428                 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
2429
2430         // output
2431         bp_.default_output_format = fromqstr(outputModule->defaultFormatCO->itemData(
2432                 outputModule->defaultFormatCO->currentIndex()).toString());
2433
2434         bool const nontexfonts = fontModule->osFontsCB->isChecked();
2435         bp_.useNonTeXFonts = nontexfonts;
2436
2437         bp_.output_sync = outputModule->outputsyncCB->isChecked();
2438         bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
2439
2440         int mathfmt = outputModule->mathoutCB->currentIndex();
2441         if (mathfmt == -1)
2442                 mathfmt = 0;
2443         BufferParams::MathOutput const mo =
2444                 static_cast<BufferParams::MathOutput>(mathfmt);
2445         bp_.html_math_output = mo;
2446         bp_.html_be_strict = outputModule->strictCB->isChecked();
2447         bp_.html_math_img_scale = outputModule->mathimgSB->value();
2448
2449         // fonts
2450         if (nontexfonts) {
2451                 if (fontModule->fontsRomanCO->currentIndex() == 0)
2452                         bp_.fonts_roman = "default";
2453                 else
2454                         bp_.fonts_roman =
2455                                 fromqstr(fontModule->fontsRomanCO->currentText());
2456         
2457                 if (fontModule->fontsSansCO->currentIndex() == 0)
2458                         bp_.fonts_sans = "default";
2459                 else
2460                         bp_.fonts_sans =
2461                                 fromqstr(fontModule->fontsSansCO->currentText());
2462         
2463                 if (fontModule->fontsTypewriterCO->currentIndex() == 0)
2464                         bp_.fonts_typewriter = "default";
2465                 else
2466                         bp_.fonts_typewriter =
2467                                 fromqstr(fontModule->fontsTypewriterCO->currentText());
2468         } else {
2469                 bp_.fonts_roman =
2470                         tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
2471         
2472                 bp_.fonts_sans =
2473                         tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
2474         
2475                 bp_.fonts_typewriter =
2476                         tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
2477         }
2478
2479         if (fontModule->fontencCO->currentIndex() == 0)
2480                 bp_.fontenc = "global";
2481         else if (fontModule->fontencCO->currentIndex() == 1)
2482                 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
2483         else if (fontModule->fontencCO->currentIndex() == 2)
2484                 bp_.fontenc = "default";
2485
2486         bp_.fonts_cjk =
2487                 fromqstr(fontModule->cjkFontLE->text());
2488
2489         bp_.fonts_sans_scale = fontModule->scaleSansSB->value();
2490
2491         bp_.fonts_typewriter_scale = fontModule->scaleTypewriterSB->value();
2492
2493         bp_.fonts_expert_sc = fontModule->fontScCB->isChecked();
2494
2495         bp_.fonts_old_figures = fontModule->fontOsfCB->isChecked();
2496
2497         if (nontexfonts)
2498                 bp_.fonts_default_family = "default";
2499         else
2500                 bp_.fonts_default_family = GuiDocument::fontfamilies[
2501                         fontModule->fontsDefaultCO->currentIndex()];
2502
2503         if (fontModule->fontsizeCO->currentIndex() == 0)
2504                 bp_.fontsize = "default";
2505         else
2506                 bp_.fontsize =
2507                         fromqstr(fontModule->fontsizeCO->currentText());
2508
2509         // paper
2510         bp_.papersize = PAPER_SIZE(
2511                 pageLayoutModule->papersizeCO->currentIndex());
2512
2513         bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
2514                 pageLayoutModule->paperwidthUnitCO);
2515
2516         bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
2517                 pageLayoutModule->paperheightUnitCO);
2518
2519         if (pageLayoutModule->facingPagesCB->isChecked())
2520                 bp_.sides = TwoSides;
2521         else
2522                 bp_.sides = OneSide;
2523
2524         if (pageLayoutModule->landscapeRB->isChecked())
2525                 bp_.orientation = ORIENTATION_LANDSCAPE;
2526         else
2527                 bp_.orientation = ORIENTATION_PORTRAIT;
2528
2529         // margins
2530         bp_.use_geometry = !marginsModule->marginCB->isChecked();
2531
2532         Ui::MarginsUi const * m = marginsModule;
2533
2534         bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
2535         bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
2536         bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
2537         bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
2538         bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
2539         bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
2540         bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
2541         bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
2542
2543         // branches
2544         branchesModule->apply(bp_);
2545
2546         // PDF support
2547         PDFOptions & pdf = bp_.pdfoptions();
2548         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
2549         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
2550         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
2551         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
2552         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
2553
2554         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
2555         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
2556         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
2557         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
2558
2559         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
2560         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
2561         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
2562         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
2563         pdf.backref =
2564                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
2565         if (pdfSupportModule->fullscreenCB->isChecked())
2566                 pdf.pagemode = pdf.pagemode_fullscreen;
2567         else
2568                 pdf.pagemode.clear();
2569         pdf.quoted_options = pdf.quoted_options_check(
2570                                 fromqstr(pdfSupportModule->optionsLE->text()));
2571 }
2572
2573
2574 void GuiDocument::paramsToDialog()
2575 {
2576         // set the default unit
2577         Length::UNIT const defaultUnit = Length::defaultUnit();
2578
2579         // preamble
2580         preambleModule->update(bp_, id());
2581         localLayout->update(bp_, id());
2582
2583         // date
2584         latexModule->suppressDateCB->setChecked(bp_.suppress_date);
2585         latexModule->refstyleCB->setChecked(bp_.use_refstyle);
2586
2587         // biblio
2588         biblioModule->citeDefaultRB->setChecked(
2589                 bp_.citeEngine() == ENGINE_BASIC);
2590
2591         biblioModule->citeNatbibRB->setChecked(
2592                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL ||
2593                 bp_.citeEngine() == ENGINE_NATBIB_AUTHORYEAR);
2594
2595         biblioModule->citeStyleCO->setCurrentIndex(
2596                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL);
2597
2598         biblioModule->citeJurabibRB->setChecked(
2599                 bp_.citeEngine() == ENGINE_JURABIB);
2600
2601         biblioModule->bibtopicCB->setChecked(
2602                 bp_.use_bibtopic);
2603
2604         string command;
2605         string options =
2606                 split(bp_.bibtex_command, command, ' ');
2607
2608         int const bpos = biblioModule->bibtexCO->findData(toqstr(command));
2609         if (bpos != -1) {
2610                 biblioModule->bibtexCO->setCurrentIndex(bpos);
2611                 biblioModule->bibtexOptionsED->setText(toqstr(options).trimmed());
2612         } else {
2613                 // We reset to default if we do not know the specified compiler
2614                 // This is for security reasons
2615                 biblioModule->bibtexCO->setCurrentIndex(
2616                         biblioModule->bibtexCO->findData(toqstr("default")));
2617                 biblioModule->bibtexOptionsED->clear();
2618         }
2619         biblioModule->bibtexOptionsED->setEnabled(
2620                 biblioModule->bibtexCO->currentIndex() != 0);
2621
2622         // indices
2623         indicesModule->update(bp_);
2624
2625         // language & quotes
2626         int const pos = langModule->languageCO->findData(toqstr(
2627                 bp_.language->lang()));
2628         langModule->languageCO->setCurrentIndex(pos);
2629
2630         langModule->quoteStyleCO->setCurrentIndex(
2631                 bp_.quotes_language);
2632
2633         bool default_enc = true;
2634         if (bp_.inputenc != "auto") {
2635                 default_enc = false;
2636                 if (bp_.inputenc == "default") {
2637                         langModule->encodingCO->setCurrentIndex(0);
2638                 } else {
2639                         string enc_gui;
2640                         Encodings::const_iterator it = encodings.begin();
2641                         Encodings::const_iterator const end = encodings.end();
2642                         for (; it != end; ++it) {
2643                                 if (it->latexName() == bp_.inputenc) {
2644                                         enc_gui = it->guiName();
2645                                         break;
2646                                 }
2647                         }
2648                         int const i = langModule->encodingCO->findText(
2649                                         qt_(enc_gui));
2650                         if (i >= 0)
2651                                 langModule->encodingCO->setCurrentIndex(i);
2652                         else
2653                                 // unknown encoding. Set to default.
2654                                 default_enc = true;
2655                 }
2656         }
2657         langModule->defaultencodingRB->setChecked(default_enc);
2658         langModule->otherencodingRB->setChecked(!default_enc);
2659
2660         int const p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
2661         if (p == -1) {
2662                 langModule->languagePackageCO->setCurrentIndex(
2663                           langModule->languagePackageCO->findData("custom"));
2664                 langModule->languagePackageED->setText(toqstr(bp_.lang_package));
2665         } else {
2666                 langModule->languagePackageCO->setCurrentIndex(p);
2667                 langModule->languagePackageED->clear();
2668         }
2669
2670         //color
2671         if (bp_.isfontcolor) {
2672                 colorModule->fontColorPB->setStyleSheet(
2673                         colorButtonStyleSheet(rgb2qcolor(bp_.fontcolor)));
2674         }
2675         set_fontcolor = bp_.fontcolor;
2676         is_fontcolor = bp_.isfontcolor;
2677
2678         colorModule->noteFontColorPB->setStyleSheet(
2679                 colorButtonStyleSheet(rgb2qcolor(bp_.notefontcolor)));
2680         set_notefontcolor = bp_.notefontcolor;
2681
2682         if (bp_.isbackgroundcolor) {
2683                 colorModule->backgroundPB->setStyleSheet(
2684                         colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
2685         }
2686         set_backgroundcolor = bp_.backgroundcolor;
2687         is_backgroundcolor = bp_.isbackgroundcolor;
2688
2689         colorModule->boxBackgroundPB->setStyleSheet(
2690                 colorButtonStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
2691         set_boxbgcolor = bp_.boxbgcolor;
2692
2693         // numbering
2694         int const min_toclevel = documentClass().min_toclevel();
2695         int const max_toclevel = documentClass().max_toclevel();
2696         if (documentClass().hasTocLevels()) {
2697                 numberingModule->setEnabled(true);
2698                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
2699                 numberingModule->depthSL->setMaximum(max_toclevel);
2700                 numberingModule->depthSL->setValue(bp_.secnumdepth);
2701                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
2702                 numberingModule->tocSL->setMaximum(max_toclevel);
2703                 numberingModule->tocSL->setValue(bp_.tocdepth);
2704                 updateNumbering();
2705         } else {
2706                 numberingModule->setEnabled(false);
2707                 numberingModule->tocTW->clear();
2708         }
2709
2710         // bullets
2711         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
2712         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
2713         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
2714         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
2715         bulletsModule->init();
2716
2717         // packages
2718         int nitem = findToken(tex_graphics, bp_.graphics_driver);
2719         if (nitem >= 0)
2720                 latexModule->psdriverCO->setCurrentIndex(nitem);
2721         updateModuleInfo();
2722         
2723         mathsModule->amsCB->setChecked(
2724                 bp_.use_amsmath == BufferParams::package_on);
2725         mathsModule->amsautoCB->setChecked(
2726                 bp_.use_amsmath == BufferParams::package_auto);
2727
2728         mathsModule->esintCB->setChecked(
2729                 bp_.use_esint == BufferParams::package_on);
2730         mathsModule->esintautoCB->setChecked(
2731                 bp_.use_esint == BufferParams::package_auto);
2732
2733         mathsModule->mhchemCB->setChecked(
2734                 bp_.use_mhchem == BufferParams::package_on);
2735         mathsModule->mhchemautoCB->setChecked(
2736                 bp_.use_mhchem == BufferParams::package_auto);
2737
2738         mathsModule->mathdotsCB->setChecked(
2739                 bp_.use_mathdots == BufferParams::package_on);
2740         mathsModule->mathdotsautoCB->setChecked(
2741                 bp_.use_mathdots == BufferParams::package_auto);
2742
2743         switch (bp_.spacing().getSpace()) {
2744                 case Spacing::Other: nitem = 3; break;
2745                 case Spacing::Double: nitem = 2; break;
2746                 case Spacing::Onehalf: nitem = 1; break;
2747                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
2748         }
2749
2750         // text layout
2751         string const & layoutID = bp_.baseClassID();
2752         setLayoutComboByIDString(layoutID);
2753
2754         updatePagestyle(documentClass().opt_pagestyle(),
2755                                  bp_.pagestyle);
2756
2757         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
2758         if (bp_.spacing().getSpace() == Spacing::Other) {
2759                 doubleToWidget(textLayoutModule->lspacingLE,
2760                         bp_.spacing().getValueAsString());
2761         }
2762         setLSpacing(nitem);
2763
2764         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
2765                 textLayoutModule->indentRB->setChecked(true);
2766                 string indentation = bp_.getIndentation().asLyXCommand();
2767                 int indent = 0;
2768                 if (indentation != "default") {
2769                         lengthToWidgets(textLayoutModule->indentLE,
2770                         textLayoutModule->indentLengthCO,
2771                         indentation, defaultUnit);
2772                         indent = 1;
2773                 }
2774                 textLayoutModule->indentCO->setCurrentIndex(indent);
2775                 setIndent(indent);
2776         } else {
2777                 textLayoutModule->skipRB->setChecked(true);
2778                 int skip = 0;
2779                 switch (bp_.getDefSkip().kind()) {
2780                 case VSpace::SMALLSKIP:
2781                         skip = 0;
2782                         break;
2783                 case VSpace::MEDSKIP:
2784                         skip = 1;
2785                         break;
2786                 case VSpace::BIGSKIP:
2787                         skip = 2;
2788                         break;
2789                 case VSpace::LENGTH:
2790                         {
2791                         skip = 3;
2792                         string const length = bp_.getDefSkip().asLyXCommand();
2793                         lengthToWidgets(textLayoutModule->skipLE,
2794                                 textLayoutModule->skipLengthCO,
2795                                 length, defaultUnit);
2796                         break;
2797                         }
2798                 default:
2799                         skip = 0;
2800                         break;
2801                 }
2802                 textLayoutModule->skipCO->setCurrentIndex(skip);
2803                 setSkip(skip);
2804         }
2805
2806         textLayoutModule->twoColumnCB->setChecked(
2807                 bp_.columns == 2);
2808
2809         if (!bp_.options.empty()) {
2810                 latexModule->optionsLE->setText(
2811                         toqstr(bp_.options));
2812         } else {
2813                 latexModule->optionsLE->setText(QString());
2814         }
2815
2816         // latex
2817         latexModule->defaultOptionsCB->setChecked(
2818                         bp_.use_default_options);
2819         updateSelectedModules();
2820         selectionManager->updateProvidedModules(
2821                         bp_.baseClass()->providedModules());
2822         selectionManager->updateExcludedModules(
2823                         bp_.baseClass()->excludedModules());
2824
2825         if (!documentClass().options().empty()) {
2826                 latexModule->defaultOptionsLE->setText(
2827                         toqstr(documentClass().options()));
2828         } else {
2829                 latexModule->defaultOptionsLE->setText(
2830                         toqstr(_("[No options predefined]")));
2831         }
2832
2833         latexModule->defaultOptionsLE->setEnabled(
2834                 bp_.use_default_options
2835                 && !documentClass().options().empty());
2836
2837         latexModule->defaultOptionsCB->setEnabled(
2838                 !documentClass().options().empty());
2839
2840         if (!bp_.master.empty()) {
2841                 latexModule->childDocGB->setChecked(true);
2842                 latexModule->childDocLE->setText(
2843                         toqstr(bp_.master));
2844         } else {
2845                 latexModule->childDocLE->setText(QString());
2846                 latexModule->childDocGB->setChecked(false);
2847         }
2848
2849         // Master/Child
2850         if (!bufferview() || !buffer().hasChildren()) {
2851                 masterChildModule->childrenTW->clear();
2852                 includeonlys_.clear();
2853                 docPS->showPanel(qt_("Child Documents"), false);
2854                 if (docPS->isCurrentPanel(qt_("Child Documents")))
2855                         docPS->setCurrentPanel(qt_("Document Class"));
2856         } else {
2857                 docPS->showPanel(qt_("Child Documents"), true);
2858                 masterChildModule->setEnabled(true);
2859                 includeonlys_ = bp_.getIncludedChildren();
2860                 updateIncludeonlys();
2861         }
2862         masterChildModule->maintainAuxCB->setChecked(
2863                 bp_.maintain_unincluded_children);
2864
2865         // Float Settings
2866         floatModule->set(bp_.float_placement);
2867
2868         // ListingsSettings
2869         // break listings_params to multiple lines
2870         string lstparams =
2871                 InsetListingsParams(bp_.listings_params).separatedParams();
2872         listingsModule->listingsED->setPlainText(toqstr(lstparams));
2873
2874         // Output
2875         // update combobox with formats
2876         updateDefaultFormat();
2877         int index = outputModule->defaultFormatCO->findData(toqstr(
2878                 bp_.default_output_format));
2879         // set to default if format is not found 
2880         if (index == -1)
2881                 index = 0;
2882         outputModule->defaultFormatCO->setCurrentIndex(index);
2883         bool const os_fonts_available =
2884                 bp_.baseClass()->outputType() == lyx::LATEX
2885                 && LaTeXFeatures::isAvailable("fontspec");
2886         fontModule->osFontsCB->setEnabled(os_fonts_available);
2887         fontModule->osFontsCB->setChecked(
2888                 os_fonts_available && bp_.useNonTeXFonts);
2889
2890         outputModule->outputsyncCB->setChecked(bp_.output_sync);
2891         outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
2892
2893         outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
2894         outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
2895         outputModule->strictCB->setChecked(bp_.html_be_strict);
2896
2897         // Fonts
2898         updateFontsize(documentClass().opt_fontsize(),
2899                         bp_.fontsize);
2900
2901         if (bp_.useNonTeXFonts && os_fonts_available) {
2902                 fontModule->fontencLA->setEnabled(false);
2903                 fontModule->fontencCO->setEnabled(false);
2904                 fontModule->fontencLE->setEnabled(false);
2905                 for (int i = 0; i < fontModule->fontsRomanCO->count(); ++i) {
2906                         if (fontModule->fontsRomanCO->itemText(i) == toqstr(bp_.fonts_roman)) {
2907                                 fontModule->fontsRomanCO->setCurrentIndex(i);
2908                                 break;
2909                         }
2910                 }
2911                 
2912                 for (int i = 0; i < fontModule->fontsSansCO->count(); ++i) {
2913                         if (fontModule->fontsSansCO->itemText(i) == toqstr(bp_.fonts_sans)) {
2914                                 fontModule->fontsSansCO->setCurrentIndex(i);
2915                                 break;
2916                         }
2917                 }
2918                 for (int i = 0; i < fontModule->fontsTypewriterCO->count(); ++i) {
2919                         if (fontModule->fontsTypewriterCO->itemText(i) == 
2920                                 toqstr(bp_.fonts_typewriter)) {
2921                                 fontModule->fontsTypewriterCO->setCurrentIndex(i);
2922                                 break;
2923                         }
2924                 }
2925         } else {
2926                 fontModule->fontencLA->setEnabled(true);
2927                 fontModule->fontencCO->setEnabled(true);
2928                 fontModule->fontencLE->setEnabled(true);
2929                 int n = findToken(tex_fonts_roman, bp_.fonts_roman);
2930                 if (n >= 0) {
2931                         fontModule->fontsRomanCO->setCurrentIndex(n);
2932                         romanChanged(n);
2933                 }
2934         
2935                 n = findToken(tex_fonts_sans, bp_.fonts_sans);
2936                 if (n >= 0) {
2937                         fontModule->fontsSansCO->setCurrentIndex(n);
2938                         sansChanged(n);
2939                 }
2940         
2941                 n = findToken(tex_fonts_monospaced, bp_.fonts_typewriter);
2942                 if (n >= 0) {
2943                         fontModule->fontsTypewriterCO->setCurrentIndex(n);
2944                         ttChanged(n);
2945                 }
2946         }
2947
2948         if (!bp_.fonts_cjk.empty())
2949                 fontModule->cjkFontLE->setText(
2950                         toqstr(bp_.fonts_cjk));
2951         else
2952                 fontModule->cjkFontLE->setText(QString());
2953
2954         fontModule->fontScCB->setChecked(bp_.fonts_expert_sc);
2955         fontModule->fontOsfCB->setChecked(bp_.fonts_old_figures);
2956         fontModule->scaleSansSB->setValue(bp_.fonts_sans_scale);
2957         fontModule->scaleTypewriterSB->setValue(bp_.fonts_typewriter_scale);
2958         
2959         int nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
2960         if (nn >= 0)
2961                 fontModule->fontsDefaultCO->setCurrentIndex(nn);
2962
2963         if (bp_.fontenc == "global") {
2964                 fontModule->fontencCO->setCurrentIndex(0);
2965                 fontModule->fontencLE->setEnabled(false);
2966         } else if (bp_.fontenc == "default") {
2967                 fontModule->fontencCO->setCurrentIndex(2);
2968                 fontModule->fontencLE->setEnabled(false);
2969         } else {
2970                 fontModule->fontencCO->setCurrentIndex(1);
2971                 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
2972         }
2973
2974         // paper
2975         bool const extern_geometry =
2976                 documentClass().provides("geometry");
2977         int const psize = bp_.papersize;
2978         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
2979         setCustomPapersize(!extern_geometry && psize == 1);
2980         pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
2981
2982         bool const landscape =
2983                 bp_.orientation == ORIENTATION_LANDSCAPE;
2984         pageLayoutModule->landscapeRB->setChecked(landscape);
2985         pageLayoutModule->portraitRB->setChecked(!landscape);
2986         pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
2987         pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
2988
2989         pageLayoutModule->facingPagesCB->setChecked(
2990                 bp_.sides == TwoSides);
2991
2992         lengthToWidgets(pageLayoutModule->paperwidthLE,
2993                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, defaultUnit);
2994         lengthToWidgets(pageLayoutModule->paperheightLE,
2995                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, defaultUnit);
2996
2997         // margins
2998         Ui::MarginsUi * m = marginsModule;
2999
3000         setMargins();
3001
3002         lengthToWidgets(m->topLE, m->topUnit,
3003                 bp_.topmargin, defaultUnit);
3004
3005         lengthToWidgets(m->bottomLE, m->bottomUnit,
3006                 bp_.bottommargin, defaultUnit);
3007
3008         lengthToWidgets(m->innerLE, m->innerUnit,
3009                 bp_.leftmargin, defaultUnit);
3010
3011         lengthToWidgets(m->outerLE, m->outerUnit,
3012                 bp_.rightmargin, defaultUnit);
3013
3014         lengthToWidgets(m->headheightLE, m->headheightUnit,
3015                 bp_.headheight, defaultUnit);
3016
3017         lengthToWidgets(m->headsepLE, m->headsepUnit,
3018                 bp_.headsep, defaultUnit);
3019
3020         lengthToWidgets(m->footskipLE, m->footskipUnit,
3021                 bp_.footskip, defaultUnit);
3022
3023         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
3024                 bp_.columnsep, defaultUnit);
3025
3026         // branches
3027         updateUnknownBranches();
3028         branchesModule->update(bp_);
3029
3030         // PDF support
3031         PDFOptions const & pdf = bp_.pdfoptions();
3032         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
3033         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
3034         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
3035         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
3036         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
3037
3038         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
3039         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
3040         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
3041
3042         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
3043
3044         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
3045         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
3046         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
3047         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
3048
3049         nn = findToken(backref_opts, pdf.backref);
3050         if (nn >= 0)
3051                 pdfSupportModule->backrefCO->setCurrentIndex(nn);
3052
3053         pdfSupportModule->fullscreenCB->setChecked
3054                 (pdf.pagemode == pdf.pagemode_fullscreen);
3055
3056         pdfSupportModule->optionsLE->setText(
3057                 toqstr(pdf.quoted_options));
3058
3059         // Make sure that the bc is in the INITIAL state
3060         if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
3061                 bc().restore();
3062
3063         // clear changed branches cache
3064         changedBranches_.clear();
3065 }
3066
3067
3068 void GuiDocument::saveDocDefault()
3069 {
3070         // we have to apply the params first
3071         applyView();
3072         saveAsDefault();
3073 }
3074
3075
3076 void GuiDocument::updateAvailableModules() 
3077 {
3078         modules_av_model_.clear();
3079         list<modInfoStruct> const & modInfoList = getModuleInfo();
3080         list<modInfoStruct>::const_iterator mit = modInfoList.begin();
3081         list<modInfoStruct>::const_iterator men = modInfoList.end();
3082         for (int i = 0; mit != men; ++mit, ++i)
3083                 modules_av_model_.insertRow(i, mit->name, mit->id, 
3084                                 mit->description);
3085 }
3086
3087
3088 void GuiDocument::updateSelectedModules() 
3089 {
3090         modules_sel_model_.clear();
3091         list<modInfoStruct> const selModList = getSelectedModules();
3092         list<modInfoStruct>::const_iterator mit = selModList.begin();
3093         list<modInfoStruct>::const_iterator men = selModList.end();
3094         for (int i = 0; mit != men; ++mit, ++i)
3095                 modules_sel_model_.insertRow(i, mit->name, mit->id, 
3096                                 mit->description);
3097 }
3098
3099
3100 void GuiDocument::updateIncludeonlys()
3101 {
3102         masterChildModule->childrenTW->clear();
3103         QString const no = qt_("No");
3104         QString const yes = qt_("Yes");
3105
3106         if (includeonlys_.empty()) {
3107                 masterChildModule->includeallRB->setChecked(true);
3108                 masterChildModule->childrenTW->setEnabled(false);
3109                 masterChildModule->maintainAuxCB->setEnabled(false);
3110         } else {
3111                 masterChildModule->includeonlyRB->setChecked(true);
3112                 masterChildModule->childrenTW->setEnabled(true);
3113                 masterChildModule->maintainAuxCB->setEnabled(true);
3114         }
3115         QTreeWidgetItem * item = 0;
3116         ListOfBuffers children = buffer().getChildren();
3117         ListOfBuffers::const_iterator it  = children.begin();
3118         ListOfBuffers::const_iterator end = children.end();
3119         bool has_unincluded = false;
3120         bool all_unincluded = true;
3121         for (; it != end; ++it) {
3122                 item = new QTreeWidgetItem(masterChildModule->childrenTW);
3123                 // FIXME Unicode
3124                 string const name =
3125                         to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
3126                                                         from_utf8(buffer().filePath())));
3127                 item->setText(0, toqstr(name));
3128                 item->setText(1, isChildIncluded(name) ? yes : no);
3129                 if (!isChildIncluded(name))
3130                         has_unincluded = true;
3131                 else
3132                         all_unincluded = false;
3133         }
3134         // Both if all childs are included and if none is included
3135         // is equal to "include all" (i.e., ommit \includeonly).
3136         // Thus, reset the GUI.
3137         if (!has_unincluded || all_unincluded) {
3138                 masterChildModule->includeallRB->setChecked(true);
3139                 masterChildModule->childrenTW->setEnabled(false);
3140                 includeonlys_.clear();
3141         }
3142         // If all are included, we need to update again.
3143         if (!has_unincluded)
3144                 updateIncludeonlys();
3145 }
3146
3147
3148 void GuiDocument::updateContents()
3149 {
3150         // Nothing to do here as the document settings is not cursor dependant.
3151         return;
3152 }
3153
3154
3155 void GuiDocument::useClassDefaults()
3156 {
3157         if (applyPB->isEnabled()) {
3158                 int const ret = Alert::prompt(_("Unapplied changes"),
3159                                 _("Some changes in the dialog were not yet applied.\n"
3160                                   "If you do not apply now, they will be lost after this action."),
3161                                 1, 1, _("&Apply"), _("&Dismiss"));
3162                 if (ret == 0)
3163                         applyView();
3164         }
3165
3166         int idx = latexModule->classCO->currentIndex();
3167         string const classname = classes_model_.getIDString(idx);
3168         if (!bp_.setBaseClass(classname)) {
3169                 Alert::error(_("Error"), _("Unable to set document class."));
3170                 return;
3171         }
3172         bp_.useClassDefaults();
3173         paramsToDialog();
3174 }
3175
3176
3177 void GuiDocument::setLayoutComboByIDString(string const & idString)
3178 {
3179         int idx = classes_model_.findIDString(idString);
3180         if (idx < 0)
3181                 Alert::warning(_("Can't set layout!"), 
3182                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
3183         else 
3184                 latexModule->classCO->setCurrentIndex(idx);
3185 }
3186
3187
3188 bool GuiDocument::isValid()
3189 {
3190         return 
3191                 validateListingsParameters().isEmpty() &&
3192                 localLayout->isValid() &&
3193                 (
3194                         // if we're asking for skips between paragraphs
3195                         !textLayoutModule->skipRB->isChecked() ||
3196                         // then either we haven't chosen custom
3197                         textLayoutModule->skipCO->currentIndex() != 3 || 
3198                         // or else a length has been given
3199                         !textLayoutModule->skipLE->text().isEmpty()
3200                 ) && 
3201                 (
3202                         // if we're asking for indentation
3203                         !textLayoutModule->indentRB->isChecked() || 
3204                         // then either we haven't chosen custom
3205                         textLayoutModule->indentCO->currentIndex() != 1 || 
3206                         // or else a length has been given
3207                         !textLayoutModule->indentLE->text().isEmpty()
3208                 );
3209 }
3210
3211
3212 char const * const GuiDocument::fontfamilies[5] = {
3213         "default", "rmdefault", "sfdefault", "ttdefault", ""
3214 };
3215
3216
3217 char const * GuiDocument::fontfamilies_gui[5] = {
3218         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
3219 };
3220
3221
3222 bool GuiDocument::initialiseParams(string const &)
3223 {
3224         BufferView const * view = bufferview();
3225         if (!view) {
3226                 bp_ = BufferParams();
3227                 paramsToDialog();
3228                 return true;
3229         }
3230         bp_ = view->buffer().params();
3231         loadModuleInfo();
3232         updateAvailableModules();
3233         //FIXME It'd be nice to make sure here that the selected
3234         //modules are consistent: That required modules are actually
3235         //selected, and that we don't have conflicts. If so, we could
3236         //at least pop up a warning.
3237         paramsToDialog();
3238         return true;
3239 }
3240
3241
3242 void GuiDocument::clearParams()
3243 {
3244         bp_ = BufferParams();
3245 }
3246
3247
3248 BufferId GuiDocument::id() const
3249 {
3250         BufferView const * const view = bufferview();
3251         return view? &view->buffer() : 0;
3252 }
3253
3254
3255 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
3256 {
3257         return moduleNames_;
3258 }
3259
3260
3261 list<GuiDocument::modInfoStruct> const 
3262                 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
3263 {
3264         LayoutModuleList::const_iterator it =  mods.begin();
3265         LayoutModuleList::const_iterator end = mods.end();
3266         list<modInfoStruct> mInfo;
3267         for (; it != end; ++it) {
3268                 modInfoStruct m;
3269                 m.id = *it;
3270                 LyXModule const * const mod = theModuleList[*it];
3271                 if (mod)
3272                         // FIXME Unicode
3273                         m.name = toqstr(translateIfPossible(from_utf8(mod->getName())));
3274                 else 
3275                         m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
3276                 mInfo.push_back(m);
3277         }
3278         return mInfo;
3279 }
3280
3281
3282 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
3283 {
3284         return makeModuleInfo(params().getModules());
3285 }
3286
3287
3288 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
3289 {
3290         return makeModuleInfo(params().baseClass()->providedModules());
3291 }
3292
3293
3294 DocumentClass const & GuiDocument::documentClass() const
3295 {
3296         return bp_.documentClass();
3297 }
3298
3299
3300 static void dispatch_bufferparams(Dialog const & dialog,
3301         BufferParams const & bp, FuncCode lfun)
3302 {
3303         ostringstream ss;
3304         ss << "\\begin_header\n";
3305         bp.writeFile(ss);
3306         ss << "\\end_header\n";
3307         dialog.dispatch(FuncRequest(lfun, ss.str()));
3308 }
3309
3310
3311 void GuiDocument::dispatchParams()
3312 {
3313         // This must come first so that a language change is correctly noticed
3314         setLanguage();
3315
3316         // Apply the BufferParams. Note that this will set the base class
3317         // and then update the buffer's layout.
3318         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
3319
3320         if (!params().master.empty()) {
3321                 FileName const master_file = support::makeAbsPath(params().master,
3322                            support::onlyPath(buffer().absFileName()));
3323                 if (isLyXFileName(master_file.absFileName())) {
3324                         Buffer * master = checkAndLoadLyXFile(master_file);
3325                         if (master) {
3326                                 if (master->isChild(const_cast<Buffer *>(&buffer())))
3327                                         const_cast<Buffer &>(buffer()).setParent(master);
3328                                 else
3329                                         Alert::warning(_("Assigned master does not include this file"), 
3330                                                 bformat(_("You must include this file in the document\n"
3331                                                           "'%1$s' in order to use the master document\n"
3332                                                           "feature."), from_utf8(params().master)));
3333                         } else
3334                                 Alert::warning(_("Could not load master"), 
3335                                                 bformat(_("The master document '%1$s'\n"
3336                                                            "could not be loaded."),
3337                                                            from_utf8(params().master)));
3338                 }
3339         }
3340
3341         // Generate the colours requested by each new branch.
3342         BranchList & branchlist = params().branchlist();
3343         if (!branchlist.empty()) {
3344                 BranchList::const_iterator it = branchlist.begin();
3345                 BranchList::const_iterator const end = branchlist.end();
3346                 for (; it != end; ++it) {
3347                         docstring const & current_branch = it->branch();
3348                         Branch const * branch = branchlist.find(current_branch);
3349                         string const x11hexname = X11hexname(branch->color());
3350                         // display the new color
3351                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
3352                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
3353                 }
3354
3355                 // Open insets of selected branches, close deselected ones
3356                 dispatch(FuncRequest(LFUN_INSET_FORALL,
3357                         "Branch inset-toggle assign"));
3358         }
3359         // rename branches in the document
3360         executeBranchRenaming();
3361         // and clear changed branches cache
3362         changedBranches_.clear();
3363         
3364         // Generate the colours requested by indices.
3365         IndicesList & indiceslist = params().indiceslist();
3366         if (!indiceslist.empty()) {
3367                 IndicesList::const_iterator it = indiceslist.begin();
3368                 IndicesList::const_iterator const end = indiceslist.end();
3369                 for (; it != end; ++it) {
3370                         docstring const & current_index = it->shortcut();
3371                         Index const * index = indiceslist.findShortcut(current_index);
3372                         string const x11hexname = X11hexname(index->color());
3373                         // display the new color
3374                         docstring const str = current_index + ' ' + from_ascii(x11hexname);
3375                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
3376                 }
3377         }
3378         // FIXME LFUN
3379         // If we used an LFUN, we would not need these two lines:
3380         BufferView * bv = const_cast<BufferView *>(bufferview());
3381         bv->processUpdateFlags(Update::Force | Update::FitCursor);
3382 }
3383
3384
3385 void GuiDocument::setLanguage() const
3386 {
3387         Language const * const newL = bp_.language;
3388         if (buffer().params().language == newL)
3389                 return;
3390
3391         string const & lang_name = newL->lang();
3392         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
3393 }
3394
3395
3396 void GuiDocument::saveAsDefault() const
3397 {
3398         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
3399 }
3400
3401
3402 bool GuiDocument::isFontAvailable(string const & font) const
3403 {
3404         if (font == "default" || font == "cmr"
3405             || font == "cmss" || font == "cmtt")
3406                 // these are standard
3407                 return true;
3408         if (font == "lmodern" || font == "lmss" || font == "lmtt")
3409                 return LaTeXFeatures::isAvailable("lmodern");
3410         if (font == "times" || font == "palatino"
3411                  || font == "helvet" || font == "courier")
3412                 return LaTeXFeatures::isAvailable("psnfss");
3413         if (font == "cmbr" || font == "cmtl")
3414                 return LaTeXFeatures::isAvailable("cmbright");
3415         if (font == "utopia")
3416                 return LaTeXFeatures::isAvailable("utopia")
3417                         || LaTeXFeatures::isAvailable("fourier");
3418         if (font == "beraserif" || font == "berasans"
3419                 || font == "beramono")
3420                 return LaTeXFeatures::isAvailable("bera");
3421         return LaTeXFeatures::isAvailable(font);
3422 }
3423
3424
3425 bool GuiDocument::providesOSF(string const & font) const
3426 {
3427         if (fontModule->osFontsCB->isChecked())
3428                 // FIXME: we should check if the fonts really
3429                 // have OSF support. But how?
3430                 return true;
3431         if (font == "cmr")
3432                 return isFontAvailable("eco");
3433         if (font == "palatino")
3434                 return isFontAvailable("mathpazo");
3435         return false;
3436 }
3437
3438
3439 bool GuiDocument::providesSC(string const & font) const
3440 {
3441         if (fontModule->osFontsCB->isChecked())
3442                 return false;
3443         if (font == "palatino")
3444                 return isFontAvailable("mathpazo");
3445         if (font == "utopia")
3446                 return isFontAvailable("fourier");
3447         return false;
3448 }
3449
3450
3451 bool GuiDocument::providesScale(string const & font) const
3452 {
3453         if (fontModule->osFontsCB->isChecked())
3454                 return true;
3455         return font == "helvet" || font == "luximono"
3456                 || font == "berasans"  || font == "beramono";
3457 }
3458
3459
3460 void GuiDocument::loadModuleInfo()
3461 {
3462         moduleNames_.clear();
3463         LyXModuleList::const_iterator it  = theModuleList.begin();
3464         LyXModuleList::const_iterator end = theModuleList.end();
3465         for (; it != end; ++it) {
3466                 modInfoStruct m;
3467                 m.id = it->getID();
3468                 // FIXME Unicode
3469                 m.name = toqstr(translateIfPossible(from_utf8(it->getName())));
3470                 // this is supposed to give us the first sentence of the description
3471                 // FIXME Unicode
3472                 QString desc =
3473                         toqstr(translateIfPossible(from_utf8(it->getDescription())));
3474                 int const pos = desc.indexOf(".");
3475                 if (pos > 0)
3476                         desc.truncate(pos + 1);
3477                 m.description = desc;
3478                 moduleNames_.push_back(m);
3479         }
3480 }
3481
3482
3483 void GuiDocument::updateUnknownBranches()
3484 {
3485         if (!bufferview())
3486                 return;
3487         list<docstring> used_branches;
3488         buffer().getUsedBranches(used_branches);
3489         list<docstring>::const_iterator it = used_branches.begin();
3490         QStringList unknown_branches;
3491         for (; it != used_branches.end() ; ++it) {
3492                 if (!buffer().params().branchlist().find(*it))
3493                         unknown_branches.append(toqstr(*it));
3494         }
3495         branchesModule->setUnknownBranches(unknown_branches);
3496 }
3497
3498
3499 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
3500 {
3501         map<docstring, docstring>::iterator it = changedBranches_.begin();
3502         for (; it != changedBranches_.end() ; ++it) {
3503                 if (it->second == oldname) {
3504                         // branch has already been renamed
3505                         it->second = newname;
3506                         return;
3507                 }
3508         }
3509         // store new name
3510         changedBranches_[oldname] = newname;
3511 }
3512
3513
3514 void GuiDocument::executeBranchRenaming() const
3515 {
3516         map<docstring, docstring>::const_iterator it = changedBranches_.begin();
3517         for (; it != changedBranches_.end() ; ++it) {
3518                 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
3519                 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
3520         }
3521 }
3522
3523
3524 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
3525
3526
3527 } // namespace frontend
3528 } // namespace lyx
3529
3530 #include "moc_GuiDocument.cpp"