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