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