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