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