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