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