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