]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiDocument.cpp
Fix handling of the add branch textfield in GuiBranches
[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         connect(branchesModule, SIGNAL(okPressed()), this, SLOT(slotOK()));
1293         updateUnknownBranches();
1294
1295
1296         // preamble
1297         preambleModule = new PreambleModule;
1298         connect(preambleModule, SIGNAL(changed()),
1299                 this, SLOT(change_adaptor()));
1300
1301         localLayout = new LocalLayout;
1302         connect(localLayout, SIGNAL(changed()),
1303                 this, SLOT(change_adaptor()));
1304
1305
1306         // bullets
1307         bulletsModule = new BulletsModule;
1308         connect(bulletsModule, SIGNAL(changed()),
1309                 this, SLOT(change_adaptor()));
1310
1311
1312         // Modules
1313         modulesModule = new UiWidget<Ui::ModulesUi>;
1314         modulesModule->availableLV->header()->setVisible(false);
1315         modulesModule->availableLV->header()->setResizeMode(QHeaderView::ResizeToContents);
1316         modulesModule->availableLV->header()->setStretchLastSection(false);
1317         selectionManager =
1318                 new ModuleSelectionManager(modulesModule->availableLV,
1319                         modulesModule->selectedLV,
1320                         modulesModule->addPB, modulesModule->deletePB,
1321                         modulesModule->upPB, modulesModule->downPB,
1322                         availableModel(), selectedModel(), this);
1323         connect(selectionManager, SIGNAL(updateHook()),
1324                 this, SLOT(updateModuleInfo()));
1325         connect(selectionManager, SIGNAL(updateHook()),
1326                 this, SLOT(change_adaptor()));
1327         connect(selectionManager, SIGNAL(selectionChanged()),
1328                 this, SLOT(modulesChanged()));
1329
1330
1331         // PDF support
1332         pdfSupportModule = new UiWidget<Ui::PDFSupportUi>;
1333         connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
1334                 this, SLOT(change_adaptor()));
1335         connect(pdfSupportModule->titleLE, SIGNAL(textChanged(QString)),
1336                 this, SLOT(change_adaptor()));
1337         connect(pdfSupportModule->authorLE, SIGNAL(textChanged(QString)),
1338                 this, SLOT(change_adaptor()));
1339         connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(QString)),
1340                 this, SLOT(change_adaptor()));
1341         connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(QString)),
1342                 this, SLOT(change_adaptor()));
1343         connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
1344                 this, SLOT(change_adaptor()));
1345         connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
1346                 this, SLOT(change_adaptor()));
1347         connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
1348                 this, SLOT(change_adaptor()));
1349         connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
1350                 this, SLOT(change_adaptor()));
1351         connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
1352                 this, SLOT(change_adaptor()));
1353         connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
1354                 this, SLOT(change_adaptor()));
1355         connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
1356                 this, SLOT(change_adaptor()));
1357         connect(pdfSupportModule->backrefCO, SIGNAL(activated(int)),
1358                 this, SLOT(change_adaptor()));
1359         connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
1360                 this, SLOT(change_adaptor()));
1361         connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
1362                 this, SLOT(change_adaptor()));
1363         connect(pdfSupportModule->optionsLE, SIGNAL(textChanged(QString)),
1364                 this, SLOT(change_adaptor()));
1365
1366         pdfSupportModule->titleLE->setValidator(new NoNewLineValidator(
1367                 pdfSupportModule->titleLE));
1368         pdfSupportModule->authorLE->setValidator(new NoNewLineValidator(
1369                 pdfSupportModule->authorLE));
1370         pdfSupportModule->subjectLE->setValidator(new NoNewLineValidator(
1371                 pdfSupportModule->subjectLE));
1372         pdfSupportModule->keywordsLE->setValidator(new NoNewLineValidator(
1373                 pdfSupportModule->keywordsLE));
1374         pdfSupportModule->optionsLE->setValidator(new NoNewLineValidator(
1375                 pdfSupportModule->optionsLE));
1376
1377         for (int i = 0; backref_opts[i][0]; ++i)
1378                 pdfSupportModule->backrefCO->addItem(qt_(backref_opts_gui[i]));
1379
1380
1381         // float
1382         floatModule = new FloatPlacement;
1383         connect(floatModule, SIGNAL(changed()),
1384                 this, SLOT(change_adaptor()));
1385
1386
1387         // listings
1388         listingsModule = new UiWidget<Ui::ListingsSettingsUi>;
1389         connect(listingsModule->listingsED, SIGNAL(textChanged()),
1390                 this, SLOT(change_adaptor()));
1391         connect(listingsModule->bypassCB, SIGNAL(clicked()),
1392                 this, SLOT(change_adaptor()));
1393         connect(listingsModule->bypassCB, SIGNAL(clicked()),
1394                 this, SLOT(setListingsMessage()));
1395         connect(listingsModule->listingsED, SIGNAL(textChanged()),
1396                 this, SLOT(setListingsMessage()));
1397         listingsModule->listingsTB->setPlainText(
1398                 qt_("Input listings parameters below. Enter ? for a list of parameters."));
1399
1400
1401         // add the panels
1402         docPS->addPanel(latexModule, qt_("Document Class"));
1403         docPS->addPanel(masterChildModule, qt_("Child Documents"));
1404         docPS->addPanel(modulesModule, qt_("Modules"));
1405         docPS->addPanel(localLayout, qt_("Local Layout"));
1406         docPS->addPanel(fontModule, qt_("Fonts"));
1407         docPS->addPanel(textLayoutModule, qt_("Text Layout"));
1408         docPS->addPanel(pageLayoutModule, qt_("Page Layout"));
1409         docPS->addPanel(marginsModule, qt_("Page Margins"));
1410         docPS->addPanel(langModule, qt_("Language"));
1411         docPS->addPanel(colorModule, qt_("Colors"));
1412         docPS->addPanel(numberingModule, qt_("Numbering & TOC"));
1413         docPS->addPanel(biblioModule, qt_("Bibliography"));
1414         docPS->addPanel(indicesModule, qt_("Indexes"));
1415         docPS->addPanel(pdfSupportModule, qt_("PDF Properties"));
1416         docPS->addPanel(mathsModule, qt_("Math Options"));
1417         docPS->addPanel(floatModule, qt_("Float Placement"));
1418         docPS->addPanel(listingsModule, qt_("Listings"));
1419         docPS->addPanel(bulletsModule, qt_("Bullets"));
1420         docPS->addPanel(branchesModule, qt_("Branches"));
1421         docPS->addPanel(outputModule, qt_("Output"));
1422         docPS->addPanel(preambleModule, qt_("LaTeX Preamble"));
1423         docPS->setCurrentPanel(qt_("Document Class"));
1424 // FIXME: hack to work around resizing bug in Qt >= 4.2
1425 // bug verified with Qt 4.2.{0-3} (JSpitzm)
1426 #if QT_VERSION >= 0x040200
1427         docPS->updateGeometry();
1428 #endif
1429 }
1430
1431
1432 void GuiDocument::saveDefaultClicked()
1433 {
1434         saveDocDefault();
1435 }
1436
1437
1438 void GuiDocument::useDefaultsClicked()
1439 {
1440         useClassDefaults();
1441 }
1442
1443
1444 void GuiDocument::change_adaptor()
1445 {
1446         changed();
1447 }
1448
1449
1450 void GuiDocument::includeonlyClicked(QTreeWidgetItem * item, int)
1451 {
1452         if (item == 0)
1453                 return;
1454
1455         string child = fromqstr(item->text(0));
1456         if (child.empty())
1457                 return;
1458
1459         if (std::find(includeonlys_.begin(),
1460                       includeonlys_.end(), child) != includeonlys_.end())
1461                 includeonlys_.remove(child);
1462         else
1463                 includeonlys_.push_back(child);
1464
1465         updateIncludeonlys();
1466         changed();
1467 }
1468
1469
1470 QString GuiDocument::validateListingsParameters()
1471 {
1472         // use a cache here to avoid repeated validation
1473         // of the same parameters
1474         static string param_cache;
1475         static QString msg_cache;
1476
1477         if (listingsModule->bypassCB->isChecked())
1478                 return QString();
1479
1480         string params = fromqstr(listingsModule->listingsED->toPlainText());
1481         if (params != param_cache) {
1482                 param_cache = params;
1483                 msg_cache = toqstr(InsetListingsParams(params).validate());
1484         }
1485         return msg_cache;
1486 }
1487
1488
1489 void GuiDocument::setListingsMessage()
1490 {
1491         static bool isOK = true;
1492         QString msg = validateListingsParameters();
1493         if (msg.isEmpty()) {
1494                 if (isOK)
1495                         return;
1496                 isOK = true;
1497                 // listingsTB->setTextColor("black");
1498                 listingsModule->listingsTB->setPlainText(
1499                         qt_("Input listings parameters below. "
1500                 "Enter ? for a list of parameters."));
1501         } else {
1502                 isOK = false;
1503                 // listingsTB->setTextColor("red");
1504                 listingsModule->listingsTB->setPlainText(msg);
1505         }
1506 }
1507
1508
1509 void GuiDocument::setLSpacing(int item)
1510 {
1511         textLayoutModule->lspacingLE->setEnabled(item == 3);
1512 }
1513
1514
1515 void GuiDocument::setIndent(int item)
1516 {
1517         bool const enable = (item == 1);
1518         textLayoutModule->indentLE->setEnabled(enable);
1519         textLayoutModule->indentLengthCO->setEnabled(enable);
1520         textLayoutModule->skipLE->setEnabled(false);
1521         textLayoutModule->skipLengthCO->setEnabled(false);
1522         isValid();
1523 }
1524
1525
1526 void GuiDocument::enableIndent(bool indent)
1527 {
1528         textLayoutModule->skipLE->setEnabled(!indent);
1529         textLayoutModule->skipLengthCO->setEnabled(!indent);
1530         if (indent)
1531                 setIndent(textLayoutModule->indentCO->currentIndex());
1532 }
1533
1534
1535 void GuiDocument::setSkip(int item)
1536 {
1537         bool const enable = (item == 3);
1538         textLayoutModule->skipLE->setEnabled(enable);
1539         textLayoutModule->skipLengthCO->setEnabled(enable);
1540         isValid();
1541 }
1542
1543
1544 void GuiDocument::enableSkip(bool skip)
1545 {
1546         textLayoutModule->indentLE->setEnabled(!skip);
1547         textLayoutModule->indentLengthCO->setEnabled(!skip);
1548         if (skip)
1549                 setSkip(textLayoutModule->skipCO->currentIndex());
1550 }
1551
1552
1553 void GuiDocument::setMargins()
1554 {
1555         bool const extern_geometry =
1556                 documentClass().provides("geometry");
1557         marginsModule->marginCB->setEnabled(!extern_geometry);
1558         if (extern_geometry) {
1559                 marginsModule->marginCB->setChecked(false);
1560                 setCustomMargins(true);
1561         } else {
1562                 marginsModule->marginCB->setChecked(!bp_.use_geometry);
1563                 setCustomMargins(!bp_.use_geometry);
1564         }
1565 }
1566
1567
1568 void GuiDocument::papersizeChanged(int paper_size)
1569 {
1570         setCustomPapersize(paper_size == 1);
1571 }
1572
1573
1574 void GuiDocument::setCustomPapersize(bool custom)
1575 {
1576         pageLayoutModule->paperwidthL->setEnabled(custom);
1577         pageLayoutModule->paperwidthLE->setEnabled(custom);
1578         pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
1579         pageLayoutModule->paperheightL->setEnabled(custom);
1580         pageLayoutModule->paperheightLE->setEnabled(custom);
1581         pageLayoutModule->paperheightLE->setFocus();
1582         pageLayoutModule->paperheightUnitCO->setEnabled(custom);
1583 }
1584
1585
1586 void GuiDocument::setColSep()
1587 {
1588         setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
1589 }
1590
1591
1592 void GuiDocument::setCustomMargins(bool custom)
1593 {
1594         marginsModule->topL->setEnabled(!custom);
1595         marginsModule->topLE->setEnabled(!custom);
1596         marginsModule->topUnit->setEnabled(!custom);
1597
1598         marginsModule->bottomL->setEnabled(!custom);
1599         marginsModule->bottomLE->setEnabled(!custom);
1600         marginsModule->bottomUnit->setEnabled(!custom);
1601
1602         marginsModule->innerL->setEnabled(!custom);
1603         marginsModule->innerLE->setEnabled(!custom);
1604         marginsModule->innerUnit->setEnabled(!custom);
1605
1606         marginsModule->outerL->setEnabled(!custom);
1607         marginsModule->outerLE->setEnabled(!custom);
1608         marginsModule->outerUnit->setEnabled(!custom);
1609
1610         marginsModule->headheightL->setEnabled(!custom);
1611         marginsModule->headheightLE->setEnabled(!custom);
1612         marginsModule->headheightUnit->setEnabled(!custom);
1613
1614         marginsModule->headsepL->setEnabled(!custom);
1615         marginsModule->headsepLE->setEnabled(!custom);
1616         marginsModule->headsepUnit->setEnabled(!custom);
1617
1618         marginsModule->footskipL->setEnabled(!custom);
1619         marginsModule->footskipLE->setEnabled(!custom);
1620         marginsModule->footskipUnit->setEnabled(!custom);
1621
1622         bool const enableColSep = !custom &&
1623                         textLayoutModule->twoColumnCB->checkState() == Qt::Checked;
1624         marginsModule->columnsepL->setEnabled(enableColSep);
1625         marginsModule->columnsepLE->setEnabled(enableColSep);
1626         marginsModule->columnsepUnit->setEnabled(enableColSep);
1627 }
1628
1629
1630 void GuiDocument::changeBackgroundColor()
1631 {
1632         QColor const & newColor = QColorDialog::getColor(
1633                 rgb2qcolor(set_backgroundcolor), asQWidget());
1634         if (!newColor.isValid())
1635                 return;
1636         // set the button color and text
1637         colorModule->backgroundPB->setStyleSheet(
1638                 colorButtonStyleSheet(newColor));
1639         colorModule->backgroundPB->setText(qt_("&Change..."));
1640         // save color
1641         set_backgroundcolor = rgbFromHexName(fromqstr(newColor.name()));
1642         is_backgroundcolor = true;
1643         changed();
1644 }
1645
1646
1647 void GuiDocument::deleteBackgroundColor()
1648 {
1649         // set the button color back to default by setting an empty StyleSheet
1650         colorModule->backgroundPB->setStyleSheet(QLatin1String(""));
1651         // change button text
1652         colorModule->backgroundPB->setText(qt_("&Default..."));
1653         // save default color (white)
1654         set_backgroundcolor = rgbFromHexName("#ffffff");
1655         is_backgroundcolor = false;
1656         changed();
1657 }
1658
1659
1660 void GuiDocument::changeFontColor()
1661 {
1662         QColor const & newColor = QColorDialog::getColor(
1663                 rgb2qcolor(set_fontcolor), asQWidget());
1664         if (!newColor.isValid())
1665                 return;
1666         // set the button color and text
1667         colorModule->fontColorPB->setStyleSheet(
1668                 colorButtonStyleSheet(newColor));
1669         colorModule->fontColorPB->setText(qt_("&Change..."));
1670         // save color
1671         set_fontcolor = rgbFromHexName(fromqstr(newColor.name()));
1672         is_fontcolor = true;
1673         changed();
1674 }
1675
1676
1677 void GuiDocument::deleteFontColor()
1678 {
1679         // set the button color back to default by setting an empty StyleSheet
1680         colorModule->fontColorPB->setStyleSheet(QLatin1String(""));
1681         // change button text
1682         colorModule->fontColorPB->setText(qt_("&Default..."));
1683         // save default color (black)
1684         set_fontcolor = rgbFromHexName("#000000");
1685         is_fontcolor = false;
1686         changed();
1687 }
1688
1689
1690 void GuiDocument::changeNoteFontColor()
1691 {
1692         QColor const & newColor = QColorDialog::getColor(
1693                 rgb2qcolor(set_notefontcolor), asQWidget());
1694         if (!newColor.isValid())
1695                 return;
1696         // set the button color
1697         colorModule->noteFontColorPB->setStyleSheet(
1698                 colorButtonStyleSheet(newColor));
1699         // save color
1700         set_notefontcolor = rgbFromHexName(fromqstr(newColor.name()));
1701         changed();
1702 }
1703
1704
1705 void GuiDocument::deleteNoteFontColor()
1706 {
1707         // set the button color back to pref
1708         theApp()->getRgbColor(Color_greyedouttext, set_notefontcolor);
1709         colorModule->noteFontColorPB->setStyleSheet(
1710                 colorButtonStyleSheet(rgb2qcolor(set_notefontcolor)));
1711         changed();
1712 }
1713
1714
1715 void GuiDocument::changeBoxBackgroundColor()
1716 {
1717         QColor const & newColor = QColorDialog::getColor(
1718                 rgb2qcolor(set_boxbgcolor), asQWidget());
1719         if (!newColor.isValid())
1720                 return;
1721         // set the button color
1722         colorModule->boxBackgroundPB->setStyleSheet(
1723                 colorButtonStyleSheet(newColor));
1724         // save color
1725         set_boxbgcolor = rgbFromHexName(fromqstr(newColor.name()));
1726         changed();
1727 }
1728
1729
1730 void GuiDocument::deleteBoxBackgroundColor()
1731 {
1732         // set the button color back to pref
1733         theApp()->getRgbColor(Color_shadedbg, set_boxbgcolor);
1734         colorModule->boxBackgroundPB->setStyleSheet(
1735                 colorButtonStyleSheet(rgb2qcolor(set_boxbgcolor)));
1736         changed();
1737 }
1738
1739
1740 void GuiDocument::osFontsChanged(bool nontexfonts)
1741 {
1742         bool const tex_fonts = !nontexfonts;
1743         updateFontlist();
1744         updateDefaultFormat();
1745         langModule->encodingCO->setEnabled(tex_fonts &&
1746                 !langModule->defaultencodingRB->isChecked());
1747         langModule->defaultencodingRB->setEnabled(tex_fonts);
1748         langModule->otherencodingRB->setEnabled(tex_fonts);
1749
1750         fontModule->fontsDefaultCO->setEnabled(tex_fonts);
1751         fontModule->fontsDefaultLA->setEnabled(tex_fonts);
1752         fontModule->cjkFontLE->setEnabled(tex_fonts);
1753         fontModule->cjkFontLA->setEnabled(tex_fonts);
1754         string font;
1755         if (tex_fonts)
1756                 font = tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1757         bool scaleable = providesScale(font);
1758         fontModule->scaleSansSB->setEnabled(scaleable);
1759         fontModule->scaleSansLA->setEnabled(scaleable);
1760         if (tex_fonts)
1761                 font = tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1762         scaleable = providesScale(font);
1763         fontModule->scaleTypewriterSB->setEnabled(scaleable);
1764         fontModule->scaleTypewriterLA->setEnabled(scaleable);
1765         if (tex_fonts)
1766                 font = tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1767         fontModule->fontScCB->setEnabled(providesSC(font));
1768         fontModule->fontOsfCB->setEnabled(providesOSF(font));
1769
1770         fontModule->fontencLA->setEnabled(tex_fonts);
1771         fontModule->fontencCO->setEnabled(tex_fonts);
1772         if (!tex_fonts)
1773                 fontModule->fontencLE->setEnabled(false);
1774         else
1775                 fontencChanged(fontModule->fontencCO->currentIndex());
1776 }
1777
1778
1779 void GuiDocument::updateFontsize(string const & items, string const & sel)
1780 {
1781         fontModule->fontsizeCO->clear();
1782         fontModule->fontsizeCO->addItem(qt_("Default"));
1783
1784         for (int n = 0; !token(items,'|',n).empty(); ++n)
1785                 fontModule->fontsizeCO->
1786                         addItem(toqstr(token(items,'|',n)));
1787
1788         for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
1789                 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
1790                         fontModule->fontsizeCO->setCurrentIndex(n);
1791                         break;
1792                 }
1793         }
1794 }
1795
1796
1797 void GuiDocument::updateFontlist()
1798 {
1799         fontModule->fontsRomanCO->clear();
1800         fontModule->fontsSansCO->clear();
1801         fontModule->fontsTypewriterCO->clear();
1802
1803         // With XeTeX, we have access to all system fonts, but not the LaTeX fonts
1804         if (fontModule->osFontsCB->isChecked()) {
1805                 fontModule->fontsRomanCO->addItem(qt_("Default"), QString("default"));
1806                 fontModule->fontsSansCO->addItem(qt_("Default"), QString("default"));
1807                 fontModule->fontsTypewriterCO->addItem(qt_("Default"), QString("default"));
1808
1809                 QFontDatabase fontdb;
1810                 QStringList families(fontdb.families());
1811                 for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
1812                         fontModule->fontsRomanCO->addItem(*it, *it);
1813                         fontModule->fontsSansCO->addItem(*it, *it);
1814                         fontModule->fontsTypewriterCO->addItem(*it, *it);
1815                 }
1816                 return;
1817         }
1818
1819         for (int n = 0; tex_fonts_roman[n][0]; ++n) {
1820                 QString font = qt_(tex_fonts_roman_gui[n]);
1821                 if (!isFontAvailable(tex_fonts_roman[n]))
1822                         font += qt_(" (not installed)");
1823                 fontModule->fontsRomanCO->addItem(font, qt_(tex_fonts_roman[n]));
1824         }
1825         for (int n = 0; tex_fonts_sans[n][0]; ++n) {
1826                 QString font = qt_(tex_fonts_sans_gui[n]);
1827                 if (!isFontAvailable(tex_fonts_sans[n]))
1828                         font += qt_(" (not installed)");
1829                 fontModule->fontsSansCO->addItem(font, qt_(tex_fonts_sans[n]));
1830         }
1831         for (int n = 0; tex_fonts_monospaced[n][0]; ++n) {
1832                 QString font = qt_(tex_fonts_monospaced_gui[n]);
1833                 if (!isFontAvailable(tex_fonts_monospaced[n]))
1834                         font += qt_(" (not installed)");
1835                 fontModule->fontsTypewriterCO->addItem(font, qt_(tex_fonts_monospaced[n]));
1836         }
1837 }
1838
1839
1840 void GuiDocument::fontencChanged(int item)
1841 {
1842         fontModule->fontencLE->setEnabled(item == 1);
1843 }
1844
1845
1846 void GuiDocument::romanChanged(int item)
1847 {
1848         if (fontModule->osFontsCB->isChecked())
1849                 return;
1850         string const font = tex_fonts_roman[item];
1851         fontModule->fontScCB->setEnabled(providesSC(font));
1852         fontModule->fontOsfCB->setEnabled(providesOSF(font));
1853 }
1854
1855
1856 void GuiDocument::sansChanged(int item)
1857 {
1858         if (fontModule->osFontsCB->isChecked())
1859                 return;
1860         string const font = tex_fonts_sans[item];
1861         bool scaleable = providesScale(font);
1862         fontModule->scaleSansSB->setEnabled(scaleable);
1863         fontModule->scaleSansLA->setEnabled(scaleable);
1864 }
1865
1866
1867 void GuiDocument::ttChanged(int item)
1868 {
1869         if (fontModule->osFontsCB->isChecked())
1870                 return;
1871         string const font = tex_fonts_monospaced[item];
1872         bool scaleable = providesScale(font);
1873         fontModule->scaleTypewriterSB->setEnabled(scaleable);
1874         fontModule->scaleTypewriterLA->setEnabled(scaleable);
1875 }
1876
1877
1878 void GuiDocument::updatePagestyle(string const & items, string const & sel)
1879 {
1880         pagestyles.clear();
1881         pageLayoutModule->pagestyleCO->clear();
1882         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1883
1884         for (int n = 0; !token(items, '|', n).empty(); ++n) {
1885                 string style = token(items, '|', n);
1886                 QString style_gui = qt_(style);
1887                 pagestyles.push_back(pair<string, QString>(style, style_gui));
1888                 pageLayoutModule->pagestyleCO->addItem(style_gui);
1889         }
1890
1891         if (sel == "default") {
1892                 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
1893                 return;
1894         }
1895
1896         int nn = 0;
1897
1898         for (size_t i = 0; i < pagestyles.size(); ++i)
1899                 if (pagestyles[i].first == sel)
1900                         nn = pageLayoutModule->pagestyleCO->findText(pagestyles[i].second);
1901
1902         if (nn > 0)
1903                 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
1904 }
1905
1906
1907 void GuiDocument::browseLayout()
1908 {
1909         QString const label1 = qt_("Layouts|#o#O");
1910         QString const dir1 = toqstr(lyxrc.document_path);
1911         QStringList const filter(qt_("LyX Layout (*.layout)"));
1912         QString file = browseRelToParent(QString(), bufferFilePath(),
1913                 qt_("Local layout file"), filter, false,
1914                 label1, dir1);
1915
1916         if (!file.endsWith(".layout"))
1917                 return;
1918
1919         FileName layoutFile = support::makeAbsPath(fromqstr(file),
1920                 fromqstr(bufferFilePath()));
1921
1922         int const ret = Alert::prompt(_("Local layout file"),
1923                 _("The layout file you have selected is a local layout\n"
1924                   "file, not one in the system or user directory. Your\n"
1925                   "document may not work with this layout if you do not\n"
1926                   "keep the layout file in the document directory."),
1927                   1, 1, _("&Set Layout"), _("&Cancel"));
1928         if (ret == 1)
1929                 return;
1930
1931         // load the layout file
1932         LayoutFileList & bcl = LayoutFileList::get();
1933         string classname = layoutFile.onlyFileName();
1934         // this will update an existing layout if that layout has been loaded before.
1935         LayoutFileIndex name = bcl.addLocalLayout(
1936                 classname.substr(0, classname.size() - 7),
1937                 layoutFile.onlyPath().absFileName());
1938
1939         if (name.empty()) {
1940                 Alert::error(_("Error"),
1941                         _("Unable to read local layout file."));
1942                 return;
1943         }
1944
1945         // do not trigger classChanged if there is no change.
1946         if (latexModule->classCO->currentText() == toqstr(name))
1947                 return;
1948
1949         // add to combo box
1950         int idx = latexModule->classCO->findText(toqstr(name));
1951         if (idx == -1) {
1952                 classes_model_.insertRow(0, toqstr(name), name);
1953                 latexModule->classCO->setCurrentIndex(0);
1954         } else
1955                 latexModule->classCO->setCurrentIndex(idx);
1956
1957         classChanged();
1958 }
1959
1960
1961 void GuiDocument::browseMaster()
1962 {
1963         QString const title = qt_("Select master document");
1964         QString const dir1 = toqstr(lyxrc.document_path);
1965         QString const old = latexModule->childDocLE->text();
1966         QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
1967         QStringList const filter(qt_("LyX Files (*.lyx)"));
1968         QString file = browseRelToSub(old, docpath, title, filter, false,
1969                 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
1970
1971         if (!file.isEmpty())
1972                 latexModule->childDocLE->setText(file);
1973 }
1974
1975
1976 void GuiDocument::classChanged()
1977 {
1978         int idx = latexModule->classCO->currentIndex();
1979         if (idx < 0)
1980                 return;
1981         string const classname = classes_model_.getIDString(idx);
1982
1983         // check whether the selected modules have changed.
1984         bool modules_changed = false;
1985         unsigned int const srows = selectedModel()->rowCount();
1986         if (srows != bp_.getModules().size())
1987                 modules_changed = true;
1988         else {
1989                 list<string>::const_iterator mit = bp_.getModules().begin();
1990                 list<string>::const_iterator men = bp_.getModules().end();
1991                 for (unsigned int i = 0; i < srows && mit != men; ++i, ++mit)
1992                         if (selectedModel()->getIDString(i) != *mit) {
1993                                 modules_changed = true;
1994                                 break;
1995                         }
1996         }
1997
1998         if (modules_changed || lyxrc.auto_reset_options) {
1999                 if (applyPB->isEnabled()) {
2000                         int const ret = Alert::prompt(_("Unapplied changes"),
2001                                         _("Some changes in the dialog were not yet applied.\n"
2002                                         "If you do not apply now, they will be lost after this action."),
2003                                         1, 1, _("&Apply"), _("&Dismiss"));
2004                         if (ret == 0)
2005                                 applyView();
2006                 }
2007         }
2008
2009         // We load the TextClass as soon as it is selected. This is
2010         // necessary so that other options in the dialog can be updated
2011         // according to the new class. Note, however, that, if you use
2012         // the scroll wheel when sitting on the combo box, we'll load a
2013         // lot of TextClass objects very quickly....
2014         if (!bp_.setBaseClass(classname)) {
2015                 Alert::error(_("Error"), _("Unable to set document class."));
2016                 return;
2017         }
2018         if (lyxrc.auto_reset_options)
2019                 bp_.useClassDefaults();
2020
2021         // With the introduction of modules came a distinction between the base
2022         // class and the document class. The former corresponds to the main layout
2023         // file; the latter is that plus the modules (or the document-specific layout,
2024         // or  whatever else there could be). Our parameters come from the document
2025         // class. So when we set the base class, we also need to recreate the document
2026         // class. Otherwise, we still have the old one.
2027         bp_.makeDocumentClass();
2028         paramsToDialog();
2029 }
2030
2031
2032 void GuiDocument::languagePackageChanged(int i)
2033 {
2034          langModule->languagePackageLE->setEnabled(
2035                 langModule->languagePackageCO->itemData(i).toString() == "custom");
2036 }
2037
2038
2039 void GuiDocument::biblioChanged()
2040 {
2041         biblioChanged_ = true;
2042         changed();
2043 }
2044
2045
2046 void GuiDocument::bibtexChanged(int n)
2047 {
2048         biblioModule->bibtexOptionsLE->setEnabled(
2049                 biblioModule->bibtexCO->itemData(n).toString() != "default");
2050         biblioChanged();
2051 }
2052
2053
2054 void GuiDocument::setAuthorYear(bool authoryear)
2055 {
2056         if (authoryear)
2057                 biblioModule->citeStyleCO->setCurrentIndex(0);
2058         biblioChanged();
2059 }
2060
2061
2062 void GuiDocument::setNumerical(bool numerical)
2063 {
2064         if (numerical)
2065                 biblioModule->citeStyleCO->setCurrentIndex(1);
2066         biblioChanged();
2067 }
2068
2069
2070 void GuiDocument::updateEngineType(string const & items, CiteEngineType const & sel)
2071 {
2072         engine_types_.clear();
2073
2074         int nn = 0;
2075
2076         for (int n = 0; !token(items, '|', n).empty(); ++n) {
2077                 nn += 1;
2078                 string style = token(items, '|', n);
2079                 engine_types_.push_back(style);
2080         }
2081
2082         switch (sel) {
2083                 case ENGINE_TYPE_AUTHORYEAR:
2084                         biblioModule->citeStyleCO->setCurrentIndex(0);
2085                         break;
2086                 case ENGINE_TYPE_NUMERICAL:
2087                         biblioModule->citeStyleCO->setCurrentIndex(1);
2088                         break;
2089         }
2090
2091         biblioModule->citationStyleL->setEnabled(nn > 1);
2092         biblioModule->citeStyleCO->setEnabled(nn > 1);
2093
2094         if (nn != 1)
2095                 return;
2096
2097         // If the textclass allows only one of authoryear or numerical,
2098         // we have no choice but to force that engine type.
2099         if (engine_types_[0] == "authoryear")
2100                 biblioModule->citeStyleCO->setCurrentIndex(0);
2101         else
2102                 biblioModule->citeStyleCO->setCurrentIndex(1);
2103 }
2104
2105
2106 namespace {
2107         // FIXME unicode
2108         // both of these should take a vector<docstring>
2109
2110         // This is an insanely complicated attempt to make this sort of thing
2111         // work with RTL languages.
2112         docstring formatStrVec(vector<string> const & v, docstring const & s)
2113         {
2114                 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
2115                 if (v.size() == 0)
2116                         return docstring();
2117                 if (v.size() == 1)
2118                         return translateIfPossible(from_utf8(v[0]));
2119                 if (v.size() == 2) {
2120                         docstring retval = _("%1$s and %2$s");
2121                         retval = subst(retval, _("and"), s);
2122                         return bformat(retval, translateIfPossible(from_utf8(v[0])),
2123                                        translateIfPossible(from_utf8(v[1])));
2124                 }
2125                 // The idea here is to format all but the last two items...
2126                 int const vSize = v.size();
2127                 docstring t2 = _("%1$s, %2$s");
2128                 docstring retval = translateIfPossible(from_utf8(v[0]));
2129                 for (int i = 1; i < vSize - 2; ++i)
2130                         retval = bformat(t2, retval, translateIfPossible(from_utf8(v[i])));
2131                 //...and then to  plug them, and the last two, into this schema
2132                 docstring t = _("%1$s, %2$s, and %3$s");
2133                 t = subst(t, _("and"), s);
2134                 return bformat(t, retval, translateIfPossible(from_utf8(v[vSize - 2])),
2135                                translateIfPossible(from_utf8(v[vSize - 1])));
2136         }
2137
2138         vector<string> idsToNames(vector<string> const & idList)
2139         {
2140                 vector<string> retval;
2141                 vector<string>::const_iterator it  = idList.begin();
2142                 vector<string>::const_iterator end = idList.end();
2143                 for (; it != end; ++it) {
2144                         LyXModule const * const mod = theModuleList[*it];
2145                         if (!mod)
2146                                 retval.push_back(to_utf8(bformat(_("%1$s (unavailable)"),
2147                                                 translateIfPossible(from_utf8(*it)))));
2148                         else
2149                                 retval.push_back(mod->getName());
2150                 }
2151                 return retval;
2152         }
2153 } // end anonymous namespace
2154
2155
2156 void GuiDocument::modulesToParams(BufferParams & bp)
2157 {
2158         // update list of loaded modules
2159         bp.clearLayoutModules();
2160         int const srows = modules_sel_model_.rowCount();
2161         for (int i = 0; i < srows; ++i)
2162                 bp.addLayoutModule(modules_sel_model_.getIDString(i));
2163
2164         // update the list of removed modules
2165         bp.clearRemovedModules();
2166         LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
2167         list<string>::const_iterator rit = reqmods.begin();
2168         list<string>::const_iterator ren = reqmods.end();
2169
2170         // check each of the default modules
2171         for (; rit != ren; rit++) {
2172                 list<string>::const_iterator mit = bp.getModules().begin();
2173                 list<string>::const_iterator men = bp.getModules().end();
2174                 bool found = false;
2175                 for (; mit != men; mit++) {
2176                         if (*rit == *mit) {
2177                                 found = true;
2178                                 break;
2179                         }
2180                 }
2181                 if (!found) {
2182                         // the module isn't present so must have been removed by the user
2183                         bp.addRemovedModule(*rit);
2184                 }
2185         }
2186 }
2187
2188 void GuiDocument::modulesChanged()
2189 {
2190         modulesToParams(bp_);
2191         bp_.makeDocumentClass();
2192         paramsToDialog();
2193 }
2194
2195
2196 void GuiDocument::updateModuleInfo()
2197 {
2198         selectionManager->update();
2199
2200         //Module description
2201         bool const focus_on_selected = selectionManager->selectedFocused();
2202         QAbstractItemView * lv;
2203         if (focus_on_selected)
2204                 lv = modulesModule->selectedLV;
2205         else
2206                 lv= modulesModule->availableLV;
2207         if (lv->selectionModel()->selectedIndexes().isEmpty()) {
2208                 modulesModule->infoML->document()->clear();
2209                 return;
2210         }
2211         QModelIndex const & idx = lv->selectionModel()->currentIndex();
2212         GuiIdListModel const & id_model =
2213                         focus_on_selected  ? modules_sel_model_ : modules_av_model_;
2214         string const modName = id_model.getIDString(idx.row());
2215         docstring desc = getModuleDescription(modName);
2216
2217         LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
2218         if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
2219                 if (!desc.empty())
2220                         desc += "\n";
2221                 desc += _("Module provided by document class.");
2222         }
2223
2224         vector<string> pkglist = getPackageList(modName);
2225         docstring pkgdesc = formatStrVec(pkglist, _("and"));
2226         if (!pkgdesc.empty()) {
2227                 if (!desc.empty())
2228                         desc += "\n";
2229                 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
2230         }
2231
2232         pkglist = getRequiredList(modName);
2233         if (!pkglist.empty()) {
2234                 vector<string> const reqdescs = idsToNames(pkglist);
2235                 pkgdesc = formatStrVec(reqdescs, _("or"));
2236                 if (!desc.empty())
2237                         desc += "\n";
2238                 desc += bformat(_("Modules required: %1$s."), pkgdesc);
2239         }
2240
2241         pkglist = getExcludedList(modName);
2242         if (!pkglist.empty()) {
2243                 vector<string> const reqdescs = idsToNames(pkglist);
2244                 pkgdesc = formatStrVec(reqdescs, _( "and"));
2245                 if (!desc.empty())
2246                         desc += "\n";
2247                 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
2248         }
2249
2250         if (!isModuleAvailable(modName)) {
2251                 if (!desc.empty())
2252                         desc += "\n";
2253                 desc += _("WARNING: Some required packages are unavailable!");
2254         }
2255
2256         modulesModule->infoML->document()->setPlainText(toqstr(desc));
2257 }
2258
2259
2260 void GuiDocument::updateNumbering()
2261 {
2262         DocumentClass const & tclass = documentClass();
2263
2264         numberingModule->tocTW->setUpdatesEnabled(false);
2265         numberingModule->tocTW->clear();
2266
2267         int const depth = numberingModule->depthSL->value();
2268         int const toc = numberingModule->tocSL->value();
2269         QString const no = qt_("No");
2270         QString const yes = qt_("Yes");
2271         QTreeWidgetItem * item = 0;
2272
2273         DocumentClass::const_iterator lit = tclass.begin();
2274         DocumentClass::const_iterator len = tclass.end();
2275         for (; lit != len; ++lit) {
2276                 int const toclevel = lit->toclevel;
2277                 if (toclevel != Layout::NOT_IN_TOC && lit->labeltype == LABEL_COUNTER) {
2278                         item = new QTreeWidgetItem(numberingModule->tocTW);
2279                         item->setText(0, toqstr(translateIfPossible(lit->name())));
2280                         item->setText(1, (toclevel <= depth) ? yes : no);
2281                         item->setText(2, (toclevel <= toc) ? yes : no);
2282                 }
2283         }
2284
2285         numberingModule->tocTW->setUpdatesEnabled(true);
2286         numberingModule->tocTW->update();
2287 }
2288
2289
2290 void GuiDocument::updateDefaultFormat()
2291 {
2292         if (!bufferview())
2293                 return;
2294         // make a copy in order to consider unapplied changes
2295         BufferParams param_copy = buffer().params();
2296         param_copy.useNonTeXFonts = fontModule->osFontsCB->isChecked();
2297         int const idx = latexModule->classCO->currentIndex();
2298         if (idx >= 0) {
2299                 string const classname = classes_model_.getIDString(idx);
2300                 param_copy.setBaseClass(classname);
2301                 param_copy.makeDocumentClass();
2302         }
2303         outputModule->defaultFormatCO->blockSignals(true);
2304         outputModule->defaultFormatCO->clear();
2305         outputModule->defaultFormatCO->addItem(qt_("Default"),
2306                                 QVariant(QString("default")));
2307         typedef vector<Format const *> Formats;
2308         Formats formats = param_copy.exportableFormats(true);
2309         Formats::const_iterator cit = formats.begin();
2310         Formats::const_iterator end = formats.end();
2311         for (; cit != end; ++cit)
2312                 outputModule->defaultFormatCO->addItem(qt_((*cit)->prettyname()),
2313                                 QVariant(toqstr((*cit)->name())));
2314         outputModule->defaultFormatCO->blockSignals(false);
2315 }
2316
2317
2318 bool GuiDocument::isChildIncluded(string const & child)
2319 {
2320         if (includeonlys_.empty())
2321                 return false;
2322         return (std::find(includeonlys_.begin(),
2323                           includeonlys_.end(), child) != includeonlys_.end());
2324 }
2325
2326
2327 void GuiDocument::applyView()
2328 {
2329         // preamble
2330         preambleModule->apply(bp_);
2331         localLayout->apply(bp_);
2332
2333         // date
2334         bp_.suppress_date = latexModule->suppressDateCB->isChecked();
2335         bp_.use_refstyle  = latexModule->refstyleCB->isChecked();
2336
2337         // biblio
2338         if (biblioModule->citeNatbibRB->isChecked())
2339                 bp_.setCiteEngine("natbib");
2340         else if (biblioModule->citeJurabibRB->isChecked())
2341                 bp_.setCiteEngine("jurabib");
2342         else
2343                 bp_.setCiteEngine("basic");
2344
2345         if (biblioModule->citeStyleCO->currentIndex())
2346                 bp_.setCiteEngineType(ENGINE_TYPE_NUMERICAL);
2347         else
2348                 bp_.setCiteEngineType(ENGINE_TYPE_AUTHORYEAR);
2349
2350         bp_.use_bibtopic =
2351                 biblioModule->bibtopicCB->isChecked();
2352
2353         bp_.biblio_style = fromqstr(biblioModule->bibtexStyleLE->text());
2354
2355         string const bibtex_command =
2356                 fromqstr(biblioModule->bibtexCO->itemData(
2357                         biblioModule->bibtexCO->currentIndex()).toString());
2358         string const bibtex_options =
2359                 fromqstr(biblioModule->bibtexOptionsLE->text());
2360         if (bibtex_command == "default" || bibtex_options.empty())
2361                 bp_.bibtex_command = bibtex_command;
2362         else
2363                 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
2364
2365         if (biblioChanged_) {
2366                 buffer().invalidateBibinfoCache();
2367                 buffer().removeBiblioTempFiles();
2368         }
2369
2370         // Indices
2371         indicesModule->apply(bp_);
2372
2373         // language & quotes
2374         if (langModule->defaultencodingRB->isChecked()) {
2375                 bp_.inputenc = "auto";
2376         } else {
2377                 int i = langModule->encodingCO->currentIndex();
2378                 if (i == 0)
2379                         bp_.inputenc = "default";
2380                 else {
2381                         QString const enc_gui =
2382                                 langModule->encodingCO->currentText();
2383                         Encodings::const_iterator it = encodings.begin();
2384                         Encodings::const_iterator const end = encodings.end();
2385                         bool found = false;
2386                         for (; it != end; ++it) {
2387                                 if (qt_(it->guiName()) == enc_gui) {
2388                                         bp_.inputenc = it->latexName();
2389                                         found = true;
2390                                         break;
2391                                 }
2392                         }
2393                         if (!found) {
2394                                 // should not happen
2395                                 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
2396                                 bp_.inputenc = "default";
2397                         }
2398                 }
2399         }
2400
2401         InsetQuotes::QuoteLanguage lga = InsetQuotes::EnglishQuotes;
2402         switch (langModule->quoteStyleCO->currentIndex()) {
2403         case 0:
2404                 lga = InsetQuotes::EnglishQuotes;
2405                 break;
2406         case 1:
2407                 lga = InsetQuotes::SwedishQuotes;
2408                 break;
2409         case 2:
2410                 lga = InsetQuotes::GermanQuotes;
2411                 break;
2412         case 3:
2413                 lga = InsetQuotes::PolishQuotes;
2414                 break;
2415         case 4:
2416                 lga = InsetQuotes::FrenchQuotes;
2417                 break;
2418         case 5:
2419                 lga = InsetQuotes::DanishQuotes;
2420                 break;
2421         }
2422         bp_.quotes_language = lga;
2423
2424         QString const lang = langModule->languageCO->itemData(
2425                 langModule->languageCO->currentIndex()).toString();
2426         bp_.language = lyx::languages.getLanguage(fromqstr(lang));
2427
2428         QString const pack = langModule->languagePackageCO->itemData(
2429                 langModule->languagePackageCO->currentIndex()).toString();
2430         if (pack == "custom")
2431                 bp_.lang_package =
2432                         fromqstr(langModule->languagePackageLE->text());
2433         else
2434                 bp_.lang_package = fromqstr(pack);
2435
2436         //color
2437         bp_.backgroundcolor = set_backgroundcolor;
2438         bp_.isbackgroundcolor = is_backgroundcolor;
2439         bp_.fontcolor = set_fontcolor;
2440         bp_.isfontcolor = is_fontcolor;
2441         bp_.notefontcolor = set_notefontcolor;
2442         bp_.boxbgcolor = set_boxbgcolor;
2443
2444         // numbering
2445         if (bp_.documentClass().hasTocLevels()) {
2446                 bp_.tocdepth = numberingModule->tocSL->value();
2447                 bp_.secnumdepth = numberingModule->depthSL->value();
2448         }
2449
2450         // bullets
2451         bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
2452         bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
2453         bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
2454         bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
2455
2456         // packages
2457         bp_.graphics_driver =
2458                 tex_graphics[latexModule->psdriverCO->currentIndex()];
2459
2460         // text layout
2461         int idx = latexModule->classCO->currentIndex();
2462         if (idx >= 0) {
2463                 string const classname = classes_model_.getIDString(idx);
2464                 bp_.setBaseClass(classname);
2465         }
2466
2467         // Modules
2468         modulesToParams(bp_);
2469
2470         // Math
2471         vector<string> const & packages = BufferParams::auto_packages();
2472         for (size_t n = 0; n < packages.size(); ++n) {
2473                 QCheckBox * autoCB = static_cast<QCheckBox *>(
2474                         mathsModule->gridLayout->itemAtPosition(2 * n, 0)->widget());
2475                 if (autoCB->isChecked())
2476                         bp_.use_package(packages[n], BufferParams::package_auto);
2477                 else {
2478                         QCheckBox * alwaysCB = static_cast<QCheckBox *>(
2479                                 mathsModule->gridLayout->itemAtPosition(2 * n + 1, 0)->widget());
2480                         if (alwaysCB->isChecked())
2481                                 bp_.use_package(packages[n], BufferParams::package_on);
2482                         else
2483                                 bp_.use_package(packages[n], BufferParams::package_off);
2484                 }
2485         }
2486
2487         // Page Layout
2488         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
2489                 bp_.pagestyle = "default";
2490         else {
2491                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
2492                 for (size_t i = 0; i != pagestyles.size(); ++i)
2493                         if (pagestyles[i].second == style_gui)
2494                                 bp_.pagestyle = pagestyles[i].first;
2495         }
2496
2497         // Text Layout
2498         switch (textLayoutModule->lspacingCO->currentIndex()) {
2499         case 0:
2500                 bp_.spacing().set(Spacing::Single);
2501                 break;
2502         case 1:
2503                 bp_.spacing().set(Spacing::Onehalf);
2504                 break;
2505         case 2:
2506                 bp_.spacing().set(Spacing::Double);
2507                 break;
2508         case 3: {
2509                 string s = widgetToDoubleStr(textLayoutModule->lspacingLE);
2510                 if (s.empty())
2511                         bp_.spacing().set(Spacing::Single);
2512                 else
2513                         bp_.spacing().set(Spacing::Other, s);
2514                 break;
2515                 }
2516         }
2517
2518         if (textLayoutModule->twoColumnCB->isChecked())
2519                 bp_.columns = 2;
2520         else
2521                 bp_.columns = 1;
2522
2523         bp_.justification = textLayoutModule->justCB->isChecked();
2524
2525         if (textLayoutModule->indentRB->isChecked()) {
2526                 // if paragraphs are separated by an indentation
2527                 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
2528                 switch (textLayoutModule->indentCO->currentIndex()) {
2529                 case 0:
2530                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2531                         break;
2532                 case 1: {
2533                         HSpace indent = HSpace(
2534                                 widgetsToLength(textLayoutModule->indentLE,
2535                                 textLayoutModule->indentLengthCO)
2536                                 );
2537                         bp_.setIndentation(indent);
2538                         break;
2539                         }
2540                 default:
2541                         // this should never happen
2542                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2543                         break;
2544                 }
2545         } else {
2546                 // if paragraphs are separated by a skip
2547                 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
2548                 switch (textLayoutModule->skipCO->currentIndex()) {
2549                 case 0:
2550                         bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
2551                         break;
2552                 case 1:
2553                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2554                         break;
2555                 case 2:
2556                         bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
2557                         break;
2558                 case 3:
2559                         {
2560                         VSpace vs = VSpace(
2561                                 widgetsToLength(textLayoutModule->skipLE,
2562                                 textLayoutModule->skipLengthCO)
2563                                 );
2564                         bp_.setDefSkip(vs);
2565                         break;
2566                         }
2567                 default:
2568                         // this should never happen
2569                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2570                         break;
2571                 }
2572         }
2573
2574         bp_.options =
2575                 fromqstr(latexModule->optionsLE->text());
2576
2577         bp_.use_default_options =
2578                 latexModule->defaultOptionsCB->isChecked();
2579
2580         if (latexModule->childDocGB->isChecked())
2581                 bp_.master =
2582                         fromqstr(latexModule->childDocLE->text());
2583         else
2584                 bp_.master = string();
2585
2586         // Master/Child
2587         bp_.clearIncludedChildren();
2588         if (masterChildModule->includeonlyRB->isChecked()) {
2589                 list<string>::const_iterator it = includeonlys_.begin();
2590                 for (; it != includeonlys_.end() ; ++it) {
2591                         bp_.addIncludedChildren(*it);
2592                 }
2593         }
2594         bp_.maintain_unincluded_children =
2595                 masterChildModule->maintainAuxCB->isChecked();
2596
2597         // Float Placement
2598         bp_.float_placement = floatModule->get();
2599
2600         // Listings
2601         // text should have passed validation
2602         bp_.listings_params =
2603                 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
2604
2605         // output
2606         bp_.default_output_format = fromqstr(outputModule->defaultFormatCO->itemData(
2607                 outputModule->defaultFormatCO->currentIndex()).toString());
2608
2609         bool const nontexfonts = fontModule->osFontsCB->isChecked();
2610         bp_.useNonTeXFonts = nontexfonts;
2611
2612         bp_.output_sync = outputModule->outputsyncCB->isChecked();
2613         
2614         bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
2615
2616         int mathfmt = outputModule->mathoutCB->currentIndex();
2617         if (mathfmt == -1)
2618                 mathfmt = 0;
2619         BufferParams::MathOutput const mo =
2620                 static_cast<BufferParams::MathOutput>(mathfmt);
2621         bp_.html_math_output = mo;
2622         bp_.html_be_strict = outputModule->strictCB->isChecked();
2623         bp_.html_css_as_file = outputModule->cssCB->isChecked();
2624         bp_.html_math_img_scale = outputModule->mathimgSB->value();
2625
2626         // fonts
2627         bp_.fonts_roman =
2628                 fromqstr(fontModule->fontsRomanCO->
2629                         itemData(fontModule->fontsRomanCO->currentIndex()).toString());
2630
2631         bp_.fonts_sans =
2632                 fromqstr(fontModule->fontsSansCO->
2633                         itemData(fontModule->fontsSansCO->currentIndex()).toString());
2634
2635         bp_.fonts_typewriter =
2636                 fromqstr(fontModule->fontsTypewriterCO->
2637                         itemData(fontModule->fontsTypewriterCO->currentIndex()).toString());
2638
2639         if (fontModule->fontencCO->currentIndex() == 0)
2640                 bp_.fontenc = "global";
2641         else if (fontModule->fontencCO->currentIndex() == 1)
2642                 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
2643         else if (fontModule->fontencCO->currentIndex() == 2)
2644                 bp_.fontenc = "default";
2645
2646         bp_.fonts_cjk =
2647                 fromqstr(fontModule->cjkFontLE->text());
2648
2649         bp_.fonts_sans_scale = fontModule->scaleSansSB->value();
2650
2651         bp_.fonts_typewriter_scale = fontModule->scaleTypewriterSB->value();
2652
2653         bp_.fonts_expert_sc = fontModule->fontScCB->isChecked();
2654
2655         bp_.fonts_old_figures = fontModule->fontOsfCB->isChecked();
2656
2657         if (nontexfonts)
2658                 bp_.fonts_default_family = "default";
2659         else
2660                 bp_.fonts_default_family = GuiDocument::fontfamilies[
2661                         fontModule->fontsDefaultCO->currentIndex()];
2662
2663         if (fontModule->fontsizeCO->currentIndex() == 0)
2664                 bp_.fontsize = "default";
2665         else
2666                 bp_.fontsize =
2667                         fromqstr(fontModule->fontsizeCO->currentText());
2668
2669         // paper
2670         bp_.papersize = PAPER_SIZE(
2671                 pageLayoutModule->papersizeCO->currentIndex());
2672
2673         bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
2674                 pageLayoutModule->paperwidthUnitCO);
2675
2676         bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
2677                 pageLayoutModule->paperheightUnitCO);
2678
2679         if (pageLayoutModule->facingPagesCB->isChecked())
2680                 bp_.sides = TwoSides;
2681         else
2682                 bp_.sides = OneSide;
2683
2684         if (pageLayoutModule->landscapeRB->isChecked())
2685                 bp_.orientation = ORIENTATION_LANDSCAPE;
2686         else
2687                 bp_.orientation = ORIENTATION_PORTRAIT;
2688
2689         // margins
2690         bp_.use_geometry = !marginsModule->marginCB->isChecked();
2691
2692         Ui::MarginsUi const * m = marginsModule;
2693
2694         bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
2695         bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
2696         bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
2697         bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
2698         bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
2699         bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
2700         bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
2701         bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
2702
2703         // branches
2704         branchesModule->apply(bp_);
2705
2706         // PDF support
2707         PDFOptions & pdf = bp_.pdfoptions();
2708         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
2709         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
2710         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
2711         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
2712         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
2713
2714         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
2715         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
2716         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
2717         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
2718
2719         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
2720         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
2721         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
2722         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
2723         pdf.backref =
2724                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
2725         if (pdfSupportModule->fullscreenCB->isChecked())
2726                 pdf.pagemode = pdf.pagemode_fullscreen;
2727         else
2728                 pdf.pagemode.clear();
2729         pdf.quoted_options = pdf.quoted_options_check(
2730                                 fromqstr(pdfSupportModule->optionsLE->text()));
2731 }
2732
2733
2734 void GuiDocument::paramsToDialog()
2735 {
2736         // set the default unit
2737         Length::UNIT const default_unit = Length::defaultUnit();
2738
2739         // preamble
2740         preambleModule->update(bp_, id());
2741         localLayout->update(bp_, id());
2742
2743         // date
2744         latexModule->suppressDateCB->setChecked(bp_.suppress_date);
2745         latexModule->refstyleCB->setChecked(bp_.use_refstyle);
2746
2747         // biblio
2748         string const cite_engine = bp_.citeEngine().list().front();
2749
2750         biblioModule->citeDefaultRB->setChecked(
2751                 cite_engine == "basic");
2752
2753         biblioModule->citeJurabibRB->setChecked(
2754                 cite_engine == "jurabib");
2755
2756         biblioModule->citeNatbibRB->setChecked(
2757                 cite_engine == "natbib");
2758
2759         biblioModule->citeStyleCO->setCurrentIndex(
2760                 bp_.citeEngineType() == ENGINE_TYPE_NUMERICAL);
2761
2762         updateEngineType(documentClass().opt_enginetype(),
2763                 bp_.citeEngineType());
2764
2765         biblioModule->bibtopicCB->setChecked(
2766                 bp_.use_bibtopic);
2767
2768         biblioModule->bibtexStyleLE->setText(toqstr(bp_.biblio_style));
2769
2770         string command;
2771         string options =
2772                 split(bp_.bibtex_command, command, ' ');
2773
2774         int const bpos = biblioModule->bibtexCO->findData(toqstr(command));
2775         if (bpos != -1) {
2776                 biblioModule->bibtexCO->setCurrentIndex(bpos);
2777                 biblioModule->bibtexOptionsLE->setText(toqstr(options).trimmed());
2778         } else {
2779                 // We reset to default if we do not know the specified compiler
2780                 // This is for security reasons
2781                 biblioModule->bibtexCO->setCurrentIndex(
2782                         biblioModule->bibtexCO->findData(toqstr("default")));
2783                 biblioModule->bibtexOptionsLE->clear();
2784         }
2785         biblioModule->bibtexOptionsLE->setEnabled(
2786                 biblioModule->bibtexCO->currentIndex() != 0);
2787
2788         biblioChanged_ = false;
2789
2790         // indices
2791         indicesModule->update(bp_);
2792
2793         // language & quotes
2794         int const pos = langModule->languageCO->findData(toqstr(
2795                 bp_.language->lang()));
2796         langModule->languageCO->setCurrentIndex(pos);
2797
2798         langModule->quoteStyleCO->setCurrentIndex(
2799                 bp_.quotes_language);
2800
2801         bool default_enc = true;
2802         if (bp_.inputenc != "auto") {
2803                 default_enc = false;
2804                 if (bp_.inputenc == "default") {
2805                         langModule->encodingCO->setCurrentIndex(0);
2806                 } else {
2807                         string enc_gui;
2808                         Encodings::const_iterator it = encodings.begin();
2809                         Encodings::const_iterator const end = encodings.end();
2810                         for (; it != end; ++it) {
2811                                 if (it->latexName() == bp_.inputenc) {
2812                                         enc_gui = it->guiName();
2813                                         break;
2814                                 }
2815                         }
2816                         int const i = langModule->encodingCO->findText(
2817                                         qt_(enc_gui));
2818                         if (i >= 0)
2819                                 langModule->encodingCO->setCurrentIndex(i);
2820                         else
2821                                 // unknown encoding. Set to default.
2822                                 default_enc = true;
2823                 }
2824         }
2825         langModule->defaultencodingRB->setChecked(default_enc);
2826         langModule->otherencodingRB->setChecked(!default_enc);
2827
2828         int const p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
2829         if (p == -1) {
2830                 langModule->languagePackageCO->setCurrentIndex(
2831                           langModule->languagePackageCO->findData("custom"));
2832                 langModule->languagePackageLE->setText(toqstr(bp_.lang_package));
2833         } else {
2834                 langModule->languagePackageCO->setCurrentIndex(p);
2835                 langModule->languagePackageLE->clear();
2836         }
2837
2838         //color
2839         if (bp_.isfontcolor) {
2840                 colorModule->fontColorPB->setStyleSheet(
2841                         colorButtonStyleSheet(rgb2qcolor(bp_.fontcolor)));
2842         }
2843         set_fontcolor = bp_.fontcolor;
2844         is_fontcolor = bp_.isfontcolor;
2845
2846         colorModule->noteFontColorPB->setStyleSheet(
2847                 colorButtonStyleSheet(rgb2qcolor(bp_.notefontcolor)));
2848         set_notefontcolor = bp_.notefontcolor;
2849
2850         if (bp_.isbackgroundcolor) {
2851                 colorModule->backgroundPB->setStyleSheet(
2852                         colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
2853         }
2854         set_backgroundcolor = bp_.backgroundcolor;
2855         is_backgroundcolor = bp_.isbackgroundcolor;
2856
2857         colorModule->boxBackgroundPB->setStyleSheet(
2858                 colorButtonStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
2859         set_boxbgcolor = bp_.boxbgcolor;
2860
2861         // numbering
2862         int const min_toclevel = documentClass().min_toclevel();
2863         int const max_toclevel = documentClass().max_toclevel();
2864         if (documentClass().hasTocLevels()) {
2865                 numberingModule->setEnabled(true);
2866                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
2867                 numberingModule->depthSL->setMaximum(max_toclevel);
2868                 numberingModule->depthSL->setValue(bp_.secnumdepth);
2869                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
2870                 numberingModule->tocSL->setMaximum(max_toclevel);
2871                 numberingModule->tocSL->setValue(bp_.tocdepth);
2872                 updateNumbering();
2873         } else {
2874                 numberingModule->setEnabled(false);
2875                 numberingModule->tocTW->clear();
2876         }
2877
2878         // bullets
2879         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
2880         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
2881         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
2882         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
2883         bulletsModule->init();
2884
2885         // packages
2886         int nitem = findToken(tex_graphics, bp_.graphics_driver);
2887         if (nitem >= 0)
2888                 latexModule->psdriverCO->setCurrentIndex(nitem);
2889         updateModuleInfo();
2890
2891         vector<string> const & packages = BufferParams::auto_packages();
2892         for (size_t n = 0; n < packages.size(); ++n) {
2893                 QCheckBox * alwaysCB = static_cast<QCheckBox *>(
2894                         mathsModule->gridLayout->itemAtPosition(2 * n + 1, 0)->widget());
2895                 alwaysCB->setChecked(bp_.use_package(packages[n]) == BufferParams::package_on);
2896                 QCheckBox * autoCB = static_cast<QCheckBox *>(
2897                         mathsModule->gridLayout->itemAtPosition(2 * n, 0)->widget());
2898                 autoCB->setChecked(bp_.use_package(packages[n]) == BufferParams::package_auto);
2899         }
2900
2901         switch (bp_.spacing().getSpace()) {
2902                 case Spacing::Other: nitem = 3; break;
2903                 case Spacing::Double: nitem = 2; break;
2904                 case Spacing::Onehalf: nitem = 1; break;
2905                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
2906         }
2907
2908         // text layout
2909         string const & layoutID = bp_.baseClassID();
2910         setLayoutComboByIDString(layoutID);
2911
2912         updatePagestyle(documentClass().opt_pagestyle(),
2913                                  bp_.pagestyle);
2914
2915         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
2916         if (bp_.spacing().getSpace() == Spacing::Other) {
2917                 doubleToWidget(textLayoutModule->lspacingLE,
2918                         bp_.spacing().getValueAsString());
2919         }
2920         setLSpacing(nitem);
2921
2922         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
2923                 textLayoutModule->indentRB->setChecked(true);
2924                 string indentation = bp_.getIndentation().asLyXCommand();
2925                 int indent = 0;
2926                 if (indentation != "default") {
2927                         lengthToWidgets(textLayoutModule->indentLE,
2928                         textLayoutModule->indentLengthCO,
2929                         indentation, default_unit);
2930                         indent = 1;
2931                 }
2932                 textLayoutModule->indentCO->setCurrentIndex(indent);
2933                 setIndent(indent);
2934         } else {
2935                 textLayoutModule->skipRB->setChecked(true);
2936                 int skip = 0;
2937                 switch (bp_.getDefSkip().kind()) {
2938                 case VSpace::SMALLSKIP:
2939                         skip = 0;
2940                         break;
2941                 case VSpace::MEDSKIP:
2942                         skip = 1;
2943                         break;
2944                 case VSpace::BIGSKIP:
2945                         skip = 2;
2946                         break;
2947                 case VSpace::LENGTH:
2948                         {
2949                         skip = 3;
2950                         string const length = bp_.getDefSkip().asLyXCommand();
2951                         lengthToWidgets(textLayoutModule->skipLE,
2952                                 textLayoutModule->skipLengthCO,
2953                                 length, default_unit);
2954                         break;
2955                         }
2956                 default:
2957                         skip = 0;
2958                         break;
2959                 }
2960                 textLayoutModule->skipCO->setCurrentIndex(skip);
2961                 setSkip(skip);
2962         }
2963
2964         textLayoutModule->twoColumnCB->setChecked(
2965                 bp_.columns == 2);
2966         textLayoutModule->justCB->setChecked(bp_.justification);
2967
2968         if (!bp_.options.empty()) {
2969                 latexModule->optionsLE->setText(
2970                         toqstr(bp_.options));
2971         } else {
2972                 latexModule->optionsLE->setText(QString());
2973         }
2974
2975         // latex
2976         latexModule->defaultOptionsCB->setChecked(
2977                         bp_.use_default_options);
2978         updateSelectedModules();
2979         selectionManager->updateProvidedModules(
2980                         bp_.baseClass()->providedModules());
2981         selectionManager->updateExcludedModules(
2982                         bp_.baseClass()->excludedModules());
2983
2984         if (!documentClass().options().empty()) {
2985                 latexModule->defaultOptionsLE->setText(
2986                         toqstr(documentClass().options()));
2987         } else {
2988                 latexModule->defaultOptionsLE->setText(
2989                         toqstr(_("[No options predefined]")));
2990         }
2991
2992         latexModule->defaultOptionsLE->setEnabled(
2993                 bp_.use_default_options
2994                 && !documentClass().options().empty());
2995
2996         latexModule->defaultOptionsCB->setEnabled(
2997                 !documentClass().options().empty());
2998
2999         if (!bp_.master.empty()) {
3000                 latexModule->childDocGB->setChecked(true);
3001                 latexModule->childDocLE->setText(
3002                         toqstr(bp_.master));
3003         } else {
3004                 latexModule->childDocLE->setText(QString());
3005                 latexModule->childDocGB->setChecked(false);
3006         }
3007
3008         // Master/Child
3009         if (!bufferview() || !buffer().hasChildren()) {
3010                 masterChildModule->childrenTW->clear();
3011                 includeonlys_.clear();
3012                 docPS->showPanel(qt_("Child Documents"), false);
3013                 if (docPS->isCurrentPanel(qt_("Child Documents")))
3014                         docPS->setCurrentPanel(qt_("Document Class"));
3015         } else {
3016                 docPS->showPanel(qt_("Child Documents"), true);
3017                 masterChildModule->setEnabled(true);
3018                 includeonlys_ = bp_.getIncludedChildren();
3019                 updateIncludeonlys();
3020         }
3021         masterChildModule->maintainAuxCB->setChecked(
3022                 bp_.maintain_unincluded_children);
3023
3024         // Float Settings
3025         floatModule->set(bp_.float_placement);
3026
3027         // ListingsSettings
3028         // break listings_params to multiple lines
3029         string lstparams =
3030                 InsetListingsParams(bp_.listings_params).separatedParams();
3031         listingsModule->listingsED->setPlainText(toqstr(lstparams));
3032
3033         // Fonts
3034         bool const os_fonts_available =
3035                 bp_.baseClass()->outputType() == lyx::LATEX
3036                 && LaTeXFeatures::isAvailable("fontspec");
3037         fontModule->osFontsCB->setEnabled(os_fonts_available);
3038         fontModule->osFontsCB->setChecked(
3039                 os_fonts_available && bp_.useNonTeXFonts);
3040         updateFontsize(documentClass().opt_fontsize(),
3041                         bp_.fontsize);
3042
3043         QString font = toqstr(bp_.fonts_roman);
3044         int rpos = fontModule->fontsRomanCO->findData(font);
3045         if (rpos == -1) {
3046                 rpos = fontModule->fontsRomanCO->count();
3047                 fontModule->fontsRomanCO->addItem(font + qt_(" (not installed)"), font);
3048         }
3049         fontModule->fontsRomanCO->setCurrentIndex(rpos);
3050
3051         font = toqstr(bp_.fonts_sans);
3052         int spos = fontModule->fontsSansCO->findData(font);
3053         if (spos == -1) {
3054                 spos = fontModule->fontsSansCO->count();
3055                 fontModule->fontsSansCO->addItem(font + qt_(" (not installed)"), font);
3056         }
3057         fontModule->fontsSansCO->setCurrentIndex(spos);
3058
3059         font = toqstr(bp_.fonts_typewriter);
3060         int tpos = fontModule->fontsTypewriterCO->findData(font);
3061         if (tpos == -1) {
3062                 tpos = fontModule->fontsTypewriterCO->count();
3063                 fontModule->fontsTypewriterCO->addItem(font + qt_(" (not installed)"), font);
3064         }
3065         fontModule->fontsTypewriterCO->setCurrentIndex(tpos);
3066
3067         if (bp_.useNonTeXFonts && os_fonts_available) {
3068                 fontModule->fontencLA->setEnabled(false);
3069                 fontModule->fontencCO->setEnabled(false);
3070                 fontModule->fontencLE->setEnabled(false);
3071         } else {
3072                 fontModule->fontencLA->setEnabled(true);
3073                 fontModule->fontencCO->setEnabled(true);
3074                 fontModule->fontencLE->setEnabled(true);
3075                 romanChanged(rpos);
3076                 sansChanged(spos);
3077                 ttChanged(tpos);
3078         }
3079
3080         if (!bp_.fonts_cjk.empty())
3081                 fontModule->cjkFontLE->setText(
3082                         toqstr(bp_.fonts_cjk));
3083         else
3084                 fontModule->cjkFontLE->setText(QString());
3085
3086         fontModule->fontScCB->setChecked(bp_.fonts_expert_sc);
3087         fontModule->fontOsfCB->setChecked(bp_.fonts_old_figures);
3088         fontModule->scaleSansSB->setValue(bp_.fonts_sans_scale);
3089         fontModule->scaleTypewriterSB->setValue(bp_.fonts_typewriter_scale);
3090
3091         int nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
3092         if (nn >= 0)
3093                 fontModule->fontsDefaultCO->setCurrentIndex(nn);
3094
3095         if (bp_.fontenc == "global") {
3096                 fontModule->fontencCO->setCurrentIndex(0);
3097                 fontModule->fontencLE->setEnabled(false);
3098         } else if (bp_.fontenc == "default") {
3099                 fontModule->fontencCO->setCurrentIndex(2);
3100                 fontModule->fontencLE->setEnabled(false);
3101         } else {
3102                 fontModule->fontencCO->setCurrentIndex(1);
3103                 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
3104         }
3105
3106         // Output
3107         // This must be set _after_ fonts since updateDefaultFormat()
3108         // checks osFontsCB settings.
3109         // update combobox with formats
3110         updateDefaultFormat();
3111         int index = outputModule->defaultFormatCO->findData(toqstr(
3112                 bp_.default_output_format));
3113         // set to default if format is not found
3114         if (index == -1)
3115                 index = 0;
3116         outputModule->defaultFormatCO->setCurrentIndex(index);
3117
3118         outputModule->outputsyncCB->setChecked(bp_.output_sync);
3119         outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
3120
3121         outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
3122         outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
3123         outputModule->strictCB->setChecked(bp_.html_be_strict);
3124         outputModule->cssCB->setChecked(bp_.html_css_as_file);
3125
3126         // paper
3127         bool const extern_geometry =
3128                 documentClass().provides("geometry");
3129         int const psize = bp_.papersize;
3130         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
3131         setCustomPapersize(!extern_geometry && psize == 1);
3132         pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
3133
3134         bool const landscape =
3135                 bp_.orientation == ORIENTATION_LANDSCAPE;
3136         pageLayoutModule->landscapeRB->setChecked(landscape);
3137         pageLayoutModule->portraitRB->setChecked(!landscape);
3138         pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
3139         pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
3140
3141         pageLayoutModule->facingPagesCB->setChecked(
3142                 bp_.sides == TwoSides);
3143
3144         lengthToWidgets(pageLayoutModule->paperwidthLE,
3145                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, default_unit);
3146         lengthToWidgets(pageLayoutModule->paperheightLE,
3147                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, default_unit);
3148
3149         // margins
3150         Ui::MarginsUi * m = marginsModule;
3151
3152         setMargins();
3153
3154         lengthToWidgets(m->topLE, m->topUnit,
3155                 bp_.topmargin, default_unit);
3156
3157         lengthToWidgets(m->bottomLE, m->bottomUnit,
3158                 bp_.bottommargin, default_unit);
3159
3160         lengthToWidgets(m->innerLE, m->innerUnit,
3161                 bp_.leftmargin, default_unit);
3162
3163         lengthToWidgets(m->outerLE, m->outerUnit,
3164                 bp_.rightmargin, default_unit);
3165
3166         lengthToWidgets(m->headheightLE, m->headheightUnit,
3167                 bp_.headheight, default_unit);
3168
3169         lengthToWidgets(m->headsepLE, m->headsepUnit,
3170                 bp_.headsep, default_unit);
3171
3172         lengthToWidgets(m->footskipLE, m->footskipUnit,
3173                 bp_.footskip, default_unit);
3174
3175         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
3176                 bp_.columnsep, default_unit);
3177
3178         // branches
3179         updateUnknownBranches();
3180         branchesModule->update(bp_);
3181
3182         // PDF support
3183         PDFOptions const & pdf = bp_.pdfoptions();
3184         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
3185         if (bp_.documentClass().provides("hyperref"))
3186                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("C&ustomize Hyperref Options"));
3187         else
3188                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("&Use Hyperref Support"));
3189         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
3190         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
3191         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
3192         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
3193
3194         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
3195         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
3196         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
3197
3198         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
3199
3200         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
3201         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
3202         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
3203         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
3204
3205         nn = findToken(backref_opts, pdf.backref);
3206         if (nn >= 0)
3207                 pdfSupportModule->backrefCO->setCurrentIndex(nn);
3208
3209         pdfSupportModule->fullscreenCB->setChecked
3210                 (pdf.pagemode == pdf.pagemode_fullscreen);
3211
3212         pdfSupportModule->optionsLE->setText(
3213                 toqstr(pdf.quoted_options));
3214
3215         // Make sure that the bc is in the INITIAL state
3216         if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
3217                 bc().restore();
3218
3219         // clear changed branches cache
3220         changedBranches_.clear();
3221 }
3222
3223
3224 void GuiDocument::saveDocDefault()
3225 {
3226         // we have to apply the params first
3227         applyView();
3228         saveAsDefault();
3229 }
3230
3231
3232 void GuiDocument::updateAvailableModules()
3233 {
3234         modules_av_model_.clear();
3235         list<modInfoStruct> const & modInfoList = getModuleInfo();
3236         list<modInfoStruct>::const_iterator mit = modInfoList.begin();
3237         list<modInfoStruct>::const_iterator men = modInfoList.end();
3238         for (int i = 0; mit != men; ++mit, ++i)
3239                 modules_av_model_.insertRow(i, mit->name, mit->id,
3240                                 mit->description);
3241 }
3242
3243
3244 void GuiDocument::updateSelectedModules()
3245 {
3246         modules_sel_model_.clear();
3247         list<modInfoStruct> const selModList = getSelectedModules();
3248         list<modInfoStruct>::const_iterator mit = selModList.begin();
3249         list<modInfoStruct>::const_iterator men = selModList.end();
3250         for (int i = 0; mit != men; ++mit, ++i)
3251                 modules_sel_model_.insertRow(i, mit->name, mit->id,
3252                                 mit->description);
3253 }
3254
3255
3256 void GuiDocument::updateIncludeonlys()
3257 {
3258         masterChildModule->childrenTW->clear();
3259         QString const no = qt_("No");
3260         QString const yes = qt_("Yes");
3261
3262         if (includeonlys_.empty()) {
3263                 masterChildModule->includeallRB->setChecked(true);
3264                 masterChildModule->childrenTW->setEnabled(false);
3265                 masterChildModule->maintainAuxCB->setEnabled(false);
3266         } else {
3267                 masterChildModule->includeonlyRB->setChecked(true);
3268                 masterChildModule->childrenTW->setEnabled(true);
3269                 masterChildModule->maintainAuxCB->setEnabled(true);
3270         }
3271         QTreeWidgetItem * item = 0;
3272         ListOfBuffers children = buffer().getChildren();
3273         ListOfBuffers::const_iterator it  = children.begin();
3274         ListOfBuffers::const_iterator end = children.end();
3275         bool has_unincluded = false;
3276         bool all_unincluded = true;
3277         for (; it != end; ++it) {
3278                 item = new QTreeWidgetItem(masterChildModule->childrenTW);
3279                 // FIXME Unicode
3280                 string const name =
3281                         to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
3282                                                         from_utf8(buffer().filePath())));
3283                 item->setText(0, toqstr(name));
3284                 item->setText(1, isChildIncluded(name) ? yes : no);
3285                 if (!isChildIncluded(name))
3286                         has_unincluded = true;
3287                 else
3288                         all_unincluded = false;
3289         }
3290         // Both if all childs are included and if none is included
3291         // is equal to "include all" (i.e., ommit \includeonly).
3292         // Thus, reset the GUI.
3293         if (!has_unincluded || all_unincluded) {
3294                 masterChildModule->includeallRB->setChecked(true);
3295                 masterChildModule->childrenTW->setEnabled(false);
3296                 includeonlys_.clear();
3297         }
3298         // If all are included, we need to update again.
3299         if (!has_unincluded)
3300                 updateIncludeonlys();
3301 }
3302
3303
3304 void GuiDocument::updateContents()
3305 {
3306         // Nothing to do here as the document settings is not cursor dependant.
3307         return;
3308 }
3309
3310
3311 void GuiDocument::useClassDefaults()
3312 {
3313         if (applyPB->isEnabled()) {
3314                 int const ret = Alert::prompt(_("Unapplied changes"),
3315                                 _("Some changes in the dialog were not yet applied.\n"
3316                                   "If you do not apply now, they will be lost after this action."),
3317                                 1, 1, _("&Apply"), _("&Dismiss"));
3318                 if (ret == 0)
3319                         applyView();
3320         }
3321
3322         int idx = latexModule->classCO->currentIndex();
3323         string const classname = classes_model_.getIDString(idx);
3324         if (!bp_.setBaseClass(classname)) {
3325                 Alert::error(_("Error"), _("Unable to set document class."));
3326                 return;
3327         }
3328         bp_.useClassDefaults();
3329         paramsToDialog();
3330 }
3331
3332
3333 void GuiDocument::setLayoutComboByIDString(string const & idString)
3334 {
3335         int idx = classes_model_.findIDString(idString);
3336         if (idx < 0)
3337                 Alert::warning(_("Can't set layout!"),
3338                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
3339         else
3340                 latexModule->classCO->setCurrentIndex(idx);
3341 }
3342
3343
3344 bool GuiDocument::isValid()
3345 {
3346         return
3347                 validateListingsParameters().isEmpty() &&
3348                 localLayout->isValid() &&
3349                 (
3350                         // if we're asking for skips between paragraphs
3351                         !textLayoutModule->skipRB->isChecked() ||
3352                         // then either we haven't chosen custom
3353                         textLayoutModule->skipCO->currentIndex() != 3 ||
3354                         // or else a length has been given
3355                         !textLayoutModule->skipLE->text().isEmpty()
3356                 ) &&
3357                 (
3358                         // if we're asking for indentation
3359                         !textLayoutModule->indentRB->isChecked() ||
3360                         // then either we haven't chosen custom
3361                         textLayoutModule->indentCO->currentIndex() != 1 ||
3362                         // or else a length has been given
3363                         !textLayoutModule->indentLE->text().isEmpty()
3364                 );
3365 }
3366
3367
3368 char const * const GuiDocument::fontfamilies[5] = {
3369         "default", "rmdefault", "sfdefault", "ttdefault", ""
3370 };
3371
3372
3373 char const * GuiDocument::fontfamilies_gui[5] = {
3374         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
3375 };
3376
3377
3378 bool GuiDocument::initialiseParams(string const &)
3379 {
3380         BufferView const * view = bufferview();
3381         if (!view) {
3382                 bp_ = BufferParams();
3383                 paramsToDialog();
3384                 return true;
3385         }
3386         bp_ = view->buffer().params();
3387         loadModuleInfo();
3388         updateAvailableModules();
3389         //FIXME It'd be nice to make sure here that the selected
3390         //modules are consistent: That required modules are actually
3391         //selected, and that we don't have conflicts. If so, we could
3392         //at least pop up a warning.
3393         paramsToDialog();
3394         return true;
3395 }
3396
3397
3398 void GuiDocument::clearParams()
3399 {
3400         bp_ = BufferParams();
3401 }
3402
3403
3404 BufferId GuiDocument::id() const
3405 {
3406         BufferView const * const view = bufferview();
3407         return view? &view->buffer() : 0;
3408 }
3409
3410
3411 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
3412 {
3413         return moduleNames_;
3414 }
3415
3416
3417 list<GuiDocument::modInfoStruct> const
3418                 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
3419 {
3420         LayoutModuleList::const_iterator it =  mods.begin();
3421         LayoutModuleList::const_iterator end = mods.end();
3422         list<modInfoStruct> mInfo;
3423         for (; it != end; ++it) {
3424                 modInfoStruct m;
3425                 m.id = *it;
3426                 LyXModule const * const mod = theModuleList[*it];
3427                 if (mod)
3428                         // FIXME Unicode
3429                         m.name = toqstr(translateIfPossible(from_utf8(mod->getName())));
3430                 else
3431                         m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
3432                 mInfo.push_back(m);
3433         }
3434         return mInfo;
3435 }
3436
3437
3438 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
3439 {
3440         return makeModuleInfo(params().getModules());
3441 }
3442
3443
3444 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
3445 {
3446         return makeModuleInfo(params().baseClass()->providedModules());
3447 }
3448
3449
3450 DocumentClass const & GuiDocument::documentClass() const
3451 {
3452         return bp_.documentClass();
3453 }
3454
3455
3456 static void dispatch_bufferparams(Dialog const & dialog,
3457         BufferParams const & bp, FuncCode lfun)
3458 {
3459         ostringstream ss;
3460         ss << "\\begin_header\n";
3461         bp.writeFile(ss);
3462         ss << "\\end_header\n";
3463         dialog.dispatch(FuncRequest(lfun, ss.str()));
3464 }
3465
3466
3467 void GuiDocument::dispatchParams()
3468 {
3469         // This must come first so that a language change is correctly noticed
3470         setLanguage();
3471
3472         // Apply the BufferParams. Note that this will set the base class
3473         // and then update the buffer's layout.
3474         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
3475
3476         if (!params().master.empty()) {
3477                 FileName const master_file = support::makeAbsPath(params().master,
3478                            support::onlyPath(buffer().absFileName()));
3479                 if (isLyXFileName(master_file.absFileName())) {
3480                         Buffer * master = checkAndLoadLyXFile(master_file);
3481                         if (master) {
3482                                 if (master->isChild(const_cast<Buffer *>(&buffer())))
3483                                         const_cast<Buffer &>(buffer()).setParent(master);
3484                                 else
3485                                         Alert::warning(_("Assigned master does not include this file"),
3486                                                 bformat(_("You must include this file in the document\n"
3487                                                           "'%1$s' in order to use the master document\n"
3488                                                           "feature."), from_utf8(params().master)));
3489                         } else
3490                                 Alert::warning(_("Could not load master"),
3491                                                 bformat(_("The master document '%1$s'\n"
3492                                                            "could not be loaded."),
3493                                                            from_utf8(params().master)));
3494                 }
3495         }
3496
3497         // Generate the colours requested by each new branch.
3498         BranchList & branchlist = params().branchlist();
3499         if (!branchlist.empty()) {
3500                 BranchList::const_iterator it = branchlist.begin();
3501                 BranchList::const_iterator const end = branchlist.end();
3502                 for (; it != end; ++it) {
3503                         docstring const & current_branch = it->branch();
3504                         Branch const * branch = branchlist.find(current_branch);
3505                         string const x11hexname = X11hexname(branch->color());
3506                         // display the new color
3507                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
3508                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
3509                 }
3510
3511                 // Open insets of selected branches, close deselected ones
3512                 dispatch(FuncRequest(LFUN_INSET_FORALL,
3513                         "Branch inset-toggle assign"));
3514         }
3515         // rename branches in the document
3516         executeBranchRenaming();
3517         // and clear changed branches cache
3518         changedBranches_.clear();
3519
3520         // Generate the colours requested by indices.
3521         IndicesList & indiceslist = params().indiceslist();
3522         if (!indiceslist.empty()) {
3523                 IndicesList::const_iterator it = indiceslist.begin();
3524                 IndicesList::const_iterator const end = indiceslist.end();
3525                 for (; it != end; ++it) {
3526                         docstring const & current_index = it->shortcut();
3527                         Index const * index = indiceslist.findShortcut(current_index);
3528                         string const x11hexname = X11hexname(index->color());
3529                         // display the new color
3530                         docstring const str = current_index + ' ' + from_ascii(x11hexname);
3531                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
3532                 }
3533         }
3534         // FIXME LFUN
3535         // If we used an LFUN, we would not need these two lines:
3536         BufferView * bv = const_cast<BufferView *>(bufferview());
3537         bv->processUpdateFlags(Update::Force | Update::FitCursor);
3538 }
3539
3540
3541 void GuiDocument::setLanguage() const
3542 {
3543         Language const * const newL = bp_.language;
3544         if (buffer().params().language == newL)
3545                 return;
3546
3547         string const & lang_name = newL->lang();
3548         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
3549 }
3550
3551
3552 void GuiDocument::saveAsDefault() const
3553 {
3554         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
3555 }
3556
3557
3558 bool GuiDocument::isFontAvailable(string const & font) const
3559 {
3560         if (font == "default" || font == "cmr"
3561             || font == "cmss" || font == "cmtt")
3562                 // these are standard
3563                 return true;
3564         if (font == "lmodern" || font == "lmss" || font == "lmtt")
3565                 return LaTeXFeatures::isAvailable("lmodern");
3566         if (font == "times" || font == "palatino"
3567                  || font == "helvet" || font == "courier")
3568                 return LaTeXFeatures::isAvailable("psnfss");
3569         if (font == "cmbr" || font == "cmtl")
3570                 return LaTeXFeatures::isAvailable("cmbright");
3571         if (font == "utopia")
3572                 return LaTeXFeatures::isAvailable("utopia")
3573                         || LaTeXFeatures::isAvailable("fourier");
3574         if (font == "beraserif" || font == "berasans"
3575                 || font == "beramono")
3576                 return LaTeXFeatures::isAvailable("bera");
3577         return LaTeXFeatures::isAvailable(font);
3578 }
3579
3580
3581 bool GuiDocument::providesOSF(string const & font) const
3582 {
3583         if (fontModule->osFontsCB->isChecked())
3584                 // FIXME: we should check if the fonts really
3585                 // have OSF support. But how?
3586                 return true;
3587         if (font == "cmr")
3588                 return isFontAvailable("eco");
3589         if (font == "palatino")
3590                 return isFontAvailable("mathpazo");
3591         return false;
3592 }
3593
3594
3595 bool GuiDocument::providesSC(string const & font) const
3596 {
3597         if (fontModule->osFontsCB->isChecked())
3598                 return false;
3599         if (font == "palatino")
3600                 return isFontAvailable("mathpazo");
3601         if (font == "utopia")
3602                 return isFontAvailable("fourier");
3603         return false;
3604 }
3605
3606
3607 bool GuiDocument::providesScale(string const & font) const
3608 {
3609         if (fontModule->osFontsCB->isChecked())
3610                 return true;
3611         return font == "helvet" || font == "luximono"
3612                 || font == "berasans"  || font == "beramono";
3613 }
3614
3615
3616 void GuiDocument::loadModuleInfo()
3617 {
3618         moduleNames_.clear();
3619         LyXModuleList::const_iterator it  = theModuleList.begin();
3620         LyXModuleList::const_iterator end = theModuleList.end();
3621         for (; it != end; ++it) {
3622                 modInfoStruct m;
3623                 m.id = it->getID();
3624                 // FIXME Unicode
3625                 m.name = toqstr(translateIfPossible(from_utf8(it->getName())));
3626                 // this is supposed to give us the first sentence of the description
3627                 // FIXME Unicode
3628                 QString desc =
3629                         toqstr(translateIfPossible(from_utf8(it->getDescription())));
3630                 int const pos = desc.indexOf(".");
3631                 if (pos > 0)
3632                         desc.truncate(pos + 1);
3633                 m.description = desc;
3634                 moduleNames_.push_back(m);
3635         }
3636 }
3637
3638
3639 void GuiDocument::updateUnknownBranches()
3640 {
3641         if (!bufferview())
3642                 return;
3643         list<docstring> used_branches;
3644         buffer().getUsedBranches(used_branches);
3645         list<docstring>::const_iterator it = used_branches.begin();
3646         QStringList unknown_branches;
3647         for (; it != used_branches.end() ; ++it) {
3648                 if (!buffer().params().branchlist().find(*it))
3649                         unknown_branches.append(toqstr(*it));
3650         }
3651         branchesModule->setUnknownBranches(unknown_branches);
3652 }
3653
3654
3655 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
3656 {
3657         map<docstring, docstring>::iterator it = changedBranches_.begin();
3658         for (; it != changedBranches_.end() ; ++it) {
3659                 if (it->second == oldname) {
3660                         // branch has already been renamed
3661                         it->second = newname;
3662                         return;
3663                 }
3664         }
3665         // store new name
3666         changedBranches_[oldname] = newname;
3667 }
3668
3669
3670 void GuiDocument::executeBranchRenaming() const
3671 {
3672         map<docstring, docstring>::const_iterator it = changedBranches_.begin();
3673         for (; it != changedBranches_.end() ; ++it) {
3674                 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
3675                 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
3676         }
3677 }
3678
3679
3680 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
3681
3682
3683 } // namespace frontend
3684 } // namespace lyx
3685
3686 #include "moc_GuiDocument.cpp"