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