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