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