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