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