]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiDocument.cpp
revert r37459 and add a note to the sources:
[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         // NOTE: we do not provide "custom" here for security reasons!
1071         biblioModule->bibtexCO->clear();
1072         biblioModule->bibtexCO->addItem(qt_("Default"), QString("default"));
1073         for (set<string>::const_iterator it = lyxrc.bibtex_alternatives.begin();
1074                              it != lyxrc.bibtex_alternatives.end(); ++it) {
1075                 QString const command = toqstr(*it).left(toqstr(*it).indexOf(" "));
1076                 biblioModule->bibtexCO->addItem(command, command);
1077         }
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         biblioModule->bibtexOptionsED->setEnabled(
1908                 biblioModule->bibtexCO->itemData(n).toString() != "default");
1909         changed();
1910 }
1911
1912
1913 namespace {
1914         // FIXME unicode 
1915         // both of these should take a vector<docstring>
1916         
1917         // This is an insanely complicated attempt to make this sort of thing
1918         // work with RTL languages.
1919         docstring formatStrVec(vector<string> const & v, docstring const & s) 
1920         {
1921                 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
1922                 if (v.size() == 0)
1923                         return docstring();
1924                 if (v.size() == 1) 
1925                         return translateIfPossible(from_utf8(v[0]));
1926                 if (v.size() == 2) {
1927                         docstring retval = _("%1$s and %2$s");
1928                         retval = subst(retval, _("and"), s);
1929                         return bformat(retval, translateIfPossible(from_utf8(v[0])),
1930                                        translateIfPossible(from_utf8(v[1])));
1931                 }
1932                 // The idea here is to format all but the last two items...
1933                 int const vSize = v.size();
1934                 docstring t2 = _("%1$s, %2$s");
1935                 docstring retval = translateIfPossible(from_utf8(v[0]));
1936                 for (int i = 1; i < vSize - 2; ++i)
1937                         retval = bformat(t2, retval, translateIfPossible(from_utf8(v[i]))); 
1938                 //...and then to  plug them, and the last two, into this schema
1939                 docstring t = _("%1$s, %2$s, and %3$s");
1940                 t = subst(t, _("and"), s);
1941                 return bformat(t, retval, translateIfPossible(from_utf8(v[vSize - 2])),
1942                                translateIfPossible(from_utf8(v[vSize - 1])));
1943         }
1944         
1945         vector<string> idsToNames(vector<string> const & idList)
1946         {
1947                 vector<string> retval;
1948                 vector<string>::const_iterator it  = idList.begin();
1949                 vector<string>::const_iterator end = idList.end();
1950                 for (; it != end; ++it) {
1951                         LyXModule const * const mod = theModuleList[*it];
1952                         if (!mod)
1953                                 retval.push_back(to_utf8(bformat(_("%1$s (unavailable)"), 
1954                                                 translateIfPossible(from_utf8(*it)))));
1955                         else
1956                                 retval.push_back(mod->getName());
1957                 }
1958                 return retval;
1959         }
1960 } // end anonymous namespace
1961
1962
1963 void GuiDocument::modulesToParams(BufferParams & bp)
1964 {
1965         // update list of loaded modules
1966         bp.clearLayoutModules();
1967         int const srows = modules_sel_model_.rowCount();
1968         for (int i = 0; i < srows; ++i)
1969                 bp.addLayoutModule(modules_sel_model_.getIDString(i));
1970
1971         // update the list of removed modules
1972         bp.clearRemovedModules();
1973         LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
1974         list<string>::const_iterator rit = reqmods.begin();
1975         list<string>::const_iterator ren = reqmods.end();
1976
1977         // check each of the default modules
1978         for (; rit != ren; rit++) {
1979                 list<string>::const_iterator mit = bp.getModules().begin();
1980                 list<string>::const_iterator men = bp.getModules().end();
1981                 bool found = false;
1982                 for (; mit != men; mit++) {
1983                         if (*rit == *mit) {
1984                                 found = true;
1985                                 break;
1986                         }
1987                 }
1988                 if (!found) {
1989                         // the module isn't present so must have been removed by the user
1990                         bp.addRemovedModule(*rit);
1991                 }
1992         }
1993 }
1994
1995 void GuiDocument::modulesChanged()
1996 {
1997         modulesToParams(bp_);
1998         bp_.makeDocumentClass();
1999         paramsToDialog();
2000 }
2001
2002
2003 void GuiDocument::updateModuleInfo()
2004 {
2005         selectionManager->update();
2006         
2007         //Module description
2008         bool const focus_on_selected = selectionManager->selectedFocused();
2009         QAbstractItemView * lv;
2010         if (focus_on_selected)
2011                 lv = modulesModule->selectedLV;
2012         else
2013                 lv= modulesModule->availableLV;
2014         if (lv->selectionModel()->selectedIndexes().isEmpty()) {
2015                 modulesModule->infoML->document()->clear();
2016                 return;
2017         }
2018         QModelIndex const & idx = lv->selectionModel()->currentIndex();
2019         GuiIdListModel const & id_model = 
2020                         focus_on_selected  ? modules_sel_model_ : modules_av_model_;
2021         string const modName = id_model.getIDString(idx.row());
2022         docstring desc = getModuleDescription(modName);
2023
2024         LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
2025         if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
2026                 if (!desc.empty())
2027                         desc += "\n";
2028                 desc += _("Module provided by document class.");
2029         }
2030
2031         vector<string> pkglist = getPackageList(modName);
2032         docstring pkgdesc = formatStrVec(pkglist, _("and"));
2033         if (!pkgdesc.empty()) {
2034                 if (!desc.empty())
2035                         desc += "\n";
2036                 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
2037         }
2038
2039         pkglist = getRequiredList(modName);
2040         if (!pkglist.empty()) {
2041                 vector<string> const reqdescs = idsToNames(pkglist);
2042                 pkgdesc = formatStrVec(reqdescs, _("or"));
2043                 if (!desc.empty())
2044                         desc += "\n";
2045                 desc += bformat(_("Modules required: %1$s."), pkgdesc);
2046         }
2047
2048         pkglist = getExcludedList(modName);
2049         if (!pkglist.empty()) {
2050                 vector<string> const reqdescs = idsToNames(pkglist);
2051                 pkgdesc = formatStrVec(reqdescs, _( "and"));
2052                 if (!desc.empty())
2053                         desc += "\n";
2054                 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
2055         }
2056
2057         if (!isModuleAvailable(modName)) {
2058                 if (!desc.empty())
2059                         desc += "\n";
2060                 desc += _("WARNING: Some required packages are unavailable!");
2061         }
2062
2063         modulesModule->infoML->document()->setPlainText(toqstr(desc));
2064 }
2065
2066
2067 void GuiDocument::updateNumbering()
2068 {
2069         DocumentClass const & tclass = documentClass();
2070
2071         numberingModule->tocTW->setUpdatesEnabled(false);
2072         numberingModule->tocTW->clear();
2073
2074         int const depth = numberingModule->depthSL->value();
2075         int const toc = numberingModule->tocSL->value();
2076         QString const no = qt_("No");
2077         QString const yes = qt_("Yes");
2078         QTreeWidgetItem * item = 0;
2079
2080         DocumentClass::const_iterator lit = tclass.begin();
2081         DocumentClass::const_iterator len = tclass.end();
2082         for (; lit != len; ++lit) {
2083                 int const toclevel = lit->toclevel;
2084                 if (toclevel != Layout::NOT_IN_TOC && lit->labeltype == LABEL_COUNTER) {
2085                         item = new QTreeWidgetItem(numberingModule->tocTW);
2086                         item->setText(0, toqstr(translateIfPossible(lit->name())));
2087                         item->setText(1, (toclevel <= depth) ? yes : no);
2088                         item->setText(2, (toclevel <= toc) ? yes : no);
2089                 }
2090         }
2091
2092         numberingModule->tocTW->setUpdatesEnabled(true);
2093         numberingModule->tocTW->update();
2094 }
2095
2096
2097 void GuiDocument::updateDefaultFormat()
2098 {
2099         if (!bufferview())
2100                 return;
2101         // make a copy in order to consider unapplied changes
2102         Buffer * tmpbuf = buffer().clone();
2103         tmpbuf->params().useNonTeXFonts =
2104                 fontModule->osFontsCB->isChecked();
2105         int idx = latexModule->classCO->currentIndex();
2106         if (idx >= 0) {
2107                 string const classname = classes_model_.getIDString(idx);
2108                 tmpbuf->params().setBaseClass(classname);
2109                 tmpbuf->params().makeDocumentClass();
2110         }
2111         outputModule->defaultFormatCO->blockSignals(true);
2112         outputModule->defaultFormatCO->clear();
2113         outputModule->defaultFormatCO->addItem(qt_("Default"),
2114                                 QVariant(QString("default")));
2115         typedef vector<Format const *> Formats;
2116         Formats formats = tmpbuf->exportableFormats(true);
2117         Formats::const_iterator cit = formats.begin();
2118         Formats::const_iterator end = formats.end();
2119         for (; cit != end; ++cit)
2120                 outputModule->defaultFormatCO->addItem(qt_((*cit)->prettyname()),
2121                                 QVariant(toqstr((*cit)->name())));
2122         outputModule->defaultFormatCO->blockSignals(false);
2123         // delete the copy
2124         delete tmpbuf;
2125 }
2126
2127
2128 bool GuiDocument::isChildIncluded(string const & child)
2129 {
2130         if (includeonlys_.empty())
2131                 return false;
2132         return (std::find(includeonlys_.begin(),
2133                           includeonlys_.end(), child) != includeonlys_.end());
2134 }
2135
2136
2137 void GuiDocument::applyView()
2138 {
2139         // preamble
2140         preambleModule->apply(bp_);
2141         localLayout->apply(bp_);
2142
2143         // date
2144         bp_.suppress_date = latexModule->suppressDateCB->isChecked();
2145         bp_.use_refstyle  = latexModule->refstyleCB->isChecked();
2146
2147         // biblio
2148         bp_.setCiteEngine(ENGINE_BASIC);
2149
2150         if (biblioModule->citeNatbibRB->isChecked()) {
2151                 bool const use_numerical_citations =
2152                         biblioModule->citeStyleCO->currentIndex();
2153                 if (use_numerical_citations)
2154                         bp_.setCiteEngine(ENGINE_NATBIB_NUMERICAL);
2155                 else
2156                         bp_.setCiteEngine(ENGINE_NATBIB_AUTHORYEAR);
2157
2158         } else if (biblioModule->citeJurabibRB->isChecked())
2159                 bp_.setCiteEngine(ENGINE_JURABIB);
2160
2161         bp_.use_bibtopic =
2162                 biblioModule->bibtopicCB->isChecked();
2163
2164         string const bibtex_command =
2165                 fromqstr(biblioModule->bibtexCO->itemData(
2166                         biblioModule->bibtexCO->currentIndex()).toString());
2167         string const bibtex_options =
2168                 fromqstr(biblioModule->bibtexOptionsED->text());
2169         if (bibtex_command == "default" || bibtex_options.empty())
2170                 bp_.bibtex_command = bibtex_command;
2171         else
2172                 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
2173
2174         // Indices
2175         indicesModule->apply(bp_);
2176
2177         // language & quotes
2178         if (langModule->defaultencodingRB->isChecked()) {
2179                 bp_.inputenc = "auto";
2180         } else {
2181                 int i = langModule->encodingCO->currentIndex();
2182                 if (i == 0)
2183                         bp_.inputenc = "default";
2184                 else {
2185                         QString const enc_gui =
2186                                 langModule->encodingCO->currentText();
2187                         Encodings::const_iterator it = encodings.begin();
2188                         Encodings::const_iterator const end = encodings.end();
2189                         bool found = false;
2190                         for (; it != end; ++it) {
2191                                 if (qt_(it->guiName()) == enc_gui) {
2192                                         bp_.inputenc = it->latexName();
2193                                         found = true;
2194                                         break;
2195                                 }
2196                         }
2197                         if (!found) {
2198                                 // should not happen
2199                                 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
2200                                 bp_.inputenc = "default";
2201                         }
2202                 }
2203         }
2204
2205         InsetQuotes::QuoteLanguage lga = InsetQuotes::EnglishQuotes;
2206         switch (langModule->quoteStyleCO->currentIndex()) {
2207         case 0:
2208                 lga = InsetQuotes::EnglishQuotes;
2209                 break;
2210         case 1:
2211                 lga = InsetQuotes::SwedishQuotes;
2212                 break;
2213         case 2:
2214                 lga = InsetQuotes::GermanQuotes;
2215                 break;
2216         case 3:
2217                 lga = InsetQuotes::PolishQuotes;
2218                 break;
2219         case 4:
2220                 lga = InsetQuotes::FrenchQuotes;
2221                 break;
2222         case 5:
2223                 lga = InsetQuotes::DanishQuotes;
2224                 break;
2225         }
2226         bp_.quotes_language = lga;
2227
2228         QString const lang = langModule->languageCO->itemData(
2229                 langModule->languageCO->currentIndex()).toString();
2230         bp_.language = lyx::languages.getLanguage(fromqstr(lang));
2231         
2232         QString const pack = langModule->languagePackageCO->itemData(
2233                 langModule->languagePackageCO->currentIndex()).toString();
2234         if (pack == "custom")
2235                 bp_.lang_package =
2236                         fromqstr(langModule->languagePackageED->text());
2237         else
2238                 bp_.lang_package = fromqstr(pack);
2239
2240         //color
2241         bp_.backgroundcolor = set_backgroundcolor;
2242         bp_.isbackgroundcolor = is_backgroundcolor;
2243         bp_.fontcolor = set_fontcolor;
2244         bp_.isfontcolor = is_fontcolor;
2245         bp_.notefontcolor = set_notefontcolor;
2246         bp_.boxbgcolor = set_boxbgcolor;
2247
2248         // numbering
2249         if (bp_.documentClass().hasTocLevels()) {
2250                 bp_.tocdepth = numberingModule->tocSL->value();
2251                 bp_.secnumdepth = numberingModule->depthSL->value();
2252         }
2253
2254         // bullets
2255         bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
2256         bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
2257         bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
2258         bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
2259
2260         // packages
2261         bp_.graphics_driver =
2262                 tex_graphics[latexModule->psdriverCO->currentIndex()];
2263         
2264         // text layout
2265         int idx = latexModule->classCO->currentIndex();
2266         if (idx >= 0) {
2267                 string const classname = classes_model_.getIDString(idx);
2268                 bp_.setBaseClass(classname);
2269         }
2270
2271         // Modules
2272         modulesToParams(bp_);
2273
2274         // Math
2275         if (mathsModule->amsautoCB->isChecked())
2276                 bp_.use_amsmath = BufferParams::package_auto;
2277         else {
2278                 if (mathsModule->amsCB->isChecked())
2279                         bp_.use_amsmath = BufferParams::package_on;
2280                 else
2281                         bp_.use_amsmath = BufferParams::package_off;
2282         }
2283         if (mathsModule->esintautoCB->isChecked())
2284                 bp_.use_esint = BufferParams::package_auto;
2285         else {
2286                 if (mathsModule->esintCB->isChecked())
2287                         bp_.use_esint = BufferParams::package_on;
2288                 else
2289                         bp_.use_esint = BufferParams::package_off;
2290         }
2291         if (mathsModule->mhchemautoCB->isChecked())
2292                 bp_.use_mhchem = BufferParams::package_auto;
2293         else {
2294                 if (mathsModule->mhchemCB->isChecked())
2295                         bp_.use_mhchem = BufferParams::package_on;
2296                 else
2297                         bp_.use_mhchem = BufferParams::package_off;
2298         }
2299         if (mathsModule->mathdotsautoCB->isChecked())
2300                 bp_.use_mathdots = BufferParams::package_auto;
2301         else {
2302                 if (mathsModule->mathdotsCB->isChecked())
2303                         bp_.use_mathdots = BufferParams::package_on;
2304                 else
2305                         bp_.use_mathdots = BufferParams::package_off;
2306         }
2307         
2308         // Page Layout
2309         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
2310                 bp_.pagestyle = "default";
2311         else {
2312                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
2313                 for (size_t i = 0; i != pagestyles.size(); ++i)
2314                         if (pagestyles[i].second == style_gui)
2315                                 bp_.pagestyle = pagestyles[i].first;
2316         }
2317
2318         // Text Layout
2319         switch (textLayoutModule->lspacingCO->currentIndex()) {
2320         case 0:
2321                 bp_.spacing().set(Spacing::Single);
2322                 break;
2323         case 1:
2324                 bp_.spacing().set(Spacing::Onehalf);
2325                 break;
2326         case 2:
2327                 bp_.spacing().set(Spacing::Double);
2328                 break;
2329         case 3: {
2330                 string s = widgetToDoubleStr(textLayoutModule->lspacingLE);
2331                 if (s.empty())
2332                         bp_.spacing().set(Spacing::Single);
2333                 else
2334                         bp_.spacing().set(Spacing::Other, s);
2335                 break;
2336                 }
2337         }
2338
2339         if (textLayoutModule->twoColumnCB->isChecked())
2340                 bp_.columns = 2;
2341         else
2342                 bp_.columns = 1;
2343
2344         if (textLayoutModule->indentRB->isChecked()) {
2345                 // if paragraphs are separated by an indentation
2346                 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
2347                 switch (textLayoutModule->indentCO->currentIndex()) {
2348                 case 0:
2349                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2350                         break;
2351                 case 1: {
2352                         HSpace indent = HSpace(
2353                                 widgetsToLength(textLayoutModule->indentLE,
2354                                 textLayoutModule->indentLengthCO)
2355                                 );
2356                         bp_.setIndentation(indent);
2357                         break;
2358                         }
2359                 default:
2360                         // this should never happen
2361                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2362                         break;
2363                 }
2364         } else {
2365                 // if paragraphs are separated by a skip
2366                 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
2367                 switch (textLayoutModule->skipCO->currentIndex()) {
2368                 case 0:
2369                         bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
2370                         break;
2371                 case 1:
2372                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2373                         break;
2374                 case 2:
2375                         bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
2376                         break;
2377                 case 3:
2378                         {
2379                         VSpace vs = VSpace(
2380                                 widgetsToLength(textLayoutModule->skipLE,
2381                                 textLayoutModule->skipLengthCO)
2382                                 );
2383                         bp_.setDefSkip(vs);
2384                         break;
2385                         }
2386                 default:
2387                         // this should never happen
2388                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2389                         break;
2390                 }
2391         }
2392
2393         bp_.options =
2394                 fromqstr(latexModule->optionsLE->text());
2395
2396         bp_.use_default_options =
2397                 latexModule->defaultOptionsCB->isChecked();
2398
2399         if (latexModule->childDocGB->isChecked())
2400                 bp_.master =
2401                         fromqstr(latexModule->childDocLE->text());
2402         else
2403                 bp_.master = string();
2404
2405         // Master/Child
2406         bp_.clearIncludedChildren();
2407         if (masterChildModule->includeonlyRB->isChecked()) {
2408                 list<string>::const_iterator it = includeonlys_.begin();
2409                 for (; it != includeonlys_.end() ; ++it) {
2410                         bp_.addIncludedChildren(*it);
2411                 }
2412         }
2413         bp_.maintain_unincluded_children =
2414                 masterChildModule->maintainAuxCB->isChecked();
2415
2416         // Float Placement
2417         bp_.float_placement = floatModule->get();
2418
2419         // Listings
2420         // text should have passed validation
2421         bp_.listings_params =
2422                 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
2423
2424         // output
2425         bp_.default_output_format = fromqstr(outputModule->defaultFormatCO->itemData(
2426                 outputModule->defaultFormatCO->currentIndex()).toString());
2427
2428         bool const nontexfonts = fontModule->osFontsCB->isChecked();
2429         bp_.useNonTeXFonts = nontexfonts;
2430
2431         bp_.output_sync = outputModule->outputsyncCB->isChecked();
2432         bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
2433
2434         int mathfmt = outputModule->mathoutCB->currentIndex();
2435         if (mathfmt == -1)
2436                 mathfmt = 0;
2437         BufferParams::MathOutput const mo =
2438                 static_cast<BufferParams::MathOutput>(mathfmt);
2439         bp_.html_math_output = mo;
2440         bp_.html_be_strict = outputModule->strictCB->isChecked();
2441         bp_.html_math_img_scale = outputModule->mathimgSB->value();
2442
2443         // fonts
2444         if (nontexfonts) {
2445                 if (fontModule->fontsRomanCO->currentIndex() == 0)
2446                         bp_.fonts_roman = "default";
2447                 else
2448                         bp_.fonts_roman =
2449                                 fromqstr(fontModule->fontsRomanCO->currentText());
2450         
2451                 if (fontModule->fontsSansCO->currentIndex() == 0)
2452                         bp_.fonts_sans = "default";
2453                 else
2454                         bp_.fonts_sans =
2455                                 fromqstr(fontModule->fontsSansCO->currentText());
2456         
2457                 if (fontModule->fontsTypewriterCO->currentIndex() == 0)
2458                         bp_.fonts_typewriter = "default";
2459                 else
2460                         bp_.fonts_typewriter =
2461                                 fromqstr(fontModule->fontsTypewriterCO->currentText());
2462         } else {
2463                 bp_.fonts_roman =
2464                         tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
2465         
2466                 bp_.fonts_sans =
2467                         tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
2468         
2469                 bp_.fonts_typewriter =
2470                         tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
2471         }
2472
2473         if (fontModule->fontencCO->currentIndex() == 0)
2474                 bp_.fontenc = "global";
2475         else if (fontModule->fontencCO->currentIndex() == 1)
2476                 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
2477         else if (fontModule->fontencCO->currentIndex() == 2)
2478                 bp_.fontenc = "default";
2479
2480         bp_.fonts_cjk =
2481                 fromqstr(fontModule->cjkFontLE->text());
2482
2483         bp_.fonts_sans_scale = fontModule->scaleSansSB->value();
2484
2485         bp_.fonts_typewriter_scale = fontModule->scaleTypewriterSB->value();
2486
2487         bp_.fonts_expert_sc = fontModule->fontScCB->isChecked();
2488
2489         bp_.fonts_old_figures = fontModule->fontOsfCB->isChecked();
2490
2491         if (nontexfonts)
2492                 bp_.fonts_default_family = "default";
2493         else
2494                 bp_.fonts_default_family = GuiDocument::fontfamilies[
2495                         fontModule->fontsDefaultCO->currentIndex()];
2496
2497         if (fontModule->fontsizeCO->currentIndex() == 0)
2498                 bp_.fontsize = "default";
2499         else
2500                 bp_.fontsize =
2501                         fromqstr(fontModule->fontsizeCO->currentText());
2502
2503         // paper
2504         bp_.papersize = PAPER_SIZE(
2505                 pageLayoutModule->papersizeCO->currentIndex());
2506
2507         bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
2508                 pageLayoutModule->paperwidthUnitCO);
2509
2510         bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
2511                 pageLayoutModule->paperheightUnitCO);
2512
2513         if (pageLayoutModule->facingPagesCB->isChecked())
2514                 bp_.sides = TwoSides;
2515         else
2516                 bp_.sides = OneSide;
2517
2518         if (pageLayoutModule->landscapeRB->isChecked())
2519                 bp_.orientation = ORIENTATION_LANDSCAPE;
2520         else
2521                 bp_.orientation = ORIENTATION_PORTRAIT;
2522
2523         // margins
2524         bp_.use_geometry = !marginsModule->marginCB->isChecked();
2525
2526         Ui::MarginsUi const * m = marginsModule;
2527
2528         bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
2529         bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
2530         bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
2531         bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
2532         bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
2533         bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
2534         bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
2535         bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
2536
2537         // branches
2538         branchesModule->apply(bp_);
2539
2540         // PDF support
2541         PDFOptions & pdf = bp_.pdfoptions();
2542         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
2543         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
2544         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
2545         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
2546         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
2547
2548         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
2549         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
2550         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
2551         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
2552
2553         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
2554         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
2555         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
2556         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
2557         pdf.backref =
2558                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
2559         if (pdfSupportModule->fullscreenCB->isChecked())
2560                 pdf.pagemode = pdf.pagemode_fullscreen;
2561         else
2562                 pdf.pagemode.clear();
2563         pdf.quoted_options = pdf.quoted_options_check(
2564                                 fromqstr(pdfSupportModule->optionsLE->text()));
2565 }
2566
2567
2568 void GuiDocument::paramsToDialog()
2569 {
2570         // set the default unit
2571         Length::UNIT const defaultUnit = Length::defaultUnit();
2572
2573         // preamble
2574         preambleModule->update(bp_, id());
2575         localLayout->update(bp_, id());
2576
2577         // date
2578         latexModule->suppressDateCB->setChecked(bp_.suppress_date);
2579         latexModule->refstyleCB->setChecked(bp_.use_refstyle);
2580
2581         // biblio
2582         biblioModule->citeDefaultRB->setChecked(
2583                 bp_.citeEngine() == ENGINE_BASIC);
2584
2585         biblioModule->citeNatbibRB->setChecked(
2586                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL ||
2587                 bp_.citeEngine() == ENGINE_NATBIB_AUTHORYEAR);
2588
2589         biblioModule->citeStyleCO->setCurrentIndex(
2590                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL);
2591
2592         biblioModule->citeJurabibRB->setChecked(
2593                 bp_.citeEngine() == ENGINE_JURABIB);
2594
2595         biblioModule->bibtopicCB->setChecked(
2596                 bp_.use_bibtopic);
2597
2598         string command;
2599         string options =
2600                 split(bp_.bibtex_command, command, ' ');
2601
2602         int const bpos = biblioModule->bibtexCO->findData(toqstr(command));
2603         if (bpos != -1) {
2604                 biblioModule->bibtexCO->setCurrentIndex(bpos);
2605                 biblioModule->bibtexOptionsED->setText(toqstr(options).trimmed());
2606         } else {
2607                 // We reset to default if we do not know the specified compiler
2608                 // This is for security reasons
2609                 biblioModule->bibtexCO->setCurrentIndex(
2610                         biblioModule->bibtexCO->findData(toqstr("default")));
2611                 biblioModule->bibtexOptionsED->clear();
2612         }
2613         biblioModule->bibtexOptionsED->setEnabled(
2614                 biblioModule->bibtexCO->currentIndex() != 0);
2615
2616         // indices
2617         indicesModule->update(bp_);
2618
2619         // language & quotes
2620         int const pos = langModule->languageCO->findData(toqstr(
2621                 bp_.language->lang()));
2622         langModule->languageCO->setCurrentIndex(pos);
2623
2624         langModule->quoteStyleCO->setCurrentIndex(
2625                 bp_.quotes_language);
2626
2627         bool default_enc = true;
2628         if (bp_.inputenc != "auto") {
2629                 default_enc = false;
2630                 if (bp_.inputenc == "default") {
2631                         langModule->encodingCO->setCurrentIndex(0);
2632                 } else {
2633                         string enc_gui;
2634                         Encodings::const_iterator it = encodings.begin();
2635                         Encodings::const_iterator const end = encodings.end();
2636                         for (; it != end; ++it) {
2637                                 if (it->latexName() == bp_.inputenc) {
2638                                         enc_gui = it->guiName();
2639                                         break;
2640                                 }
2641                         }
2642                         int const i = langModule->encodingCO->findText(
2643                                         qt_(enc_gui));
2644                         if (i >= 0)
2645                                 langModule->encodingCO->setCurrentIndex(i);
2646                         else
2647                                 // unknown encoding. Set to default.
2648                                 default_enc = true;
2649                 }
2650         }
2651         langModule->defaultencodingRB->setChecked(default_enc);
2652         langModule->otherencodingRB->setChecked(!default_enc);
2653
2654         int const p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
2655         if (p == -1) {
2656                 langModule->languagePackageCO->setCurrentIndex(
2657                           langModule->languagePackageCO->findData("custom"));
2658                 langModule->languagePackageED->setText(toqstr(bp_.lang_package));
2659         } else {
2660                 langModule->languagePackageCO->setCurrentIndex(p);
2661                 langModule->languagePackageED->clear();
2662         }
2663
2664         //color
2665         if (bp_.isfontcolor) {
2666                 colorModule->fontColorPB->setStyleSheet(
2667                         colorButtonStyleSheet(rgb2qcolor(bp_.fontcolor)));
2668         }
2669         set_fontcolor = bp_.fontcolor;
2670         is_fontcolor = bp_.isfontcolor;
2671
2672         colorModule->noteFontColorPB->setStyleSheet(
2673                 colorButtonStyleSheet(rgb2qcolor(bp_.notefontcolor)));
2674         set_notefontcolor = bp_.notefontcolor;
2675
2676         if (bp_.isbackgroundcolor) {
2677                 colorModule->backgroundPB->setStyleSheet(
2678                         colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
2679         }
2680         set_backgroundcolor = bp_.backgroundcolor;
2681         is_backgroundcolor = bp_.isbackgroundcolor;
2682
2683         colorModule->boxBackgroundPB->setStyleSheet(
2684                 colorButtonStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
2685         set_boxbgcolor = bp_.boxbgcolor;
2686
2687         // numbering
2688         int const min_toclevel = documentClass().min_toclevel();
2689         int const max_toclevel = documentClass().max_toclevel();
2690         if (documentClass().hasTocLevels()) {
2691                 numberingModule->setEnabled(true);
2692                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
2693                 numberingModule->depthSL->setMaximum(max_toclevel);
2694                 numberingModule->depthSL->setValue(bp_.secnumdepth);
2695                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
2696                 numberingModule->tocSL->setMaximum(max_toclevel);
2697                 numberingModule->tocSL->setValue(bp_.tocdepth);
2698                 updateNumbering();
2699         } else {
2700                 numberingModule->setEnabled(false);
2701                 numberingModule->tocTW->clear();
2702         }
2703
2704         // bullets
2705         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
2706         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
2707         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
2708         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
2709         bulletsModule->init();
2710
2711         // packages
2712         int nitem = findToken(tex_graphics, bp_.graphics_driver);
2713         if (nitem >= 0)
2714                 latexModule->psdriverCO->setCurrentIndex(nitem);
2715         updateModuleInfo();
2716         
2717         mathsModule->amsCB->setChecked(
2718                 bp_.use_amsmath == BufferParams::package_on);
2719         mathsModule->amsautoCB->setChecked(
2720                 bp_.use_amsmath == BufferParams::package_auto);
2721
2722         mathsModule->esintCB->setChecked(
2723                 bp_.use_esint == BufferParams::package_on);
2724         mathsModule->esintautoCB->setChecked(
2725                 bp_.use_esint == BufferParams::package_auto);
2726
2727         mathsModule->mhchemCB->setChecked(
2728                 bp_.use_mhchem == BufferParams::package_on);
2729         mathsModule->mhchemautoCB->setChecked(
2730                 bp_.use_mhchem == BufferParams::package_auto);
2731
2732         mathsModule->mathdotsCB->setChecked(
2733                 bp_.use_mathdots == BufferParams::package_on);
2734         mathsModule->mathdotsautoCB->setChecked(
2735                 bp_.use_mathdots == BufferParams::package_auto);
2736
2737         switch (bp_.spacing().getSpace()) {
2738                 case Spacing::Other: nitem = 3; break;
2739                 case Spacing::Double: nitem = 2; break;
2740                 case Spacing::Onehalf: nitem = 1; break;
2741                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
2742         }
2743
2744         // text layout
2745         string const & layoutID = bp_.baseClassID();
2746         setLayoutComboByIDString(layoutID);
2747
2748         updatePagestyle(documentClass().opt_pagestyle(),
2749                                  bp_.pagestyle);
2750
2751         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
2752         if (bp_.spacing().getSpace() == Spacing::Other) {
2753                 doubleToWidget(textLayoutModule->lspacingLE,
2754                         bp_.spacing().getValueAsString());
2755         }
2756         setLSpacing(nitem);
2757
2758         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
2759                 textLayoutModule->indentRB->setChecked(true);
2760                 string indentation = bp_.getIndentation().asLyXCommand();
2761                 int indent = 0;
2762                 if (indentation != "default") {
2763                         lengthToWidgets(textLayoutModule->indentLE,
2764                         textLayoutModule->indentLengthCO,
2765                         indentation, defaultUnit);
2766                         indent = 1;
2767                 }
2768                 textLayoutModule->indentCO->setCurrentIndex(indent);
2769                 setIndent(indent);
2770         } else {
2771                 textLayoutModule->skipRB->setChecked(true);
2772                 int skip = 0;
2773                 switch (bp_.getDefSkip().kind()) {
2774                 case VSpace::SMALLSKIP:
2775                         skip = 0;
2776                         break;
2777                 case VSpace::MEDSKIP:
2778                         skip = 1;
2779                         break;
2780                 case VSpace::BIGSKIP:
2781                         skip = 2;
2782                         break;
2783                 case VSpace::LENGTH:
2784                         {
2785                         skip = 3;
2786                         string const length = bp_.getDefSkip().asLyXCommand();
2787                         lengthToWidgets(textLayoutModule->skipLE,
2788                                 textLayoutModule->skipLengthCO,
2789                                 length, defaultUnit);
2790                         break;
2791                         }
2792                 default:
2793                         skip = 0;
2794                         break;
2795                 }
2796                 textLayoutModule->skipCO->setCurrentIndex(skip);
2797                 setSkip(skip);
2798         }
2799
2800         textLayoutModule->twoColumnCB->setChecked(
2801                 bp_.columns == 2);
2802
2803         if (!bp_.options.empty()) {
2804                 latexModule->optionsLE->setText(
2805                         toqstr(bp_.options));
2806         } else {
2807                 latexModule->optionsLE->setText(QString());
2808         }
2809
2810         // latex
2811         latexModule->defaultOptionsCB->setChecked(
2812                         bp_.use_default_options);
2813         updateSelectedModules();
2814         selectionManager->updateProvidedModules(
2815                         bp_.baseClass()->providedModules());
2816         selectionManager->updateExcludedModules(
2817                         bp_.baseClass()->excludedModules());
2818
2819         if (!documentClass().options().empty()) {
2820                 latexModule->defaultOptionsLE->setText(
2821                         toqstr(documentClass().options()));
2822         } else {
2823                 latexModule->defaultOptionsLE->setText(
2824                         toqstr(_("[No options predefined]")));
2825         }
2826
2827         latexModule->defaultOptionsLE->setEnabled(
2828                 bp_.use_default_options
2829                 && !documentClass().options().empty());
2830
2831         latexModule->defaultOptionsCB->setEnabled(
2832                 !documentClass().options().empty());
2833
2834         if (!bp_.master.empty()) {
2835                 latexModule->childDocGB->setChecked(true);
2836                 latexModule->childDocLE->setText(
2837                         toqstr(bp_.master));
2838         } else {
2839                 latexModule->childDocLE->setText(QString());
2840                 latexModule->childDocGB->setChecked(false);
2841         }
2842
2843         // Master/Child
2844         if (!bufferview() || !buffer().hasChildren()) {
2845                 masterChildModule->childrenTW->clear();
2846                 includeonlys_.clear();
2847                 docPS->showPanel(qt_("Child Documents"), false);
2848                 if (docPS->isCurrentPanel(qt_("Child Documents")))
2849                         docPS->setCurrentPanel(qt_("Document Class"));
2850         } else {
2851                 docPS->showPanel(qt_("Child Documents"), true);
2852                 masterChildModule->setEnabled(true);
2853                 includeonlys_ = bp_.getIncludedChildren();
2854                 updateIncludeonlys();
2855         }
2856         masterChildModule->maintainAuxCB->setChecked(
2857                 bp_.maintain_unincluded_children);
2858
2859         // Float Settings
2860         floatModule->set(bp_.float_placement);
2861
2862         // ListingsSettings
2863         // break listings_params to multiple lines
2864         string lstparams =
2865                 InsetListingsParams(bp_.listings_params).separatedParams();
2866         listingsModule->listingsED->setPlainText(toqstr(lstparams));
2867
2868         // Output
2869         // update combobox with formats
2870         updateDefaultFormat();
2871         int index = outputModule->defaultFormatCO->findData(toqstr(
2872                 bp_.default_output_format));
2873         // set to default if format is not found 
2874         if (index == -1)
2875                 index = 0;
2876         outputModule->defaultFormatCO->setCurrentIndex(index);
2877         fontModule->osFontsCB->setEnabled(bp_.baseClass()->outputType() == lyx::LATEX);
2878         fontModule->osFontsCB->setChecked(
2879                 bp_.baseClass()->outputType() == lyx::LATEX && bp_.useNonTeXFonts);
2880
2881         outputModule->outputsyncCB->setChecked(bp_.output_sync);
2882         outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
2883
2884         outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
2885         outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
2886         outputModule->strictCB->setChecked(bp_.html_be_strict);
2887
2888         // Fonts
2889         updateFontsize(documentClass().opt_fontsize(),
2890                         bp_.fontsize);
2891
2892         if (bp_.useNonTeXFonts) {
2893                 fontModule->fontencLA->setEnabled(false);
2894                 fontModule->fontencCO->setEnabled(false);
2895                 fontModule->fontencLE->setEnabled(false);
2896                 for (int i = 0; i < fontModule->fontsRomanCO->count(); ++i) {
2897                         if (fontModule->fontsRomanCO->itemText(i) == toqstr(bp_.fonts_roman)) {
2898                                 fontModule->fontsRomanCO->setCurrentIndex(i);
2899                                 break;
2900                         }
2901                 }
2902                 
2903                 for (int i = 0; i < fontModule->fontsSansCO->count(); ++i) {
2904                         if (fontModule->fontsSansCO->itemText(i) == toqstr(bp_.fonts_sans)) {
2905                                 fontModule->fontsSansCO->setCurrentIndex(i);
2906                                 break;
2907                         }
2908                 }
2909                 for (int i = 0; i < fontModule->fontsTypewriterCO->count(); ++i) {
2910                         if (fontModule->fontsTypewriterCO->itemText(i) == 
2911                                 toqstr(bp_.fonts_typewriter)) {
2912                                 fontModule->fontsTypewriterCO->setCurrentIndex(i);
2913                                 break;
2914                         }
2915                 }
2916         } else {
2917                 fontModule->fontencLA->setEnabled(true);
2918                 fontModule->fontencCO->setEnabled(true);
2919                 fontModule->fontencLE->setEnabled(true);
2920                 int n = findToken(tex_fonts_roman, bp_.fonts_roman);
2921                 if (n >= 0) {
2922                         fontModule->fontsRomanCO->setCurrentIndex(n);
2923                         romanChanged(n);
2924                 }
2925         
2926                 n = findToken(tex_fonts_sans, bp_.fonts_sans);
2927                 if (n >= 0) {
2928                         fontModule->fontsSansCO->setCurrentIndex(n);
2929                         sansChanged(n);
2930                 }
2931         
2932                 n = findToken(tex_fonts_monospaced, bp_.fonts_typewriter);
2933                 if (n >= 0) {
2934                         fontModule->fontsTypewriterCO->setCurrentIndex(n);
2935                         ttChanged(n);
2936                 }
2937         }
2938
2939         if (!bp_.fonts_cjk.empty())
2940                 fontModule->cjkFontLE->setText(
2941                         toqstr(bp_.fonts_cjk));
2942         else
2943                 fontModule->cjkFontLE->setText(QString());
2944
2945         fontModule->fontScCB->setChecked(bp_.fonts_expert_sc);
2946         fontModule->fontOsfCB->setChecked(bp_.fonts_old_figures);
2947         fontModule->scaleSansSB->setValue(bp_.fonts_sans_scale);
2948         fontModule->scaleTypewriterSB->setValue(bp_.fonts_typewriter_scale);
2949         
2950         int nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
2951         if (nn >= 0)
2952                 fontModule->fontsDefaultCO->setCurrentIndex(nn);
2953
2954         if (bp_.fontenc == "global") {
2955                 fontModule->fontencCO->setCurrentIndex(0);
2956                 fontModule->fontencLE->setEnabled(false);
2957         } else if (bp_.fontenc == "default") {
2958                 fontModule->fontencCO->setCurrentIndex(2);
2959                 fontModule->fontencLE->setEnabled(false);
2960         } else {
2961                 fontModule->fontencCO->setCurrentIndex(1);
2962                 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
2963         }
2964
2965         // paper
2966         bool const extern_geometry =
2967                 documentClass().provides("geometry");
2968         int const psize = bp_.papersize;
2969         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
2970         setCustomPapersize(!extern_geometry && psize == 1);
2971         pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
2972
2973         bool const landscape =
2974                 bp_.orientation == ORIENTATION_LANDSCAPE;
2975         pageLayoutModule->landscapeRB->setChecked(landscape);
2976         pageLayoutModule->portraitRB->setChecked(!landscape);
2977         pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
2978         pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
2979
2980         pageLayoutModule->facingPagesCB->setChecked(
2981                 bp_.sides == TwoSides);
2982
2983         lengthToWidgets(pageLayoutModule->paperwidthLE,
2984                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, defaultUnit);
2985         lengthToWidgets(pageLayoutModule->paperheightLE,
2986                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, defaultUnit);
2987
2988         // margins
2989         Ui::MarginsUi * m = marginsModule;
2990
2991         setMargins();
2992
2993         lengthToWidgets(m->topLE, m->topUnit,
2994                 bp_.topmargin, defaultUnit);
2995
2996         lengthToWidgets(m->bottomLE, m->bottomUnit,
2997                 bp_.bottommargin, defaultUnit);
2998
2999         lengthToWidgets(m->innerLE, m->innerUnit,
3000                 bp_.leftmargin, defaultUnit);
3001
3002         lengthToWidgets(m->outerLE, m->outerUnit,
3003                 bp_.rightmargin, defaultUnit);
3004
3005         lengthToWidgets(m->headheightLE, m->headheightUnit,
3006                 bp_.headheight, defaultUnit);
3007
3008         lengthToWidgets(m->headsepLE, m->headsepUnit,
3009                 bp_.headsep, defaultUnit);
3010
3011         lengthToWidgets(m->footskipLE, m->footskipUnit,
3012                 bp_.footskip, defaultUnit);
3013
3014         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
3015                 bp_.columnsep, defaultUnit);
3016
3017         // branches
3018         updateUnknownBranches();
3019         branchesModule->update(bp_);
3020
3021         // PDF support
3022         PDFOptions const & pdf = bp_.pdfoptions();
3023         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
3024         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
3025         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
3026         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
3027         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
3028
3029         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
3030         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
3031         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
3032
3033         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
3034
3035         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
3036         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
3037         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
3038         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
3039
3040         nn = findToken(backref_opts, pdf.backref);
3041         if (nn >= 0)
3042                 pdfSupportModule->backrefCO->setCurrentIndex(nn);
3043
3044         pdfSupportModule->fullscreenCB->setChecked
3045                 (pdf.pagemode == pdf.pagemode_fullscreen);
3046
3047         pdfSupportModule->optionsLE->setText(
3048                 toqstr(pdf.quoted_options));
3049
3050         // Make sure that the bc is in the INITIAL state
3051         if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
3052                 bc().restore();
3053
3054         // clear changed branches cache
3055         changedBranches_.clear();
3056 }
3057
3058
3059 void GuiDocument::saveDocDefault()
3060 {
3061         // we have to apply the params first
3062         applyView();
3063         saveAsDefault();
3064 }
3065
3066
3067 void GuiDocument::updateAvailableModules() 
3068 {
3069         modules_av_model_.clear();
3070         list<modInfoStruct> const & modInfoList = getModuleInfo();
3071         list<modInfoStruct>::const_iterator mit = modInfoList.begin();
3072         list<modInfoStruct>::const_iterator men = modInfoList.end();
3073         for (int i = 0; mit != men; ++mit, ++i)
3074                 modules_av_model_.insertRow(i, mit->name, mit->id, 
3075                                 mit->description);
3076 }
3077
3078
3079 void GuiDocument::updateSelectedModules() 
3080 {
3081         modules_sel_model_.clear();
3082         list<modInfoStruct> const selModList = getSelectedModules();
3083         list<modInfoStruct>::const_iterator mit = selModList.begin();
3084         list<modInfoStruct>::const_iterator men = selModList.end();
3085         for (int i = 0; mit != men; ++mit, ++i)
3086                 modules_sel_model_.insertRow(i, mit->name, mit->id, 
3087                                 mit->description);
3088 }
3089
3090
3091 void GuiDocument::updateIncludeonlys()
3092 {
3093         masterChildModule->childrenTW->clear();
3094         QString const no = qt_("No");
3095         QString const yes = qt_("Yes");
3096
3097         if (includeonlys_.empty()) {
3098                 masterChildModule->includeallRB->setChecked(true);
3099                 masterChildModule->childrenTW->setEnabled(false);
3100                 masterChildModule->maintainAuxCB->setEnabled(false);
3101         } else {
3102                 masterChildModule->includeonlyRB->setChecked(true);
3103                 masterChildModule->childrenTW->setEnabled(true);
3104                 masterChildModule->maintainAuxCB->setEnabled(true);
3105         }
3106         QTreeWidgetItem * item = 0;
3107         ListOfBuffers children = buffer().getChildren();
3108         ListOfBuffers::const_iterator it  = children.begin();
3109         ListOfBuffers::const_iterator end = children.end();
3110         bool has_unincluded = false;
3111         bool all_unincluded = true;
3112         for (; it != end; ++it) {
3113                 item = new QTreeWidgetItem(masterChildModule->childrenTW);
3114                 // FIXME Unicode
3115                 string const name =
3116                         to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
3117                                                         from_utf8(buffer().filePath())));
3118                 item->setText(0, toqstr(name));
3119                 item->setText(1, isChildIncluded(name) ? yes : no);
3120                 if (!isChildIncluded(name))
3121                         has_unincluded = true;
3122                 else
3123                         all_unincluded = false;
3124         }
3125         // Both if all childs are included and if none is included
3126         // is equal to "include all" (i.e., ommit \includeonly).
3127         // Thus, reset the GUI.
3128         if (!has_unincluded || all_unincluded) {
3129                 masterChildModule->includeallRB->setChecked(true);
3130                 masterChildModule->childrenTW->setEnabled(false);
3131                 includeonlys_.clear();
3132         }
3133         // If all are included, we need to update again.
3134         if (!has_unincluded)
3135                 updateIncludeonlys();
3136 }
3137
3138
3139 void GuiDocument::updateContents()
3140 {
3141         // Nothing to do here as the document settings is not cursor dependant.
3142         return;
3143 }
3144
3145
3146 void GuiDocument::useClassDefaults()
3147 {
3148         if (applyPB->isEnabled()) {
3149                 int const ret = Alert::prompt(_("Unapplied changes"),
3150                                 _("Some changes in the dialog were not yet applied.\n"
3151                                   "If you do not apply now, they will be lost after this action."),
3152                                 1, 1, _("&Apply"), _("&Dismiss"));
3153                 if (ret == 0)
3154                         applyView();
3155         }
3156
3157         int idx = latexModule->classCO->currentIndex();
3158         string const classname = classes_model_.getIDString(idx);
3159         if (!bp_.setBaseClass(classname)) {
3160                 Alert::error(_("Error"), _("Unable to set document class."));
3161                 return;
3162         }
3163         bp_.useClassDefaults();
3164         paramsToDialog();
3165 }
3166
3167
3168 void GuiDocument::setLayoutComboByIDString(string const & idString)
3169 {
3170         int idx = classes_model_.findIDString(idString);
3171         if (idx < 0)
3172                 Alert::warning(_("Can't set layout!"), 
3173                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
3174         else 
3175                 latexModule->classCO->setCurrentIndex(idx);
3176 }
3177
3178
3179 bool GuiDocument::isValid()
3180 {
3181         return 
3182                 validateListingsParameters().isEmpty() &&
3183                 localLayout->isValid() &&
3184                 (
3185                         // if we're asking for skips between paragraphs
3186                         !textLayoutModule->skipRB->isChecked() ||
3187                         // then either we haven't chosen custom
3188                         textLayoutModule->skipCO->currentIndex() != 3 || 
3189                         // or else a length has been given
3190                         !textLayoutModule->skipLE->text().isEmpty()
3191                 ) && 
3192                 (
3193                         // if we're asking for indentation
3194                         !textLayoutModule->indentRB->isChecked() || 
3195                         // then either we haven't chosen custom
3196                         textLayoutModule->indentCO->currentIndex() != 1 || 
3197                         // or else a length has been given
3198                         !textLayoutModule->indentLE->text().isEmpty()
3199                 );
3200 }
3201
3202
3203 char const * const GuiDocument::fontfamilies[5] = {
3204         "default", "rmdefault", "sfdefault", "ttdefault", ""
3205 };
3206
3207
3208 char const * GuiDocument::fontfamilies_gui[5] = {
3209         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
3210 };
3211
3212
3213 bool GuiDocument::initialiseParams(string const &)
3214 {
3215         BufferView const * view = bufferview();
3216         if (!view) {
3217                 bp_ = BufferParams();
3218                 paramsToDialog();
3219                 return true;
3220         }
3221         bp_ = view->buffer().params();
3222         loadModuleInfo();
3223         updateAvailableModules();
3224         //FIXME It'd be nice to make sure here that the selected
3225         //modules are consistent: That required modules are actually
3226         //selected, and that we don't have conflicts. If so, we could
3227         //at least pop up a warning.
3228         paramsToDialog();
3229         return true;
3230 }
3231
3232
3233 void GuiDocument::clearParams()
3234 {
3235         bp_ = BufferParams();
3236 }
3237
3238
3239 BufferId GuiDocument::id() const
3240 {
3241         BufferView const * const view = bufferview();
3242         return view? &view->buffer() : 0;
3243 }
3244
3245
3246 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
3247 {
3248         return moduleNames_;
3249 }
3250
3251
3252 list<GuiDocument::modInfoStruct> const 
3253                 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
3254 {
3255         LayoutModuleList::const_iterator it =  mods.begin();
3256         LayoutModuleList::const_iterator end = mods.end();
3257         list<modInfoStruct> mInfo;
3258         for (; it != end; ++it) {
3259                 modInfoStruct m;
3260                 m.id = *it;
3261                 LyXModule const * const mod = theModuleList[*it];
3262                 if (mod)
3263                         // FIXME Unicode
3264                         m.name = toqstr(translateIfPossible(from_utf8(mod->getName())));
3265                 else 
3266                         m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
3267                 mInfo.push_back(m);
3268         }
3269         return mInfo;
3270 }
3271
3272
3273 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
3274 {
3275         return makeModuleInfo(params().getModules());
3276 }
3277
3278
3279 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
3280 {
3281         return makeModuleInfo(params().baseClass()->providedModules());
3282 }
3283
3284
3285 DocumentClass const & GuiDocument::documentClass() const
3286 {
3287         return bp_.documentClass();
3288 }
3289
3290
3291 static void dispatch_bufferparams(Dialog const & dialog,
3292         BufferParams const & bp, FuncCode lfun)
3293 {
3294         ostringstream ss;
3295         ss << "\\begin_header\n";
3296         bp.writeFile(ss);
3297         ss << "\\end_header\n";
3298         dialog.dispatch(FuncRequest(lfun, ss.str()));
3299 }
3300
3301
3302 void GuiDocument::dispatchParams()
3303 {
3304         // This must come first so that a language change is correctly noticed
3305         setLanguage();
3306
3307         // Apply the BufferParams. Note that this will set the base class
3308         // and then update the buffer's layout.
3309         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
3310
3311         if (!params().master.empty()) {
3312                 FileName const master_file = support::makeAbsPath(params().master,
3313                            support::onlyPath(buffer().absFileName()));
3314                 if (isLyXFileName(master_file.absFileName())) {
3315                         Buffer * master = checkAndLoadLyXFile(master_file);
3316                         if (master) {
3317                                 if (master->isChild(const_cast<Buffer *>(&buffer())))
3318                                         const_cast<Buffer &>(buffer()).setParent(master);
3319                                 else
3320                                         Alert::warning(_("Assigned master does not include this file"), 
3321                                                 bformat(_("You must include this file in the document\n"
3322                                                           "'%1$s' in order to use the master document\n"
3323                                                           "feature."), from_utf8(params().master)));
3324                         } else
3325                                 Alert::warning(_("Could not load master"), 
3326                                                 bformat(_("The master document '%1$s'\n"
3327                                                            "could not be loaded."),
3328                                                            from_utf8(params().master)));
3329                 }
3330         }
3331
3332         // Generate the colours requested by each new branch.
3333         BranchList & branchlist = params().branchlist();
3334         if (!branchlist.empty()) {
3335                 BranchList::const_iterator it = branchlist.begin();
3336                 BranchList::const_iterator const end = branchlist.end();
3337                 for (; it != end; ++it) {
3338                         docstring const & current_branch = it->branch();
3339                         Branch const * branch = branchlist.find(current_branch);
3340                         string const x11hexname = X11hexname(branch->color());
3341                         // display the new color
3342                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
3343                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
3344                 }
3345
3346                 // Open insets of selected branches, close deselected ones
3347                 dispatch(FuncRequest(LFUN_INSET_FORALL,
3348                         "Branch inset-toggle assign"));
3349         }
3350         // rename branches in the document
3351         executeBranchRenaming();
3352         // and clear changed branches cache
3353         changedBranches_.clear();
3354         
3355         // Generate the colours requested by indices.
3356         IndicesList & indiceslist = params().indiceslist();
3357         if (!indiceslist.empty()) {
3358                 IndicesList::const_iterator it = indiceslist.begin();
3359                 IndicesList::const_iterator const end = indiceslist.end();
3360                 for (; it != end; ++it) {
3361                         docstring const & current_index = it->shortcut();
3362                         Index const * index = indiceslist.findShortcut(current_index);
3363                         string const x11hexname = X11hexname(index->color());
3364                         // display the new color
3365                         docstring const str = current_index + ' ' + from_ascii(x11hexname);
3366                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
3367                 }
3368         }
3369         // FIXME LFUN
3370         // If we used an LFUN, we would not need these two lines:
3371         BufferView * bv = const_cast<BufferView *>(bufferview());
3372         bv->processUpdateFlags(Update::Force | Update::FitCursor);
3373 }
3374
3375
3376 void GuiDocument::setLanguage() const
3377 {
3378         Language const * const newL = bp_.language;
3379         if (buffer().params().language == newL)
3380                 return;
3381
3382         string const & lang_name = newL->lang();
3383         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
3384 }
3385
3386
3387 void GuiDocument::saveAsDefault() const
3388 {
3389         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
3390 }
3391
3392
3393 bool GuiDocument::isFontAvailable(string const & font) const
3394 {
3395         if (font == "default" || font == "cmr"
3396             || font == "cmss" || font == "cmtt")
3397                 // these are standard
3398                 return true;
3399         if (font == "lmodern" || font == "lmss" || font == "lmtt")
3400                 return LaTeXFeatures::isAvailable("lmodern");
3401         if (font == "times" || font == "palatino"
3402                  || font == "helvet" || font == "courier")
3403                 return LaTeXFeatures::isAvailable("psnfss");
3404         if (font == "cmbr" || font == "cmtl")
3405                 return LaTeXFeatures::isAvailable("cmbright");
3406         if (font == "utopia")
3407                 return LaTeXFeatures::isAvailable("utopia")
3408                         || LaTeXFeatures::isAvailable("fourier");
3409         if (font == "beraserif" || font == "berasans"
3410                 || font == "beramono")
3411                 return LaTeXFeatures::isAvailable("bera");
3412         return LaTeXFeatures::isAvailable(font);
3413 }
3414
3415
3416 bool GuiDocument::providesOSF(string const & font) const
3417 {
3418         if (fontModule->osFontsCB->isChecked())
3419                 // FIXME: we should check if the fonts really
3420                 // have OSF support. But how?
3421                 return true;
3422         if (font == "cmr")
3423                 return isFontAvailable("eco");
3424         if (font == "palatino")
3425                 return isFontAvailable("mathpazo");
3426         return false;
3427 }
3428
3429
3430 bool GuiDocument::providesSC(string const & font) const
3431 {
3432         if (fontModule->osFontsCB->isChecked())
3433                 return false;
3434         if (font == "palatino")
3435                 return isFontAvailable("mathpazo");
3436         if (font == "utopia")
3437                 return isFontAvailable("fourier");
3438         return false;
3439 }
3440
3441
3442 bool GuiDocument::providesScale(string const & font) const
3443 {
3444         if (fontModule->osFontsCB->isChecked())
3445                 return true;
3446         return font == "helvet" || font == "luximono"
3447                 || font == "berasans"  || font == "beramono";
3448 }
3449
3450
3451 void GuiDocument::loadModuleInfo()
3452 {
3453         moduleNames_.clear();
3454         LyXModuleList::const_iterator it  = theModuleList.begin();
3455         LyXModuleList::const_iterator end = theModuleList.end();
3456         for (; it != end; ++it) {
3457                 modInfoStruct m;
3458                 m.id = it->getID();
3459                 // FIXME Unicode
3460                 m.name = toqstr(translateIfPossible(from_utf8(it->getName())));
3461                 // this is supposed to give us the first sentence of the description
3462                 // FIXME Unicode
3463                 QString desc =
3464                         toqstr(translateIfPossible(from_utf8(it->getDescription())));
3465                 int const pos = desc.indexOf(".");
3466                 if (pos > 0)
3467                         desc.truncate(pos + 1);
3468                 m.description = desc;
3469                 moduleNames_.push_back(m);
3470         }
3471 }
3472
3473
3474 void GuiDocument::updateUnknownBranches()
3475 {
3476         if (!bufferview())
3477                 return;
3478         list<docstring> used_branches;
3479         buffer().getUsedBranches(used_branches);
3480         list<docstring>::const_iterator it = used_branches.begin();
3481         QStringList unknown_branches;
3482         for (; it != used_branches.end() ; ++it) {
3483                 if (!buffer().params().branchlist().find(*it))
3484                         unknown_branches.append(toqstr(*it));
3485         }
3486         branchesModule->setUnknownBranches(unknown_branches);
3487 }
3488
3489
3490 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
3491 {
3492         map<docstring, docstring>::iterator it = changedBranches_.begin();
3493         for (; it != changedBranches_.end() ; ++it) {
3494                 if (it->second == oldname) {
3495                         // branch has already been renamed
3496                         it->second = newname;
3497                         return;
3498                 }
3499         }
3500         // store new name
3501         changedBranches_[oldname] = newname;
3502 }
3503
3504
3505 void GuiDocument::executeBranchRenaming() const
3506 {
3507         map<docstring, docstring>::const_iterator it = changedBranches_.begin();
3508         for (; it != changedBranches_.end() ; ++it) {
3509                 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
3510                 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
3511         }
3512 }
3513
3514
3515 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
3516
3517
3518 } // namespace frontend
3519 } // namespace lyx
3520
3521 #include "moc_GuiDocument.cpp"