]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiDocument.cpp
e763aad4a9c7b95a922285862c3c132393cacba6
[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                         biblioModule->citeStyleCO->setCurrentIndex(1);
2255                         break;
2256         }
2257
2258         biblioModule->citationStyleL->setEnabled(nn > 1);
2259         biblioModule->citeStyleCO->setEnabled(nn > 1);
2260
2261         if (nn != 1)
2262                 return;
2263
2264         // If the textclass allows only one of authoryear or numerical,
2265         // we have no choice but to force that engine type.
2266         if (engine_types_[0] == "authoryear")
2267                 biblioModule->citeStyleCO->setCurrentIndex(0);
2268         else
2269                 biblioModule->citeStyleCO->setCurrentIndex(1);
2270 }
2271
2272
2273 namespace {
2274         // FIXME unicode
2275         // both of these should take a vector<docstring>
2276
2277         // This is an insanely complicated attempt to make this sort of thing
2278         // work with RTL languages.
2279         docstring formatStrVec(vector<string> const & v, docstring const & s)
2280         {
2281                 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
2282                 if (v.empty())
2283                         return docstring();
2284                 if (v.size() == 1)
2285                         return translateIfPossible(from_utf8(v[0]));
2286                 if (v.size() == 2) {
2287                         docstring retval = _("%1$s and %2$s");
2288                         retval = subst(retval, _("and"), s);
2289                         return bformat(retval, translateIfPossible(from_utf8(v[0])),
2290                                        translateIfPossible(from_utf8(v[1])));
2291                 }
2292                 // The idea here is to format all but the last two items...
2293                 int const vSize = v.size();
2294                 docstring t2 = _("%1$s, %2$s");
2295                 docstring retval = translateIfPossible(from_utf8(v[0]));
2296                 for (int i = 1; i < vSize - 2; ++i)
2297                         retval = bformat(t2, retval, translateIfPossible(from_utf8(v[i])));
2298                 //...and then to  plug them, and the last two, into this schema
2299                 docstring t = _("%1$s, %2$s, and %3$s");
2300                 t = subst(t, _("and"), s);
2301                 return bformat(t, retval, translateIfPossible(from_utf8(v[vSize - 2])),
2302                                translateIfPossible(from_utf8(v[vSize - 1])));
2303         }
2304
2305         vector<string> idsToNames(vector<string> const & idList)
2306         {
2307                 vector<string> retval;
2308                 vector<string>::const_iterator it  = idList.begin();
2309                 vector<string>::const_iterator end = idList.end();
2310                 for (; it != end; ++it) {
2311                         LyXModule const * const mod = theModuleList[*it];
2312                         if (!mod)
2313                                 retval.push_back(to_utf8(bformat(_("%1$s (unavailable)"),
2314                                                 translateIfPossible(from_utf8(*it)))));
2315                         else
2316                                 retval.push_back(mod->getName());
2317                 }
2318                 return retval;
2319         }
2320 } // end anonymous namespace
2321
2322
2323 void GuiDocument::modulesToParams(BufferParams & bp)
2324 {
2325         // update list of loaded modules
2326         bp.clearLayoutModules();
2327         int const srows = modules_sel_model_.rowCount();
2328         for (int i = 0; i < srows; ++i)
2329                 bp.addLayoutModule(modules_sel_model_.getIDString(i));
2330
2331         // update the list of removed modules
2332         bp.clearRemovedModules();
2333         LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
2334         list<string>::const_iterator rit = reqmods.begin();
2335         list<string>::const_iterator ren = reqmods.end();
2336
2337         // check each of the default modules
2338         for (; rit != ren; ++rit) {
2339                 list<string>::const_iterator mit = bp.getModules().begin();
2340                 list<string>::const_iterator men = bp.getModules().end();
2341                 bool found = false;
2342                 for (; mit != men; ++mit) {
2343                         if (*rit == *mit) {
2344                                 found = true;
2345                                 break;
2346                         }
2347                 }
2348                 if (!found) {
2349                         // the module isn't present so must have been removed by the user
2350                         bp.addRemovedModule(*rit);
2351                 }
2352         }
2353 }
2354
2355 void GuiDocument::modulesChanged()
2356 {
2357         modulesToParams(bp_);
2358         bp_.makeDocumentClass();
2359         paramsToDialog();
2360 }
2361
2362
2363 void GuiDocument::updateModuleInfo()
2364 {
2365         selectionManager->update();
2366
2367         //Module description
2368         bool const focus_on_selected = selectionManager->selectedFocused();
2369         QAbstractItemView * lv;
2370         if (focus_on_selected)
2371                 lv = modulesModule->selectedLV;
2372         else
2373                 lv = modulesModule->availableLV;
2374         if (lv->selectionModel()->selectedIndexes().isEmpty()) {
2375                 modulesModule->infoML->document()->clear();
2376                 return;
2377         }
2378         QModelIndex const & idx = lv->selectionModel()->currentIndex();
2379         GuiIdListModel const & id_model =
2380                         focus_on_selected  ? modules_sel_model_ : modules_av_model_;
2381         string const modName = id_model.getIDString(idx.row());
2382         docstring desc = getModuleDescription(modName);
2383
2384         LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
2385         if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
2386                 if (!desc.empty())
2387                         desc += "\n";
2388                 desc += _("Module provided by document class.");
2389         }
2390
2391         docstring cat = getModuleCategory(modName);
2392         if (!cat.empty()) {
2393                 if (!desc.empty())
2394                         desc += "\n";
2395                 desc += bformat(_("Category: %1$s."), cat);
2396         }
2397
2398         vector<string> pkglist = getPackageList(modName);
2399         docstring pkgdesc = formatStrVec(pkglist, _("and"));
2400         if (!pkgdesc.empty()) {
2401                 if (!desc.empty())
2402                         desc += "\n";
2403                 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
2404         }
2405
2406         pkglist = getRequiredList(modName);
2407         if (!pkglist.empty()) {
2408                 vector<string> const reqdescs = idsToNames(pkglist);
2409                 pkgdesc = formatStrVec(reqdescs, _("or"));
2410                 if (!desc.empty())
2411                         desc += "\n";
2412                 desc += bformat(_("Modules required: %1$s."), pkgdesc);
2413         }
2414
2415         pkglist = getExcludedList(modName);
2416         if (!pkglist.empty()) {
2417                 vector<string> const reqdescs = idsToNames(pkglist);
2418                 pkgdesc = formatStrVec(reqdescs, _( "and"));
2419                 if (!desc.empty())
2420                         desc += "\n";
2421                 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
2422         }
2423
2424         if (!isModuleAvailable(modName)) {
2425                 if (!desc.empty())
2426                         desc += "\n";
2427                 desc += _("WARNING: Some required packages are unavailable!");
2428         }
2429
2430         modulesModule->infoML->document()->setPlainText(toqstr(desc));
2431 }
2432
2433
2434 void GuiDocument::updateNumbering()
2435 {
2436         DocumentClass const & tclass = documentClass();
2437
2438         numberingModule->tocTW->setUpdatesEnabled(false);
2439         numberingModule->tocTW->clear();
2440
2441         int const depth = numberingModule->depthSL->value();
2442         int const toc = numberingModule->tocSL->value();
2443         QString const no = qt_("No");
2444         QString const yes = qt_("Yes");
2445         QTreeWidgetItem * item = 0;
2446
2447         DocumentClass::const_iterator lit = tclass.begin();
2448         DocumentClass::const_iterator len = tclass.end();
2449         for (; lit != len; ++lit) {
2450                 int const toclevel = lit->toclevel;
2451                 if (toclevel != Layout::NOT_IN_TOC && !lit->counter.empty()) {
2452                         item = new QTreeWidgetItem(numberingModule->tocTW);
2453                         item->setText(0, toqstr(translateIfPossible(lit->name())));
2454                         item->setText(1, (toclevel <= depth) ? yes : no);
2455                         item->setText(2, (toclevel <= toc) ? yes : no);
2456                 }
2457         }
2458
2459         numberingModule->tocTW->setUpdatesEnabled(true);
2460         numberingModule->tocTW->update();
2461 }
2462
2463
2464 void GuiDocument::updateDefaultFormat()
2465 {
2466         if (!bufferview())
2467                 return;
2468         // make a copy in order to consider unapplied changes
2469         BufferParams param_copy = buffer().params();
2470         param_copy.useNonTeXFonts = fontModule->osFontsCB->isChecked();
2471         int const idx = latexModule->classCO->currentIndex();
2472         if (idx >= 0) {
2473                 string const classname = fromqstr(latexModule->classCO->getData(idx));
2474                 param_copy.setBaseClass(classname);
2475                 param_copy.makeDocumentClass();
2476         }
2477         outputModule->defaultFormatCO->blockSignals(true);
2478         outputModule->defaultFormatCO->clear();
2479         outputModule->defaultFormatCO->addItem(qt_("Default"),
2480                                 QVariant(QString("default")));
2481         typedef vector<Format const *> Formats;
2482         Formats formats = param_copy.exportableFormats(true);
2483         sort(formats.begin(), formats.end(), Format::formatSorter);
2484         Formats::const_iterator cit = formats.begin();
2485         Formats::const_iterator end = formats.end();
2486         for (; cit != end; ++cit)
2487                 outputModule->defaultFormatCO->addItem(qt_((*cit)->prettyname()),
2488                                 QVariant(toqstr((*cit)->name())));
2489         outputModule->defaultFormatCO->blockSignals(false);
2490 }
2491
2492
2493 bool GuiDocument::isChildIncluded(string const & child)
2494 {
2495         if (includeonlys_.empty())
2496                 return false;
2497         return (std::find(includeonlys_.begin(),
2498                           includeonlys_.end(), child) != includeonlys_.end());
2499 }
2500
2501
2502 void GuiDocument::applyView()
2503 {
2504         // preamble
2505         preambleModule->apply(bp_);
2506         localLayout->apply(bp_);
2507
2508         // date
2509         bp_.suppress_date = latexModule->suppressDateCB->isChecked();
2510         bp_.use_refstyle  = latexModule->refstyleCB->isChecked();
2511
2512         // biblio
2513         if (biblioModule->citeNatbibRB->isChecked())
2514                 bp_.setCiteEngine("natbib");
2515         else if (biblioModule->citeJurabibRB->isChecked())
2516                 bp_.setCiteEngine("jurabib");
2517         else
2518                 bp_.setCiteEngine("basic");
2519
2520         if (biblioModule->citeStyleCO->currentIndex())
2521                 bp_.setCiteEngineType(ENGINE_TYPE_NUMERICAL);
2522         else
2523                 bp_.setCiteEngineType(ENGINE_TYPE_AUTHORYEAR);
2524
2525         bp_.use_bibtopic =
2526                 biblioModule->bibtopicCB->isChecked();
2527
2528         bp_.biblio_style = fromqstr(biblioModule->bibtexStyleLE->text());
2529
2530         string const bibtex_command =
2531                 fromqstr(biblioModule->bibtexCO->itemData(
2532                         biblioModule->bibtexCO->currentIndex()).toString());
2533         string const bibtex_options =
2534                 fromqstr(biblioModule->bibtexOptionsLE->text());
2535         if (bibtex_command == "default" || bibtex_options.empty())
2536                 bp_.bibtex_command = bibtex_command;
2537         else
2538                 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
2539
2540         if (biblioChanged_) {
2541                 buffer().invalidateBibinfoCache();
2542                 buffer().removeBiblioTempFiles();
2543         }
2544
2545         // Indices
2546         indicesModule->apply(bp_);
2547
2548         // language & quotes
2549         if (langModule->defaultencodingRB->isChecked()) {
2550                 bp_.inputenc = "auto";
2551         } else {
2552                 int i = langModule->encodingCO->currentIndex();
2553                 if (i == 0)
2554                         bp_.inputenc = "default";
2555                 else {
2556                         QString const enc_gui =
2557                                 langModule->encodingCO->currentText();
2558                         Encodings::const_iterator it = encodings.begin();
2559                         Encodings::const_iterator const end = encodings.end();
2560                         bool found = false;
2561                         for (; it != end; ++it) {
2562                                 if (qt_(it->guiName()) == enc_gui &&
2563                                     !it->unsafe()) {
2564                                         bp_.inputenc = it->name();
2565                                         found = true;
2566                                         break;
2567                                 }
2568                         }
2569                         if (!found) {
2570                                 // should not happen
2571                                 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
2572                                 bp_.inputenc = "default";
2573                         }
2574                 }
2575         }
2576
2577         bp_.quotes_language = (InsetQuotes::QuoteLanguage) langModule->quoteStyleCO->itemData(
2578                 langModule->quoteStyleCO->currentIndex()).toInt();
2579
2580         QString const lang = langModule->languageCO->itemData(
2581                 langModule->languageCO->currentIndex()).toString();
2582         bp_.language = lyx::languages.getLanguage(fromqstr(lang));
2583
2584         QString const pack = langModule->languagePackageCO->itemData(
2585                 langModule->languagePackageCO->currentIndex()).toString();
2586         if (pack == "custom")
2587                 bp_.lang_package =
2588                         fromqstr(langModule->languagePackageLE->text());
2589         else
2590                 bp_.lang_package = fromqstr(pack);
2591
2592         //color
2593         bp_.backgroundcolor = set_backgroundcolor;
2594         bp_.isbackgroundcolor = is_backgroundcolor;
2595         bp_.fontcolor = set_fontcolor;
2596         bp_.isfontcolor = is_fontcolor;
2597         bp_.notefontcolor = set_notefontcolor;
2598         bp_.boxbgcolor = set_boxbgcolor;
2599
2600         // numbering
2601         if (bp_.documentClass().hasTocLevels()) {
2602                 bp_.tocdepth = numberingModule->tocSL->value();
2603                 bp_.secnumdepth = numberingModule->depthSL->value();
2604         }
2605
2606         // bullets
2607         bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
2608         bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
2609         bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
2610         bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
2611
2612         // packages
2613         bp_.graphics_driver =
2614                 tex_graphics[latexModule->psdriverCO->currentIndex()];
2615
2616         // text layout
2617         int idx = latexModule->classCO->currentIndex();
2618         if (idx >= 0) {
2619                 string const classname = fromqstr(latexModule->classCO->getData(idx));
2620                 bp_.setBaseClass(classname);
2621         }
2622
2623         // Modules
2624         modulesToParams(bp_);
2625
2626         // Math
2627         map<string, string> const & packages = BufferParams::auto_packages();
2628         for (map<string, string>::const_iterator it = packages.begin();
2629              it != packages.end(); ++it) {
2630                 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
2631                 if (!item)
2632                         continue;
2633                 int row = mathsModule->packagesTW->row(item);
2634                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1);
2635                 if (rb->isChecked()) {
2636                         bp_.use_package(it->first, BufferParams::package_auto);
2637                         continue;
2638                 }
2639                 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2);
2640                 if (rb->isChecked()) {
2641                         bp_.use_package(it->first, BufferParams::package_on);
2642                         continue;
2643                 }
2644                 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3);
2645                 if (rb->isChecked())
2646                         bp_.use_package(it->first, BufferParams::package_off);
2647         }
2648
2649         // Page Layout
2650         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
2651                 bp_.pagestyle = "default";
2652         else {
2653                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
2654                 for (size_t i = 0; i != pagestyles.size(); ++i)
2655                         if (pagestyles[i].second == style_gui)
2656                                 bp_.pagestyle = pagestyles[i].first;
2657         }
2658
2659         // Text Layout
2660         switch (textLayoutModule->lspacingCO->currentIndex()) {
2661         case 0:
2662                 bp_.spacing().set(Spacing::Single);
2663                 break;
2664         case 1:
2665                 bp_.spacing().set(Spacing::Onehalf);
2666                 break;
2667         case 2:
2668                 bp_.spacing().set(Spacing::Double);
2669                 break;
2670         case 3: {
2671                 string s = widgetToDoubleStr(textLayoutModule->lspacingLE);
2672                 if (s.empty())
2673                         bp_.spacing().set(Spacing::Single);
2674                 else
2675                         bp_.spacing().set(Spacing::Other, s);
2676                 break;
2677                 }
2678         }
2679
2680         if (textLayoutModule->twoColumnCB->isChecked())
2681                 bp_.columns = 2;
2682         else
2683                 bp_.columns = 1;
2684
2685         bp_.justification = textLayoutModule->justCB->isChecked();
2686
2687         if (textLayoutModule->indentRB->isChecked()) {
2688                 // if paragraphs are separated by an indentation
2689                 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
2690                 switch (textLayoutModule->indentCO->currentIndex()) {
2691                 case 0:
2692                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2693                         break;
2694                 case 1: {
2695                         HSpace indent = HSpace(
2696                                 widgetsToLength(textLayoutModule->indentLE,
2697                                 textLayoutModule->indentLengthCO)
2698                                 );
2699                         bp_.setIndentation(indent);
2700                         break;
2701                         }
2702                 default:
2703                         // this should never happen
2704                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2705                         break;
2706                 }
2707         } else {
2708                 // if paragraphs are separated by a skip
2709                 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
2710                 switch (textLayoutModule->skipCO->currentIndex()) {
2711                 case 0:
2712                         bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
2713                         break;
2714                 case 1:
2715                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2716                         break;
2717                 case 2:
2718                         bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
2719                         break;
2720                 case 3:
2721                         {
2722                         VSpace vs = VSpace(
2723                                 widgetsToLength(textLayoutModule->skipLE,
2724                                 textLayoutModule->skipLengthCO)
2725                                 );
2726                         bp_.setDefSkip(vs);
2727                         break;
2728                         }
2729                 default:
2730                         // this should never happen
2731                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2732                         break;
2733                 }
2734         }
2735
2736         bp_.options =
2737                 fromqstr(latexModule->optionsLE->text());
2738
2739         bp_.use_default_options =
2740                 latexModule->defaultOptionsCB->isChecked();
2741
2742         if (latexModule->childDocGB->isChecked())
2743                 bp_.master =
2744                         fromqstr(latexModule->childDocLE->text());
2745         else
2746                 bp_.master = string();
2747
2748         // Master/Child
2749         bp_.clearIncludedChildren();
2750         if (masterChildModule->includeonlyRB->isChecked()) {
2751                 list<string>::const_iterator it = includeonlys_.begin();
2752                 for (; it != includeonlys_.end() ; ++it) {
2753                         bp_.addIncludedChildren(*it);
2754                 }
2755         }
2756         bp_.maintain_unincluded_children =
2757                 masterChildModule->maintainAuxCB->isChecked();
2758
2759         // Float Placement
2760         bp_.float_placement = floatModule->get();
2761
2762         // Listings
2763         // text should have passed validation
2764         bp_.listings_params =
2765                 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
2766
2767         // output
2768         bp_.default_output_format = fromqstr(outputModule->defaultFormatCO->itemData(
2769                 outputModule->defaultFormatCO->currentIndex()).toString());
2770
2771         bool const nontexfonts = fontModule->osFontsCB->isChecked();
2772         bp_.useNonTeXFonts = nontexfonts;
2773
2774         bp_.output_sync = outputModule->outputsyncCB->isChecked();
2775         
2776         bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
2777
2778         int mathfmt = outputModule->mathoutCB->currentIndex();
2779         if (mathfmt == -1)
2780                 mathfmt = 0;
2781         BufferParams::MathOutput const mo =
2782                 static_cast<BufferParams::MathOutput>(mathfmt);
2783         bp_.html_math_output = mo;
2784         bp_.html_be_strict = outputModule->strictCB->isChecked();
2785         bp_.html_css_as_file = outputModule->cssCB->isChecked();
2786         bp_.html_math_img_scale = outputModule->mathimgSB->value();
2787
2788         // fonts
2789         bp_.fonts_roman =
2790                 fromqstr(fontModule->fontsRomanCO->
2791                         itemData(fontModule->fontsRomanCO->currentIndex()).toString());
2792
2793         bp_.fonts_sans =
2794                 fromqstr(fontModule->fontsSansCO->
2795                         itemData(fontModule->fontsSansCO->currentIndex()).toString());
2796
2797         bp_.fonts_typewriter =
2798                 fromqstr(fontModule->fontsTypewriterCO->
2799                         itemData(fontModule->fontsTypewriterCO->currentIndex()).toString());
2800
2801         bp_.fonts_math =
2802                 fromqstr(fontModule->fontsMathCO->
2803                         itemData(fontModule->fontsMathCO->currentIndex()).toString());
2804
2805         QString const fontenc =
2806                 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
2807         if (fontenc == "custom")
2808                 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
2809         else
2810                 bp_.fontenc = fromqstr(fontenc);
2811
2812         bp_.fonts_cjk =
2813                 fromqstr(fontModule->cjkFontLE->text());
2814
2815         bp_.fonts_sans_scale = fontModule->scaleSansSB->value();
2816
2817         bp_.fonts_typewriter_scale = fontModule->scaleTypewriterSB->value();
2818
2819         bp_.fonts_expert_sc = fontModule->fontScCB->isChecked();
2820
2821         bp_.fonts_old_figures = fontModule->fontOsfCB->isChecked();
2822
2823         if (nontexfonts)
2824                 bp_.fonts_default_family = "default";
2825         else
2826                 bp_.fonts_default_family = GuiDocument::fontfamilies[
2827                         fontModule->fontsDefaultCO->currentIndex()];
2828
2829         if (fontModule->fontsizeCO->currentIndex() == 0)
2830                 bp_.fontsize = "default";
2831         else
2832                 bp_.fontsize =
2833                         fromqstr(fontModule->fontsizeCO->currentText());
2834
2835         // paper
2836         bp_.papersize = PAPER_SIZE(
2837                 pageLayoutModule->papersizeCO->currentIndex());
2838
2839         bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
2840                 pageLayoutModule->paperwidthUnitCO);
2841
2842         bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
2843                 pageLayoutModule->paperheightUnitCO);
2844
2845         if (pageLayoutModule->facingPagesCB->isChecked())
2846                 bp_.sides = TwoSides;
2847         else
2848                 bp_.sides = OneSide;
2849
2850         if (pageLayoutModule->landscapeRB->isChecked())
2851                 bp_.orientation = ORIENTATION_LANDSCAPE;
2852         else
2853                 bp_.orientation = ORIENTATION_PORTRAIT;
2854
2855         // margins
2856         bp_.use_geometry = !marginsModule->marginCB->isChecked();
2857
2858         Ui::MarginsUi const * m = marginsModule;
2859
2860         bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
2861         bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
2862         bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
2863         bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
2864         bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
2865         bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
2866         bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
2867         bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
2868
2869         // branches
2870         branchesModule->apply(bp_);
2871
2872         // PDF support
2873         PDFOptions & pdf = bp_.pdfoptions();
2874         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
2875         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
2876         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
2877         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
2878         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
2879
2880         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
2881         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
2882         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
2883         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
2884
2885         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
2886         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
2887         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
2888         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
2889         pdf.backref =
2890                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
2891         if (pdfSupportModule->fullscreenCB->isChecked())
2892                 pdf.pagemode = pdf.pagemode_fullscreen;
2893         else
2894                 pdf.pagemode.clear();
2895         pdf.quoted_options = pdf.quoted_options_check(
2896                                 fromqstr(pdfSupportModule->optionsLE->text()));
2897 }
2898
2899
2900 void GuiDocument::paramsToDialog()
2901 {
2902         // set the default unit
2903         Length::UNIT const default_unit = Length::defaultUnit();
2904
2905         // preamble
2906         preambleModule->update(bp_, id());
2907         localLayout->update(bp_, id());
2908
2909         // date
2910         latexModule->suppressDateCB->setChecked(bp_.suppress_date);
2911         latexModule->refstyleCB->setChecked(bp_.use_refstyle);
2912
2913         // biblio
2914         string const cite_engine = bp_.citeEngine().list().front();
2915
2916         biblioModule->citeDefaultRB->setChecked(
2917                 cite_engine == "basic");
2918
2919         biblioModule->citeJurabibRB->setChecked(
2920                 cite_engine == "jurabib");
2921
2922         biblioModule->citeNatbibRB->setChecked(
2923                 cite_engine == "natbib");
2924
2925         biblioModule->citeStyleCO->setCurrentIndex(
2926                 bp_.citeEngineType() == ENGINE_TYPE_NUMERICAL);
2927
2928         updateEngineType(documentClass().opt_enginetype(),
2929                 bp_.citeEngineType());
2930
2931         biblioModule->bibtopicCB->setChecked(
2932                 bp_.use_bibtopic);
2933
2934         biblioModule->bibtexStyleLE->setText(toqstr(bp_.biblio_style));
2935
2936         string command;
2937         string options =
2938                 split(bp_.bibtex_command, command, ' ');
2939
2940         int const bpos = biblioModule->bibtexCO->findData(toqstr(command));
2941         if (bpos != -1) {
2942                 biblioModule->bibtexCO->setCurrentIndex(bpos);
2943                 biblioModule->bibtexOptionsLE->setText(toqstr(options).trimmed());
2944         } else {
2945                 // We reset to default if we do not know the specified compiler
2946                 // This is for security reasons
2947                 biblioModule->bibtexCO->setCurrentIndex(
2948                         biblioModule->bibtexCO->findData(toqstr("default")));
2949                 biblioModule->bibtexOptionsLE->clear();
2950         }
2951         biblioModule->bibtexOptionsLE->setEnabled(
2952                 biblioModule->bibtexCO->currentIndex() != 0);
2953
2954         biblioChanged_ = false;
2955
2956         // indices
2957         indicesModule->update(bp_);
2958
2959         // language & quotes
2960         int const pos = langModule->languageCO->findData(toqstr(
2961                 bp_.language->lang()));
2962         langModule->languageCO->setCurrentIndex(pos);
2963
2964         langModule->quoteStyleCO->setCurrentIndex(
2965                 bp_.quotes_language);
2966
2967         bool default_enc = true;
2968         if (bp_.inputenc != "auto") {
2969                 default_enc = false;
2970                 if (bp_.inputenc == "default") {
2971                         langModule->encodingCO->setCurrentIndex(0);
2972                 } else {
2973                         string enc_gui;
2974                         Encodings::const_iterator it = encodings.begin();
2975                         Encodings::const_iterator const end = encodings.end();
2976                         for (; it != end; ++it) {
2977                                 if (it->name() == bp_.inputenc &&
2978                                     !it->unsafe()) {
2979                                         enc_gui = it->guiName();
2980                                         break;
2981                                 }
2982                         }
2983                         int const i = langModule->encodingCO->findText(
2984                                         qt_(enc_gui));
2985                         if (i >= 0)
2986                                 langModule->encodingCO->setCurrentIndex(i);
2987                         else
2988                                 // unknown encoding. Set to default.
2989                                 default_enc = true;
2990                 }
2991         }
2992         langModule->defaultencodingRB->setChecked(default_enc);
2993         langModule->otherencodingRB->setChecked(!default_enc);
2994
2995         int const p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
2996         if (p == -1) {
2997                 langModule->languagePackageCO->setCurrentIndex(
2998                           langModule->languagePackageCO->findData("custom"));
2999                 langModule->languagePackageLE->setText(toqstr(bp_.lang_package));
3000         } else {
3001                 langModule->languagePackageCO->setCurrentIndex(p);
3002                 langModule->languagePackageLE->clear();
3003         }
3004
3005         //color
3006         if (bp_.isfontcolor) {
3007                 colorModule->fontColorPB->setStyleSheet(
3008                         colorButtonStyleSheet(rgb2qcolor(bp_.fontcolor)));
3009         }
3010         set_fontcolor = bp_.fontcolor;
3011         is_fontcolor = bp_.isfontcolor;
3012
3013         colorModule->noteFontColorPB->setStyleSheet(
3014                 colorButtonStyleSheet(rgb2qcolor(bp_.notefontcolor)));
3015         set_notefontcolor = bp_.notefontcolor;
3016
3017         if (bp_.isbackgroundcolor) {
3018                 colorModule->backgroundPB->setStyleSheet(
3019                         colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
3020         }
3021         set_backgroundcolor = bp_.backgroundcolor;
3022         is_backgroundcolor = bp_.isbackgroundcolor;
3023
3024         colorModule->boxBackgroundPB->setStyleSheet(
3025                 colorButtonStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
3026         set_boxbgcolor = bp_.boxbgcolor;
3027
3028         // numbering
3029         int const min_toclevel = documentClass().min_toclevel();
3030         int const max_toclevel = documentClass().max_toclevel();
3031         if (documentClass().hasTocLevels()) {
3032                 numberingModule->setEnabled(true);
3033                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
3034                 numberingModule->depthSL->setMaximum(max_toclevel);
3035                 numberingModule->depthSL->setValue(bp_.secnumdepth);
3036                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
3037                 numberingModule->tocSL->setMaximum(max_toclevel);
3038                 numberingModule->tocSL->setValue(bp_.tocdepth);
3039                 updateNumbering();
3040         } else {
3041                 numberingModule->setEnabled(false);
3042                 numberingModule->tocTW->clear();
3043         }
3044
3045         // bullets
3046         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
3047         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
3048         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
3049         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
3050         bulletsModule->init();
3051
3052         // packages
3053         int nitem = findToken(tex_graphics, bp_.graphics_driver);
3054         if (nitem >= 0)
3055                 latexModule->psdriverCO->setCurrentIndex(nitem);
3056         updateModuleInfo();
3057
3058         map<string, string> const & packages = BufferParams::auto_packages();
3059         for (map<string, string>::const_iterator it = packages.begin();
3060              it != packages.end(); ++it) {
3061                 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
3062                 if (!item)
3063                         continue;
3064                 int row = mathsModule->packagesTW->row(item);
3065                 switch (bp_.use_package(it->first)) {
3066                         case BufferParams::package_off: {
3067                                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3);
3068                                 rb->setChecked(true);
3069                                 break;
3070                         }
3071                         case BufferParams::package_on: {
3072                                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2);
3073                                 rb->setChecked(true);
3074                                 break;
3075                         }
3076                         case BufferParams::package_auto: {
3077                                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1);
3078                                 rb->setChecked(true);
3079                                 break;
3080                         }
3081                 }
3082         }
3083
3084         switch (bp_.spacing().getSpace()) {
3085                 case Spacing::Other: nitem = 3; break;
3086                 case Spacing::Double: nitem = 2; break;
3087                 case Spacing::Onehalf: nitem = 1; break;
3088                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
3089         }
3090
3091         // text layout
3092         string const & layoutID = bp_.baseClassID();
3093         setLayoutComboByIDString(layoutID);
3094
3095         updatePagestyle(documentClass().opt_pagestyle(),
3096                                  bp_.pagestyle);
3097
3098         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
3099         if (bp_.spacing().getSpace() == Spacing::Other) {
3100                 doubleToWidget(textLayoutModule->lspacingLE,
3101                         bp_.spacing().getValueAsString());
3102         }
3103         setLSpacing(nitem);
3104
3105         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
3106                 textLayoutModule->indentRB->setChecked(true);
3107                 string indentation = bp_.getIndentation().asLyXCommand();
3108                 int indent = 0;
3109                 if (indentation != "default") {
3110                         lengthToWidgets(textLayoutModule->indentLE,
3111                         textLayoutModule->indentLengthCO,
3112                         indentation, default_unit);
3113                         indent = 1;
3114                 }
3115                 textLayoutModule->indentCO->setCurrentIndex(indent);
3116                 setIndent(indent);
3117         } else {
3118                 textLayoutModule->skipRB->setChecked(true);
3119                 int skip = 0;
3120                 switch (bp_.getDefSkip().kind()) {
3121                 case VSpace::SMALLSKIP:
3122                         skip = 0;
3123                         break;
3124                 case VSpace::MEDSKIP:
3125                         skip = 1;
3126                         break;
3127                 case VSpace::BIGSKIP:
3128                         skip = 2;
3129                         break;
3130                 case VSpace::LENGTH:
3131                         {
3132                         skip = 3;
3133                         string const length = bp_.getDefSkip().asLyXCommand();
3134                         lengthToWidgets(textLayoutModule->skipLE,
3135                                 textLayoutModule->skipLengthCO,
3136                                 length, default_unit);
3137                         break;
3138                         }
3139                 default:
3140                         skip = 0;
3141                         break;
3142                 }
3143                 textLayoutModule->skipCO->setCurrentIndex(skip);
3144                 setSkip(skip);
3145         }
3146
3147         textLayoutModule->twoColumnCB->setChecked(
3148                 bp_.columns == 2);
3149         textLayoutModule->justCB->setChecked(bp_.justification);
3150
3151         if (!bp_.options.empty()) {
3152                 latexModule->optionsLE->setText(
3153                         toqstr(bp_.options));
3154         } else {
3155                 latexModule->optionsLE->setText(QString());
3156         }
3157
3158         // latex
3159         latexModule->defaultOptionsCB->setChecked(
3160                         bp_.use_default_options);
3161         updateSelectedModules();
3162         selectionManager->updateProvidedModules(
3163                         bp_.baseClass()->providedModules());
3164         selectionManager->updateExcludedModules(
3165                         bp_.baseClass()->excludedModules());
3166
3167         if (!documentClass().options().empty()) {
3168                 latexModule->defaultOptionsLE->setText(
3169                         toqstr(documentClass().options()));
3170         } else {
3171                 latexModule->defaultOptionsLE->setText(
3172                         toqstr(_("[No options predefined]")));
3173         }
3174
3175         latexModule->defaultOptionsLE->setEnabled(
3176                 bp_.use_default_options
3177                 && !documentClass().options().empty());
3178
3179         latexModule->defaultOptionsCB->setEnabled(
3180                 !documentClass().options().empty());
3181
3182         if (!bp_.master.empty()) {
3183                 latexModule->childDocGB->setChecked(true);
3184                 latexModule->childDocLE->setText(
3185                         toqstr(bp_.master));
3186         } else {
3187                 latexModule->childDocLE->setText(QString());
3188                 latexModule->childDocGB->setChecked(false);
3189         }
3190
3191         // Master/Child
3192         if (!bufferview() || !buffer().hasChildren()) {
3193                 masterChildModule->childrenTW->clear();
3194                 includeonlys_.clear();
3195                 docPS->showPanel("Child Documents", false);
3196                 if (docPS->isCurrentPanel("Child Documents"))
3197                         docPS->setCurrentPanel("Document Class");
3198         } else {
3199                 docPS->showPanel("Child Documents", true);
3200                 masterChildModule->setEnabled(true);
3201                 includeonlys_ = bp_.getIncludedChildren();
3202                 updateIncludeonlys();
3203         }
3204         masterChildModule->maintainAuxCB->setChecked(
3205                 bp_.maintain_unincluded_children);
3206
3207         // Float Settings
3208         floatModule->set(bp_.float_placement);
3209
3210         // ListingsSettings
3211         // break listings_params to multiple lines
3212         string lstparams =
3213                 InsetListingsParams(bp_.listings_params).separatedParams();
3214         listingsModule->listingsED->setPlainText(toqstr(lstparams));
3215
3216         // Fonts
3217         bool const os_fonts_available =
3218                 bp_.baseClass()->outputType() == lyx::LATEX
3219                 && LaTeXFeatures::isAvailable("fontspec");
3220         fontModule->osFontsCB->setEnabled(os_fonts_available);
3221         fontModule->osFontsCB->setChecked(
3222                 os_fonts_available && bp_.useNonTeXFonts);
3223         updateFontsize(documentClass().opt_fontsize(),
3224                         bp_.fontsize);
3225
3226         QString font = toqstr(bp_.fonts_roman);
3227         int rpos = fontModule->fontsRomanCO->findData(font);
3228         if (rpos == -1) {
3229                 rpos = fontModule->fontsRomanCO->count();
3230                 fontModule->fontsRomanCO->addItem(font + qt_(" (not installed)"), font);
3231         }
3232         fontModule->fontsRomanCO->setCurrentIndex(rpos);
3233
3234         font = toqstr(bp_.fonts_sans);
3235         int spos = fontModule->fontsSansCO->findData(font);
3236         if (spos == -1) {
3237                 spos = fontModule->fontsSansCO->count();
3238                 fontModule->fontsSansCO->addItem(font + qt_(" (not installed)"), font);
3239         }
3240         fontModule->fontsSansCO->setCurrentIndex(spos);
3241
3242         font = toqstr(bp_.fonts_typewriter);
3243         int tpos = fontModule->fontsTypewriterCO->findData(font);
3244         if (tpos == -1) {
3245                 tpos = fontModule->fontsTypewriterCO->count();
3246                 fontModule->fontsTypewriterCO->addItem(font + qt_(" (not installed)"), font);
3247         }
3248         fontModule->fontsTypewriterCO->setCurrentIndex(tpos);
3249
3250         font = toqstr(bp_.fonts_math);
3251         int mpos = fontModule->fontsMathCO->findData(font);
3252         if (mpos == -1) {
3253                 mpos = fontModule->fontsMathCO->count();
3254                 fontModule->fontsMathCO->addItem(font + qt_(" (not installed)"), font);
3255         }
3256         fontModule->fontsMathCO->setCurrentIndex(mpos);
3257
3258         if (bp_.useNonTeXFonts && os_fonts_available) {
3259                 fontModule->fontencLA->setEnabled(false);
3260                 fontModule->fontencCO->setEnabled(false);
3261                 fontModule->fontencLE->setEnabled(false);
3262         } else {
3263                 fontModule->fontencLA->setEnabled(true);
3264                 fontModule->fontencCO->setEnabled(true);
3265                 fontModule->fontencLE->setEnabled(true);
3266                 romanChanged(rpos);
3267                 sansChanged(spos);
3268                 ttChanged(tpos);
3269         }
3270
3271         if (!bp_.fonts_cjk.empty())
3272                 fontModule->cjkFontLE->setText(
3273                         toqstr(bp_.fonts_cjk));
3274         else
3275                 fontModule->cjkFontLE->setText(QString());
3276
3277         fontModule->fontScCB->setChecked(bp_.fonts_expert_sc);
3278         fontModule->fontOsfCB->setChecked(bp_.fonts_old_figures);
3279         fontModule->scaleSansSB->setValue(bp_.fonts_sans_scale);
3280         fontModule->scaleTypewriterSB->setValue(bp_.fonts_typewriter_scale);
3281
3282         int nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
3283         if (nn >= 0)
3284                 fontModule->fontsDefaultCO->setCurrentIndex(nn);
3285
3286         if (bp_.fontenc == "global" || bp_.fontenc == "default") {
3287                 fontModule->fontencCO->setCurrentIndex(
3288                         fontModule->fontencCO->findData(toqstr(bp_.fontenc)));
3289                 fontModule->fontencLE->setEnabled(false);
3290         } else {
3291                 fontModule->fontencCO->setCurrentIndex(1);
3292                 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
3293         }
3294
3295         // Output
3296         // This must be set _after_ fonts since updateDefaultFormat()
3297         // checks osFontsCB settings.
3298         // update combobox with formats
3299         updateDefaultFormat();
3300         int index = outputModule->defaultFormatCO->findData(toqstr(
3301                 bp_.default_output_format));
3302         // set to default if format is not found
3303         if (index == -1)
3304                 index = 0;
3305         outputModule->defaultFormatCO->setCurrentIndex(index);
3306
3307         outputModule->outputsyncCB->setChecked(bp_.output_sync);
3308         outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
3309
3310         outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
3311         outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
3312         outputModule->strictCB->setChecked(bp_.html_be_strict);
3313         outputModule->cssCB->setChecked(bp_.html_css_as_file);
3314
3315         // paper
3316         bool const extern_geometry =
3317                 documentClass().provides("geometry");
3318         int const psize = bp_.papersize;
3319         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
3320         setCustomPapersize(!extern_geometry && psize == 1);
3321         pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
3322
3323         bool const landscape =
3324                 bp_.orientation == ORIENTATION_LANDSCAPE;
3325         pageLayoutModule->landscapeRB->setChecked(landscape);
3326         pageLayoutModule->portraitRB->setChecked(!landscape);
3327         pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
3328         pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
3329
3330         pageLayoutModule->facingPagesCB->setChecked(
3331                 bp_.sides == TwoSides);
3332
3333         lengthToWidgets(pageLayoutModule->paperwidthLE,
3334                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, default_unit);
3335         lengthToWidgets(pageLayoutModule->paperheightLE,
3336                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, default_unit);
3337
3338         // margins
3339         Ui::MarginsUi * m = marginsModule;
3340
3341         setMargins();
3342
3343         lengthToWidgets(m->topLE, m->topUnit,
3344                 bp_.topmargin, default_unit);
3345
3346         lengthToWidgets(m->bottomLE, m->bottomUnit,
3347                 bp_.bottommargin, default_unit);
3348
3349         lengthToWidgets(m->innerLE, m->innerUnit,
3350                 bp_.leftmargin, default_unit);
3351
3352         lengthToWidgets(m->outerLE, m->outerUnit,
3353                 bp_.rightmargin, default_unit);
3354
3355         lengthToWidgets(m->headheightLE, m->headheightUnit,
3356                 bp_.headheight, default_unit);
3357
3358         lengthToWidgets(m->headsepLE, m->headsepUnit,
3359                 bp_.headsep, default_unit);
3360
3361         lengthToWidgets(m->footskipLE, m->footskipUnit,
3362                 bp_.footskip, default_unit);
3363
3364         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
3365                 bp_.columnsep, default_unit);
3366
3367         // branches
3368         updateUnknownBranches();
3369         branchesModule->update(bp_);
3370
3371         // PDF support
3372         PDFOptions const & pdf = bp_.pdfoptions();
3373         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
3374         if (bp_.documentClass().provides("hyperref"))
3375                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("C&ustomize Hyperref Options"));
3376         else
3377                 pdfSupportModule->use_hyperrefGB->setTitle(qt_("&Use Hyperref Support"));
3378         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
3379         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
3380         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
3381         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
3382
3383         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
3384         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
3385         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
3386
3387         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
3388
3389         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
3390         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
3391         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
3392         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
3393
3394         nn = findToken(backref_opts, pdf.backref);
3395         if (nn >= 0)
3396                 pdfSupportModule->backrefCO->setCurrentIndex(nn);
3397
3398         pdfSupportModule->fullscreenCB->setChecked
3399                 (pdf.pagemode == pdf.pagemode_fullscreen);
3400
3401         pdfSupportModule->optionsLE->setText(
3402                 toqstr(pdf.quoted_options));
3403
3404         // Make sure that the bc is in the INITIAL state
3405         if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
3406                 bc().restore();
3407
3408         // clear changed branches cache
3409         changedBranches_.clear();
3410 }
3411
3412
3413 void GuiDocument::saveDocDefault()
3414 {
3415         // we have to apply the params first
3416         applyView();
3417         saveAsDefault();
3418 }
3419
3420
3421 void GuiDocument::updateAvailableModules()
3422 {
3423         modules_av_model_.clear();
3424         list<modInfoStruct> const & modInfoList = getModuleInfo();
3425         list<modInfoStruct>::const_iterator mit = modInfoList.begin();
3426         list<modInfoStruct>::const_iterator men = modInfoList.end();
3427         for (int i = 0; mit != men; ++mit, ++i)
3428                 modules_av_model_.insertRow(i, mit->name, mit->id,
3429                                 mit->description);
3430 }
3431
3432
3433 void GuiDocument::updateSelectedModules()
3434 {
3435         modules_sel_model_.clear();
3436         list<modInfoStruct> const selModList = getSelectedModules();
3437         list<modInfoStruct>::const_iterator mit = selModList.begin();
3438         list<modInfoStruct>::const_iterator men = selModList.end();
3439         for (int i = 0; mit != men; ++mit, ++i)
3440                 modules_sel_model_.insertRow(i, mit->name, mit->id,
3441                                 mit->description);
3442 }
3443
3444
3445 void GuiDocument::updateIncludeonlys()
3446 {
3447         masterChildModule->childrenTW->clear();
3448         QString const no = qt_("No");
3449         QString const yes = qt_("Yes");
3450
3451         if (includeonlys_.empty()) {
3452                 masterChildModule->includeallRB->setChecked(true);
3453                 masterChildModule->childrenTW->setEnabled(false);
3454                 masterChildModule->maintainAuxCB->setEnabled(false);
3455         } else {
3456                 masterChildModule->includeonlyRB->setChecked(true);
3457                 masterChildModule->childrenTW->setEnabled(true);
3458                 masterChildModule->maintainAuxCB->setEnabled(true);
3459         }
3460         QTreeWidgetItem * item = 0;
3461         ListOfBuffers children = buffer().getChildren();
3462         ListOfBuffers::const_iterator it  = children.begin();
3463         ListOfBuffers::const_iterator end = children.end();
3464         bool has_unincluded = false;
3465         bool all_unincluded = true;
3466         for (; it != end; ++it) {
3467                 item = new QTreeWidgetItem(masterChildModule->childrenTW);
3468                 // FIXME Unicode
3469                 string const name =
3470                         to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
3471                                                         from_utf8(buffer().filePath())));
3472                 item->setText(0, toqstr(name));
3473                 item->setText(1, isChildIncluded(name) ? yes : no);
3474                 if (!isChildIncluded(name))
3475                         has_unincluded = true;
3476                 else
3477                         all_unincluded = false;
3478         }
3479         // Both if all childs are included and if none is included
3480         // is equal to "include all" (i.e., ommit \includeonly).
3481         // Thus, reset the GUI.
3482         if (!has_unincluded || all_unincluded) {
3483                 masterChildModule->includeallRB->setChecked(true);
3484                 masterChildModule->childrenTW->setEnabled(false);
3485                 includeonlys_.clear();
3486         }
3487         // If all are included, we need to update again.
3488         if (!has_unincluded)
3489                 updateIncludeonlys();
3490 }
3491
3492
3493 void GuiDocument::updateContents()
3494 {
3495         // Nothing to do here as the document settings is not cursor dependant.
3496         return;
3497 }
3498
3499
3500 void GuiDocument::useClassDefaults()
3501 {
3502         if (applyPB->isEnabled()) {
3503                 int const ret = Alert::prompt(_("Unapplied changes"),
3504                                 _("Some changes in the dialog were not yet applied.\n"
3505                                   "If you do not apply now, they will be lost after this action."),
3506                                 1, 1, _("&Apply"), _("&Dismiss"));
3507                 if (ret == 0)
3508                         applyView();
3509         }
3510
3511         int idx = latexModule->classCO->currentIndex();
3512         string const classname = fromqstr(latexModule->classCO->getData(idx));
3513         if (!bp_.setBaseClass(classname)) {
3514                 Alert::error(_("Error"), _("Unable to set document class."));
3515                 return;
3516         }
3517         bp_.useClassDefaults();
3518         paramsToDialog();
3519 }
3520
3521
3522 void GuiDocument::setLayoutComboByIDString(string const & idString)
3523 {
3524         if (!latexModule->classCO->set(toqstr(idString)))
3525                 Alert::warning(_("Can't set layout!"),
3526                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
3527 }
3528
3529
3530 bool GuiDocument::isValid()
3531 {
3532         return
3533                 validateListingsParameters().isEmpty() &&
3534                 localLayout->isValid() &&
3535                 (
3536                         // if we're asking for skips between paragraphs
3537                         !textLayoutModule->skipRB->isChecked() ||
3538                         // then either we haven't chosen custom
3539                         textLayoutModule->skipCO->currentIndex() != 3 ||
3540                         // or else a length has been given
3541                         !textLayoutModule->skipLE->text().isEmpty()
3542                 ) &&
3543                 (
3544                         // if we're asking for indentation
3545                         !textLayoutModule->indentRB->isChecked() ||
3546                         // then either we haven't chosen custom
3547                         textLayoutModule->indentCO->currentIndex() != 1 ||
3548                         // or else a length has been given
3549                         !textLayoutModule->indentLE->text().isEmpty()
3550                 );
3551 }
3552
3553
3554 char const * const GuiDocument::fontfamilies[5] = {
3555         "default", "rmdefault", "sfdefault", "ttdefault", ""
3556 };
3557
3558
3559 char const * GuiDocument::fontfamilies_gui[5] = {
3560         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
3561 };
3562
3563
3564 bool GuiDocument::initialiseParams(string const &)
3565 {
3566         BufferView const * view = bufferview();
3567         if (!view) {
3568                 bp_ = BufferParams();
3569                 paramsToDialog();
3570                 return true;
3571         }
3572         bp_ = view->buffer().params();
3573         loadModuleInfo();
3574         updateAvailableModules();
3575         //FIXME It'd be nice to make sure here that the selected
3576         //modules are consistent: That required modules are actually
3577         //selected, and that we don't have conflicts. If so, we could
3578         //at least pop up a warning.
3579         paramsToDialog();
3580         return true;
3581 }
3582
3583
3584 void GuiDocument::clearParams()
3585 {
3586         bp_ = BufferParams();
3587 }
3588
3589
3590 BufferId GuiDocument::id() const
3591 {
3592         BufferView const * const view = bufferview();
3593         return view? &view->buffer() : 0;
3594 }
3595
3596
3597 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
3598 {
3599         return moduleNames_;
3600 }
3601
3602
3603 list<GuiDocument::modInfoStruct> const
3604                 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
3605 {
3606         LayoutModuleList::const_iterator it =  mods.begin();
3607         LayoutModuleList::const_iterator end = mods.end();
3608         list<modInfoStruct> mInfo;
3609         for (; it != end; ++it) {
3610                 modInfoStruct m;
3611                 m.id = *it;
3612                 LyXModule const * const mod = theModuleList[*it];
3613                 if (mod)
3614                         // FIXME Unicode
3615                         m.name = toqstr(translateIfPossible(from_utf8(mod->getName())));
3616                 else
3617                         m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
3618                 mInfo.push_back(m);
3619         }
3620         return mInfo;
3621 }
3622
3623
3624 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
3625 {
3626         return makeModuleInfo(params().getModules());
3627 }
3628
3629
3630 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
3631 {
3632         return makeModuleInfo(params().baseClass()->providedModules());
3633 }
3634
3635
3636 DocumentClass const & GuiDocument::documentClass() const
3637 {
3638         return bp_.documentClass();
3639 }
3640
3641
3642 static void dispatch_bufferparams(Dialog const & dialog,
3643         BufferParams const & bp, FuncCode lfun)
3644 {
3645         ostringstream ss;
3646         ss << "\\begin_header\n";
3647         bp.writeFile(ss);
3648         ss << "\\end_header\n";
3649         dialog.dispatch(FuncRequest(lfun, ss.str()));
3650 }
3651
3652
3653 void GuiDocument::dispatchParams()
3654 {
3655         // This must come first so that a language change is correctly noticed
3656         setLanguage();
3657
3658         // Apply the BufferParams. Note that this will set the base class
3659         // and then update the buffer's layout.
3660         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
3661
3662         if (!params().master.empty()) {
3663                 FileName const master_file = support::makeAbsPath(params().master,
3664                            support::onlyPath(buffer().absFileName()));
3665                 if (isLyXFileName(master_file.absFileName())) {
3666                         Buffer * master = checkAndLoadLyXFile(master_file);
3667                         if (master) {
3668                                 if (master->isChild(const_cast<Buffer *>(&buffer())))
3669                                         const_cast<Buffer &>(buffer()).setParent(master);
3670                                 else
3671                                         Alert::warning(_("Assigned master does not include this file"),
3672                                                 bformat(_("You must include this file in the document\n"
3673                                                           "'%1$s' in order to use the master document\n"
3674                                                           "feature."), from_utf8(params().master)));
3675                         } else
3676                                 Alert::warning(_("Could not load master"),
3677                                                 bformat(_("The master document '%1$s'\n"
3678                                                            "could not be loaded."),
3679                                                            from_utf8(params().master)));
3680                 }
3681         }
3682
3683         // Generate the colours requested by each new branch.
3684         BranchList & branchlist = params().branchlist();
3685         if (!branchlist.empty()) {
3686                 BranchList::const_iterator it = branchlist.begin();
3687                 BranchList::const_iterator const end = branchlist.end();
3688                 for (; it != end; ++it) {
3689                         docstring const & current_branch = it->branch();
3690                         Branch const * branch = branchlist.find(current_branch);
3691                         string const x11hexname = X11hexname(branch->color());
3692                         // display the new color
3693                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
3694                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
3695                 }
3696
3697                 // Open insets of selected branches, close deselected ones
3698                 dispatch(FuncRequest(LFUN_INSET_FORALL,
3699                         "Branch inset-toggle assign"));
3700         }
3701         // rename branches in the document
3702         executeBranchRenaming();
3703         // and clear changed branches cache
3704         changedBranches_.clear();
3705
3706         // Generate the colours requested by indices.
3707         IndicesList & indiceslist = params().indiceslist();
3708         if (!indiceslist.empty()) {
3709                 IndicesList::const_iterator it = indiceslist.begin();
3710                 IndicesList::const_iterator const end = indiceslist.end();
3711                 for (; it != end; ++it) {
3712                         docstring const & current_index = it->shortcut();
3713                         Index const * index = indiceslist.findShortcut(current_index);
3714                         string const x11hexname = X11hexname(index->color());
3715                         // display the new color
3716                         docstring const str = current_index + ' ' + from_ascii(x11hexname);
3717                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
3718                 }
3719         }
3720         // FIXME LFUN
3721         // If we used an LFUN, we would not need these two lines:
3722         BufferView * bv = const_cast<BufferView *>(bufferview());
3723         bv->processUpdateFlags(Update::Force | Update::FitCursor);
3724 }
3725
3726
3727 void GuiDocument::setLanguage() const
3728 {
3729         Language const * const newL = bp_.language;
3730         if (buffer().params().language == newL)
3731                 return;
3732
3733         string const & lang_name = newL->lang();
3734         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
3735 }
3736
3737
3738 void GuiDocument::saveAsDefault() const
3739 {
3740         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
3741 }
3742
3743
3744 bool GuiDocument::providesOSF(QString const & font) const
3745 {
3746         if (fontModule->osFontsCB->isChecked())
3747                 // FIXME: we should check if the fonts really
3748                 // have OSF support. But how?
3749                 return true;
3750         return theLaTeXFonts().getLaTeXFont(
3751                                 qstring_to_ucs4(font)).providesOSF(ot1(),
3752                                                                    completeFontset(),
3753                                                                    noMathFont());
3754 }
3755
3756
3757 bool GuiDocument::providesSC(QString const & font) const
3758 {
3759         if (fontModule->osFontsCB->isChecked())
3760                 return false;
3761         return theLaTeXFonts().getLaTeXFont(
3762                                 qstring_to_ucs4(font)).providesSC(ot1(),
3763                                                                   completeFontset(),
3764                                                                   noMathFont());
3765 }
3766
3767
3768 bool GuiDocument::providesScale(QString const & font) const
3769 {
3770         if (fontModule->osFontsCB->isChecked())
3771                 return true;
3772         return theLaTeXFonts().getLaTeXFont(
3773                                 qstring_to_ucs4(font)).providesScale(ot1(),
3774                                                                      completeFontset(),
3775                                                                      noMathFont());
3776 }
3777
3778
3779 bool GuiDocument::providesNoMath(QString const & font) const
3780 {
3781         if (fontModule->osFontsCB->isChecked())
3782                 return false;
3783         return theLaTeXFonts().getLaTeXFont(
3784                                 qstring_to_ucs4(font)).providesNoMath(ot1(),
3785                                                                       completeFontset());
3786 }
3787
3788
3789 bool GuiDocument::hasMonolithicExpertSet(QString const & font) const
3790 {
3791         if (fontModule->osFontsCB->isChecked())
3792                 return false;
3793         return theLaTeXFonts().getLaTeXFont(
3794                                 qstring_to_ucs4(font)).hasMonolithicExpertSet(ot1(),
3795                                                                               completeFontset(),
3796                                                                               noMathFont());
3797 }
3798
3799
3800 void GuiDocument::loadModuleInfo()
3801 {
3802         moduleNames_.clear();
3803         LyXModuleList::const_iterator it  = theModuleList.begin();
3804         LyXModuleList::const_iterator end = theModuleList.end();
3805         for (; it != end; ++it) {
3806                 modInfoStruct m;
3807                 m.id = it->getID();
3808                 // FIXME Unicode
3809                 m.name = toqstr(translateIfPossible(from_utf8(it->getName())));
3810                 // this is supposed to give us the first sentence of the description
3811                 // FIXME Unicode
3812                 QString desc =
3813                         toqstr(translateIfPossible(from_utf8(it->getDescription())));
3814                 int const pos = desc.indexOf(".");
3815                 if (pos > 0)
3816                         desc.truncate(pos + 1);
3817                 m.description = desc;
3818                 if (it->category().substr(0, 8) != "Citation")
3819                         moduleNames_.push_back(m);
3820         }
3821 }
3822
3823
3824 void GuiDocument::updateUnknownBranches()
3825 {
3826         if (!bufferview())
3827                 return;
3828         list<docstring> used_branches;
3829         buffer().getUsedBranches(used_branches);
3830         list<docstring>::const_iterator it = used_branches.begin();
3831         QStringList unknown_branches;
3832         for (; it != used_branches.end() ; ++it) {
3833                 if (!buffer().params().branchlist().find(*it))
3834                         unknown_branches.append(toqstr(*it));
3835         }
3836         branchesModule->setUnknownBranches(unknown_branches);
3837 }
3838
3839
3840 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
3841 {
3842         map<docstring, docstring>::iterator it = changedBranches_.begin();
3843         for (; it != changedBranches_.end() ; ++it) {
3844                 if (it->second == oldname) {
3845                         // branch has already been renamed
3846                         it->second = newname;
3847                         return;
3848                 }
3849         }
3850         // store new name
3851         changedBranches_[oldname] = newname;
3852 }
3853
3854
3855 void GuiDocument::executeBranchRenaming() const
3856 {
3857         map<docstring, docstring>::const_iterator it = changedBranches_.begin();
3858         for (; it != changedBranches_.end() ; ++it) {
3859                 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
3860                 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
3861         }
3862 }
3863
3864
3865 void GuiDocument::allPackagesAuto()
3866 {
3867         allPackages(1);
3868 }
3869
3870
3871 void GuiDocument::allPackagesAlways()
3872 {
3873         allPackages(2);
3874 }
3875
3876
3877 void GuiDocument::allPackagesNot()
3878 {
3879         allPackages(3);
3880 }
3881
3882
3883 void GuiDocument::allPackages(int col)
3884 {
3885         for (int row = 0; row < mathsModule->packagesTW->rowCount(); ++row) {
3886                 QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, col);
3887                 rb->setChecked(true);
3888         }
3889 }
3890
3891
3892 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
3893
3894
3895 } // namespace frontend
3896 } // namespace lyx
3897
3898 #include "moc_GuiDocument.cpp"