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