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