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