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