]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiDocument.cpp
UI for XHTML options. I removed the xml line from OutputUi.ui
[lyx.git] / src / frontends / qt4 / GuiDocument.cpp
1 /**
2  * \file GuiDocument.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Edwin Leuven
7  * \author Richard Heck (modules)
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "GuiDocument.h"
15
16 #include "GuiApplication.h"
17 #include "GuiBranches.h"
18 #include "GuiIndices.h"
19 #include "GuiSelectionManager.h"
20 #include "LaTeXHighlighter.h"
21 #include "LengthCombo.h"
22 #include "PanelStack.h"
23 #include "Validator.h"
24
25 #include "LayoutFile.h"
26 #include "BranchList.h"
27 #include "buffer_funcs.h"
28 #include "Buffer.h"
29 #include "BufferParams.h"
30 #include "BufferView.h"
31 #include "Color.h"
32 #include "ColorCache.h"
33 #include "Encoding.h"
34 #include "FloatPlacement.h"
35 #include "Format.h"
36 #include "FuncRequest.h"
37 #include "HSpace.h"
38 #include "IndicesList.h"
39 #include "Language.h"
40 #include "LaTeXFeatures.h"
41 #include "Layout.h"
42 #include "LayoutModuleList.h"
43 #include "LyXRC.h"
44 #include "ModuleList.h"
45 #include "OutputParams.h"
46 #include "PDFOptions.h"
47 #include "qt_helpers.h"
48 #include "Spacing.h"
49
50 #include "insets/InsetListingsParams.h"
51
52 #include "support/debug.h"
53 #include "support/FileName.h"
54 #include "support/filetools.h"
55 #include "support/gettext.h"
56 #include "support/lstrings.h"
57
58 #include "frontends/alert.h"
59
60 #include <QAbstractItemModel>
61 #include <QHeaderView>
62 #include <QColor>
63 #include <QColorDialog>
64 #include <QCloseEvent>
65 #include <QFontDatabase>
66 #include <QScrollBar>
67 #include <QTextCursor>
68
69 #include <sstream>
70 #include <vector>
71
72 #ifdef IN
73 #undef IN
74 #endif
75
76
77 // a style sheet for buttons
78 // this is for example used for the background color setting button
79 static inline QString colorButtonStyleSheet(QColor const & bgColor)
80 {
81         if (bgColor.isValid()) {
82                 QString rc = QLatin1String("background-color:");
83                 rc += bgColor.name();
84                 return rc;
85         }
86         return QString();
87 }
88
89
90 using namespace std;
91 using namespace lyx::support;
92
93
94 namespace {
95
96 char const * const tex_graphics[] =
97 {
98         "default", "dvialw", "dvilaser", "dvipdf", "dvipdfm", "dvipdfmx",
99         "dvips", "dvipsone", "dvitops", "dviwin", "dviwindo", "dvi2ps", "emtex",
100         "ln", "oztex", "pctexhp", "pctexps", "pctexwin", "pctex32", "pdftex",
101         "psprint", "pubps", "tcidvi", "textures", "truetex", "vtex", "xdvi",
102         "xetex", "none", ""
103 };
104
105
106 char const * const tex_graphics_gui[] =
107 {
108         N_("Default"), "dvialw", "DviLaser", "dvipdf", "DVIPDFM", "DVIPDFMx",
109         "Dvips", "DVIPSONE", "DVItoPS", "DVIWIN", "DVIWindo", "dvi2ps", "EmTeX",
110         "LN", "OzTeX", "pctexhp", "pctexps", "pctexwin", "PCTeX32", "pdfTeX",
111         "psprint", "pubps", "tcidvi", "Textures", "TrueTeX", "VTeX", "xdvi",
112         "XeTeX", N_("None"), ""
113 };
114
115
116 char const * const tex_fonts_roman[] =
117 {
118         "default", "cmr", "lmodern", "ae", "times", "palatino",
119         "charter", "newcent", "bookman", "utopia", "beraserif",
120         "ccfonts", "chancery", ""
121 };
122
123
124 char const * tex_fonts_roman_gui[] =
125 {
126         N_("Default"), N_("Computer Modern Roman"), N_("Latin Modern Roman"),
127         N_("AE (Almost European)"), N_("Times Roman"), N_("Palatino"),
128         N_("Bitstream Charter"), N_("New Century Schoolbook"), N_("Bookman"),
129         N_("Utopia"),  N_("Bera Serif"), N_("Concrete Roman"), N_("Zapf Chancery"),
130         ""
131 };
132
133
134 char const * const tex_fonts_sans[] =
135 {
136         "default", "cmss", "lmss", "helvet", "avant", "berasans", "cmbr", ""
137 };
138
139
140 char const * tex_fonts_sans_gui[] =
141 {
142         N_("Default"), N_("Computer Modern Sans"), N_("Latin Modern Sans"),
143         N_("Helvetica"), N_("Avant Garde"), N_("Bera Sans"), N_("CM Bright"), ""
144 };
145
146
147 char const * const tex_fonts_monospaced[] =
148 {
149         "default", "cmtt", "lmtt", "courier", "beramono", "luximono", "cmtl", ""
150 };
151
152
153 char const * tex_fonts_monospaced_gui[] =
154 {
155         N_("Default"), N_("Computer Modern Typewriter"),
156         N_("Latin Modern Typewriter"), N_("Courier"), N_("Bera Mono"),
157         N_("LuxiMono"), N_("CM Typewriter Light"), ""
158 };
159
160
161 char const * backref_opts[] =
162 {
163         "false", "section", "slide", "page", ""
164 };
165
166
167 char const * backref_opts_gui[] =
168 {
169         N_("Off"), N_("Section"), N_("Slide"), N_("Page"), ""
170 };
171
172
173 vector<pair<string, QString> > pagestyles;
174
175
176 } // anonymous namespace
177
178 namespace lyx {
179
180 RGBColor set_backgroundcolor;
181 bool is_backgroundcolor;
182 RGBColor set_fontcolor;
183 bool is_fontcolor;
184 RGBColor set_notefontcolor;
185 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                 bp_.spacing().set(Spacing::Other,
2168                         widgetToDoubleStr(textLayoutModule->lspacingLE));
2169                 break;
2170         }
2171
2172         if (textLayoutModule->twoColumnCB->isChecked())
2173                 bp_.columns = 2;
2174         else
2175                 bp_.columns = 1;
2176
2177         if (textLayoutModule->indentRB->isChecked()) {
2178                 // if paragraphs are separated by an indentation
2179                 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
2180                 switch (textLayoutModule->indentCO->currentIndex()) {
2181                 case 0:
2182                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2183                         break;
2184                 case 1: {
2185                         HSpace indent = HSpace(
2186                                 widgetsToLength(textLayoutModule->indentLE,
2187                                 textLayoutModule->indentLengthCO)
2188                                 );
2189                         bp_.setIndentation(indent);
2190                         break;
2191                         }
2192                 default:
2193                         // this should never happen
2194                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2195                         break;
2196                 }
2197         } else {
2198                 // if paragraphs are separated by a skip
2199                 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
2200                 switch (textLayoutModule->skipCO->currentIndex()) {
2201                 case 0:
2202                         bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
2203                         break;
2204                 case 1:
2205                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2206                         break;
2207                 case 2:
2208                         bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
2209                         break;
2210                 case 3:
2211                         {
2212                         VSpace vs = VSpace(
2213                                 widgetsToLength(textLayoutModule->skipLE,
2214                                 textLayoutModule->skipLengthCO)
2215                                 );
2216                         bp_.setDefSkip(vs);
2217                         break;
2218                         }
2219                 default:
2220                         // this should never happen
2221                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2222                         break;
2223                 }
2224         }
2225
2226         bp_.options =
2227                 fromqstr(latexModule->optionsLE->text());
2228
2229         bp_.use_default_options =
2230                 latexModule->defaultOptionsCB->isChecked();
2231
2232         if (latexModule->childDocGB->isChecked())
2233                 bp_.master =
2234                         fromqstr(latexModule->childDocLE->text());
2235         else
2236                 bp_.master = string();
2237
2238         // Master/Child
2239         bp_.clearIncludedChildren();
2240         if (masterChildModule->includeonlyRB->isChecked()) {
2241                 list<string>::const_iterator it = includeonlys_.begin();
2242                 for (; it != includeonlys_.end() ; ++it) {
2243                         bp_.addIncludedChildren(*it);
2244                 }
2245         }
2246         bp_.maintain_unincluded_children =
2247                 masterChildModule->maintainAuxCB->isChecked();
2248
2249         // Float Placement
2250         bp_.float_placement = floatModule->get();
2251
2252         // Listings
2253         // text should have passed validation
2254         bp_.listings_params =
2255                 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
2256
2257         // output
2258         bp_.defaultOutputFormat = fromqstr(outputModule->defaultFormatCO->itemData(
2259                 outputModule->defaultFormatCO->currentIndex()).toString());
2260
2261         bool const xetex = outputModule->xetexCB->isChecked();
2262         bp_.useXetex = xetex;
2263
2264         int mathfmt = outputModule->mathoutCB->currentIndex();
2265         if (mathfmt == -1)
2266                 mathfmt = 0;
2267         BufferParams::MathOutput const mo =
2268                 static_cast<BufferParams::MathOutput>(mathfmt);
2269         bp_.html_math_output = mo;
2270         bp_.html_be_strict = outputModule->strictCB->isChecked();
2271         bp_.html_math_img_scale = outputModule->mathimgSB->value();
2272
2273         // fonts
2274         if (xetex) {
2275                 if (fontModule->fontsRomanCO->currentIndex() == 0)
2276                         bp_.fontsRoman = "default";
2277                 else
2278                         bp_.fontsRoman =
2279                                 fromqstr(fontModule->fontsRomanCO->currentText());
2280         
2281                 if (fontModule->fontsSansCO->currentIndex() == 0)
2282                         bp_.fontsSans = "default";
2283                 else
2284                         bp_.fontsSans =
2285                                 fromqstr(fontModule->fontsSansCO->currentText());
2286         
2287                 if (fontModule->fontsTypewriterCO->currentIndex() == 0)
2288                         bp_.fontsTypewriter = "default";
2289                 else
2290                         bp_.fontsTypewriter =
2291                                 fromqstr(fontModule->fontsTypewriterCO->currentText());
2292         } else {
2293                 bp_.fontsRoman =
2294                         tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
2295         
2296                 bp_.fontsSans =
2297                         tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
2298         
2299                 bp_.fontsTypewriter =
2300                         tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
2301         }
2302
2303         if (fontModule->fontencCO->currentIndex() == 0)
2304                 bp_.fontenc = "global";
2305         else if (fontModule->fontencCO->currentIndex() == 1)
2306                 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
2307         else if (fontModule->fontencCO->currentIndex() == 2)
2308                 bp_.fontenc = "default";
2309
2310         bp_.fontsCJK =
2311                 fromqstr(fontModule->cjkFontLE->text());
2312
2313         bp_.fontsSansScale = fontModule->scaleSansSB->value();
2314
2315         bp_.fontsTypewriterScale = fontModule->scaleTypewriterSB->value();
2316
2317         bp_.fontsSC = fontModule->fontScCB->isChecked();
2318
2319         bp_.fontsOSF = fontModule->fontOsfCB->isChecked();
2320
2321         if (xetex)
2322                 bp_.fontsDefaultFamily = "default";
2323         else
2324                 bp_.fontsDefaultFamily = GuiDocument::fontfamilies[
2325                         fontModule->fontsDefaultCO->currentIndex()];
2326
2327         if (fontModule->fontsizeCO->currentIndex() == 0)
2328                 bp_.fontsize = "default";
2329         else
2330                 bp_.fontsize =
2331                         fromqstr(fontModule->fontsizeCO->currentText());
2332
2333         // paper
2334         bp_.papersize = PAPER_SIZE(
2335                 pageLayoutModule->papersizeCO->currentIndex());
2336
2337         // custom, A3, B3 and B4 paper sizes need geometry
2338         int psize = pageLayoutModule->papersizeCO->currentIndex();
2339         bool geom_papersize = (psize == 1 || psize == 5 || psize == 8 || psize == 9);
2340
2341         bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
2342                 pageLayoutModule->paperwidthUnitCO);
2343
2344         bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
2345                 pageLayoutModule->paperheightUnitCO);
2346
2347         if (pageLayoutModule->facingPagesCB->isChecked())
2348                 bp_.sides = TwoSides;
2349         else
2350                 bp_.sides = OneSide;
2351
2352         if (pageLayoutModule->landscapeRB->isChecked())
2353                 bp_.orientation = ORIENTATION_LANDSCAPE;
2354         else
2355                 bp_.orientation = ORIENTATION_PORTRAIT;
2356
2357         // margins
2358         bp_.use_geometry = !marginsModule->marginCB->isChecked()
2359                 || geom_papersize;
2360
2361         Ui::MarginsUi const * m = marginsModule;
2362
2363         bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
2364         bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
2365         bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
2366         bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
2367         bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
2368         bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
2369         bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
2370         bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
2371
2372         // branches
2373         branchesModule->apply(bp_);
2374
2375         // PDF support
2376         PDFOptions & pdf = bp_.pdfoptions();
2377         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
2378         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
2379         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
2380         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
2381         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
2382
2383         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
2384         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
2385         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
2386         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
2387
2388         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
2389         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
2390         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
2391         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
2392         pdf.backref =
2393                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
2394         if (pdfSupportModule->fullscreenCB->isChecked())
2395                 pdf.pagemode = pdf.pagemode_fullscreen;
2396         else
2397                 pdf.pagemode.clear();
2398         pdf.quoted_options = pdf.quoted_options_check(
2399                                 fromqstr(pdfSupportModule->optionsLE->text()));
2400 }
2401
2402
2403 void GuiDocument::paramsToDialog()
2404 {
2405         // set the default unit
2406         Length::UNIT const defaultUnit = Length::defaultUnit();
2407
2408         // preamble
2409         preambleModule->update(bp_, id());
2410
2411         // date
2412         latexModule->suppressDateCB->setChecked(bp_.suppress_date);
2413
2414         // biblio
2415         biblioModule->citeDefaultRB->setChecked(
2416                 bp_.citeEngine() == ENGINE_BASIC);
2417
2418         biblioModule->citeNatbibRB->setChecked(
2419                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL ||
2420                 bp_.citeEngine() == ENGINE_NATBIB_AUTHORYEAR);
2421
2422         biblioModule->citeStyleCO->setCurrentIndex(
2423                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL);
2424
2425         biblioModule->citeJurabibRB->setChecked(
2426                 bp_.citeEngine() == ENGINE_JURABIB);
2427
2428         biblioModule->bibtopicCB->setChecked(
2429                 bp_.use_bibtopic);
2430
2431         string command;
2432         string options =
2433                 split(bp_.bibtex_command, command, ' ');
2434
2435         int const bpos = biblioModule->bibtexCO->findData(toqstr(command));
2436         if (bpos != -1) {
2437                 biblioModule->bibtexCO->setCurrentIndex(bpos);
2438                 biblioModule->bibtexOptionsED->setText(toqstr(options).trimmed());
2439         } else {
2440                 biblioModule->bibtexCO->setCurrentIndex(0);
2441                 biblioModule->bibtexOptionsED->clear();
2442         }
2443         biblioModule->bibtexOptionsED->setEnabled(
2444                 biblioModule->bibtexCO->currentIndex() != 0);
2445
2446         // indices
2447         indicesModule->update(bp_);
2448
2449         // language & quotes
2450         int const pos = langModule->languageCO->findData(toqstr(
2451                 bp_.language->lang()));
2452         langModule->languageCO->setCurrentIndex(pos);
2453
2454         langModule->quoteStyleCO->setCurrentIndex(
2455                 bp_.quotes_language);
2456
2457         bool default_enc = true;
2458         if (bp_.inputenc != "auto") {
2459                 default_enc = false;
2460                 if (bp_.inputenc == "default") {
2461                         langModule->encodingCO->setCurrentIndex(0);
2462                 } else {
2463                         string enc_gui;
2464                         Encodings::const_iterator it = encodings.begin();
2465                         Encodings::const_iterator const end = encodings.end();
2466                         for (; it != end; ++it) {
2467                                 if (it->latexName() == bp_.inputenc) {
2468                                         enc_gui = it->guiName();
2469                                         break;
2470                                 }
2471                         }
2472                         int const i = langModule->encodingCO->findText(
2473                                         qt_(enc_gui));
2474                         if (i >= 0)
2475                                 langModule->encodingCO->setCurrentIndex(i);
2476                         else
2477                                 // unknown encoding. Set to default.
2478                                 default_enc = true;
2479                 }
2480         }
2481         langModule->defaultencodingRB->setChecked(default_enc);
2482         langModule->otherencodingRB->setChecked(!default_enc);
2483
2484         //color
2485         if (bp_.isfontcolor) {
2486                 colorModule->fontColorPB->setStyleSheet(
2487                         colorButtonStyleSheet(rgb2qcolor(bp_.fontcolor)));
2488         }
2489         set_fontcolor = bp_.fontcolor;
2490         is_fontcolor = bp_.isfontcolor;
2491
2492         colorModule->noteFontColorPB->setStyleSheet(
2493                 colorButtonStyleSheet(rgb2qcolor(bp_.notefontcolor)));
2494         set_notefontcolor = bp_.notefontcolor;
2495
2496         if (bp_.isbackgroundcolor) {
2497                 colorModule->backgroundPB->setStyleSheet(
2498                         colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
2499         }
2500         set_backgroundcolor = bp_.backgroundcolor;
2501         is_backgroundcolor = bp_.isbackgroundcolor;
2502
2503         colorModule->boxBackgroundPB->setStyleSheet(
2504                 colorButtonStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
2505         set_boxbgcolor = bp_.boxbgcolor;
2506
2507         // numbering
2508         int const min_toclevel = documentClass().min_toclevel();
2509         int const max_toclevel = documentClass().max_toclevel();
2510         if (documentClass().hasTocLevels()) {
2511                 numberingModule->setEnabled(true);
2512                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
2513                 numberingModule->depthSL->setMaximum(max_toclevel);
2514                 numberingModule->depthSL->setValue(bp_.secnumdepth);
2515                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
2516                 numberingModule->tocSL->setMaximum(max_toclevel);
2517                 numberingModule->tocSL->setValue(bp_.tocdepth);
2518                 updateNumbering();
2519         } else {
2520                 numberingModule->setEnabled(false);
2521                 numberingModule->tocTW->clear();
2522         }
2523
2524         // bullets
2525         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
2526         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
2527         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
2528         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
2529         bulletsModule->init();
2530
2531         // packages
2532         int nitem = findToken(tex_graphics, bp_.graphicsDriver);
2533         if (nitem >= 0)
2534                 latexModule->psdriverCO->setCurrentIndex(nitem);
2535         updateModuleInfo();
2536         
2537         mathsModule->amsCB->setChecked(
2538                 bp_.use_amsmath == BufferParams::package_on);
2539         mathsModule->amsautoCB->setChecked(
2540                 bp_.use_amsmath == BufferParams::package_auto);
2541
2542         mathsModule->esintCB->setChecked(
2543                 bp_.use_esint == BufferParams::package_on);
2544         mathsModule->esintautoCB->setChecked(
2545                 bp_.use_esint == BufferParams::package_auto);
2546
2547         mathsModule->mhchemCB->setChecked(
2548                 bp_.use_mhchem == BufferParams::package_on);
2549         mathsModule->mhchemautoCB->setChecked(
2550                 bp_.use_mhchem == BufferParams::package_auto);
2551
2552         switch (bp_.spacing().getSpace()) {
2553                 case Spacing::Other: nitem = 3; break;
2554                 case Spacing::Double: nitem = 2; break;
2555                 case Spacing::Onehalf: nitem = 1; break;
2556                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
2557         }
2558
2559         // text layout
2560         string const & layoutID = bp_.baseClassID();
2561         setLayoutComboByIDString(layoutID);
2562
2563         updatePagestyle(documentClass().opt_pagestyle(),
2564                                  bp_.pagestyle);
2565
2566         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
2567         if (bp_.spacing().getSpace() == Spacing::Other) {
2568                 doubleToWidget(textLayoutModule->lspacingLE,
2569                         bp_.spacing().getValueAsString());
2570         }
2571         setLSpacing(nitem);
2572
2573         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
2574                 textLayoutModule->indentRB->setChecked(true);
2575                 string indentation = bp_.getIndentation().asLyXCommand();
2576                 int indent = 0;
2577                 if (indentation != "default") {
2578                         lengthToWidgets(textLayoutModule->indentLE,
2579                         textLayoutModule->indentLengthCO,
2580                         indentation, defaultUnit);
2581                         indent = 1;
2582                 }
2583                 textLayoutModule->indentCO->setCurrentIndex(indent);
2584                 setIndent(indent);
2585         } else {
2586                 textLayoutModule->skipRB->setChecked(true);
2587                 int skip = 0;
2588                 switch (bp_.getDefSkip().kind()) {
2589                 case VSpace::SMALLSKIP:
2590                         skip = 0;
2591                         break;
2592                 case VSpace::MEDSKIP:
2593                         skip = 1;
2594                         break;
2595                 case VSpace::BIGSKIP:
2596                         skip = 2;
2597                         break;
2598                 case VSpace::LENGTH:
2599                         {
2600                         skip = 3;
2601                         string const length = bp_.getDefSkip().asLyXCommand();
2602                         lengthToWidgets(textLayoutModule->skipLE,
2603                                 textLayoutModule->skipLengthCO,
2604                                 length, defaultUnit);
2605                         break;
2606                         }
2607                 default:
2608                         skip = 0;
2609                         break;
2610                 }
2611                 textLayoutModule->skipCO->setCurrentIndex(skip);
2612                 setSkip(skip);
2613         }
2614
2615         textLayoutModule->twoColumnCB->setChecked(
2616                 bp_.columns == 2);
2617
2618         if (!bp_.options.empty()) {
2619                 latexModule->optionsLE->setText(
2620                         toqstr(bp_.options));
2621         } else {
2622                 latexModule->optionsLE->setText(QString());
2623         }
2624
2625         // latex
2626         latexModule->defaultOptionsCB->setChecked(
2627                         bp_.use_default_options);
2628         updateSelectedModules();
2629         selectionManager->updateProvidedModules(
2630                         bp_.baseClass()->providedModules());
2631         selectionManager->updateExcludedModules(
2632                         bp_.baseClass()->excludedModules());
2633
2634         if (!documentClass().options().empty()) {
2635                 latexModule->defaultOptionsLE->setText(
2636                         toqstr(documentClass().options()));
2637         } else {
2638                 latexModule->defaultOptionsLE->setText(
2639                         toqstr(_("[No options predefined]")));
2640         }
2641
2642         latexModule->defaultOptionsLE->setEnabled(
2643                 bp_.use_default_options
2644                 && !documentClass().options().empty());
2645
2646         latexModule->defaultOptionsCB->setEnabled(
2647                 !documentClass().options().empty());
2648
2649         if (!bp_.master.empty()) {
2650                 latexModule->childDocGB->setChecked(true);
2651                 latexModule->childDocLE->setText(
2652                         toqstr(bp_.master));
2653         } else {
2654                 latexModule->childDocLE->setText(QString());
2655                 latexModule->childDocGB->setChecked(false);
2656         }
2657
2658         // Master/Child
2659         std::vector<Buffer *> children;
2660         if (bufferview())
2661                 children = buffer().getChildren(false);
2662         if (children.empty()) {
2663                 masterChildModule->childrenTW->clear();
2664                 includeonlys_.clear();
2665                 docPS->showPanel(qt_("Child Documents"), false);
2666                 if (docPS->isCurrentPanel(qt_("Child Documents")))
2667                         docPS->setCurrentPanel(qt_("Document Class"));
2668         } else {
2669                 docPS->showPanel(qt_("Child Documents"), true);
2670                 masterChildModule->setEnabled(true);
2671                 includeonlys_ = bp_.getIncludedChildren();
2672                 updateIncludeonlys();
2673         }
2674         masterChildModule->maintainAuxCB->setChecked(
2675                 bp_.maintain_unincluded_children);
2676
2677         // Float Settings
2678         floatModule->set(bp_.float_placement);
2679
2680         // ListingsSettings
2681         // break listings_params to multiple lines
2682         string lstparams =
2683                 InsetListingsParams(bp_.listings_params).separatedParams();
2684         listingsModule->listingsED->setPlainText(toqstr(lstparams));
2685
2686         // Output
2687         // update combobox with formats
2688         updateDefaultFormat();
2689         int index = outputModule->defaultFormatCO->findData(toqstr(
2690                 bp_.defaultOutputFormat));
2691         // set to default if format is not found 
2692         if (index == -1)
2693                 index = 0;
2694         outputModule->defaultFormatCO->setCurrentIndex(index);
2695         outputModule->xetexCB->setEnabled(bp_.baseClass()->outputType() == lyx::LATEX);
2696         outputModule->xetexCB->setChecked(
2697                 bp_.baseClass()->outputType() == lyx::LATEX && bp_.useXetex);
2698
2699         outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
2700         outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
2701         outputModule->strictCB->setChecked(bp_.html_be_strict);
2702
2703         // Fonts
2704         updateFontsize(documentClass().opt_fontsize(),
2705                         bp_.fontsize);
2706
2707         if (bp_.useXetex) {
2708                 fontModule->fontencLA->setEnabled(false);
2709                 fontModule->fontencCO->setEnabled(false);
2710                 fontModule->fontencLE->setEnabled(false);
2711                 for (int i = 0; i < fontModule->fontsRomanCO->count(); ++i) {
2712                         if (fontModule->fontsRomanCO->itemText(i) == toqstr(bp_.fontsRoman)) {
2713                                 fontModule->fontsRomanCO->setCurrentIndex(i);
2714                                 return;
2715                         }
2716                 }
2717                 
2718                 for (int i = 0; i < fontModule->fontsSansCO->count(); ++i) {
2719                         if (fontModule->fontsSansCO->itemText(i) == toqstr(bp_.fontsSans)) {
2720                                 fontModule->fontsSansCO->setCurrentIndex(i);
2721                                 return;
2722                         }
2723                 }
2724                 for (int i = 0; i < fontModule->fontsTypewriterCO->count(); ++i) {
2725                         if (fontModule->fontsTypewriterCO->itemText(i) == 
2726                                 toqstr(bp_.fontsTypewriter)) {
2727                                 fontModule->fontsTypewriterCO->setCurrentIndex(i);
2728                                 return;
2729                         }
2730                 }
2731         } else {
2732                 fontModule->fontencLA->setEnabled(true);
2733                 fontModule->fontencCO->setEnabled(true);
2734                 fontModule->fontencLE->setEnabled(true);
2735                 int n = findToken(tex_fonts_roman, bp_.fontsRoman);
2736                 if (n >= 0) {
2737                         fontModule->fontsRomanCO->setCurrentIndex(n);
2738                         romanChanged(n);
2739                 }
2740         
2741                 n = findToken(tex_fonts_sans, bp_.fontsSans);
2742                 if (n >= 0) {
2743                         fontModule->fontsSansCO->setCurrentIndex(n);
2744                         sansChanged(n);
2745                 }
2746         
2747                 n = findToken(tex_fonts_monospaced, bp_.fontsTypewriter);
2748                 if (n >= 0) {
2749                         fontModule->fontsTypewriterCO->setCurrentIndex(n);
2750                         ttChanged(n);
2751                 }
2752         }
2753
2754         if (!bp_.fontsCJK.empty())
2755                 fontModule->cjkFontLE->setText(
2756                         toqstr(bp_.fontsCJK));
2757         else
2758                 fontModule->cjkFontLE->setText(QString());
2759
2760         fontModule->fontScCB->setChecked(bp_.fontsSC);
2761         fontModule->fontOsfCB->setChecked(bp_.fontsOSF);
2762         fontModule->scaleSansSB->setValue(bp_.fontsSansScale);
2763         fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale);
2764         
2765         int nn = findToken(GuiDocument::fontfamilies, bp_.fontsDefaultFamily);
2766         if (nn >= 0)
2767                 fontModule->fontsDefaultCO->setCurrentIndex(nn);
2768
2769         if (bp_.fontenc == "global")
2770                 fontModule->fontencCO->setCurrentIndex(0);
2771         else if (bp_.fontenc == "default")
2772                 fontModule->fontencCO->setCurrentIndex(2);
2773         else {
2774                 fontModule->fontencCO->setCurrentIndex(1);
2775                 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
2776         }
2777
2778         // paper
2779         bool const extern_geometry =
2780                 documentClass().provides("geometry");
2781         int const psize = bp_.papersize;
2782         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
2783         setCustomPapersize(!extern_geometry && psize == 1);
2784         pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
2785
2786         bool const landscape =
2787                 bp_.orientation == ORIENTATION_LANDSCAPE;
2788         pageLayoutModule->landscapeRB->setChecked(landscape);
2789         pageLayoutModule->portraitRB->setChecked(!landscape);
2790         pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
2791         pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
2792
2793         pageLayoutModule->facingPagesCB->setChecked(
2794                 bp_.sides == TwoSides);
2795
2796         lengthToWidgets(pageLayoutModule->paperwidthLE,
2797                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, defaultUnit);
2798         lengthToWidgets(pageLayoutModule->paperheightLE,
2799                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, defaultUnit);
2800
2801         // margins
2802         Ui::MarginsUi * m = marginsModule;
2803
2804         setMargins(!bp_.use_geometry);
2805
2806         lengthToWidgets(m->topLE, m->topUnit,
2807                 bp_.topmargin, defaultUnit);
2808
2809         lengthToWidgets(m->bottomLE, m->bottomUnit,
2810                 bp_.bottommargin, defaultUnit);
2811
2812         lengthToWidgets(m->innerLE, m->innerUnit,
2813                 bp_.leftmargin, defaultUnit);
2814
2815         lengthToWidgets(m->outerLE, m->outerUnit,
2816                 bp_.rightmargin, defaultUnit);
2817
2818         lengthToWidgets(m->headheightLE, m->headheightUnit,
2819                 bp_.headheight, defaultUnit);
2820
2821         lengthToWidgets(m->headsepLE, m->headsepUnit,
2822                 bp_.headsep, defaultUnit);
2823
2824         lengthToWidgets(m->footskipLE, m->footskipUnit,
2825                 bp_.footskip, defaultUnit);
2826
2827         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
2828                 bp_.columnsep, defaultUnit);
2829
2830         // branches
2831         updateUnknownBranches();
2832         branchesModule->update(bp_);
2833
2834         // PDF support
2835         PDFOptions const & pdf = bp_.pdfoptions();
2836         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
2837         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
2838         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
2839         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
2840         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
2841
2842         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
2843         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
2844         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
2845
2846         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
2847
2848         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
2849         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
2850         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
2851         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
2852
2853         nn = findToken(backref_opts, pdf.backref);
2854         if (nn >= 0)
2855                 pdfSupportModule->backrefCO->setCurrentIndex(nn);
2856
2857         pdfSupportModule->fullscreenCB->setChecked
2858                 (pdf.pagemode == pdf.pagemode_fullscreen);
2859
2860         pdfSupportModule->optionsLE->setText(
2861                 toqstr(pdf.quoted_options));
2862
2863         // Make sure that the bc is in the INITIAL state
2864         if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
2865                 bc().restore();
2866
2867         // clear changed branches cache
2868         changedBranches_.clear();
2869 }
2870
2871
2872 void GuiDocument::saveDocDefault()
2873 {
2874         // we have to apply the params first
2875         applyView();
2876         saveAsDefault();
2877 }
2878
2879
2880 void GuiDocument::updateAvailableModules() 
2881 {
2882         modules_av_model_.clear();
2883         list<modInfoStruct> const & modInfoList = getModuleInfo();
2884         list<modInfoStruct>::const_iterator mit = modInfoList.begin();
2885         list<modInfoStruct>::const_iterator men = modInfoList.end();
2886         for (int i = 0; mit != men; ++mit, ++i)
2887                 modules_av_model_.insertRow(i, mit->name, mit->id, 
2888                                 mit->description);
2889 }
2890
2891
2892 void GuiDocument::updateSelectedModules() 
2893 {
2894         modules_sel_model_.clear();
2895         list<modInfoStruct> const selModList = getSelectedModules();
2896         list<modInfoStruct>::const_iterator mit = selModList.begin();
2897         list<modInfoStruct>::const_iterator men = selModList.end();
2898         for (int i = 0; mit != men; ++mit, ++i)
2899                 modules_sel_model_.insertRow(i, mit->name, mit->id, 
2900                                 mit->description);
2901 }
2902
2903
2904 void GuiDocument::updateIncludeonlys()
2905 {
2906         masterChildModule->childrenTW->clear();
2907         QString const no = qt_("No");
2908         QString const yes = qt_("Yes");
2909
2910         if (includeonlys_.empty()) {
2911                 masterChildModule->includeallRB->setChecked(true);
2912                 masterChildModule->childrenTW->setEnabled(false);
2913                 masterChildModule->maintainAuxCB->setEnabled(false);
2914         } else {
2915                 masterChildModule->includeonlyRB->setChecked(true);
2916                 masterChildModule->childrenTW->setEnabled(true);
2917                 masterChildModule->maintainAuxCB->setEnabled(true);
2918         }
2919         QTreeWidgetItem * item = 0;
2920         std::vector<Buffer *> children = buffer().getChildren(false);
2921         vector<Buffer *>::const_iterator it  = children.begin();
2922         vector<Buffer *>::const_iterator end = children.end();
2923         bool has_unincluded = false;
2924         bool all_unincluded = true;
2925         for (; it != end; ++it) {
2926                 item = new QTreeWidgetItem(masterChildModule->childrenTW);
2927                 // FIXME Unicode
2928                 string const name =
2929                         to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
2930                                                         from_utf8(buffer().filePath())));
2931                 item->setText(0, toqstr(name));
2932                 item->setText(1, isChildIncluded(name) ? yes : no);
2933                 if (!isChildIncluded(name))
2934                         has_unincluded = true;
2935                 else
2936                         all_unincluded = false;
2937         }
2938         // Both if all childs are included and if none is included
2939         // is equal to "include all" (i.e., ommit \includeonly).
2940         // Thus, reset the GUI.
2941         if (!has_unincluded || all_unincluded) {
2942                 masterChildModule->includeallRB->setChecked(true);
2943                 masterChildModule->childrenTW->setEnabled(false);
2944                 includeonlys_.clear();
2945         }
2946         // If all are included, we need to update again.
2947         if (!has_unincluded)
2948                 updateIncludeonlys();
2949 }
2950
2951
2952 void GuiDocument::updateContents()
2953 {
2954         // Nothing to do here as the document settings is not cursor dependant.
2955         return;
2956 }
2957
2958
2959 void GuiDocument::useClassDefaults()
2960 {
2961         if (applyPB->isEnabled()) {
2962                 int const ret = Alert::prompt(_("Unapplied changes"),
2963                                 _("Some changes in the dialog were not yet applied.\n"
2964                                   "If you do not apply now, they will be lost after this action."),
2965                                 1, 1, _("&Apply"), _("&Dismiss"));
2966                 if (ret == 0)
2967                         applyView();
2968         }
2969
2970         int idx = latexModule->classCO->currentIndex();
2971         string const classname = classes_model_.getIDString(idx);
2972         if (!bp_.setBaseClass(classname)) {
2973                 Alert::error(_("Error"), _("Unable to set document class."));
2974                 return;
2975         }
2976         bp_.useClassDefaults();
2977         paramsToDialog();
2978 }
2979
2980
2981 void GuiDocument::setLayoutComboByIDString(string const & idString)
2982 {
2983         int idx = classes_model_.findIDString(idString);
2984         if (idx < 0)
2985                 Alert::warning(_("Can't set layout!"), 
2986                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
2987         else 
2988                 latexModule->classCO->setCurrentIndex(idx);
2989 }
2990
2991
2992 bool GuiDocument::isValid()
2993 {
2994         return validateListingsParameters().isEmpty()
2995                 && (textLayoutModule->skipCO->currentIndex() != 3
2996                         || !textLayoutModule->skipLE->text().isEmpty()
2997                         || textLayoutModule->indentRB->isChecked())
2998                 && (textLayoutModule->indentCO->currentIndex() != 1
2999                         || !textLayoutModule->indentLE->text().isEmpty()
3000                         || textLayoutModule->skipRB->isChecked());
3001 }
3002
3003
3004 char const * const GuiDocument::fontfamilies[5] = {
3005         "default", "rmdefault", "sfdefault", "ttdefault", ""
3006 };
3007
3008
3009 char const * GuiDocument::fontfamilies_gui[5] = {
3010         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
3011 };
3012
3013
3014 bool GuiDocument::initialiseParams(string const &)
3015 {
3016         BufferView const * view = bufferview();
3017         if (!view) {
3018                 bp_ = BufferParams();
3019                 paramsToDialog();
3020                 return true;
3021         }
3022         bp_ = view->buffer().params();
3023         loadModuleInfo();
3024         updateAvailableModules();
3025         //FIXME It'd be nice to make sure here that the selected
3026         //modules are consistent: That required modules are actually
3027         //selected, and that we don't have conflicts. If so, we could
3028         //at least pop up a warning.
3029         paramsToDialog();
3030         return true;
3031 }
3032
3033
3034 void GuiDocument::clearParams()
3035 {
3036         bp_ = BufferParams();
3037 }
3038
3039
3040 BufferId GuiDocument::id() const
3041 {
3042         BufferView const * const view = bufferview();
3043         return view? &view->buffer() : 0;
3044 }
3045
3046
3047 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
3048 {
3049         return moduleNames_;
3050 }
3051
3052
3053 list<GuiDocument::modInfoStruct> const 
3054                 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
3055 {
3056         LayoutModuleList::const_iterator it =  mods.begin();
3057         LayoutModuleList::const_iterator end = mods.end();
3058         list<modInfoStruct> mInfo;
3059         for (; it != end; ++it) {
3060                 modInfoStruct m;
3061                 m.id = *it;
3062                 LyXModule const * const mod = theModuleList[*it];
3063                 if (mod)
3064                         // FIXME Unicode
3065                         m.name = toqstr(translateIfPossible(from_utf8(mod->getName())));
3066                 else 
3067                         m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
3068                 mInfo.push_back(m);
3069         }
3070         return mInfo;
3071 }
3072
3073
3074 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
3075 {
3076         return makeModuleInfo(params().getModules());
3077 }
3078
3079
3080 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
3081 {
3082         return makeModuleInfo(params().baseClass()->providedModules());
3083 }
3084
3085
3086 DocumentClass const & GuiDocument::documentClass() const
3087 {
3088         return bp_.documentClass();
3089 }
3090
3091
3092 static void dispatch_bufferparams(Dialog const & dialog,
3093         BufferParams const & bp, FuncCode lfun)
3094 {
3095         ostringstream ss;
3096         ss << "\\begin_header\n";
3097         bp.writeFile(ss);
3098         ss << "\\end_header\n";
3099         dialog.dispatch(FuncRequest(lfun, ss.str()));
3100 }
3101
3102
3103 void GuiDocument::dispatchParams()
3104 {
3105         // This must come first so that a language change is correctly noticed
3106         setLanguage();
3107
3108         // Apply the BufferParams. Note that this will set the base class
3109         // and then update the buffer's layout.
3110         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
3111
3112         if (!params().master.empty()) {
3113                 FileName const master_file = support::makeAbsPath(params().master,
3114                            support::onlyPath(buffer().absFileName()));
3115                 if (isLyXFileName(master_file.absFileName())) {
3116                         Buffer * master = checkAndLoadLyXFile(master_file);
3117                         if (master) {
3118                                 if (master->isChild(const_cast<Buffer *>(&buffer())))
3119                                         const_cast<Buffer &>(buffer()).setParent(master);
3120                                 else
3121                                         Alert::warning(_("Assigned master does not include this file"), 
3122                                                 bformat(_("You must include this file in the document\n"
3123                                                           "'%1$s' in order to use the master document\n"
3124                                                           "feature."), from_utf8(params().master)));
3125                         } else
3126                                 Alert::warning(_("Could not load master"), 
3127                                                 bformat(_("The master document '%1$s'\n"
3128                                                            "could not be loaded."),
3129                                                            from_utf8(params().master)));
3130                 }
3131         }
3132
3133         // Generate the colours requested by each new branch.
3134         BranchList & branchlist = params().branchlist();
3135         if (!branchlist.empty()) {
3136                 BranchList::const_iterator it = branchlist.begin();
3137                 BranchList::const_iterator const end = branchlist.end();
3138                 for (; it != end; ++it) {
3139                         docstring const & current_branch = it->branch();
3140                         Branch const * branch = branchlist.find(current_branch);
3141                         string const x11hexname = X11hexname(branch->color());
3142                         // display the new color
3143                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
3144                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
3145                 }
3146
3147                 // Open insets of selected branches, close deselected ones
3148                 dispatch(FuncRequest(LFUN_INSET_FORALL,
3149                         "Branch inset-toggle assign"));
3150         }
3151         // rename branches in the document
3152         executeBranchRenaming();
3153         // and clear changed branches cache
3154         changedBranches_.clear();
3155         
3156         // Generate the colours requested by indices.
3157         IndicesList & indiceslist = params().indiceslist();
3158         if (!indiceslist.empty()) {
3159                 IndicesList::const_iterator it = indiceslist.begin();
3160                 IndicesList::const_iterator const end = indiceslist.end();
3161                 for (; it != end; ++it) {
3162                         docstring const & current_index = it->shortcut();
3163                         Index const * index = indiceslist.findShortcut(current_index);
3164                         string const x11hexname = X11hexname(index->color());
3165                         // display the new color
3166                         docstring const str = current_index + ' ' + from_ascii(x11hexname);
3167                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
3168                 }
3169         }
3170         // FIXME: If we used an LFUN, we would not need those two lines:
3171         BufferView * bv = const_cast<BufferView *>(bufferview());
3172         bv->processUpdateFlags(Update::Force | Update::FitCursor);
3173 }
3174
3175
3176 void GuiDocument::setLanguage() const
3177 {
3178         Language const * const newL = bp_.language;
3179         if (buffer().params().language == newL)
3180                 return;
3181
3182         string const & lang_name = newL->lang();
3183         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
3184 }
3185
3186
3187 void GuiDocument::saveAsDefault() const
3188 {
3189         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
3190 }
3191
3192
3193 bool GuiDocument::isFontAvailable(string const & font) const
3194 {
3195         if (font == "default" || font == "cmr"
3196             || font == "cmss" || font == "cmtt")
3197                 // these are standard
3198                 return true;
3199         if (font == "lmodern" || font == "lmss" || font == "lmtt")
3200                 return LaTeXFeatures::isAvailable("lmodern");
3201         if (font == "times" || font == "palatino"
3202                  || font == "helvet" || font == "courier")
3203                 return LaTeXFeatures::isAvailable("psnfss");
3204         if (font == "cmbr" || font == "cmtl")
3205                 return LaTeXFeatures::isAvailable("cmbright");
3206         if (font == "utopia")
3207                 return LaTeXFeatures::isAvailable("utopia")
3208                         || LaTeXFeatures::isAvailable("fourier");
3209         if (font == "beraserif" || font == "berasans"
3210                 || font == "beramono")
3211                 return LaTeXFeatures::isAvailable("bera");
3212         return LaTeXFeatures::isAvailable(font);
3213 }
3214
3215
3216 bool GuiDocument::providesOSF(string const & font) const
3217 {
3218         if (outputModule->xetexCB->isChecked())
3219                 // FIXME: we should check if the fonts really
3220                 // have OSF support. But how?
3221                 return true;
3222         if (font == "cmr")
3223                 return isFontAvailable("eco");
3224         if (font == "palatino")
3225                 return isFontAvailable("mathpazo");
3226         return false;
3227 }
3228
3229
3230 bool GuiDocument::providesSC(string const & font) const
3231 {
3232         if (outputModule->xetexCB->isChecked())
3233                 return false;
3234         if (font == "palatino")
3235                 return isFontAvailable("mathpazo");
3236         if (font == "utopia")
3237                 return isFontAvailable("fourier");
3238         return false;
3239 }
3240
3241
3242 bool GuiDocument::providesScale(string const & font) const
3243 {
3244         if (outputModule->xetexCB->isChecked())
3245                 return true;
3246         return font == "helvet" || font == "luximono"
3247                 || font == "berasans"  || font == "beramono";
3248 }
3249
3250
3251 void GuiDocument::loadModuleInfo()
3252 {
3253         moduleNames_.clear();
3254         LyXModuleList::const_iterator it  = theModuleList.begin();
3255         LyXModuleList::const_iterator end = theModuleList.end();
3256         for (; it != end; ++it) {
3257                 modInfoStruct m;
3258                 m.id = it->getID();
3259                 // FIXME Unicode
3260                 m.name = toqstr(translateIfPossible(from_utf8(it->getName())));
3261                 // this is supposed to give us the first sentence of the description
3262                 // FIXME Unicode
3263                 QString desc =
3264                         toqstr(translateIfPossible(from_utf8(it->getDescription())));
3265                 int const pos = desc.indexOf(".");
3266                 if (pos > 0)
3267                         desc.truncate(pos + 1);
3268                 m.description = desc;
3269                 moduleNames_.push_back(m);
3270         }
3271 }
3272
3273
3274 void GuiDocument::updateUnknownBranches()
3275 {
3276         if (!bufferview())
3277                 return;
3278         list<docstring> used_branches;
3279         buffer().getUsedBranches(used_branches);
3280         list<docstring>::const_iterator it = used_branches.begin();
3281         QStringList unknown_branches;
3282         for (; it != used_branches.end() ; ++it) {
3283                 if (!buffer().params().branchlist().find(*it))
3284                         unknown_branches.append(toqstr(*it));
3285         }
3286         branchesModule->setUnknownBranches(unknown_branches);
3287 }
3288
3289
3290 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
3291 {
3292         map<docstring, docstring>::iterator it = changedBranches_.begin();
3293         for (; it != changedBranches_.end() ; ++it) {
3294                 if (it->second == oldname) {
3295                         // branch has already been renamed
3296                         it->second = newname;
3297                         return;
3298                 }
3299         }
3300         // store new name
3301         changedBranches_[oldname] = newname;
3302 }
3303
3304
3305 void GuiDocument::executeBranchRenaming() const
3306 {
3307         map<docstring, docstring>::const_iterator it = changedBranches_.begin();
3308         for (; it != changedBranches_.end() ; ++it) {
3309                 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
3310                 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
3311         }
3312 }
3313
3314
3315 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
3316
3317
3318 } // namespace frontend
3319 } // namespace lyx
3320
3321 #include "moc_GuiDocument.cpp"