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