]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiDocument.cpp
693bd57be43bc4be9f1a487a45afc867e0572afb
[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         fontModule->fontencLE->setEnabled(!xetex);
1529 }
1530
1531
1532 void GuiDocument::updateFontsize(string const & items, string const & sel)
1533 {
1534         fontModule->fontsizeCO->clear();
1535         fontModule->fontsizeCO->addItem(qt_("Default"));
1536
1537         for (int n = 0; !token(items,'|',n).empty(); ++n)
1538                 fontModule->fontsizeCO->
1539                         addItem(toqstr(token(items,'|',n)));
1540
1541         for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
1542                 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
1543                         fontModule->fontsizeCO->setCurrentIndex(n);
1544                         break;
1545                 }
1546         }
1547 }
1548
1549
1550 void GuiDocument::updateFontlist()
1551 {
1552         fontModule->fontsRomanCO->clear();
1553         fontModule->fontsSansCO->clear();
1554         fontModule->fontsTypewriterCO->clear();
1555
1556         // With XeTeX, we have access to all system fonts, but not the LaTeX fonts
1557         if (outputModule->xetexCB->isChecked()) {
1558                 fontModule->fontsRomanCO->addItem(qt_("Default"));
1559                 fontModule->fontsSansCO->addItem(qt_("Default"));
1560                 fontModule->fontsTypewriterCO->addItem(qt_("Default"));
1561         
1562                 QFontDatabase fontdb;
1563                 QStringList families(fontdb.families());
1564                 for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
1565                         fontModule->fontsRomanCO->addItem(*it);
1566                         fontModule->fontsSansCO->addItem(*it);
1567                         fontModule->fontsTypewriterCO->addItem(*it);
1568                 }
1569                 return;
1570         }
1571
1572         for (int n = 0; tex_fonts_roman[n][0]; ++n) {
1573                 QString font = qt_(tex_fonts_roman_gui[n]);
1574                 if (!isFontAvailable(tex_fonts_roman[n]))
1575                         font += qt_(" (not installed)");
1576                 fontModule->fontsRomanCO->addItem(font);
1577         }
1578         for (int n = 0; tex_fonts_sans[n][0]; ++n) {
1579                 QString font = qt_(tex_fonts_sans_gui[n]);
1580                 if (!isFontAvailable(tex_fonts_sans[n]))
1581                         font += qt_(" (not installed)");
1582                 fontModule->fontsSansCO->addItem(font);
1583         }
1584         for (int n = 0; tex_fonts_monospaced[n][0]; ++n) {
1585                 QString font = qt_(tex_fonts_monospaced_gui[n]);
1586                 if (!isFontAvailable(tex_fonts_monospaced[n]))
1587                         font += qt_(" (not installed)");
1588                 fontModule->fontsTypewriterCO->addItem(font);
1589         }
1590 }
1591
1592
1593 void GuiDocument::fontencChanged(int item)
1594 {
1595         fontModule->fontencLE->setEnabled(item == 1);
1596 }
1597
1598
1599 void GuiDocument::romanChanged(int item)
1600 {
1601         if (outputModule->xetexCB->isChecked())
1602                 return;
1603         string const font = tex_fonts_roman[item];
1604         fontModule->fontScCB->setEnabled(providesSC(font));
1605         fontModule->fontOsfCB->setEnabled(providesOSF(font));
1606 }
1607
1608
1609 void GuiDocument::sansChanged(int item)
1610 {
1611         if (outputModule->xetexCB->isChecked())
1612                 return;
1613         string const font = tex_fonts_sans[item];
1614         bool scaleable = providesScale(font);
1615         fontModule->scaleSansSB->setEnabled(scaleable);
1616         fontModule->scaleSansLA->setEnabled(scaleable);
1617 }
1618
1619
1620 void GuiDocument::ttChanged(int item)
1621 {
1622         if (outputModule->xetexCB->isChecked())
1623                 return;
1624         string const font = tex_fonts_monospaced[item];
1625         bool scaleable = providesScale(font);
1626         fontModule->scaleTypewriterSB->setEnabled(scaleable);
1627         fontModule->scaleTypewriterLA->setEnabled(scaleable);
1628 }
1629
1630
1631 void GuiDocument::updatePagestyle(string const & items, string const & sel)
1632 {
1633         pagestyles.clear();
1634         pageLayoutModule->pagestyleCO->clear();
1635         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1636
1637         for (int n = 0; !token(items, '|', n).empty(); ++n) {
1638                 string style = token(items, '|', n);
1639                 QString style_gui = qt_(style);
1640                 pagestyles.push_back(pair<string, QString>(style, style_gui));
1641                 pageLayoutModule->pagestyleCO->addItem(style_gui);
1642         }
1643
1644         if (sel == "default") {
1645                 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
1646                 return;
1647         }
1648
1649         int nn = 0;
1650
1651         for (size_t i = 0; i < pagestyles.size(); ++i)
1652                 if (pagestyles[i].first == sel)
1653                         nn = pageLayoutModule->pagestyleCO->findText(pagestyles[i].second);
1654
1655         if (nn > 0)
1656                 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
1657 }
1658
1659
1660 void GuiDocument::browseLayout()
1661 {
1662         QString const label1 = qt_("Layouts|#o#O");
1663         QString const dir1 = toqstr(lyxrc.document_path);
1664         QStringList const filter(qt_("LyX Layout (*.layout)"));
1665         QString file = browseRelFile(QString(), bufferFilePath(),
1666                 qt_("Local layout file"), filter, false,
1667                 label1, dir1);
1668
1669         if (!file.endsWith(".layout"))
1670                 return;
1671
1672         FileName layoutFile = support::makeAbsPath(fromqstr(file),
1673                 fromqstr(bufferFilePath()));
1674         
1675         int const ret = Alert::prompt(_("Local layout file"),
1676                 _("The layout file you have selected is a local layout\n"
1677                   "file, not one in the system or user directory. Your\n"
1678                   "document may not work with this layout if you do not\n"
1679                   "keep the layout file in the document directory."),
1680                   1, 1, _("&Set Layout"), _("&Cancel"));
1681         if (ret == 1)
1682                 return;
1683
1684         // load the layout file
1685         LayoutFileList & bcl = LayoutFileList::get();
1686         string classname = layoutFile.onlyFileName();
1687         // this will update an existing layout if that layout has been loaded before.
1688         LayoutFileIndex name = bcl.addLocalLayout(
1689                 classname.substr(0, classname.size() - 7),
1690                 layoutFile.onlyPath().absFileName());
1691
1692         if (name.empty()) {
1693                 Alert::error(_("Error"),
1694                         _("Unable to read local layout file."));                
1695                 return;
1696         }
1697
1698         // do not trigger classChanged if there is no change.
1699         if (latexModule->classCO->currentText() == toqstr(name))
1700                 return;
1701                 
1702         // add to combo box
1703         int idx = latexModule->classCO->findText(toqstr(name));
1704         if (idx == -1) {
1705                 classes_model_.insertRow(0, toqstr(name), name);
1706                 latexModule->classCO->setCurrentIndex(0);
1707         } else
1708                 latexModule->classCO->setCurrentIndex(idx);
1709         
1710         classChanged();
1711 }
1712
1713
1714 void GuiDocument::browseMaster()
1715 {
1716         QString const title = qt_("Select master document");
1717         QString const dir1 = toqstr(lyxrc.document_path);
1718         QString const old = latexModule->childDocLE->text();
1719         QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
1720         QStringList const filter(qt_("LyX Files (*.lyx)"));
1721         QString file = browseRelFile(old, docpath, title, filter, false,
1722                 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
1723
1724         if (!file.isEmpty())
1725                 latexModule->childDocLE->setText(file);
1726 }
1727
1728
1729 void GuiDocument::classChanged()
1730 {
1731         int idx = latexModule->classCO->currentIndex();
1732         if (idx < 0) 
1733                 return;
1734         string const classname = classes_model_.getIDString(idx);
1735
1736         // check whether the selected modules have changed.
1737         bool modules_changed = false;
1738         unsigned int const srows = selectedModel()->rowCount();
1739         if (srows != bp_.getModules().size())
1740                 modules_changed = true;
1741         else {
1742                 list<string>::const_iterator mit = bp_.getModules().begin();
1743                 list<string>::const_iterator men = bp_.getModules().end();
1744                 for (unsigned int i = 0; i < srows && mit != men; ++i, ++mit)
1745                         if (selectedModel()->getIDString(i) != *mit) {
1746                                 modules_changed = true;
1747                                 break;
1748                         }
1749         }
1750
1751         if (modules_changed || lyxrc.auto_reset_options) {
1752                 if (applyPB->isEnabled()) {
1753                         int const ret = Alert::prompt(_("Unapplied changes"),
1754                                         _("Some changes in the dialog were not yet applied.\n"
1755                                         "If you do not apply now, they will be lost after this action."),
1756                                         1, 1, _("&Apply"), _("&Dismiss"));
1757                         if (ret == 0)
1758                                 applyView();
1759                 }
1760         }
1761
1762         // We load the TextClass as soon as it is selected. This is
1763         // necessary so that other options in the dialog can be updated
1764         // according to the new class. Note, however, that, if you use 
1765         // the scroll wheel when sitting on the combo box, we'll load a 
1766         // lot of TextClass objects very quickly....
1767         if (!bp_.setBaseClass(classname)) {
1768                 Alert::error(_("Error"), _("Unable to set document class."));
1769                 return;
1770         }
1771         if (lyxrc.auto_reset_options)
1772                 bp_.useClassDefaults();
1773
1774         // With the introduction of modules came a distinction between the base 
1775         // class and the document class. The former corresponds to the main layout 
1776         // file; the latter is that plus the modules (or the document-specific layout,
1777         // or  whatever else there could be). Our parameters come from the document 
1778         // class. So when we set the base class, we also need to recreate the document 
1779         // class. Otherwise, we still have the old one.
1780         bp_.makeDocumentClass();
1781         paramsToDialog();
1782 }
1783
1784
1785 void GuiDocument::bibtexChanged(int n)
1786 {
1787         biblioModule->bibtexOptionsED->setEnabled(n != 0);
1788         changed();
1789 }
1790
1791
1792 namespace {
1793         // This is an insanely complicated attempt to make this sort of thing
1794         // work with RTL languages.
1795         docstring formatStrVec(vector<string> const & v, docstring const & s) 
1796         {
1797                 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
1798                 if (v.size() == 0)
1799                         return docstring();
1800                 if (v.size() == 1) 
1801                         return from_utf8(v[0]);
1802                 if (v.size() == 2) {
1803                         docstring retval = _("%1$s and %2$s");
1804                         retval = subst(retval, _("and"), s);
1805                         return bformat(retval, from_utf8(v[0]), from_utf8(v[1]));
1806                 }
1807                 // The idea here is to format all but the last two items...
1808                 int const vSize = v.size();
1809                 docstring t2 = _("%1$s, %2$s");
1810                 docstring retval = from_utf8(v[0]);
1811                 for (int i = 1; i < vSize - 2; ++i)
1812                         retval = bformat(t2, retval, from_utf8(v[i])); 
1813                 //...and then to  plug them, and the last two, into this schema
1814                 docstring t = _("%1$s, %2$s, and %3$s");
1815                 t = subst(t, _("and"), s);
1816                 return bformat(t, retval, from_utf8(v[vSize - 2]), from_utf8(v[vSize - 1]));
1817         }
1818         
1819         vector<string> idsToNames(vector<string> const & idList)
1820         {
1821                 vector<string> retval;
1822                 vector<string>::const_iterator it  = idList.begin();
1823                 vector<string>::const_iterator end = idList.end();
1824                 for (; it != end; ++it) {
1825                         LyXModule const * const mod = theModuleList[*it];
1826                         if (!mod)
1827                                 retval.push_back(*it + " (Unavailable)");
1828                         else
1829                                 retval.push_back(mod->getName());
1830                 }
1831                 return retval;
1832         }
1833 }
1834
1835
1836 void GuiDocument::modulesToParams(BufferParams & bp)
1837 {
1838         // update list of loaded modules
1839         bp.clearLayoutModules();
1840         int const srows = modules_sel_model_.rowCount();
1841         for (int i = 0; i < srows; ++i)
1842                 bp.addLayoutModule(modules_sel_model_.getIDString(i));
1843
1844         // update the list of removed modules
1845         bp.clearRemovedModules();
1846         LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
1847         list<string>::const_iterator rit = reqmods.begin();
1848         list<string>::const_iterator ren = reqmods.end();
1849
1850         // check each of the default modules
1851         for (; rit != ren; rit++) {
1852                 list<string>::const_iterator mit = bp.getModules().begin();
1853                 list<string>::const_iterator men = bp.getModules().end();
1854                 bool found = false;
1855                 for (; mit != men; mit++) {
1856                         if (*rit == *mit) {
1857                                 found = true;
1858                                 break;
1859                         }
1860                 }
1861                 if (!found) {
1862                         // the module isn't present so must have been removed by the user
1863                         bp.addRemovedModule(*rit);
1864                 }
1865         }
1866 }
1867
1868 void GuiDocument::modulesChanged()
1869 {
1870         modulesToParams(bp_);
1871         bp_.makeDocumentClass();
1872         paramsToDialog();
1873 }
1874
1875
1876 void GuiDocument::updateModuleInfo()
1877 {
1878         selectionManager->update();
1879         
1880         //Module description
1881         bool const focus_on_selected = selectionManager->selectedFocused();
1882         QAbstractItemView * lv;
1883         if (focus_on_selected)
1884                 lv = modulesModule->selectedLV;
1885         else
1886                 lv= modulesModule->availableLV;
1887         if (lv->selectionModel()->selectedIndexes().isEmpty()) {
1888                 modulesModule->infoML->document()->clear();
1889                 return;
1890         }
1891         QModelIndex const & idx = lv->selectionModel()->currentIndex();
1892         GuiIdListModel const & id_model = 
1893                         focus_on_selected  ? modules_sel_model_ : modules_av_model_;
1894         string const modName = id_model.getIDString(idx.row());
1895         docstring desc = getModuleDescription(modName);
1896
1897         LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
1898         if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
1899                 if (!desc.empty())
1900                         desc += "\n";
1901                 desc += _("Module provided by document class.");
1902         }
1903
1904         vector<string> pkglist = getPackageList(modName);
1905         docstring pkgdesc = formatStrVec(pkglist, _("and"));
1906         if (!pkgdesc.empty()) {
1907                 if (!desc.empty())
1908                         desc += "\n";
1909                 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
1910         }
1911
1912         pkglist = getRequiredList(modName);
1913         if (!pkglist.empty()) {
1914                 vector<string> const reqdescs = idsToNames(pkglist);
1915                 pkgdesc = formatStrVec(reqdescs, _("or"));
1916                 if (!desc.empty())
1917                         desc += "\n";
1918                 desc += bformat(_("Module required: %1$s."), pkgdesc);
1919         }
1920
1921         pkglist = getExcludedList(modName);
1922         if (!pkglist.empty()) {
1923                 vector<string> const reqdescs = idsToNames(pkglist);
1924                 pkgdesc = formatStrVec(reqdescs, _( "and"));
1925                 if (!desc.empty())
1926                         desc += "\n";
1927                 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
1928         }
1929
1930         if (!isModuleAvailable(modName)) {
1931                 if (!desc.empty())
1932                         desc += "\n";
1933                 desc += _("WARNING: Some required packages are unavailable!");
1934         }
1935
1936         modulesModule->infoML->document()->setPlainText(toqstr(desc));
1937 }
1938
1939
1940 void GuiDocument::updateNumbering()
1941 {
1942         DocumentClass const & tclass = documentClass();
1943
1944         numberingModule->tocTW->setUpdatesEnabled(false);
1945         numberingModule->tocTW->clear();
1946
1947         int const depth = numberingModule->depthSL->value();
1948         int const toc = numberingModule->tocSL->value();
1949         QString const no = qt_("No");
1950         QString const yes = qt_("Yes");
1951         QTreeWidgetItem * item = 0;
1952
1953         DocumentClass::const_iterator lit = tclass.begin();
1954         DocumentClass::const_iterator len = tclass.end();
1955         for (; lit != len; ++lit) {
1956                 int const toclevel = lit->toclevel;
1957                 if (toclevel != Layout::NOT_IN_TOC && lit->labeltype == LABEL_COUNTER) {
1958                         item = new QTreeWidgetItem(numberingModule->tocTW);
1959                         item->setText(0, toqstr(translateIfPossible(lit->name())));
1960                         item->setText(1, (toclevel <= depth) ? yes : no);
1961                         item->setText(2, (toclevel <= toc) ? yes : no);
1962                 }
1963         }
1964
1965         numberingModule->tocTW->setUpdatesEnabled(true);
1966         numberingModule->tocTW->update();
1967 }
1968
1969
1970 void GuiDocument::updateDefaultFormat()
1971 {
1972         if (!bufferview())
1973                 return;
1974         // make a copy in order to consider unapplied changes
1975         Buffer * tmpbuf = buffer().clone();
1976         tmpbuf->params().useXetex = outputModule->xetexCB->isChecked();
1977         int idx = latexModule->classCO->currentIndex();
1978         if (idx >= 0) {
1979                 string const classname = classes_model_.getIDString(idx);
1980                 tmpbuf->params().setBaseClass(classname);
1981                 tmpbuf->params().makeDocumentClass();
1982         }
1983         outputModule->defaultFormatCO->blockSignals(true);
1984         outputModule->defaultFormatCO->clear();
1985         outputModule->defaultFormatCO->addItem(qt_("Default"),
1986                                 QVariant(QString("default")));
1987         typedef vector<Format const *> Formats;
1988         Formats formats = tmpbuf->exportableFormats(true);
1989         Formats::const_iterator cit = formats.begin();
1990         Formats::const_iterator end = formats.end();
1991         for (; cit != end; ++cit)
1992                 outputModule->defaultFormatCO->addItem(qt_((*cit)->prettyname()),
1993                                 QVariant(toqstr((*cit)->name())));
1994         outputModule->defaultFormatCO->blockSignals(false);
1995         // delete the copy
1996         delete tmpbuf;
1997 }
1998
1999
2000 bool GuiDocument::isChildIncluded(string const & child)
2001 {
2002         if (includeonlys_.empty())
2003                 return false;
2004         return (std::find(includeonlys_.begin(),
2005                           includeonlys_.end(), child) != includeonlys_.end());
2006 }
2007
2008
2009 void GuiDocument::applyView()
2010 {
2011         // preamble
2012         preambleModule->apply(bp_);
2013
2014         // date
2015         bp_.suppress_date = latexModule->suppressDateCB->isChecked();
2016
2017         // biblio
2018         bp_.setCiteEngine(ENGINE_BASIC);
2019
2020         if (biblioModule->citeNatbibRB->isChecked()) {
2021                 bool const use_numerical_citations =
2022                         biblioModule->citeStyleCO->currentIndex();
2023                 if (use_numerical_citations)
2024                         bp_.setCiteEngine(ENGINE_NATBIB_NUMERICAL);
2025                 else
2026                         bp_.setCiteEngine(ENGINE_NATBIB_AUTHORYEAR);
2027
2028         } else if (biblioModule->citeJurabibRB->isChecked())
2029                 bp_.setCiteEngine(ENGINE_JURABIB);
2030
2031         bp_.use_bibtopic =
2032                 biblioModule->bibtopicCB->isChecked();
2033
2034         string const bibtex_command =
2035                 fromqstr(biblioModule->bibtexCO->itemData(
2036                         biblioModule->bibtexCO->currentIndex()).toString());
2037         string const bibtex_options =
2038                 fromqstr(biblioModule->bibtexOptionsED->text());
2039         if (bibtex_command == "default" || bibtex_options.empty())
2040                 bp_.bibtex_command = bibtex_command;
2041         else
2042                 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
2043
2044         // Indices
2045         indicesModule->apply(bp_);
2046
2047         // language & quotes
2048         if (langModule->defaultencodingRB->isChecked()) {
2049                 bp_.inputenc = "auto";
2050         } else {
2051                 int i = langModule->encodingCO->currentIndex();
2052                 if (i == 0)
2053                         bp_.inputenc = "default";
2054                 else {
2055                         QString const enc_gui =
2056                                 langModule->encodingCO->currentText();
2057                         Encodings::const_iterator it = encodings.begin();
2058                         Encodings::const_iterator const end = encodings.end();
2059                         bool found = false;
2060                         for (; it != end; ++it) {
2061                                 if (qt_(it->guiName()) == enc_gui) {
2062                                         bp_.inputenc = it->latexName();
2063                                         found = true;
2064                                         break;
2065                                 }
2066                         }
2067                         if (!found) {
2068                                 // should not happen
2069                                 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
2070                                 bp_.inputenc = "default";
2071                         }
2072                 }
2073         }
2074
2075         InsetQuotes::QuoteLanguage lga = InsetQuotes::EnglishQuotes;
2076         switch (langModule->quoteStyleCO->currentIndex()) {
2077         case 0:
2078                 lga = InsetQuotes::EnglishQuotes;
2079                 break;
2080         case 1:
2081                 lga = InsetQuotes::SwedishQuotes;
2082                 break;
2083         case 2:
2084                 lga = InsetQuotes::GermanQuotes;
2085                 break;
2086         case 3:
2087                 lga = InsetQuotes::PolishQuotes;
2088                 break;
2089         case 4:
2090                 lga = InsetQuotes::FrenchQuotes;
2091                 break;
2092         case 5:
2093                 lga = InsetQuotes::DanishQuotes;
2094                 break;
2095         }
2096         bp_.quotes_language = lga;
2097
2098         QString const lang = langModule->languageCO->itemData(
2099                 langModule->languageCO->currentIndex()).toString();
2100         bp_.language = lyx::languages.getLanguage(fromqstr(lang));
2101
2102         //color
2103         bp_.backgroundcolor = set_backgroundcolor;
2104         bp_.isbackgroundcolor = is_backgroundcolor;
2105         bp_.fontcolor = set_fontcolor;
2106         bp_.isfontcolor = is_fontcolor;
2107         bp_.notefontcolor = set_notefontcolor;
2108         bp_.boxbgcolor = set_boxbgcolor;
2109
2110         // numbering
2111         if (bp_.documentClass().hasTocLevels()) {
2112                 bp_.tocdepth = numberingModule->tocSL->value();
2113                 bp_.secnumdepth = numberingModule->depthSL->value();
2114         }
2115
2116         // bullets
2117         bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
2118         bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
2119         bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
2120         bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
2121
2122         // packages
2123         bp_.graphicsDriver =
2124                 tex_graphics[latexModule->psdriverCO->currentIndex()];
2125         
2126         // text layout
2127         int idx = latexModule->classCO->currentIndex();
2128         if (idx >= 0) {
2129                 string const classname = classes_model_.getIDString(idx);
2130                 bp_.setBaseClass(classname);
2131         }
2132
2133         // Modules
2134         modulesToParams(bp_);
2135
2136         // Math
2137         if (mathsModule->amsautoCB->isChecked()) {
2138                 bp_.use_amsmath = BufferParams::package_auto;
2139         } else {
2140                 if (mathsModule->amsCB->isChecked())
2141                         bp_.use_amsmath = BufferParams::package_on;
2142                 else
2143                         bp_.use_amsmath = BufferParams::package_off;
2144         }
2145         if (mathsModule->esintautoCB->isChecked())
2146                 bp_.use_esint = BufferParams::package_auto;
2147         else {
2148                 if (mathsModule->esintCB->isChecked())
2149                         bp_.use_esint = BufferParams::package_on;
2150                 else
2151                         bp_.use_esint = BufferParams::package_off;
2152         }
2153         if (mathsModule->mhchemautoCB->isChecked())
2154                 bp_.use_mhchem = BufferParams::package_auto;
2155         else {
2156                 if (mathsModule->mhchemCB->isChecked())
2157                         bp_.use_mhchem = BufferParams::package_on;
2158                 else
2159                         bp_.use_mhchem = BufferParams::package_off;
2160         }
2161
2162         // Page Layout
2163         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
2164                 bp_.pagestyle = "default";
2165         else {
2166                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
2167                 for (size_t i = 0; i != pagestyles.size(); ++i)
2168                         if (pagestyles[i].second == style_gui)
2169                                 bp_.pagestyle = pagestyles[i].first;
2170         }
2171
2172         // Text Layout
2173         switch (textLayoutModule->lspacingCO->currentIndex()) {
2174         case 0:
2175                 bp_.spacing().set(Spacing::Single);
2176                 break;
2177         case 1:
2178                 bp_.spacing().set(Spacing::Onehalf);
2179                 break;
2180         case 2:
2181                 bp_.spacing().set(Spacing::Double);
2182                 break;
2183         case 3: {
2184                 string s = widgetToDoubleStr(textLayoutModule->lspacingLE);
2185                 if (s.empty())
2186                         bp_.spacing().set(Spacing::Single);
2187                 else
2188                         bp_.spacing().set(Spacing::Other, s);
2189                 break;
2190                 }
2191         }
2192
2193         if (textLayoutModule->twoColumnCB->isChecked())
2194                 bp_.columns = 2;
2195         else
2196                 bp_.columns = 1;
2197
2198         if (textLayoutModule->indentRB->isChecked()) {
2199                 // if paragraphs are separated by an indentation
2200                 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
2201                 switch (textLayoutModule->indentCO->currentIndex()) {
2202                 case 0:
2203                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2204                         break;
2205                 case 1: {
2206                         HSpace indent = HSpace(
2207                                 widgetsToLength(textLayoutModule->indentLE,
2208                                 textLayoutModule->indentLengthCO)
2209                                 );
2210                         bp_.setIndentation(indent);
2211                         break;
2212                         }
2213                 default:
2214                         // this should never happen
2215                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2216                         break;
2217                 }
2218         } else {
2219                 // if paragraphs are separated by a skip
2220                 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
2221                 switch (textLayoutModule->skipCO->currentIndex()) {
2222                 case 0:
2223                         bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
2224                         break;
2225                 case 1:
2226                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2227                         break;
2228                 case 2:
2229                         bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
2230                         break;
2231                 case 3:
2232                         {
2233                         VSpace vs = VSpace(
2234                                 widgetsToLength(textLayoutModule->skipLE,
2235                                 textLayoutModule->skipLengthCO)
2236                                 );
2237                         bp_.setDefSkip(vs);
2238                         break;
2239                         }
2240                 default:
2241                         // this should never happen
2242                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2243                         break;
2244                 }
2245         }
2246
2247         bp_.options =
2248                 fromqstr(latexModule->optionsLE->text());
2249
2250         bp_.use_default_options =
2251                 latexModule->defaultOptionsCB->isChecked();
2252
2253         if (latexModule->childDocGB->isChecked())
2254                 bp_.master =
2255                         fromqstr(latexModule->childDocLE->text());
2256         else
2257                 bp_.master = string();
2258
2259         // Master/Child
2260         bp_.clearIncludedChildren();
2261         if (masterChildModule->includeonlyRB->isChecked()) {
2262                 list<string>::const_iterator it = includeonlys_.begin();
2263                 for (; it != includeonlys_.end() ; ++it) {
2264                         bp_.addIncludedChildren(*it);
2265                 }
2266         }
2267         bp_.maintain_unincluded_children =
2268                 masterChildModule->maintainAuxCB->isChecked();
2269
2270         // Float Placement
2271         bp_.float_placement = floatModule->get();
2272
2273         // Listings
2274         // text should have passed validation
2275         bp_.listings_params =
2276                 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
2277
2278         // output
2279         bp_.defaultOutputFormat = fromqstr(outputModule->defaultFormatCO->itemData(
2280                 outputModule->defaultFormatCO->currentIndex()).toString());
2281
2282         bool const xetex = outputModule->xetexCB->isChecked();
2283         bp_.useXetex = xetex;
2284
2285         bp_.output_sync = outputModule->outputsyncCB->isChecked();
2286         bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
2287
2288         int mathfmt = outputModule->mathoutCB->currentIndex();
2289         if (mathfmt == -1)
2290                 mathfmt = 0;
2291         BufferParams::MathOutput const mo =
2292                 static_cast<BufferParams::MathOutput>(mathfmt);
2293         bp_.html_math_output = mo;
2294         bp_.html_be_strict = outputModule->strictCB->isChecked();
2295         bp_.html_math_img_scale = outputModule->mathimgSB->value();
2296
2297         // fonts
2298         if (xetex) {
2299                 if (fontModule->fontsRomanCO->currentIndex() == 0)
2300                         bp_.fontsRoman = "default";
2301                 else
2302                         bp_.fontsRoman =
2303                                 fromqstr(fontModule->fontsRomanCO->currentText());
2304         
2305                 if (fontModule->fontsSansCO->currentIndex() == 0)
2306                         bp_.fontsSans = "default";
2307                 else
2308                         bp_.fontsSans =
2309                                 fromqstr(fontModule->fontsSansCO->currentText());
2310         
2311                 if (fontModule->fontsTypewriterCO->currentIndex() == 0)
2312                         bp_.fontsTypewriter = "default";
2313                 else
2314                         bp_.fontsTypewriter =
2315                                 fromqstr(fontModule->fontsTypewriterCO->currentText());
2316         } else {
2317                 bp_.fontsRoman =
2318                         tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
2319         
2320                 bp_.fontsSans =
2321                         tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
2322         
2323                 bp_.fontsTypewriter =
2324                         tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
2325         }
2326
2327         if (fontModule->fontencCO->currentIndex() == 0)
2328                 bp_.fontenc = "global";
2329         else if (fontModule->fontencCO->currentIndex() == 1)
2330                 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
2331         else if (fontModule->fontencCO->currentIndex() == 2)
2332                 bp_.fontenc = "default";
2333
2334         bp_.fontsCJK =
2335                 fromqstr(fontModule->cjkFontLE->text());
2336
2337         bp_.fontsSansScale = fontModule->scaleSansSB->value();
2338
2339         bp_.fontsTypewriterScale = fontModule->scaleTypewriterSB->value();
2340
2341         bp_.fontsSC = fontModule->fontScCB->isChecked();
2342
2343         bp_.fontsOSF = fontModule->fontOsfCB->isChecked();
2344
2345         if (xetex)
2346                 bp_.fontsDefaultFamily = "default";
2347         else
2348                 bp_.fontsDefaultFamily = GuiDocument::fontfamilies[
2349                         fontModule->fontsDefaultCO->currentIndex()];
2350
2351         if (fontModule->fontsizeCO->currentIndex() == 0)
2352                 bp_.fontsize = "default";
2353         else
2354                 bp_.fontsize =
2355                         fromqstr(fontModule->fontsizeCO->currentText());
2356
2357         // paper
2358         bp_.papersize = PAPER_SIZE(
2359                 pageLayoutModule->papersizeCO->currentIndex());
2360
2361         bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
2362                 pageLayoutModule->paperwidthUnitCO);
2363
2364         bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
2365                 pageLayoutModule->paperheightUnitCO);
2366
2367         if (pageLayoutModule->facingPagesCB->isChecked())
2368                 bp_.sides = TwoSides;
2369         else
2370                 bp_.sides = OneSide;
2371
2372         if (pageLayoutModule->landscapeRB->isChecked())
2373                 bp_.orientation = ORIENTATION_LANDSCAPE;
2374         else
2375                 bp_.orientation = ORIENTATION_PORTRAIT;
2376
2377         // margins
2378         bp_.use_geometry = !marginsModule->marginCB->isChecked();
2379
2380         Ui::MarginsUi const * m = marginsModule;
2381
2382         bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
2383         bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
2384         bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
2385         bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
2386         bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
2387         bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
2388         bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
2389         bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
2390
2391         // branches
2392         branchesModule->apply(bp_);
2393
2394         // PDF support
2395         PDFOptions & pdf = bp_.pdfoptions();
2396         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
2397         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
2398         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
2399         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
2400         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
2401
2402         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
2403         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
2404         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
2405         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
2406
2407         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
2408         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
2409         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
2410         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
2411         pdf.backref =
2412                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
2413         if (pdfSupportModule->fullscreenCB->isChecked())
2414                 pdf.pagemode = pdf.pagemode_fullscreen;
2415         else
2416                 pdf.pagemode.clear();
2417         pdf.quoted_options = pdf.quoted_options_check(
2418                                 fromqstr(pdfSupportModule->optionsLE->text()));
2419 }
2420
2421
2422 void GuiDocument::paramsToDialog()
2423 {
2424         // set the default unit
2425         Length::UNIT const defaultUnit = Length::defaultUnit();
2426
2427         // preamble
2428         preambleModule->update(bp_, id());
2429
2430         // date
2431         latexModule->suppressDateCB->setChecked(bp_.suppress_date);
2432
2433         // biblio
2434         biblioModule->citeDefaultRB->setChecked(
2435                 bp_.citeEngine() == ENGINE_BASIC);
2436
2437         biblioModule->citeNatbibRB->setChecked(
2438                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL ||
2439                 bp_.citeEngine() == ENGINE_NATBIB_AUTHORYEAR);
2440
2441         biblioModule->citeStyleCO->setCurrentIndex(
2442                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL);
2443
2444         biblioModule->citeJurabibRB->setChecked(
2445                 bp_.citeEngine() == ENGINE_JURABIB);
2446
2447         biblioModule->bibtopicCB->setChecked(
2448                 bp_.use_bibtopic);
2449
2450         string command;
2451         string options =
2452                 split(bp_.bibtex_command, command, ' ');
2453
2454         int const bpos = biblioModule->bibtexCO->findData(toqstr(command));
2455         if (bpos != -1) {
2456                 biblioModule->bibtexCO->setCurrentIndex(bpos);
2457                 biblioModule->bibtexOptionsED->setText(toqstr(options).trimmed());
2458         } else {
2459                 biblioModule->bibtexCO->setCurrentIndex(0);
2460                 biblioModule->bibtexOptionsED->clear();
2461         }
2462         biblioModule->bibtexOptionsED->setEnabled(
2463                 biblioModule->bibtexCO->currentIndex() != 0);
2464
2465         // indices
2466         indicesModule->update(bp_);
2467
2468         // language & quotes
2469         int const pos = langModule->languageCO->findData(toqstr(
2470                 bp_.language->lang()));
2471         langModule->languageCO->setCurrentIndex(pos);
2472
2473         langModule->quoteStyleCO->setCurrentIndex(
2474                 bp_.quotes_language);
2475
2476         bool default_enc = true;
2477         if (bp_.inputenc != "auto") {
2478                 default_enc = false;
2479                 if (bp_.inputenc == "default") {
2480                         langModule->encodingCO->setCurrentIndex(0);
2481                 } else {
2482                         string enc_gui;
2483                         Encodings::const_iterator it = encodings.begin();
2484                         Encodings::const_iterator const end = encodings.end();
2485                         for (; it != end; ++it) {
2486                                 if (it->latexName() == bp_.inputenc) {
2487                                         enc_gui = it->guiName();
2488                                         break;
2489                                 }
2490                         }
2491                         int const i = langModule->encodingCO->findText(
2492                                         qt_(enc_gui));
2493                         if (i >= 0)
2494                                 langModule->encodingCO->setCurrentIndex(i);
2495                         else
2496                                 // unknown encoding. Set to default.
2497                                 default_enc = true;
2498                 }
2499         }
2500         langModule->defaultencodingRB->setChecked(default_enc);
2501         langModule->otherencodingRB->setChecked(!default_enc);
2502
2503         //color
2504         if (bp_.isfontcolor) {
2505                 colorModule->fontColorPB->setStyleSheet(
2506                         colorButtonStyleSheet(rgb2qcolor(bp_.fontcolor)));
2507         }
2508         set_fontcolor = bp_.fontcolor;
2509         is_fontcolor = bp_.isfontcolor;
2510
2511         colorModule->noteFontColorPB->setStyleSheet(
2512                 colorButtonStyleSheet(rgb2qcolor(bp_.notefontcolor)));
2513         set_notefontcolor = bp_.notefontcolor;
2514
2515         if (bp_.isbackgroundcolor) {
2516                 colorModule->backgroundPB->setStyleSheet(
2517                         colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
2518         }
2519         set_backgroundcolor = bp_.backgroundcolor;
2520         is_backgroundcolor = bp_.isbackgroundcolor;
2521
2522         colorModule->boxBackgroundPB->setStyleSheet(
2523                 colorButtonStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
2524         set_boxbgcolor = bp_.boxbgcolor;
2525
2526         // numbering
2527         int const min_toclevel = documentClass().min_toclevel();
2528         int const max_toclevel = documentClass().max_toclevel();
2529         if (documentClass().hasTocLevels()) {
2530                 numberingModule->setEnabled(true);
2531                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
2532                 numberingModule->depthSL->setMaximum(max_toclevel);
2533                 numberingModule->depthSL->setValue(bp_.secnumdepth);
2534                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
2535                 numberingModule->tocSL->setMaximum(max_toclevel);
2536                 numberingModule->tocSL->setValue(bp_.tocdepth);
2537                 updateNumbering();
2538         } else {
2539                 numberingModule->setEnabled(false);
2540                 numberingModule->tocTW->clear();
2541         }
2542
2543         // bullets
2544         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
2545         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
2546         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
2547         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
2548         bulletsModule->init();
2549
2550         // packages
2551         int nitem = findToken(tex_graphics, bp_.graphicsDriver);
2552         if (nitem >= 0)
2553                 latexModule->psdriverCO->setCurrentIndex(nitem);
2554         updateModuleInfo();
2555         
2556         mathsModule->amsCB->setChecked(
2557                 bp_.use_amsmath == BufferParams::package_on);
2558         mathsModule->amsautoCB->setChecked(
2559                 bp_.use_amsmath == BufferParams::package_auto);
2560
2561         mathsModule->esintCB->setChecked(
2562                 bp_.use_esint == BufferParams::package_on);
2563         mathsModule->esintautoCB->setChecked(
2564                 bp_.use_esint == BufferParams::package_auto);
2565
2566         mathsModule->mhchemCB->setChecked(
2567                 bp_.use_mhchem == BufferParams::package_on);
2568         mathsModule->mhchemautoCB->setChecked(
2569                 bp_.use_mhchem == BufferParams::package_auto);
2570
2571         switch (bp_.spacing().getSpace()) {
2572                 case Spacing::Other: nitem = 3; break;
2573                 case Spacing::Double: nitem = 2; break;
2574                 case Spacing::Onehalf: nitem = 1; break;
2575                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
2576         }
2577
2578         // text layout
2579         string const & layoutID = bp_.baseClassID();
2580         setLayoutComboByIDString(layoutID);
2581
2582         updatePagestyle(documentClass().opt_pagestyle(),
2583                                  bp_.pagestyle);
2584
2585         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
2586         if (bp_.spacing().getSpace() == Spacing::Other) {
2587                 doubleToWidget(textLayoutModule->lspacingLE,
2588                         bp_.spacing().getValueAsString());
2589         }
2590         setLSpacing(nitem);
2591
2592         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
2593                 textLayoutModule->indentRB->setChecked(true);
2594                 string indentation = bp_.getIndentation().asLyXCommand();
2595                 int indent = 0;
2596                 if (indentation != "default") {
2597                         lengthToWidgets(textLayoutModule->indentLE,
2598                         textLayoutModule->indentLengthCO,
2599                         indentation, defaultUnit);
2600                         indent = 1;
2601                 }
2602                 textLayoutModule->indentCO->setCurrentIndex(indent);
2603                 setIndent(indent);
2604         } else {
2605                 textLayoutModule->skipRB->setChecked(true);
2606                 int skip = 0;
2607                 switch (bp_.getDefSkip().kind()) {
2608                 case VSpace::SMALLSKIP:
2609                         skip = 0;
2610                         break;
2611                 case VSpace::MEDSKIP:
2612                         skip = 1;
2613                         break;
2614                 case VSpace::BIGSKIP:
2615                         skip = 2;
2616                         break;
2617                 case VSpace::LENGTH:
2618                         {
2619                         skip = 3;
2620                         string const length = bp_.getDefSkip().asLyXCommand();
2621                         lengthToWidgets(textLayoutModule->skipLE,
2622                                 textLayoutModule->skipLengthCO,
2623                                 length, defaultUnit);
2624                         break;
2625                         }
2626                 default:
2627                         skip = 0;
2628                         break;
2629                 }
2630                 textLayoutModule->skipCO->setCurrentIndex(skip);
2631                 setSkip(skip);
2632         }
2633
2634         textLayoutModule->twoColumnCB->setChecked(
2635                 bp_.columns == 2);
2636
2637         if (!bp_.options.empty()) {
2638                 latexModule->optionsLE->setText(
2639                         toqstr(bp_.options));
2640         } else {
2641                 latexModule->optionsLE->setText(QString());
2642         }
2643
2644         // latex
2645         latexModule->defaultOptionsCB->setChecked(
2646                         bp_.use_default_options);
2647         updateSelectedModules();
2648         selectionManager->updateProvidedModules(
2649                         bp_.baseClass()->providedModules());
2650         selectionManager->updateExcludedModules(
2651                         bp_.baseClass()->excludedModules());
2652
2653         if (!documentClass().options().empty()) {
2654                 latexModule->defaultOptionsLE->setText(
2655                         toqstr(documentClass().options()));
2656         } else {
2657                 latexModule->defaultOptionsLE->setText(
2658                         toqstr(_("[No options predefined]")));
2659         }
2660
2661         latexModule->defaultOptionsLE->setEnabled(
2662                 bp_.use_default_options
2663                 && !documentClass().options().empty());
2664
2665         latexModule->defaultOptionsCB->setEnabled(
2666                 !documentClass().options().empty());
2667
2668         if (!bp_.master.empty()) {
2669                 latexModule->childDocGB->setChecked(true);
2670                 latexModule->childDocLE->setText(
2671                         toqstr(bp_.master));
2672         } else {
2673                 latexModule->childDocLE->setText(QString());
2674                 latexModule->childDocGB->setChecked(false);
2675         }
2676
2677         // Master/Child
2678         std::vector<Buffer *> children;
2679         if (bufferview())
2680                 children = buffer().getChildren(false);
2681         if (children.empty()) {
2682                 masterChildModule->childrenTW->clear();
2683                 includeonlys_.clear();
2684                 docPS->showPanel(qt_("Child Documents"), false);
2685                 if (docPS->isCurrentPanel(qt_("Child Documents")))
2686                         docPS->setCurrentPanel(qt_("Document Class"));
2687         } else {
2688                 docPS->showPanel(qt_("Child Documents"), true);
2689                 masterChildModule->setEnabled(true);
2690                 includeonlys_ = bp_.getIncludedChildren();
2691                 updateIncludeonlys();
2692         }
2693         masterChildModule->maintainAuxCB->setChecked(
2694                 bp_.maintain_unincluded_children);
2695
2696         // Float Settings
2697         floatModule->set(bp_.float_placement);
2698
2699         // ListingsSettings
2700         // break listings_params to multiple lines
2701         string lstparams =
2702                 InsetListingsParams(bp_.listings_params).separatedParams();
2703         listingsModule->listingsED->setPlainText(toqstr(lstparams));
2704
2705         // Output
2706         // update combobox with formats
2707         updateDefaultFormat();
2708         int index = outputModule->defaultFormatCO->findData(toqstr(
2709                 bp_.defaultOutputFormat));
2710         // set to default if format is not found 
2711         if (index == -1)
2712                 index = 0;
2713         outputModule->defaultFormatCO->setCurrentIndex(index);
2714         outputModule->xetexCB->setEnabled(bp_.baseClass()->outputType() == lyx::LATEX);
2715         outputModule->xetexCB->setChecked(
2716                 bp_.baseClass()->outputType() == lyx::LATEX && bp_.useXetex);
2717
2718         outputModule->outputsyncCB->setChecked(bp_.output_sync);
2719         outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
2720
2721         outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
2722         outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
2723         outputModule->strictCB->setChecked(bp_.html_be_strict);
2724
2725         // Fonts
2726         updateFontsize(documentClass().opt_fontsize(),
2727                         bp_.fontsize);
2728
2729         if (bp_.useXetex) {
2730                 fontModule->fontencLA->setEnabled(false);
2731                 fontModule->fontencCO->setEnabled(false);
2732                 fontModule->fontencLE->setEnabled(false);
2733                 for (int i = 0; i < fontModule->fontsRomanCO->count(); ++i) {
2734                         if (fontModule->fontsRomanCO->itemText(i) == toqstr(bp_.fontsRoman)) {
2735                                 fontModule->fontsRomanCO->setCurrentIndex(i);
2736                                 return;
2737                         }
2738                 }
2739                 
2740                 for (int i = 0; i < fontModule->fontsSansCO->count(); ++i) {
2741                         if (fontModule->fontsSansCO->itemText(i) == toqstr(bp_.fontsSans)) {
2742                                 fontModule->fontsSansCO->setCurrentIndex(i);
2743                                 return;
2744                         }
2745                 }
2746                 for (int i = 0; i < fontModule->fontsTypewriterCO->count(); ++i) {
2747                         if (fontModule->fontsTypewriterCO->itemText(i) == 
2748                                 toqstr(bp_.fontsTypewriter)) {
2749                                 fontModule->fontsTypewriterCO->setCurrentIndex(i);
2750                                 return;
2751                         }
2752                 }
2753         } else {
2754                 fontModule->fontencLA->setEnabled(true);
2755                 fontModule->fontencCO->setEnabled(true);
2756                 fontModule->fontencLE->setEnabled(true);
2757                 int n = findToken(tex_fonts_roman, bp_.fontsRoman);
2758                 if (n >= 0) {
2759                         fontModule->fontsRomanCO->setCurrentIndex(n);
2760                         romanChanged(n);
2761                 }
2762         
2763                 n = findToken(tex_fonts_sans, bp_.fontsSans);
2764                 if (n >= 0) {
2765                         fontModule->fontsSansCO->setCurrentIndex(n);
2766                         sansChanged(n);
2767                 }
2768         
2769                 n = findToken(tex_fonts_monospaced, bp_.fontsTypewriter);
2770                 if (n >= 0) {
2771                         fontModule->fontsTypewriterCO->setCurrentIndex(n);
2772                         ttChanged(n);
2773                 }
2774         }
2775
2776         if (!bp_.fontsCJK.empty())
2777                 fontModule->cjkFontLE->setText(
2778                         toqstr(bp_.fontsCJK));
2779         else
2780                 fontModule->cjkFontLE->setText(QString());
2781
2782         fontModule->fontScCB->setChecked(bp_.fontsSC);
2783         fontModule->fontOsfCB->setChecked(bp_.fontsOSF);
2784         fontModule->scaleSansSB->setValue(bp_.fontsSansScale);
2785         fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale);
2786         
2787         int nn = findToken(GuiDocument::fontfamilies, bp_.fontsDefaultFamily);
2788         if (nn >= 0)
2789                 fontModule->fontsDefaultCO->setCurrentIndex(nn);
2790
2791         if (bp_.fontenc == "global")
2792                 fontModule->fontencCO->setCurrentIndex(0);
2793         else if (bp_.fontenc == "default")
2794                 fontModule->fontencCO->setCurrentIndex(2);
2795         else {
2796                 fontModule->fontencCO->setCurrentIndex(1);
2797                 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
2798         }
2799
2800         // paper
2801         bool const extern_geometry =
2802                 documentClass().provides("geometry");
2803         int const psize = bp_.papersize;
2804         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
2805         setCustomPapersize(!extern_geometry && psize == 1);
2806         pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
2807
2808         bool const landscape =
2809                 bp_.orientation == ORIENTATION_LANDSCAPE;
2810         pageLayoutModule->landscapeRB->setChecked(landscape);
2811         pageLayoutModule->portraitRB->setChecked(!landscape);
2812         pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
2813         pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
2814
2815         pageLayoutModule->facingPagesCB->setChecked(
2816                 bp_.sides == TwoSides);
2817
2818         lengthToWidgets(pageLayoutModule->paperwidthLE,
2819                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, defaultUnit);
2820         lengthToWidgets(pageLayoutModule->paperheightLE,
2821                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, defaultUnit);
2822
2823         // margins
2824         Ui::MarginsUi * m = marginsModule;
2825
2826         setMargins();
2827
2828         lengthToWidgets(m->topLE, m->topUnit,
2829                 bp_.topmargin, defaultUnit);
2830
2831         lengthToWidgets(m->bottomLE, m->bottomUnit,
2832                 bp_.bottommargin, defaultUnit);
2833
2834         lengthToWidgets(m->innerLE, m->innerUnit,
2835                 bp_.leftmargin, defaultUnit);
2836
2837         lengthToWidgets(m->outerLE, m->outerUnit,
2838                 bp_.rightmargin, defaultUnit);
2839
2840         lengthToWidgets(m->headheightLE, m->headheightUnit,
2841                 bp_.headheight, defaultUnit);
2842
2843         lengthToWidgets(m->headsepLE, m->headsepUnit,
2844                 bp_.headsep, defaultUnit);
2845
2846         lengthToWidgets(m->footskipLE, m->footskipUnit,
2847                 bp_.footskip, defaultUnit);
2848
2849         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
2850                 bp_.columnsep, defaultUnit);
2851
2852         // branches
2853         updateUnknownBranches();
2854         branchesModule->update(bp_);
2855
2856         // PDF support
2857         PDFOptions const & pdf = bp_.pdfoptions();
2858         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
2859         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
2860         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
2861         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
2862         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
2863
2864         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
2865         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
2866         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
2867
2868         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
2869
2870         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
2871         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
2872         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
2873         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
2874
2875         nn = findToken(backref_opts, pdf.backref);
2876         if (nn >= 0)
2877                 pdfSupportModule->backrefCO->setCurrentIndex(nn);
2878
2879         pdfSupportModule->fullscreenCB->setChecked
2880                 (pdf.pagemode == pdf.pagemode_fullscreen);
2881
2882         pdfSupportModule->optionsLE->setText(
2883                 toqstr(pdf.quoted_options));
2884
2885         // Make sure that the bc is in the INITIAL state
2886         if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
2887                 bc().restore();
2888
2889         // clear changed branches cache
2890         changedBranches_.clear();
2891 }
2892
2893
2894 void GuiDocument::saveDocDefault()
2895 {
2896         // we have to apply the params first
2897         applyView();
2898         saveAsDefault();
2899 }
2900
2901
2902 void GuiDocument::updateAvailableModules() 
2903 {
2904         modules_av_model_.clear();
2905         list<modInfoStruct> const & modInfoList = getModuleInfo();
2906         list<modInfoStruct>::const_iterator mit = modInfoList.begin();
2907         list<modInfoStruct>::const_iterator men = modInfoList.end();
2908         for (int i = 0; mit != men; ++mit, ++i)
2909                 modules_av_model_.insertRow(i, mit->name, mit->id, 
2910                                 mit->description);
2911 }
2912
2913
2914 void GuiDocument::updateSelectedModules() 
2915 {
2916         modules_sel_model_.clear();
2917         list<modInfoStruct> const selModList = getSelectedModules();
2918         list<modInfoStruct>::const_iterator mit = selModList.begin();
2919         list<modInfoStruct>::const_iterator men = selModList.end();
2920         for (int i = 0; mit != men; ++mit, ++i)
2921                 modules_sel_model_.insertRow(i, mit->name, mit->id, 
2922                                 mit->description);
2923 }
2924
2925
2926 void GuiDocument::updateIncludeonlys()
2927 {
2928         masterChildModule->childrenTW->clear();
2929         QString const no = qt_("No");
2930         QString const yes = qt_("Yes");
2931
2932         if (includeonlys_.empty()) {
2933                 masterChildModule->includeallRB->setChecked(true);
2934                 masterChildModule->childrenTW->setEnabled(false);
2935                 masterChildModule->maintainAuxCB->setEnabled(false);
2936         } else {
2937                 masterChildModule->includeonlyRB->setChecked(true);
2938                 masterChildModule->childrenTW->setEnabled(true);
2939                 masterChildModule->maintainAuxCB->setEnabled(true);
2940         }
2941         QTreeWidgetItem * item = 0;
2942         std::vector<Buffer *> children = buffer().getChildren(false);
2943         vector<Buffer *>::const_iterator it  = children.begin();
2944         vector<Buffer *>::const_iterator end = children.end();
2945         bool has_unincluded = false;
2946         bool all_unincluded = true;
2947         for (; it != end; ++it) {
2948                 item = new QTreeWidgetItem(masterChildModule->childrenTW);
2949                 // FIXME Unicode
2950                 string const name =
2951                         to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
2952                                                         from_utf8(buffer().filePath())));
2953                 item->setText(0, toqstr(name));
2954                 item->setText(1, isChildIncluded(name) ? yes : no);
2955                 if (!isChildIncluded(name))
2956                         has_unincluded = true;
2957                 else
2958                         all_unincluded = false;
2959         }
2960         // Both if all childs are included and if none is included
2961         // is equal to "include all" (i.e., ommit \includeonly).
2962         // Thus, reset the GUI.
2963         if (!has_unincluded || all_unincluded) {
2964                 masterChildModule->includeallRB->setChecked(true);
2965                 masterChildModule->childrenTW->setEnabled(false);
2966                 includeonlys_.clear();
2967         }
2968         // If all are included, we need to update again.
2969         if (!has_unincluded)
2970                 updateIncludeonlys();
2971 }
2972
2973
2974 void GuiDocument::updateContents()
2975 {
2976         // Nothing to do here as the document settings is not cursor dependant.
2977         return;
2978 }
2979
2980
2981 void GuiDocument::useClassDefaults()
2982 {
2983         if (applyPB->isEnabled()) {
2984                 int const ret = Alert::prompt(_("Unapplied changes"),
2985                                 _("Some changes in the dialog were not yet applied.\n"
2986                                   "If you do not apply now, they will be lost after this action."),
2987                                 1, 1, _("&Apply"), _("&Dismiss"));
2988                 if (ret == 0)
2989                         applyView();
2990         }
2991
2992         int idx = latexModule->classCO->currentIndex();
2993         string const classname = classes_model_.getIDString(idx);
2994         if (!bp_.setBaseClass(classname)) {
2995                 Alert::error(_("Error"), _("Unable to set document class."));
2996                 return;
2997         }
2998         bp_.useClassDefaults();
2999         paramsToDialog();
3000 }
3001
3002
3003 void GuiDocument::setLayoutComboByIDString(string const & idString)
3004 {
3005         int idx = classes_model_.findIDString(idString);
3006         if (idx < 0)
3007                 Alert::warning(_("Can't set layout!"), 
3008                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
3009         else 
3010                 latexModule->classCO->setCurrentIndex(idx);
3011 }
3012
3013
3014 bool GuiDocument::isValid()
3015 {
3016         return validateListingsParameters().isEmpty()
3017                 && (textLayoutModule->skipCO->currentIndex() != 3
3018                         || !textLayoutModule->skipLE->text().isEmpty()
3019                         || textLayoutModule->indentRB->isChecked())
3020                 && (textLayoutModule->indentCO->currentIndex() != 1
3021                         || !textLayoutModule->indentLE->text().isEmpty()
3022                         || textLayoutModule->skipRB->isChecked());
3023 }
3024
3025
3026 char const * const GuiDocument::fontfamilies[5] = {
3027         "default", "rmdefault", "sfdefault", "ttdefault", ""
3028 };
3029
3030
3031 char const * GuiDocument::fontfamilies_gui[5] = {
3032         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
3033 };
3034
3035
3036 bool GuiDocument::initialiseParams(string const &)
3037 {
3038         BufferView const * view = bufferview();
3039         if (!view) {
3040                 bp_ = BufferParams();
3041                 paramsToDialog();
3042                 return true;
3043         }
3044         bp_ = view->buffer().params();
3045         loadModuleInfo();
3046         updateAvailableModules();
3047         //FIXME It'd be nice to make sure here that the selected
3048         //modules are consistent: That required modules are actually
3049         //selected, and that we don't have conflicts. If so, we could
3050         //at least pop up a warning.
3051         paramsToDialog();
3052         return true;
3053 }
3054
3055
3056 void GuiDocument::clearParams()
3057 {
3058         bp_ = BufferParams();
3059 }
3060
3061
3062 BufferId GuiDocument::id() const
3063 {
3064         BufferView const * const view = bufferview();
3065         return view? &view->buffer() : 0;
3066 }
3067
3068
3069 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
3070 {
3071         return moduleNames_;
3072 }
3073
3074
3075 list<GuiDocument::modInfoStruct> const 
3076                 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
3077 {
3078         LayoutModuleList::const_iterator it =  mods.begin();
3079         LayoutModuleList::const_iterator end = mods.end();
3080         list<modInfoStruct> mInfo;
3081         for (; it != end; ++it) {
3082                 modInfoStruct m;
3083                 m.id = *it;
3084                 LyXModule const * const mod = theModuleList[*it];
3085                 if (mod)
3086                         // FIXME Unicode
3087                         m.name = toqstr(translateIfPossible(from_utf8(mod->getName())));
3088                 else 
3089                         m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
3090                 mInfo.push_back(m);
3091         }
3092         return mInfo;
3093 }
3094
3095
3096 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
3097 {
3098         return makeModuleInfo(params().getModules());
3099 }
3100
3101
3102 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
3103 {
3104         return makeModuleInfo(params().baseClass()->providedModules());
3105 }
3106
3107
3108 DocumentClass const & GuiDocument::documentClass() const
3109 {
3110         return bp_.documentClass();
3111 }
3112
3113
3114 static void dispatch_bufferparams(Dialog const & dialog,
3115         BufferParams const & bp, FuncCode lfun)
3116 {
3117         ostringstream ss;
3118         ss << "\\begin_header\n";
3119         bp.writeFile(ss);
3120         ss << "\\end_header\n";
3121         dialog.dispatch(FuncRequest(lfun, ss.str()));
3122 }
3123
3124
3125 void GuiDocument::dispatchParams()
3126 {
3127         // This must come first so that a language change is correctly noticed
3128         setLanguage();
3129
3130         // Apply the BufferParams. Note that this will set the base class
3131         // and then update the buffer's layout.
3132         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
3133
3134         if (!params().master.empty()) {
3135                 FileName const master_file = support::makeAbsPath(params().master,
3136                            support::onlyPath(buffer().absFileName()));
3137                 if (isLyXFileName(master_file.absFileName())) {
3138                         Buffer * master = checkAndLoadLyXFile(master_file);
3139                         if (master) {
3140                                 if (master->isChild(const_cast<Buffer *>(&buffer())))
3141                                         const_cast<Buffer &>(buffer()).setParent(master);
3142                                 else
3143                                         Alert::warning(_("Assigned master does not include this file"), 
3144                                                 bformat(_("You must include this file in the document\n"
3145                                                           "'%1$s' in order to use the master document\n"
3146                                                           "feature."), from_utf8(params().master)));
3147                         } else
3148                                 Alert::warning(_("Could not load master"), 
3149                                                 bformat(_("The master document '%1$s'\n"
3150                                                            "could not be loaded."),
3151                                                            from_utf8(params().master)));
3152                 }
3153         }
3154
3155         // Generate the colours requested by each new branch.
3156         BranchList & branchlist = params().branchlist();
3157         if (!branchlist.empty()) {
3158                 BranchList::const_iterator it = branchlist.begin();
3159                 BranchList::const_iterator const end = branchlist.end();
3160                 for (; it != end; ++it) {
3161                         docstring const & current_branch = it->branch();
3162                         Branch const * branch = branchlist.find(current_branch);
3163                         string const x11hexname = X11hexname(branch->color());
3164                         // display the new color
3165                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
3166                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
3167                 }
3168
3169                 // Open insets of selected branches, close deselected ones
3170                 dispatch(FuncRequest(LFUN_INSET_FORALL,
3171                         "Branch inset-toggle assign"));
3172         }
3173         // rename branches in the document
3174         executeBranchRenaming();
3175         // and clear changed branches cache
3176         changedBranches_.clear();
3177         
3178         // Generate the colours requested by indices.
3179         IndicesList & indiceslist = params().indiceslist();
3180         if (!indiceslist.empty()) {
3181                 IndicesList::const_iterator it = indiceslist.begin();
3182                 IndicesList::const_iterator const end = indiceslist.end();
3183                 for (; it != end; ++it) {
3184                         docstring const & current_index = it->shortcut();
3185                         Index const * index = indiceslist.findShortcut(current_index);
3186                         string const x11hexname = X11hexname(index->color());
3187                         // display the new color
3188                         docstring const str = current_index + ' ' + from_ascii(x11hexname);
3189                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
3190                 }
3191         }
3192         // FIXME: If we used an LFUN, we would not need those two lines:
3193         BufferView * bv = const_cast<BufferView *>(bufferview());
3194         bv->processUpdateFlags(Update::Force | Update::FitCursor);
3195 }
3196
3197
3198 void GuiDocument::setLanguage() const
3199 {
3200         Language const * const newL = bp_.language;
3201         if (buffer().params().language == newL)
3202                 return;
3203
3204         string const & lang_name = newL->lang();
3205         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
3206 }
3207
3208
3209 void GuiDocument::saveAsDefault() const
3210 {
3211         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
3212 }
3213
3214
3215 bool GuiDocument::isFontAvailable(string const & font) const
3216 {
3217         if (font == "default" || font == "cmr"
3218             || font == "cmss" || font == "cmtt")
3219                 // these are standard
3220                 return true;
3221         if (font == "lmodern" || font == "lmss" || font == "lmtt")
3222                 return LaTeXFeatures::isAvailable("lmodern");
3223         if (font == "times" || font == "palatino"
3224                  || font == "helvet" || font == "courier")
3225                 return LaTeXFeatures::isAvailable("psnfss");
3226         if (font == "cmbr" || font == "cmtl")
3227                 return LaTeXFeatures::isAvailable("cmbright");
3228         if (font == "utopia")
3229                 return LaTeXFeatures::isAvailable("utopia")
3230                         || LaTeXFeatures::isAvailable("fourier");
3231         if (font == "beraserif" || font == "berasans"
3232                 || font == "beramono")
3233                 return LaTeXFeatures::isAvailable("bera");
3234         return LaTeXFeatures::isAvailable(font);
3235 }
3236
3237
3238 bool GuiDocument::providesOSF(string const & font) const
3239 {
3240         if (outputModule->xetexCB->isChecked())
3241                 // FIXME: we should check if the fonts really
3242                 // have OSF support. But how?
3243                 return true;
3244         if (font == "cmr")
3245                 return isFontAvailable("eco");
3246         if (font == "palatino")
3247                 return isFontAvailable("mathpazo");
3248         return false;
3249 }
3250
3251
3252 bool GuiDocument::providesSC(string const & font) const
3253 {
3254         if (outputModule->xetexCB->isChecked())
3255                 return false;
3256         if (font == "palatino")
3257                 return isFontAvailable("mathpazo");
3258         if (font == "utopia")
3259                 return isFontAvailable("fourier");
3260         return false;
3261 }
3262
3263
3264 bool GuiDocument::providesScale(string const & font) const
3265 {
3266         if (outputModule->xetexCB->isChecked())
3267                 return true;
3268         return font == "helvet" || font == "luximono"
3269                 || font == "berasans"  || font == "beramono";
3270 }
3271
3272
3273 void GuiDocument::loadModuleInfo()
3274 {
3275         moduleNames_.clear();
3276         LyXModuleList::const_iterator it  = theModuleList.begin();
3277         LyXModuleList::const_iterator end = theModuleList.end();
3278         for (; it != end; ++it) {
3279                 modInfoStruct m;
3280                 m.id = it->getID();
3281                 // FIXME Unicode
3282                 m.name = toqstr(translateIfPossible(from_utf8(it->getName())));
3283                 // this is supposed to give us the first sentence of the description
3284                 // FIXME Unicode
3285                 QString desc =
3286                         toqstr(translateIfPossible(from_utf8(it->getDescription())));
3287                 int const pos = desc.indexOf(".");
3288                 if (pos > 0)
3289                         desc.truncate(pos + 1);
3290                 m.description = desc;
3291                 moduleNames_.push_back(m);
3292         }
3293 }
3294
3295
3296 void GuiDocument::updateUnknownBranches()
3297 {
3298         if (!bufferview())
3299                 return;
3300         list<docstring> used_branches;
3301         buffer().getUsedBranches(used_branches);
3302         list<docstring>::const_iterator it = used_branches.begin();
3303         QStringList unknown_branches;
3304         for (; it != used_branches.end() ; ++it) {
3305                 if (!buffer().params().branchlist().find(*it))
3306                         unknown_branches.append(toqstr(*it));
3307         }
3308         branchesModule->setUnknownBranches(unknown_branches);
3309 }
3310
3311
3312 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
3313 {
3314         map<docstring, docstring>::iterator it = changedBranches_.begin();
3315         for (; it != changedBranches_.end() ; ++it) {
3316                 if (it->second == oldname) {
3317                         // branch has already been renamed
3318                         it->second = newname;
3319                         return;
3320                 }
3321         }
3322         // store new name
3323         changedBranches_[oldname] = newname;
3324 }
3325
3326
3327 void GuiDocument::executeBranchRenaming() const
3328 {
3329         map<docstring, docstring>::const_iterator it = changedBranches_.begin();
3330         for (; it != changedBranches_.end() ; ++it) {
3331                 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
3332                 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
3333         }
3334 }
3335
3336
3337 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
3338
3339
3340 } // namespace frontend
3341 } // namespace lyx
3342
3343 #include "moc_GuiDocument.cpp"