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