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