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