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