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