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