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