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