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