]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiDocument.cpp
Please Abdel
[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(toqstr("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 epmty StyleSheet
1522         colorModule->backgroundPB->setStyleSheet(QLatin1String(""));
1523         // change button text
1524         colorModule->backgroundPB->setText(toqstr("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(toqstr("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 epmty StyleSheet
1552         colorModule->fontColorPB->setStyleSheet(QLatin1String(""));
1553         // change button text
1554         colorModule->fontColorPB->setText(toqstr("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 light gray
1580         colorModule->noteFontColorPB->setStyleSheet(
1581                 colorButtonStyleSheet(QColor(204, 204, 204, 255)));
1582         // save light gray as the set color
1583         set_notefontcolor = rgbFromHexName("#cccccc");
1584         changed();
1585 }
1586
1587
1588 void GuiDocument::changeBoxBackgroundColor()
1589 {
1590         QColor const & newColor = QColorDialog::getColor(
1591                 rgb2qcolor(set_boxbgcolor), asQWidget());
1592         if (!newColor.isValid())
1593                 return;
1594         // set the button color
1595         colorModule->boxBackgroundPB->setStyleSheet(
1596                 colorButtonStyleSheet(newColor));
1597         // save color
1598         set_boxbgcolor = rgbFromHexName(fromqstr(newColor.name()));
1599         changed();
1600 }
1601
1602
1603 void GuiDocument::deleteBoxBackgroundColor()
1604 {
1605         // set the button color back to red
1606         colorModule->boxBackgroundPB->setStyleSheet(
1607                 colorButtonStyleSheet(QColor(Qt::red)));
1608         // save red as the set color
1609         set_boxbgcolor = rgbFromHexName("#ff0000");
1610         changed();
1611 }
1612
1613
1614 void GuiDocument::osFontsChanged(bool nontexfonts)
1615 {
1616         bool const tex_fonts = !nontexfonts;
1617         updateFontlist();
1618         updateDefaultFormat();
1619         langModule->encodingCO->setEnabled(tex_fonts &&
1620                 !langModule->defaultencodingRB->isChecked());
1621         langModule->defaultencodingRB->setEnabled(tex_fonts);
1622         langModule->otherencodingRB->setEnabled(tex_fonts);
1623
1624         fontModule->fontsDefaultCO->setEnabled(tex_fonts);
1625         fontModule->fontsDefaultLA->setEnabled(tex_fonts);
1626         fontModule->cjkFontLE->setEnabled(tex_fonts);
1627         fontModule->cjkFontLA->setEnabled(tex_fonts);
1628         string font;
1629         if (tex_fonts)
1630                 font = tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1631         bool scaleable = providesScale(font);
1632         fontModule->scaleSansSB->setEnabled(scaleable);
1633         fontModule->scaleSansLA->setEnabled(scaleable);
1634         if (tex_fonts)
1635                 font = tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1636         scaleable = providesScale(font);
1637         fontModule->scaleTypewriterSB->setEnabled(scaleable);
1638         fontModule->scaleTypewriterLA->setEnabled(scaleable);
1639         if (tex_fonts)
1640                 font = tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1641         fontModule->fontScCB->setEnabled(providesSC(font));
1642         fontModule->fontOsfCB->setEnabled(providesOSF(font));
1643         
1644         fontModule->fontencLA->setEnabled(tex_fonts);
1645         fontModule->fontencCO->setEnabled(tex_fonts);
1646         if (!tex_fonts)
1647                 fontModule->fontencLE->setEnabled(false);
1648         else
1649                 fontencChanged(fontModule->fontencCO->currentIndex());
1650 }
1651
1652
1653 void GuiDocument::updateFontsize(string const & items, string const & sel)
1654 {
1655         fontModule->fontsizeCO->clear();
1656         fontModule->fontsizeCO->addItem(qt_("Default"));
1657
1658         for (int n = 0; !token(items,'|',n).empty(); ++n)
1659                 fontModule->fontsizeCO->
1660                         addItem(toqstr(token(items,'|',n)));
1661
1662         for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
1663                 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
1664                         fontModule->fontsizeCO->setCurrentIndex(n);
1665                         break;
1666                 }
1667         }
1668 }
1669
1670
1671 void GuiDocument::updateFontlist()
1672 {
1673         fontModule->fontsRomanCO->clear();
1674         fontModule->fontsSansCO->clear();
1675         fontModule->fontsTypewriterCO->clear();
1676
1677         // With XeTeX, we have access to all system fonts, but not the LaTeX fonts
1678         if (fontModule->osFontsCB->isChecked()) {
1679                 fontModule->fontsRomanCO->addItem(qt_("Default"));
1680                 fontModule->fontsSansCO->addItem(qt_("Default"));
1681                 fontModule->fontsTypewriterCO->addItem(qt_("Default"));
1682         
1683                 QFontDatabase fontdb;
1684                 QStringList families(fontdb.families());
1685                 for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
1686                         fontModule->fontsRomanCO->addItem(*it);
1687                         fontModule->fontsSansCO->addItem(*it);
1688                         fontModule->fontsTypewriterCO->addItem(*it);
1689                 }
1690                 return;
1691         }
1692
1693         for (int n = 0; tex_fonts_roman[n][0]; ++n) {
1694                 QString font = qt_(tex_fonts_roman_gui[n]);
1695                 if (!isFontAvailable(tex_fonts_roman[n]))
1696                         font += qt_(" (not installed)");
1697                 fontModule->fontsRomanCO->addItem(font);
1698         }
1699         for (int n = 0; tex_fonts_sans[n][0]; ++n) {
1700                 QString font = qt_(tex_fonts_sans_gui[n]);
1701                 if (!isFontAvailable(tex_fonts_sans[n]))
1702                         font += qt_(" (not installed)");
1703                 fontModule->fontsSansCO->addItem(font);
1704         }
1705         for (int n = 0; tex_fonts_monospaced[n][0]; ++n) {
1706                 QString font = qt_(tex_fonts_monospaced_gui[n]);
1707                 if (!isFontAvailable(tex_fonts_monospaced[n]))
1708                         font += qt_(" (not installed)");
1709                 fontModule->fontsTypewriterCO->addItem(font);
1710         }
1711 }
1712
1713
1714 void GuiDocument::fontencChanged(int item)
1715 {
1716         fontModule->fontencLE->setEnabled(item == 1);
1717 }
1718
1719
1720 void GuiDocument::romanChanged(int item)
1721 {
1722         if (fontModule->osFontsCB->isChecked())
1723                 return;
1724         string const font = tex_fonts_roman[item];
1725         fontModule->fontScCB->setEnabled(providesSC(font));
1726         fontModule->fontOsfCB->setEnabled(providesOSF(font));
1727 }
1728
1729
1730 void GuiDocument::sansChanged(int item)
1731 {
1732         if (fontModule->osFontsCB->isChecked())
1733                 return;
1734         string const font = tex_fonts_sans[item];
1735         bool scaleable = providesScale(font);
1736         fontModule->scaleSansSB->setEnabled(scaleable);
1737         fontModule->scaleSansLA->setEnabled(scaleable);
1738 }
1739
1740
1741 void GuiDocument::ttChanged(int item)
1742 {
1743         if (fontModule->osFontsCB->isChecked())
1744                 return;
1745         string const font = tex_fonts_monospaced[item];
1746         bool scaleable = providesScale(font);
1747         fontModule->scaleTypewriterSB->setEnabled(scaleable);
1748         fontModule->scaleTypewriterLA->setEnabled(scaleable);
1749 }
1750
1751
1752 void GuiDocument::updatePagestyle(string const & items, string const & sel)
1753 {
1754         pagestyles.clear();
1755         pageLayoutModule->pagestyleCO->clear();
1756         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1757
1758         for (int n = 0; !token(items, '|', n).empty(); ++n) {
1759                 string style = token(items, '|', n);
1760                 QString style_gui = qt_(style);
1761                 pagestyles.push_back(pair<string, QString>(style, style_gui));
1762                 pageLayoutModule->pagestyleCO->addItem(style_gui);
1763         }
1764
1765         if (sel == "default") {
1766                 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
1767                 return;
1768         }
1769
1770         int nn = 0;
1771
1772         for (size_t i = 0; i < pagestyles.size(); ++i)
1773                 if (pagestyles[i].first == sel)
1774                         nn = pageLayoutModule->pagestyleCO->findText(pagestyles[i].second);
1775
1776         if (nn > 0)
1777                 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
1778 }
1779
1780
1781 void GuiDocument::browseLayout()
1782 {
1783         QString const label1 = qt_("Layouts|#o#O");
1784         QString const dir1 = toqstr(lyxrc.document_path);
1785         QStringList const filter(qt_("LyX Layout (*.layout)"));
1786         QString file = browseRelFile(QString(), bufferFilePath(),
1787                 qt_("Local layout file"), filter, false,
1788                 label1, dir1);
1789
1790         if (!file.endsWith(".layout"))
1791                 return;
1792
1793         FileName layoutFile = support::makeAbsPath(fromqstr(file),
1794                 fromqstr(bufferFilePath()));
1795         
1796         int const ret = Alert::prompt(_("Local layout file"),
1797                 _("The layout file you have selected is a local layout\n"
1798                   "file, not one in the system or user directory. Your\n"
1799                   "document may not work with this layout if you do not\n"
1800                   "keep the layout file in the document directory."),
1801                   1, 1, _("&Set Layout"), _("&Cancel"));
1802         if (ret == 1)
1803                 return;
1804
1805         // load the layout file
1806         LayoutFileList & bcl = LayoutFileList::get();
1807         string classname = layoutFile.onlyFileName();
1808         // this will update an existing layout if that layout has been loaded before.
1809         LayoutFileIndex name = bcl.addLocalLayout(
1810                 classname.substr(0, classname.size() - 7),
1811                 layoutFile.onlyPath().absFileName());
1812
1813         if (name.empty()) {
1814                 Alert::error(_("Error"),
1815                         _("Unable to read local layout file."));                
1816                 return;
1817         }
1818
1819         // do not trigger classChanged if there is no change.
1820         if (latexModule->classCO->currentText() == toqstr(name))
1821                 return;
1822                 
1823         // add to combo box
1824         int idx = latexModule->classCO->findText(toqstr(name));
1825         if (idx == -1) {
1826                 classes_model_.insertRow(0, toqstr(name), name);
1827                 latexModule->classCO->setCurrentIndex(0);
1828         } else
1829                 latexModule->classCO->setCurrentIndex(idx);
1830         
1831         classChanged();
1832 }
1833
1834
1835 void GuiDocument::browseMaster()
1836 {
1837         QString const title = qt_("Select master document");
1838         QString const dir1 = toqstr(lyxrc.document_path);
1839         QString const old = latexModule->childDocLE->text();
1840         QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
1841         QStringList const filter(qt_("LyX Files (*.lyx)"));
1842         QString file = browseRelFile(old, docpath, title, filter, false,
1843                 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
1844
1845         if (!file.isEmpty())
1846                 latexModule->childDocLE->setText(file);
1847 }
1848
1849
1850 void GuiDocument::classChanged()
1851 {
1852         int idx = latexModule->classCO->currentIndex();
1853         if (idx < 0) 
1854                 return;
1855         string const classname = classes_model_.getIDString(idx);
1856
1857         // check whether the selected modules have changed.
1858         bool modules_changed = false;
1859         unsigned int const srows = selectedModel()->rowCount();
1860         if (srows != bp_.getModules().size())
1861                 modules_changed = true;
1862         else {
1863                 list<string>::const_iterator mit = bp_.getModules().begin();
1864                 list<string>::const_iterator men = bp_.getModules().end();
1865                 for (unsigned int i = 0; i < srows && mit != men; ++i, ++mit)
1866                         if (selectedModel()->getIDString(i) != *mit) {
1867                                 modules_changed = true;
1868                                 break;
1869                         }
1870         }
1871
1872         if (modules_changed || lyxrc.auto_reset_options) {
1873                 if (applyPB->isEnabled()) {
1874                         int const ret = Alert::prompt(_("Unapplied changes"),
1875                                         _("Some changes in the dialog were not yet applied.\n"
1876                                         "If you do not apply now, they will be lost after this action."),
1877                                         1, 1, _("&Apply"), _("&Dismiss"));
1878                         if (ret == 0)
1879                                 applyView();
1880                 }
1881         }
1882
1883         // We load the TextClass as soon as it is selected. This is
1884         // necessary so that other options in the dialog can be updated
1885         // according to the new class. Note, however, that, if you use 
1886         // the scroll wheel when sitting on the combo box, we'll load a 
1887         // lot of TextClass objects very quickly....
1888         if (!bp_.setBaseClass(classname)) {
1889                 Alert::error(_("Error"), _("Unable to set document class."));
1890                 return;
1891         }
1892         if (lyxrc.auto_reset_options)
1893                 bp_.useClassDefaults();
1894
1895         // With the introduction of modules came a distinction between the base 
1896         // class and the document class. The former corresponds to the main layout 
1897         // file; the latter is that plus the modules (or the document-specific layout,
1898         // or  whatever else there could be). Our parameters come from the document 
1899         // class. So when we set the base class, we also need to recreate the document 
1900         // class. Otherwise, we still have the old one.
1901         bp_.makeDocumentClass();
1902         paramsToDialog();
1903 }
1904
1905
1906 void GuiDocument::languagePackageChanged(int i)
1907 {
1908          langModule->languagePackageED->setEnabled(
1909                 langModule->languagePackageCO->itemData(i).toString() == "custom");
1910 }
1911
1912
1913 void GuiDocument::bibtexChanged(int n)
1914 {
1915         biblioModule->bibtexOptionsED->setEnabled(
1916                 biblioModule->bibtexCO->itemData(n).toString() != "default");
1917         changed();
1918 }
1919
1920
1921 namespace {
1922         // FIXME unicode 
1923         // both of these should take a vector<docstring>
1924         
1925         // This is an insanely complicated attempt to make this sort of thing
1926         // work with RTL languages.
1927         docstring formatStrVec(vector<string> const & v, docstring const & s) 
1928         {
1929                 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
1930                 if (v.size() == 0)
1931                         return docstring();
1932                 if (v.size() == 1) 
1933                         return translateIfPossible(from_utf8(v[0]));
1934                 if (v.size() == 2) {
1935                         docstring retval = _("%1$s and %2$s");
1936                         retval = subst(retval, _("and"), s);
1937                         return bformat(retval, translateIfPossible(from_utf8(v[0])),
1938                                        translateIfPossible(from_utf8(v[1])));
1939                 }
1940                 // The idea here is to format all but the last two items...
1941                 int const vSize = v.size();
1942                 docstring t2 = _("%1$s, %2$s");
1943                 docstring retval = translateIfPossible(from_utf8(v[0]));
1944                 for (int i = 1; i < vSize - 2; ++i)
1945                         retval = bformat(t2, retval, translateIfPossible(from_utf8(v[i]))); 
1946                 //...and then to  plug them, and the last two, into this schema
1947                 docstring t = _("%1$s, %2$s, and %3$s");
1948                 t = subst(t, _("and"), s);
1949                 return bformat(t, retval, translateIfPossible(from_utf8(v[vSize - 2])),
1950                                translateIfPossible(from_utf8(v[vSize - 1])));
1951         }
1952         
1953         vector<string> idsToNames(vector<string> const & idList)
1954         {
1955                 vector<string> retval;
1956                 vector<string>::const_iterator it  = idList.begin();
1957                 vector<string>::const_iterator end = idList.end();
1958                 for (; it != end; ++it) {
1959                         LyXModule const * const mod = theModuleList[*it];
1960                         if (!mod)
1961                                 retval.push_back(to_utf8(bformat(_("%1$s (unavailable)"), 
1962                                                 translateIfPossible(from_utf8(*it)))));
1963                         else
1964                                 retval.push_back(mod->getName());
1965                 }
1966                 return retval;
1967         }
1968 } // end anonymous namespace
1969
1970
1971 void GuiDocument::modulesToParams(BufferParams & bp)
1972 {
1973         // update list of loaded modules
1974         bp.clearLayoutModules();
1975         int const srows = modules_sel_model_.rowCount();
1976         for (int i = 0; i < srows; ++i)
1977                 bp.addLayoutModule(modules_sel_model_.getIDString(i));
1978
1979         // update the list of removed modules
1980         bp.clearRemovedModules();
1981         LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
1982         list<string>::const_iterator rit = reqmods.begin();
1983         list<string>::const_iterator ren = reqmods.end();
1984
1985         // check each of the default modules
1986         for (; rit != ren; rit++) {
1987                 list<string>::const_iterator mit = bp.getModules().begin();
1988                 list<string>::const_iterator men = bp.getModules().end();
1989                 bool found = false;
1990                 for (; mit != men; mit++) {
1991                         if (*rit == *mit) {
1992                                 found = true;
1993                                 break;
1994                         }
1995                 }
1996                 if (!found) {
1997                         // the module isn't present so must have been removed by the user
1998                         bp.addRemovedModule(*rit);
1999                 }
2000         }
2001 }
2002
2003 void GuiDocument::modulesChanged()
2004 {
2005         modulesToParams(bp_);
2006         bp_.makeDocumentClass();
2007         paramsToDialog();
2008 }
2009
2010
2011 void GuiDocument::updateModuleInfo()
2012 {
2013         selectionManager->update();
2014         
2015         //Module description
2016         bool const focus_on_selected = selectionManager->selectedFocused();
2017         QAbstractItemView * lv;
2018         if (focus_on_selected)
2019                 lv = modulesModule->selectedLV;
2020         else
2021                 lv= modulesModule->availableLV;
2022         if (lv->selectionModel()->selectedIndexes().isEmpty()) {
2023                 modulesModule->infoML->document()->clear();
2024                 return;
2025         }
2026         QModelIndex const & idx = lv->selectionModel()->currentIndex();
2027         GuiIdListModel const & id_model = 
2028                         focus_on_selected  ? modules_sel_model_ : modules_av_model_;
2029         string const modName = id_model.getIDString(idx.row());
2030         docstring desc = getModuleDescription(modName);
2031
2032         LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
2033         if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
2034                 if (!desc.empty())
2035                         desc += "\n";
2036                 desc += _("Module provided by document class.");
2037         }
2038
2039         vector<string> pkglist = getPackageList(modName);
2040         docstring pkgdesc = formatStrVec(pkglist, _("and"));
2041         if (!pkgdesc.empty()) {
2042                 if (!desc.empty())
2043                         desc += "\n";
2044                 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
2045         }
2046
2047         pkglist = getRequiredList(modName);
2048         if (!pkglist.empty()) {
2049                 vector<string> const reqdescs = idsToNames(pkglist);
2050                 pkgdesc = formatStrVec(reqdescs, _("or"));
2051                 if (!desc.empty())
2052                         desc += "\n";
2053                 desc += bformat(_("Modules required: %1$s."), pkgdesc);
2054         }
2055
2056         pkglist = getExcludedList(modName);
2057         if (!pkglist.empty()) {
2058                 vector<string> const reqdescs = idsToNames(pkglist);
2059                 pkgdesc = formatStrVec(reqdescs, _( "and"));
2060                 if (!desc.empty())
2061                         desc += "\n";
2062                 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
2063         }
2064
2065         if (!isModuleAvailable(modName)) {
2066                 if (!desc.empty())
2067                         desc += "\n";
2068                 desc += _("WARNING: Some required packages are unavailable!");
2069         }
2070
2071         modulesModule->infoML->document()->setPlainText(toqstr(desc));
2072 }
2073
2074
2075 void GuiDocument::updateNumbering()
2076 {
2077         DocumentClass const & tclass = documentClass();
2078
2079         numberingModule->tocTW->setUpdatesEnabled(false);
2080         numberingModule->tocTW->clear();
2081
2082         int const depth = numberingModule->depthSL->value();
2083         int const toc = numberingModule->tocSL->value();
2084         QString const no = qt_("No");
2085         QString const yes = qt_("Yes");
2086         QTreeWidgetItem * item = 0;
2087
2088         DocumentClass::const_iterator lit = tclass.begin();
2089         DocumentClass::const_iterator len = tclass.end();
2090         for (; lit != len; ++lit) {
2091                 int const toclevel = lit->toclevel;
2092                 if (toclevel != Layout::NOT_IN_TOC && lit->labeltype == LABEL_COUNTER) {
2093                         item = new QTreeWidgetItem(numberingModule->tocTW);
2094                         item->setText(0, toqstr(translateIfPossible(lit->name())));
2095                         item->setText(1, (toclevel <= depth) ? yes : no);
2096                         item->setText(2, (toclevel <= toc) ? yes : no);
2097                 }
2098         }
2099
2100         numberingModule->tocTW->setUpdatesEnabled(true);
2101         numberingModule->tocTW->update();
2102 }
2103
2104
2105 void GuiDocument::updateDefaultFormat()
2106 {
2107         if (!bufferview())
2108                 return;
2109         // make a copy in order to consider unapplied changes
2110         Buffer * tmpbuf = buffer().clone();
2111         tmpbuf->params().useNonTeXFonts =
2112                 fontModule->osFontsCB->isChecked();
2113         int idx = latexModule->classCO->currentIndex();
2114         if (idx >= 0) {
2115                 string const classname = classes_model_.getIDString(idx);
2116                 tmpbuf->params().setBaseClass(classname);
2117                 tmpbuf->params().makeDocumentClass();
2118         }
2119         outputModule->defaultFormatCO->blockSignals(true);
2120         outputModule->defaultFormatCO->clear();
2121         outputModule->defaultFormatCO->addItem(qt_("Default"),
2122                                 QVariant(QString("default")));
2123         typedef vector<Format const *> Formats;
2124         Formats formats = tmpbuf->exportableFormats(true);
2125         Formats::const_iterator cit = formats.begin();
2126         Formats::const_iterator end = formats.end();
2127         for (; cit != end; ++cit)
2128                 outputModule->defaultFormatCO->addItem(qt_((*cit)->prettyname()),
2129                                 QVariant(toqstr((*cit)->name())));
2130         outputModule->defaultFormatCO->blockSignals(false);
2131         // delete the copy
2132         delete tmpbuf;
2133 }
2134
2135
2136 bool GuiDocument::isChildIncluded(string const & child)
2137 {
2138         if (includeonlys_.empty())
2139                 return false;
2140         return (std::find(includeonlys_.begin(),
2141                           includeonlys_.end(), child) != includeonlys_.end());
2142 }
2143
2144
2145 void GuiDocument::applyView()
2146 {
2147         // preamble
2148         preambleModule->apply(bp_);
2149         localLayout->apply(bp_);
2150
2151         // date
2152         bp_.suppress_date = latexModule->suppressDateCB->isChecked();
2153         bp_.use_refstyle  = latexModule->refstyleCB->isChecked();
2154
2155         // biblio
2156         bp_.setCiteEngine(ENGINE_BASIC);
2157
2158         if (biblioModule->citeNatbibRB->isChecked()) {
2159                 bool const use_numerical_citations =
2160                         biblioModule->citeStyleCO->currentIndex();
2161                 if (use_numerical_citations)
2162                         bp_.setCiteEngine(ENGINE_NATBIB_NUMERICAL);
2163                 else
2164                         bp_.setCiteEngine(ENGINE_NATBIB_AUTHORYEAR);
2165
2166         } else if (biblioModule->citeJurabibRB->isChecked())
2167                 bp_.setCiteEngine(ENGINE_JURABIB);
2168
2169         bp_.use_bibtopic =
2170                 biblioModule->bibtopicCB->isChecked();
2171
2172         string const bibtex_command =
2173                 fromqstr(biblioModule->bibtexCO->itemData(
2174                         biblioModule->bibtexCO->currentIndex()).toString());
2175         string const bibtex_options =
2176                 fromqstr(biblioModule->bibtexOptionsED->text());
2177         if (bibtex_command == "default" || bibtex_options.empty())
2178                 bp_.bibtex_command = bibtex_command;
2179         else
2180                 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
2181
2182         // Indices
2183         indicesModule->apply(bp_);
2184
2185         // language & quotes
2186         if (langModule->defaultencodingRB->isChecked()) {
2187                 bp_.inputenc = "auto";
2188         } else {
2189                 int i = langModule->encodingCO->currentIndex();
2190                 if (i == 0)
2191                         bp_.inputenc = "default";
2192                 else {
2193                         QString const enc_gui =
2194                                 langModule->encodingCO->currentText();
2195                         Encodings::const_iterator it = encodings.begin();
2196                         Encodings::const_iterator const end = encodings.end();
2197                         bool found = false;
2198                         for (; it != end; ++it) {
2199                                 if (qt_(it->guiName()) == enc_gui) {
2200                                         bp_.inputenc = it->latexName();
2201                                         found = true;
2202                                         break;
2203                                 }
2204                         }
2205                         if (!found) {
2206                                 // should not happen
2207                                 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
2208                                 bp_.inputenc = "default";
2209                         }
2210                 }
2211         }
2212
2213         InsetQuotes::QuoteLanguage lga = InsetQuotes::EnglishQuotes;
2214         switch (langModule->quoteStyleCO->currentIndex()) {
2215         case 0:
2216                 lga = InsetQuotes::EnglishQuotes;
2217                 break;
2218         case 1:
2219                 lga = InsetQuotes::SwedishQuotes;
2220                 break;
2221         case 2:
2222                 lga = InsetQuotes::GermanQuotes;
2223                 break;
2224         case 3:
2225                 lga = InsetQuotes::PolishQuotes;
2226                 break;
2227         case 4:
2228                 lga = InsetQuotes::FrenchQuotes;
2229                 break;
2230         case 5:
2231                 lga = InsetQuotes::DanishQuotes;
2232                 break;
2233         }
2234         bp_.quotes_language = lga;
2235
2236         QString const lang = langModule->languageCO->itemData(
2237                 langModule->languageCO->currentIndex()).toString();
2238         bp_.language = lyx::languages.getLanguage(fromqstr(lang));
2239         
2240         QString const pack = langModule->languagePackageCO->itemData(
2241                 langModule->languagePackageCO->currentIndex()).toString();
2242         if (pack == "custom")
2243                 bp_.lang_package =
2244                         fromqstr(langModule->languagePackageED->text());
2245         else
2246                 bp_.lang_package = fromqstr(pack);
2247
2248         //color
2249         bp_.backgroundcolor = set_backgroundcolor;
2250         bp_.isbackgroundcolor = is_backgroundcolor;
2251         bp_.fontcolor = set_fontcolor;
2252         bp_.isfontcolor = is_fontcolor;
2253         bp_.notefontcolor = set_notefontcolor;
2254         bp_.boxbgcolor = set_boxbgcolor;
2255
2256         // numbering
2257         if (bp_.documentClass().hasTocLevels()) {
2258                 bp_.tocdepth = numberingModule->tocSL->value();
2259                 bp_.secnumdepth = numberingModule->depthSL->value();
2260         }
2261
2262         // bullets
2263         bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
2264         bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
2265         bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
2266         bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
2267
2268         // packages
2269         bp_.graphics_driver =
2270                 tex_graphics[latexModule->psdriverCO->currentIndex()];
2271         
2272         // text layout
2273         int idx = latexModule->classCO->currentIndex();
2274         if (idx >= 0) {
2275                 string const classname = classes_model_.getIDString(idx);
2276                 bp_.setBaseClass(classname);
2277         }
2278
2279         // Modules
2280         modulesToParams(bp_);
2281
2282         // Math
2283         if (mathsModule->amsautoCB->isChecked())
2284                 bp_.use_amsmath = BufferParams::package_auto;
2285         else {
2286                 if (mathsModule->amsCB->isChecked())
2287                         bp_.use_amsmath = BufferParams::package_on;
2288                 else
2289                         bp_.use_amsmath = BufferParams::package_off;
2290         }
2291         if (mathsModule->esintautoCB->isChecked())
2292                 bp_.use_esint = BufferParams::package_auto;
2293         else {
2294                 if (mathsModule->esintCB->isChecked())
2295                         bp_.use_esint = BufferParams::package_on;
2296                 else
2297                         bp_.use_esint = BufferParams::package_off;
2298         }
2299         if (mathsModule->mhchemautoCB->isChecked())
2300                 bp_.use_mhchem = BufferParams::package_auto;
2301         else {
2302                 if (mathsModule->mhchemCB->isChecked())
2303                         bp_.use_mhchem = BufferParams::package_on;
2304                 else
2305                         bp_.use_mhchem = BufferParams::package_off;
2306         }
2307         if (mathsModule->mathdotsautoCB->isChecked())
2308                 bp_.use_mathdots = BufferParams::package_auto;
2309         else {
2310                 if (mathsModule->mathdotsCB->isChecked())
2311                         bp_.use_mathdots = BufferParams::package_on;
2312                 else
2313                         bp_.use_mathdots = BufferParams::package_off;
2314         }
2315         
2316         // Page Layout
2317         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
2318                 bp_.pagestyle = "default";
2319         else {
2320                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
2321                 for (size_t i = 0; i != pagestyles.size(); ++i)
2322                         if (pagestyles[i].second == style_gui)
2323                                 bp_.pagestyle = pagestyles[i].first;
2324         }
2325
2326         // Text Layout
2327         switch (textLayoutModule->lspacingCO->currentIndex()) {
2328         case 0:
2329                 bp_.spacing().set(Spacing::Single);
2330                 break;
2331         case 1:
2332                 bp_.spacing().set(Spacing::Onehalf);
2333                 break;
2334         case 2:
2335                 bp_.spacing().set(Spacing::Double);
2336                 break;
2337         case 3: {
2338                 string s = widgetToDoubleStr(textLayoutModule->lspacingLE);
2339                 if (s.empty())
2340                         bp_.spacing().set(Spacing::Single);
2341                 else
2342                         bp_.spacing().set(Spacing::Other, s);
2343                 break;
2344                 }
2345         }
2346
2347         if (textLayoutModule->twoColumnCB->isChecked())
2348                 bp_.columns = 2;
2349         else
2350                 bp_.columns = 1;
2351
2352         if (textLayoutModule->indentRB->isChecked()) {
2353                 // if paragraphs are separated by an indentation
2354                 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
2355                 switch (textLayoutModule->indentCO->currentIndex()) {
2356                 case 0:
2357                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2358                         break;
2359                 case 1: {
2360                         HSpace indent = HSpace(
2361                                 widgetsToLength(textLayoutModule->indentLE,
2362                                 textLayoutModule->indentLengthCO)
2363                                 );
2364                         bp_.setIndentation(indent);
2365                         break;
2366                         }
2367                 default:
2368                         // this should never happen
2369                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2370                         break;
2371                 }
2372         } else {
2373                 // if paragraphs are separated by a skip
2374                 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
2375                 switch (textLayoutModule->skipCO->currentIndex()) {
2376                 case 0:
2377                         bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
2378                         break;
2379                 case 1:
2380                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2381                         break;
2382                 case 2:
2383                         bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
2384                         break;
2385                 case 3:
2386                         {
2387                         VSpace vs = VSpace(
2388                                 widgetsToLength(textLayoutModule->skipLE,
2389                                 textLayoutModule->skipLengthCO)
2390                                 );
2391                         bp_.setDefSkip(vs);
2392                         break;
2393                         }
2394                 default:
2395                         // this should never happen
2396                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2397                         break;
2398                 }
2399         }
2400
2401         bp_.options =
2402                 fromqstr(latexModule->optionsLE->text());
2403
2404         bp_.use_default_options =
2405                 latexModule->defaultOptionsCB->isChecked();
2406
2407         if (latexModule->childDocGB->isChecked())
2408                 bp_.master =
2409                         fromqstr(latexModule->childDocLE->text());
2410         else
2411                 bp_.master = string();
2412
2413         // Master/Child
2414         bp_.clearIncludedChildren();
2415         if (masterChildModule->includeonlyRB->isChecked()) {
2416                 list<string>::const_iterator it = includeonlys_.begin();
2417                 for (; it != includeonlys_.end() ; ++it) {
2418                         bp_.addIncludedChildren(*it);
2419                 }
2420         }
2421         bp_.maintain_unincluded_children =
2422                 masterChildModule->maintainAuxCB->isChecked();
2423
2424         // Float Placement
2425         bp_.float_placement = floatModule->get();
2426
2427         // Listings
2428         // text should have passed validation
2429         bp_.listings_params =
2430                 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
2431
2432         // output
2433         bp_.default_output_format = fromqstr(outputModule->defaultFormatCO->itemData(
2434                 outputModule->defaultFormatCO->currentIndex()).toString());
2435
2436         bool const nontexfonts = fontModule->osFontsCB->isChecked();
2437         bp_.useNonTeXFonts = nontexfonts;
2438
2439         bp_.output_sync = outputModule->outputsyncCB->isChecked();
2440         bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
2441
2442         int mathfmt = outputModule->mathoutCB->currentIndex();
2443         if (mathfmt == -1)
2444                 mathfmt = 0;
2445         BufferParams::MathOutput const mo =
2446                 static_cast<BufferParams::MathOutput>(mathfmt);
2447         bp_.html_math_output = mo;
2448         bp_.html_be_strict = outputModule->strictCB->isChecked();
2449         bp_.html_math_img_scale = outputModule->mathimgSB->value();
2450
2451         // fonts
2452         if (nontexfonts) {
2453                 if (fontModule->fontsRomanCO->currentIndex() == 0)
2454                         bp_.fonts_roman = "default";
2455                 else
2456                         bp_.fonts_roman =
2457                                 fromqstr(fontModule->fontsRomanCO->currentText());
2458         
2459                 if (fontModule->fontsSansCO->currentIndex() == 0)
2460                         bp_.fonts_sans = "default";
2461                 else
2462                         bp_.fonts_sans =
2463                                 fromqstr(fontModule->fontsSansCO->currentText());
2464         
2465                 if (fontModule->fontsTypewriterCO->currentIndex() == 0)
2466                         bp_.fonts_typewriter = "default";
2467                 else
2468                         bp_.fonts_typewriter =
2469                                 fromqstr(fontModule->fontsTypewriterCO->currentText());
2470         } else {
2471                 bp_.fonts_roman =
2472                         tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
2473         
2474                 bp_.fonts_sans =
2475                         tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
2476         
2477                 bp_.fonts_typewriter =
2478                         tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
2479         }
2480
2481         if (fontModule->fontencCO->currentIndex() == 0)
2482                 bp_.fontenc = "global";
2483         else if (fontModule->fontencCO->currentIndex() == 1)
2484                 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
2485         else if (fontModule->fontencCO->currentIndex() == 2)
2486                 bp_.fontenc = "default";
2487
2488         bp_.fonts_cjk =
2489                 fromqstr(fontModule->cjkFontLE->text());
2490
2491         bp_.fonts_sans_scale = fontModule->scaleSansSB->value();
2492
2493         bp_.fonts_typewriter_scale = fontModule->scaleTypewriterSB->value();
2494
2495         bp_.fonts_expert_sc = fontModule->fontScCB->isChecked();
2496
2497         bp_.fonts_old_figures = fontModule->fontOsfCB->isChecked();
2498
2499         if (nontexfonts)
2500                 bp_.fonts_default_family = "default";
2501         else
2502                 bp_.fonts_default_family = GuiDocument::fontfamilies[
2503                         fontModule->fontsDefaultCO->currentIndex()];
2504
2505         if (fontModule->fontsizeCO->currentIndex() == 0)
2506                 bp_.fontsize = "default";
2507         else
2508                 bp_.fontsize =
2509                         fromqstr(fontModule->fontsizeCO->currentText());
2510
2511         // paper
2512         bp_.papersize = PAPER_SIZE(
2513                 pageLayoutModule->papersizeCO->currentIndex());
2514
2515         bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
2516                 pageLayoutModule->paperwidthUnitCO);
2517
2518         bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
2519                 pageLayoutModule->paperheightUnitCO);
2520
2521         if (pageLayoutModule->facingPagesCB->isChecked())
2522                 bp_.sides = TwoSides;
2523         else
2524                 bp_.sides = OneSide;
2525
2526         if (pageLayoutModule->landscapeRB->isChecked())
2527                 bp_.orientation = ORIENTATION_LANDSCAPE;
2528         else
2529                 bp_.orientation = ORIENTATION_PORTRAIT;
2530
2531         // margins
2532         bp_.use_geometry = !marginsModule->marginCB->isChecked();
2533
2534         Ui::MarginsUi const * m = marginsModule;
2535
2536         bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
2537         bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
2538         bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
2539         bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
2540         bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
2541         bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
2542         bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
2543         bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
2544
2545         // branches
2546         branchesModule->apply(bp_);
2547
2548         // PDF support
2549         PDFOptions & pdf = bp_.pdfoptions();
2550         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
2551         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
2552         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
2553         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
2554         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
2555
2556         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
2557         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
2558         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
2559         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
2560
2561         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
2562         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
2563         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
2564         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
2565         pdf.backref =
2566                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
2567         if (pdfSupportModule->fullscreenCB->isChecked())
2568                 pdf.pagemode = pdf.pagemode_fullscreen;
2569         else
2570                 pdf.pagemode.clear();
2571         pdf.quoted_options = pdf.quoted_options_check(
2572                                 fromqstr(pdfSupportModule->optionsLE->text()));
2573 }
2574
2575
2576 void GuiDocument::paramsToDialog()
2577 {
2578         // set the default unit
2579         Length::UNIT const defaultUnit = Length::defaultUnit();
2580
2581         // preamble
2582         preambleModule->update(bp_, id());
2583         localLayout->update(bp_, id());
2584
2585         // date
2586         latexModule->suppressDateCB->setChecked(bp_.suppress_date);
2587         latexModule->refstyleCB->setChecked(bp_.use_refstyle);
2588
2589         // biblio
2590         biblioModule->citeDefaultRB->setChecked(
2591                 bp_.citeEngine() == ENGINE_BASIC);
2592
2593         biblioModule->citeNatbibRB->setChecked(
2594                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL ||
2595                 bp_.citeEngine() == ENGINE_NATBIB_AUTHORYEAR);
2596
2597         biblioModule->citeStyleCO->setCurrentIndex(
2598                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL);
2599
2600         biblioModule->citeJurabibRB->setChecked(
2601                 bp_.citeEngine() == ENGINE_JURABIB);
2602
2603         biblioModule->bibtopicCB->setChecked(
2604                 bp_.use_bibtopic);
2605
2606         string command;
2607         string options =
2608                 split(bp_.bibtex_command, command, ' ');
2609
2610         int const bpos = biblioModule->bibtexCO->findData(toqstr(command));
2611         if (bpos != -1) {
2612                 biblioModule->bibtexCO->setCurrentIndex(bpos);
2613                 biblioModule->bibtexOptionsED->setText(toqstr(options).trimmed());
2614         } else {
2615                 // We reset to default if we do not know the specified compiler
2616                 // This is for security reasons
2617                 biblioModule->bibtexCO->setCurrentIndex(
2618                         biblioModule->bibtexCO->findData(toqstr("default")));
2619                 biblioModule->bibtexOptionsED->clear();
2620         }
2621         biblioModule->bibtexOptionsED->setEnabled(
2622                 biblioModule->bibtexCO->currentIndex() != 0);
2623
2624         // indices
2625         indicesModule->update(bp_);
2626
2627         // language & quotes
2628         int const pos = langModule->languageCO->findData(toqstr(
2629                 bp_.language->lang()));
2630         langModule->languageCO->setCurrentIndex(pos);
2631
2632         langModule->quoteStyleCO->setCurrentIndex(
2633                 bp_.quotes_language);
2634
2635         bool default_enc = true;
2636         if (bp_.inputenc != "auto") {
2637                 default_enc = false;
2638                 if (bp_.inputenc == "default") {
2639                         langModule->encodingCO->setCurrentIndex(0);
2640                 } else {
2641                         string enc_gui;
2642                         Encodings::const_iterator it = encodings.begin();
2643                         Encodings::const_iterator const end = encodings.end();
2644                         for (; it != end; ++it) {
2645                                 if (it->latexName() == bp_.inputenc) {
2646                                         enc_gui = it->guiName();
2647                                         break;
2648                                 }
2649                         }
2650                         int const i = langModule->encodingCO->findText(
2651                                         qt_(enc_gui));
2652                         if (i >= 0)
2653                                 langModule->encodingCO->setCurrentIndex(i);
2654                         else
2655                                 // unknown encoding. Set to default.
2656                                 default_enc = true;
2657                 }
2658         }
2659         langModule->defaultencodingRB->setChecked(default_enc);
2660         langModule->otherencodingRB->setChecked(!default_enc);
2661
2662         int const p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
2663         if (p == -1) {
2664                 langModule->languagePackageCO->setCurrentIndex(
2665                           langModule->languagePackageCO->findData("custom"));
2666                 langModule->languagePackageED->setText(toqstr(bp_.lang_package));
2667         } else {
2668                 langModule->languagePackageCO->setCurrentIndex(p);
2669                 langModule->languagePackageED->clear();
2670         }
2671
2672         //color
2673         if (bp_.isfontcolor) {
2674                 colorModule->fontColorPB->setStyleSheet(
2675                         colorButtonStyleSheet(rgb2qcolor(bp_.fontcolor)));
2676         }
2677         set_fontcolor = bp_.fontcolor;
2678         is_fontcolor = bp_.isfontcolor;
2679
2680         colorModule->noteFontColorPB->setStyleSheet(
2681                 colorButtonStyleSheet(rgb2qcolor(bp_.notefontcolor)));
2682         set_notefontcolor = bp_.notefontcolor;
2683
2684         if (bp_.isbackgroundcolor) {
2685                 colorModule->backgroundPB->setStyleSheet(
2686                         colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
2687         }
2688         set_backgroundcolor = bp_.backgroundcolor;
2689         is_backgroundcolor = bp_.isbackgroundcolor;
2690
2691         colorModule->boxBackgroundPB->setStyleSheet(
2692                 colorButtonStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
2693         set_boxbgcolor = bp_.boxbgcolor;
2694
2695         // numbering
2696         int const min_toclevel = documentClass().min_toclevel();
2697         int const max_toclevel = documentClass().max_toclevel();
2698         if (documentClass().hasTocLevels()) {
2699                 numberingModule->setEnabled(true);
2700                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
2701                 numberingModule->depthSL->setMaximum(max_toclevel);
2702                 numberingModule->depthSL->setValue(bp_.secnumdepth);
2703                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
2704                 numberingModule->tocSL->setMaximum(max_toclevel);
2705                 numberingModule->tocSL->setValue(bp_.tocdepth);
2706                 updateNumbering();
2707         } else {
2708                 numberingModule->setEnabled(false);
2709                 numberingModule->tocTW->clear();
2710         }
2711
2712         // bullets
2713         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
2714         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
2715         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
2716         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
2717         bulletsModule->init();
2718
2719         // packages
2720         int nitem = findToken(tex_graphics, bp_.graphics_driver);
2721         if (nitem >= 0)
2722                 latexModule->psdriverCO->setCurrentIndex(nitem);
2723         updateModuleInfo();
2724         
2725         mathsModule->amsCB->setChecked(
2726                 bp_.use_amsmath == BufferParams::package_on);
2727         mathsModule->amsautoCB->setChecked(
2728                 bp_.use_amsmath == BufferParams::package_auto);
2729
2730         mathsModule->esintCB->setChecked(
2731                 bp_.use_esint == BufferParams::package_on);
2732         mathsModule->esintautoCB->setChecked(
2733                 bp_.use_esint == BufferParams::package_auto);
2734
2735         mathsModule->mhchemCB->setChecked(
2736                 bp_.use_mhchem == BufferParams::package_on);
2737         mathsModule->mhchemautoCB->setChecked(
2738                 bp_.use_mhchem == BufferParams::package_auto);
2739
2740         mathsModule->mathdotsCB->setChecked(
2741                 bp_.use_mathdots == BufferParams::package_on);
2742         mathsModule->mathdotsautoCB->setChecked(
2743                 bp_.use_mathdots == BufferParams::package_auto);
2744
2745         switch (bp_.spacing().getSpace()) {
2746                 case Spacing::Other: nitem = 3; break;
2747                 case Spacing::Double: nitem = 2; break;
2748                 case Spacing::Onehalf: nitem = 1; break;
2749                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
2750         }
2751
2752         // text layout
2753         string const & layoutID = bp_.baseClassID();
2754         setLayoutComboByIDString(layoutID);
2755
2756         updatePagestyle(documentClass().opt_pagestyle(),
2757                                  bp_.pagestyle);
2758
2759         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
2760         if (bp_.spacing().getSpace() == Spacing::Other) {
2761                 doubleToWidget(textLayoutModule->lspacingLE,
2762                         bp_.spacing().getValueAsString());
2763         }
2764         setLSpacing(nitem);
2765
2766         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
2767                 textLayoutModule->indentRB->setChecked(true);
2768                 string indentation = bp_.getIndentation().asLyXCommand();
2769                 int indent = 0;
2770                 if (indentation != "default") {
2771                         lengthToWidgets(textLayoutModule->indentLE,
2772                         textLayoutModule->indentLengthCO,
2773                         indentation, defaultUnit);
2774                         indent = 1;
2775                 }
2776                 textLayoutModule->indentCO->setCurrentIndex(indent);
2777                 setIndent(indent);
2778         } else {
2779                 textLayoutModule->skipRB->setChecked(true);
2780                 int skip = 0;
2781                 switch (bp_.getDefSkip().kind()) {
2782                 case VSpace::SMALLSKIP:
2783                         skip = 0;
2784                         break;
2785                 case VSpace::MEDSKIP:
2786                         skip = 1;
2787                         break;
2788                 case VSpace::BIGSKIP:
2789                         skip = 2;
2790                         break;
2791                 case VSpace::LENGTH:
2792                         {
2793                         skip = 3;
2794                         string const length = bp_.getDefSkip().asLyXCommand();
2795                         lengthToWidgets(textLayoutModule->skipLE,
2796                                 textLayoutModule->skipLengthCO,
2797                                 length, defaultUnit);
2798                         break;
2799                         }
2800                 default:
2801                         skip = 0;
2802                         break;
2803                 }
2804                 textLayoutModule->skipCO->setCurrentIndex(skip);
2805                 setSkip(skip);
2806         }
2807
2808         textLayoutModule->twoColumnCB->setChecked(
2809                 bp_.columns == 2);
2810
2811         if (!bp_.options.empty()) {
2812                 latexModule->optionsLE->setText(
2813                         toqstr(bp_.options));
2814         } else {
2815                 latexModule->optionsLE->setText(QString());
2816         }
2817
2818         // latex
2819         latexModule->defaultOptionsCB->setChecked(
2820                         bp_.use_default_options);
2821         updateSelectedModules();
2822         selectionManager->updateProvidedModules(
2823                         bp_.baseClass()->providedModules());
2824         selectionManager->updateExcludedModules(
2825                         bp_.baseClass()->excludedModules());
2826
2827         if (!documentClass().options().empty()) {
2828                 latexModule->defaultOptionsLE->setText(
2829                         toqstr(documentClass().options()));
2830         } else {
2831                 latexModule->defaultOptionsLE->setText(
2832                         toqstr(_("[No options predefined]")));
2833         }
2834
2835         latexModule->defaultOptionsLE->setEnabled(
2836                 bp_.use_default_options
2837                 && !documentClass().options().empty());
2838
2839         latexModule->defaultOptionsCB->setEnabled(
2840                 !documentClass().options().empty());
2841
2842         if (!bp_.master.empty()) {
2843                 latexModule->childDocGB->setChecked(true);
2844                 latexModule->childDocLE->setText(
2845                         toqstr(bp_.master));
2846         } else {
2847                 latexModule->childDocLE->setText(QString());
2848                 latexModule->childDocGB->setChecked(false);
2849         }
2850
2851         // Master/Child
2852         if (!bufferview() || !buffer().hasChildren()) {
2853                 masterChildModule->childrenTW->clear();
2854                 includeonlys_.clear();
2855                 docPS->showPanel(qt_("Child Documents"), false);
2856                 if (docPS->isCurrentPanel(qt_("Child Documents")))
2857                         docPS->setCurrentPanel(qt_("Document Class"));
2858         } else {
2859                 docPS->showPanel(qt_("Child Documents"), true);
2860                 masterChildModule->setEnabled(true);
2861                 includeonlys_ = bp_.getIncludedChildren();
2862                 updateIncludeonlys();
2863         }
2864         masterChildModule->maintainAuxCB->setChecked(
2865                 bp_.maintain_unincluded_children);
2866
2867         // Float Settings
2868         floatModule->set(bp_.float_placement);
2869
2870         // ListingsSettings
2871         // break listings_params to multiple lines
2872         string lstparams =
2873                 InsetListingsParams(bp_.listings_params).separatedParams();
2874         listingsModule->listingsED->setPlainText(toqstr(lstparams));
2875
2876         // Output
2877         // update combobox with formats
2878         updateDefaultFormat();
2879         int index = outputModule->defaultFormatCO->findData(toqstr(
2880                 bp_.default_output_format));
2881         // set to default if format is not found 
2882         if (index == -1)
2883                 index = 0;
2884         outputModule->defaultFormatCO->setCurrentIndex(index);
2885         bool const os_fonts_available =
2886                 bp_.baseClass()->outputType() == lyx::LATEX
2887                 && LaTeXFeatures::isAvailable("fontspec");
2888         fontModule->osFontsCB->setEnabled(os_fonts_available);
2889         fontModule->osFontsCB->setChecked(
2890                 os_fonts_available && bp_.useNonTeXFonts);
2891
2892         outputModule->outputsyncCB->setChecked(bp_.output_sync);
2893         outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
2894
2895         outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
2896         outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
2897         outputModule->strictCB->setChecked(bp_.html_be_strict);
2898
2899         // Fonts
2900         updateFontsize(documentClass().opt_fontsize(),
2901                         bp_.fontsize);
2902
2903         if (bp_.useNonTeXFonts && os_fonts_available) {
2904                 fontModule->fontencLA->setEnabled(false);
2905                 fontModule->fontencCO->setEnabled(false);
2906                 fontModule->fontencLE->setEnabled(false);
2907                 for (int i = 0; i < fontModule->fontsRomanCO->count(); ++i) {
2908                         if (fontModule->fontsRomanCO->itemText(i) == toqstr(bp_.fonts_roman)) {
2909                                 fontModule->fontsRomanCO->setCurrentIndex(i);
2910                                 break;
2911                         }
2912                 }
2913                 
2914                 for (int i = 0; i < fontModule->fontsSansCO->count(); ++i) {
2915                         if (fontModule->fontsSansCO->itemText(i) == toqstr(bp_.fonts_sans)) {
2916                                 fontModule->fontsSansCO->setCurrentIndex(i);
2917                                 break;
2918                         }
2919                 }
2920                 for (int i = 0; i < fontModule->fontsTypewriterCO->count(); ++i) {
2921                         if (fontModule->fontsTypewriterCO->itemText(i) == 
2922                                 toqstr(bp_.fonts_typewriter)) {
2923                                 fontModule->fontsTypewriterCO->setCurrentIndex(i);
2924                                 break;
2925                         }
2926                 }
2927         } else {
2928                 fontModule->fontencLA->setEnabled(true);
2929                 fontModule->fontencCO->setEnabled(true);
2930                 fontModule->fontencLE->setEnabled(true);
2931                 int n = findToken(tex_fonts_roman, bp_.fonts_roman);
2932                 if (n >= 0) {
2933                         fontModule->fontsRomanCO->setCurrentIndex(n);
2934                         romanChanged(n);
2935                 }
2936         
2937                 n = findToken(tex_fonts_sans, bp_.fonts_sans);
2938                 if (n >= 0) {
2939                         fontModule->fontsSansCO->setCurrentIndex(n);
2940                         sansChanged(n);
2941                 }
2942         
2943                 n = findToken(tex_fonts_monospaced, bp_.fonts_typewriter);
2944                 if (n >= 0) {
2945                         fontModule->fontsTypewriterCO->setCurrentIndex(n);
2946                         ttChanged(n);
2947                 }
2948         }
2949
2950         if (!bp_.fonts_cjk.empty())
2951                 fontModule->cjkFontLE->setText(
2952                         toqstr(bp_.fonts_cjk));
2953         else
2954                 fontModule->cjkFontLE->setText(QString());
2955
2956         fontModule->fontScCB->setChecked(bp_.fonts_expert_sc);
2957         fontModule->fontOsfCB->setChecked(bp_.fonts_old_figures);
2958         fontModule->scaleSansSB->setValue(bp_.fonts_sans_scale);
2959         fontModule->scaleTypewriterSB->setValue(bp_.fonts_typewriter_scale);
2960         
2961         int nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
2962         if (nn >= 0)
2963                 fontModule->fontsDefaultCO->setCurrentIndex(nn);
2964
2965         if (bp_.fontenc == "global") {
2966                 fontModule->fontencCO->setCurrentIndex(0);
2967                 fontModule->fontencLE->setEnabled(false);
2968         } else if (bp_.fontenc == "default") {
2969                 fontModule->fontencCO->setCurrentIndex(2);
2970                 fontModule->fontencLE->setEnabled(false);
2971         } else {
2972                 fontModule->fontencCO->setCurrentIndex(1);
2973                 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
2974         }
2975
2976         // paper
2977         bool const extern_geometry =
2978                 documentClass().provides("geometry");
2979         int const psize = bp_.papersize;
2980         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
2981         setCustomPapersize(!extern_geometry && psize == 1);
2982         pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
2983
2984         bool const landscape =
2985                 bp_.orientation == ORIENTATION_LANDSCAPE;
2986         pageLayoutModule->landscapeRB->setChecked(landscape);
2987         pageLayoutModule->portraitRB->setChecked(!landscape);
2988         pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
2989         pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
2990
2991         pageLayoutModule->facingPagesCB->setChecked(
2992                 bp_.sides == TwoSides);
2993
2994         lengthToWidgets(pageLayoutModule->paperwidthLE,
2995                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, defaultUnit);
2996         lengthToWidgets(pageLayoutModule->paperheightLE,
2997                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, defaultUnit);
2998
2999         // margins
3000         Ui::MarginsUi * m = marginsModule;
3001
3002         setMargins();
3003
3004         lengthToWidgets(m->topLE, m->topUnit,
3005                 bp_.topmargin, defaultUnit);
3006
3007         lengthToWidgets(m->bottomLE, m->bottomUnit,
3008                 bp_.bottommargin, defaultUnit);
3009
3010         lengthToWidgets(m->innerLE, m->innerUnit,
3011                 bp_.leftmargin, defaultUnit);
3012
3013         lengthToWidgets(m->outerLE, m->outerUnit,
3014                 bp_.rightmargin, defaultUnit);
3015
3016         lengthToWidgets(m->headheightLE, m->headheightUnit,
3017                 bp_.headheight, defaultUnit);
3018
3019         lengthToWidgets(m->headsepLE, m->headsepUnit,
3020                 bp_.headsep, defaultUnit);
3021
3022         lengthToWidgets(m->footskipLE, m->footskipUnit,
3023                 bp_.footskip, defaultUnit);
3024
3025         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
3026                 bp_.columnsep, defaultUnit);
3027
3028         // branches
3029         updateUnknownBranches();
3030         branchesModule->update(bp_);
3031
3032         // PDF support
3033         PDFOptions const & pdf = bp_.pdfoptions();
3034         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
3035         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
3036         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
3037         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
3038         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
3039
3040         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
3041         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
3042         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
3043
3044         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
3045
3046         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
3047         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
3048         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
3049         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
3050
3051         nn = findToken(backref_opts, pdf.backref);
3052         if (nn >= 0)
3053                 pdfSupportModule->backrefCO->setCurrentIndex(nn);
3054
3055         pdfSupportModule->fullscreenCB->setChecked
3056                 (pdf.pagemode == pdf.pagemode_fullscreen);
3057
3058         pdfSupportModule->optionsLE->setText(
3059                 toqstr(pdf.quoted_options));
3060
3061         // Make sure that the bc is in the INITIAL state
3062         if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
3063                 bc().restore();
3064
3065         // clear changed branches cache
3066         changedBranches_.clear();
3067 }
3068
3069
3070 void GuiDocument::saveDocDefault()
3071 {
3072         // we have to apply the params first
3073         applyView();
3074         saveAsDefault();
3075 }
3076
3077
3078 void GuiDocument::updateAvailableModules() 
3079 {
3080         modules_av_model_.clear();
3081         list<modInfoStruct> const & modInfoList = getModuleInfo();
3082         list<modInfoStruct>::const_iterator mit = modInfoList.begin();
3083         list<modInfoStruct>::const_iterator men = modInfoList.end();
3084         for (int i = 0; mit != men; ++mit, ++i)
3085                 modules_av_model_.insertRow(i, mit->name, mit->id, 
3086                                 mit->description);
3087 }
3088
3089
3090 void GuiDocument::updateSelectedModules() 
3091 {
3092         modules_sel_model_.clear();
3093         list<modInfoStruct> const selModList = getSelectedModules();
3094         list<modInfoStruct>::const_iterator mit = selModList.begin();
3095         list<modInfoStruct>::const_iterator men = selModList.end();
3096         for (int i = 0; mit != men; ++mit, ++i)
3097                 modules_sel_model_.insertRow(i, mit->name, mit->id, 
3098                                 mit->description);
3099 }
3100
3101
3102 void GuiDocument::updateIncludeonlys()
3103 {
3104         masterChildModule->childrenTW->clear();
3105         QString const no = qt_("No");
3106         QString const yes = qt_("Yes");
3107
3108         if (includeonlys_.empty()) {
3109                 masterChildModule->includeallRB->setChecked(true);
3110                 masterChildModule->childrenTW->setEnabled(false);
3111                 masterChildModule->maintainAuxCB->setEnabled(false);
3112         } else {
3113                 masterChildModule->includeonlyRB->setChecked(true);
3114                 masterChildModule->childrenTW->setEnabled(true);
3115                 masterChildModule->maintainAuxCB->setEnabled(true);
3116         }
3117         QTreeWidgetItem * item = 0;
3118         ListOfBuffers children = buffer().getChildren();
3119         ListOfBuffers::const_iterator it  = children.begin();
3120         ListOfBuffers::const_iterator end = children.end();
3121         bool has_unincluded = false;
3122         bool all_unincluded = true;
3123         for (; it != end; ++it) {
3124                 item = new QTreeWidgetItem(masterChildModule->childrenTW);
3125                 // FIXME Unicode
3126                 string const name =
3127                         to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
3128                                                         from_utf8(buffer().filePath())));
3129                 item->setText(0, toqstr(name));
3130                 item->setText(1, isChildIncluded(name) ? yes : no);
3131                 if (!isChildIncluded(name))
3132                         has_unincluded = true;
3133                 else
3134                         all_unincluded = false;
3135         }
3136         // Both if all childs are included and if none is included
3137         // is equal to "include all" (i.e., ommit \includeonly).
3138         // Thus, reset the GUI.
3139         if (!has_unincluded || all_unincluded) {
3140                 masterChildModule->includeallRB->setChecked(true);
3141                 masterChildModule->childrenTW->setEnabled(false);
3142                 includeonlys_.clear();
3143         }
3144         // If all are included, we need to update again.
3145         if (!has_unincluded)
3146                 updateIncludeonlys();
3147 }
3148
3149
3150 void GuiDocument::updateContents()
3151 {
3152         // Nothing to do here as the document settings is not cursor dependant.
3153         return;
3154 }
3155
3156
3157 void GuiDocument::useClassDefaults()
3158 {
3159         if (applyPB->isEnabled()) {
3160                 int const ret = Alert::prompt(_("Unapplied changes"),
3161                                 _("Some changes in the dialog were not yet applied.\n"
3162                                   "If you do not apply now, they will be lost after this action."),
3163                                 1, 1, _("&Apply"), _("&Dismiss"));
3164                 if (ret == 0)
3165                         applyView();
3166         }
3167
3168         int idx = latexModule->classCO->currentIndex();
3169         string const classname = classes_model_.getIDString(idx);
3170         if (!bp_.setBaseClass(classname)) {
3171                 Alert::error(_("Error"), _("Unable to set document class."));
3172                 return;
3173         }
3174         bp_.useClassDefaults();
3175         paramsToDialog();
3176 }
3177
3178
3179 void GuiDocument::setLayoutComboByIDString(string const & idString)
3180 {
3181         int idx = classes_model_.findIDString(idString);
3182         if (idx < 0)
3183                 Alert::warning(_("Can't set layout!"), 
3184                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
3185         else 
3186                 latexModule->classCO->setCurrentIndex(idx);
3187 }
3188
3189
3190 bool GuiDocument::isValid()
3191 {
3192         return 
3193                 validateListingsParameters().isEmpty() &&
3194                 localLayout->isValid() &&
3195                 (
3196                         // if we're asking for skips between paragraphs
3197                         !textLayoutModule->skipRB->isChecked() ||
3198                         // then either we haven't chosen custom
3199                         textLayoutModule->skipCO->currentIndex() != 3 || 
3200                         // or else a length has been given
3201                         !textLayoutModule->skipLE->text().isEmpty()
3202                 ) && 
3203                 (
3204                         // if we're asking for indentation
3205                         !textLayoutModule->indentRB->isChecked() || 
3206                         // then either we haven't chosen custom
3207                         textLayoutModule->indentCO->currentIndex() != 1 || 
3208                         // or else a length has been given
3209                         !textLayoutModule->indentLE->text().isEmpty()
3210                 );
3211 }
3212
3213
3214 char const * const GuiDocument::fontfamilies[5] = {
3215         "default", "rmdefault", "sfdefault", "ttdefault", ""
3216 };
3217
3218
3219 char const * GuiDocument::fontfamilies_gui[5] = {
3220         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
3221 };
3222
3223
3224 bool GuiDocument::initialiseParams(string const &)
3225 {
3226         BufferView const * view = bufferview();
3227         if (!view) {
3228                 bp_ = BufferParams();
3229                 paramsToDialog();
3230                 return true;
3231         }
3232         bp_ = view->buffer().params();
3233         loadModuleInfo();
3234         updateAvailableModules();
3235         //FIXME It'd be nice to make sure here that the selected
3236         //modules are consistent: That required modules are actually
3237         //selected, and that we don't have conflicts. If so, we could
3238         //at least pop up a warning.
3239         paramsToDialog();
3240         return true;
3241 }
3242
3243
3244 void GuiDocument::clearParams()
3245 {
3246         bp_ = BufferParams();
3247 }
3248
3249
3250 BufferId GuiDocument::id() const
3251 {
3252         BufferView const * const view = bufferview();
3253         return view? &view->buffer() : 0;
3254 }
3255
3256
3257 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
3258 {
3259         return moduleNames_;
3260 }
3261
3262
3263 list<GuiDocument::modInfoStruct> const 
3264                 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
3265 {
3266         LayoutModuleList::const_iterator it =  mods.begin();
3267         LayoutModuleList::const_iterator end = mods.end();
3268         list<modInfoStruct> mInfo;
3269         for (; it != end; ++it) {
3270                 modInfoStruct m;
3271                 m.id = *it;
3272                 LyXModule const * const mod = theModuleList[*it];
3273                 if (mod)
3274                         // FIXME Unicode
3275                         m.name = toqstr(translateIfPossible(from_utf8(mod->getName())));
3276                 else 
3277                         m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
3278                 mInfo.push_back(m);
3279         }
3280         return mInfo;
3281 }
3282
3283
3284 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
3285 {
3286         return makeModuleInfo(params().getModules());
3287 }
3288
3289
3290 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
3291 {
3292         return makeModuleInfo(params().baseClass()->providedModules());
3293 }
3294
3295
3296 DocumentClass const & GuiDocument::documentClass() const
3297 {
3298         return bp_.documentClass();
3299 }
3300
3301
3302 static void dispatch_bufferparams(Dialog const & dialog,
3303         BufferParams const & bp, FuncCode lfun)
3304 {
3305         ostringstream ss;
3306         ss << "\\begin_header\n";
3307         bp.writeFile(ss);
3308         ss << "\\end_header\n";
3309         dialog.dispatch(FuncRequest(lfun, ss.str()));
3310 }
3311
3312
3313 void GuiDocument::dispatchParams()
3314 {
3315         // This must come first so that a language change is correctly noticed
3316         setLanguage();
3317
3318         // Apply the BufferParams. Note that this will set the base class
3319         // and then update the buffer's layout.
3320         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
3321
3322         if (!params().master.empty()) {
3323                 FileName const master_file = support::makeAbsPath(params().master,
3324                            support::onlyPath(buffer().absFileName()));
3325                 if (isLyXFileName(master_file.absFileName())) {
3326                         Buffer * master = checkAndLoadLyXFile(master_file);
3327                         if (master) {
3328                                 if (master->isChild(const_cast<Buffer *>(&buffer())))
3329                                         const_cast<Buffer &>(buffer()).setParent(master);
3330                                 else
3331                                         Alert::warning(_("Assigned master does not include this file"), 
3332                                                 bformat(_("You must include this file in the document\n"
3333                                                           "'%1$s' in order to use the master document\n"
3334                                                           "feature."), from_utf8(params().master)));
3335                         } else
3336                                 Alert::warning(_("Could not load master"), 
3337                                                 bformat(_("The master document '%1$s'\n"
3338                                                            "could not be loaded."),
3339                                                            from_utf8(params().master)));
3340                 }
3341         }
3342
3343         // Generate the colours requested by each new branch.
3344         BranchList & branchlist = params().branchlist();
3345         if (!branchlist.empty()) {
3346                 BranchList::const_iterator it = branchlist.begin();
3347                 BranchList::const_iterator const end = branchlist.end();
3348                 for (; it != end; ++it) {
3349                         docstring const & current_branch = it->branch();
3350                         Branch const * branch = branchlist.find(current_branch);
3351                         string const x11hexname = X11hexname(branch->color());
3352                         // display the new color
3353                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
3354                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
3355                 }
3356
3357                 // Open insets of selected branches, close deselected ones
3358                 dispatch(FuncRequest(LFUN_INSET_FORALL,
3359                         "Branch inset-toggle assign"));
3360         }
3361         // rename branches in the document
3362         executeBranchRenaming();
3363         // and clear changed branches cache
3364         changedBranches_.clear();
3365         
3366         // Generate the colours requested by indices.
3367         IndicesList & indiceslist = params().indiceslist();
3368         if (!indiceslist.empty()) {
3369                 IndicesList::const_iterator it = indiceslist.begin();
3370                 IndicesList::const_iterator const end = indiceslist.end();
3371                 for (; it != end; ++it) {
3372                         docstring const & current_index = it->shortcut();
3373                         Index const * index = indiceslist.findShortcut(current_index);
3374                         string const x11hexname = X11hexname(index->color());
3375                         // display the new color
3376                         docstring const str = current_index + ' ' + from_ascii(x11hexname);
3377                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
3378                 }
3379         }
3380         // FIXME LFUN
3381         // If we used an LFUN, we would not need these two lines:
3382         BufferView * bv = const_cast<BufferView *>(bufferview());
3383         bv->processUpdateFlags(Update::Force | Update::FitCursor);
3384 }
3385
3386
3387 void GuiDocument::setLanguage() const
3388 {
3389         Language const * const newL = bp_.language;
3390         if (buffer().params().language == newL)
3391                 return;
3392
3393         string const & lang_name = newL->lang();
3394         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
3395 }
3396
3397
3398 void GuiDocument::saveAsDefault() const
3399 {
3400         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
3401 }
3402
3403
3404 bool GuiDocument::isFontAvailable(string const & font) const
3405 {
3406         if (font == "default" || font == "cmr"
3407             || font == "cmss" || font == "cmtt")
3408                 // these are standard
3409                 return true;
3410         if (font == "lmodern" || font == "lmss" || font == "lmtt")
3411                 return LaTeXFeatures::isAvailable("lmodern");
3412         if (font == "times" || font == "palatino"
3413                  || font == "helvet" || font == "courier")
3414                 return LaTeXFeatures::isAvailable("psnfss");
3415         if (font == "cmbr" || font == "cmtl")
3416                 return LaTeXFeatures::isAvailable("cmbright");
3417         if (font == "utopia")
3418                 return LaTeXFeatures::isAvailable("utopia")
3419                         || LaTeXFeatures::isAvailable("fourier");
3420         if (font == "beraserif" || font == "berasans"
3421                 || font == "beramono")
3422                 return LaTeXFeatures::isAvailable("bera");
3423         return LaTeXFeatures::isAvailable(font);
3424 }
3425
3426
3427 bool GuiDocument::providesOSF(string const & font) const
3428 {
3429         if (fontModule->osFontsCB->isChecked())
3430                 // FIXME: we should check if the fonts really
3431                 // have OSF support. But how?
3432                 return true;
3433         if (font == "cmr")
3434                 return isFontAvailable("eco");
3435         if (font == "palatino")
3436                 return isFontAvailable("mathpazo");
3437         return false;
3438 }
3439
3440
3441 bool GuiDocument::providesSC(string const & font) const
3442 {
3443         if (fontModule->osFontsCB->isChecked())
3444                 return false;
3445         if (font == "palatino")
3446                 return isFontAvailable("mathpazo");
3447         if (font == "utopia")
3448                 return isFontAvailable("fourier");
3449         return false;
3450 }
3451
3452
3453 bool GuiDocument::providesScale(string const & font) const
3454 {
3455         if (fontModule->osFontsCB->isChecked())
3456                 return true;
3457         return font == "helvet" || font == "luximono"
3458                 || font == "berasans"  || font == "beramono";
3459 }
3460
3461
3462 void GuiDocument::loadModuleInfo()
3463 {
3464         moduleNames_.clear();
3465         LyXModuleList::const_iterator it  = theModuleList.begin();
3466         LyXModuleList::const_iterator end = theModuleList.end();
3467         for (; it != end; ++it) {
3468                 modInfoStruct m;
3469                 m.id = it->getID();
3470                 // FIXME Unicode
3471                 m.name = toqstr(translateIfPossible(from_utf8(it->getName())));
3472                 // this is supposed to give us the first sentence of the description
3473                 // FIXME Unicode
3474                 QString desc =
3475                         toqstr(translateIfPossible(from_utf8(it->getDescription())));
3476                 int const pos = desc.indexOf(".");
3477                 if (pos > 0)
3478                         desc.truncate(pos + 1);
3479                 m.description = desc;
3480                 moduleNames_.push_back(m);
3481         }
3482 }
3483
3484
3485 void GuiDocument::updateUnknownBranches()
3486 {
3487         if (!bufferview())
3488                 return;
3489         list<docstring> used_branches;
3490         buffer().getUsedBranches(used_branches);
3491         list<docstring>::const_iterator it = used_branches.begin();
3492         QStringList unknown_branches;
3493         for (; it != used_branches.end() ; ++it) {
3494                 if (!buffer().params().branchlist().find(*it))
3495                         unknown_branches.append(toqstr(*it));
3496         }
3497         branchesModule->setUnknownBranches(unknown_branches);
3498 }
3499
3500
3501 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
3502 {
3503         map<docstring, docstring>::iterator it = changedBranches_.begin();
3504         for (; it != changedBranches_.end() ; ++it) {
3505                 if (it->second == oldname) {
3506                         // branch has already been renamed
3507                         it->second = newname;
3508                         return;
3509                 }
3510         }
3511         // store new name
3512         changedBranches_[oldname] = newname;
3513 }
3514
3515
3516 void GuiDocument::executeBranchRenaming() const
3517 {
3518         map<docstring, docstring>::const_iterator it = changedBranches_.begin();
3519         for (; it != changedBranches_.end() ; ++it) {
3520                 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
3521                 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
3522         }
3523 }
3524
3525
3526 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
3527
3528
3529 } // namespace frontend
3530 } // namespace lyx
3531
3532 #include "moc_GuiDocument.cpp"