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