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