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