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