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