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