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