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