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