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