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