]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiDocument.cpp
91137cbb226f1630296d1128d7fcd082f0b07ca3
[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         if (!file.isEmpty())
1537                 latexModule->childDocLE->setText(file);
1538 }
1539
1540
1541 void GuiDocument::classChanged()
1542 {
1543         int idx = latexModule->classCO->currentIndex();
1544         if (idx < 0) 
1545                 return;
1546         string const classname = classes_model_.getIDString(idx);
1547
1548         // check whether the selected modules have changed.
1549         bool modules_changed = false;
1550         unsigned int const srows = selectedModel()->rowCount();
1551         if (srows != bp_.getModules().size())
1552                 modules_changed = true;
1553         else {
1554                 list<string>::const_iterator mit = bp_.getModules().begin();
1555                 list<string>::const_iterator men = bp_.getModules().end();
1556                 for (unsigned int i = 0; i < srows && mit != men; ++i, ++mit)
1557                         if (selectedModel()->getIDString(i) != *mit) {
1558                                 modules_changed = true;
1559                                 break;
1560                         }
1561         }
1562
1563         if (modules_changed || lyxrc.auto_reset_options) {
1564                 if (applyPB->isEnabled()) {
1565                         int const ret = Alert::prompt(_("Unapplied changes"),
1566                                         _("Some changes in the dialog were not yet applied.\n"
1567                                         "If you do not apply now, they will be lost after this action."),
1568                                         1, 1, _("&Apply"), _("&Dismiss"));
1569                         if (ret == 0)
1570                                 applyView();
1571                 }
1572         }
1573
1574         // We load the TextClass as soon as it is selected. This is
1575         // necessary so that other options in the dialog can be updated
1576         // according to the new class. Note, however, that, if you use 
1577         // the scroll wheel when sitting on the combo box, we'll load a 
1578         // lot of TextClass objects very quickly....
1579         if (!bp_.setBaseClass(classname)) {
1580                 Alert::error(_("Error"), _("Unable to set document class."));
1581                 return;
1582         }
1583         if (lyxrc.auto_reset_options)
1584                 bp_.useClassDefaults();
1585
1586         // With the introduction of modules came a distinction between the base 
1587         // class and the document class. The former corresponds to the main layout 
1588         // file; the latter is that plus the modules (or the document-specific layout,
1589         // or  whatever else there could be). Our parameters come from the document 
1590         // class. So when we set the base class, we also need to recreate the document 
1591         // class. Otherwise, we still have the old one.
1592         bp_.makeDocumentClass();
1593         paramsToDialog();
1594 }
1595
1596
1597 void GuiDocument::bibtexChanged(int n)
1598 {
1599         biblioModule->bibtexOptionsED->setEnabled(n != 0);
1600         changed();
1601 }
1602
1603
1604 namespace {
1605         // This is an insanely complicated attempt to make this sort of thing
1606         // work with RTL languages.
1607         docstring formatStrVec(vector<string> const & v, docstring const & s) 
1608         {
1609                 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
1610                 if (v.size() == 0)
1611                         return docstring();
1612                 if (v.size() == 1) 
1613                         return from_utf8(v[0]);
1614                 if (v.size() == 2) {
1615                         docstring retval = _("%1$s and %2$s");
1616                         retval = subst(retval, _("and"), s);
1617                         return bformat(retval, from_utf8(v[0]), from_utf8(v[1]));
1618                 }
1619                 // The idea here is to format all but the last two items...
1620                 int const vSize = v.size();
1621                 docstring t2 = _("%1$s, %2$s");
1622                 docstring retval = from_utf8(v[0]);
1623                 for (int i = 1; i < vSize - 2; ++i)
1624                         retval = bformat(t2, retval, from_utf8(v[i])); 
1625                 //...and then to  plug them, and the last two, into this schema
1626                 docstring t = _("%1$s, %2$s, and %3$s");
1627                 t = subst(t, _("and"), s);
1628                 return bformat(t, retval, from_utf8(v[vSize - 2]), from_utf8(v[vSize - 1]));
1629         }
1630         
1631         vector<string> idsToNames(vector<string> const & idList)
1632         {
1633                 vector<string> retval;
1634                 vector<string>::const_iterator it  = idList.begin();
1635                 vector<string>::const_iterator end = idList.end();
1636                 for (; it != end; ++it) {
1637                         LyXModule const * const mod = theModuleList[*it];
1638                         if (!mod)
1639                                 retval.push_back(*it + " (Unavailable)");
1640                         else
1641                                 retval.push_back(mod->getName());
1642                 }
1643                 return retval;
1644         }
1645 }
1646
1647
1648 void GuiDocument::modulesToParams(BufferParams & bp)
1649 {
1650         // update list of loaded modules
1651         bp.clearLayoutModules();
1652         int const srows = modules_sel_model_.rowCount();
1653         for (int i = 0; i < srows; ++i)
1654                 bp.addLayoutModule(modules_sel_model_.getIDString(i));
1655
1656         // update the list of removed modules
1657         bp.clearRemovedModules();
1658         LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
1659         list<string>::const_iterator rit = reqmods.begin();
1660         list<string>::const_iterator ren = reqmods.end();
1661
1662         // check each of the default modules
1663         for (; rit != ren; rit++) {
1664                 list<string>::const_iterator mit = bp.getModules().begin();
1665                 list<string>::const_iterator men = bp.getModules().end();
1666                 bool found = false;
1667                 for (; mit != men; mit++) {
1668                         if (*rit == *mit) {
1669                                 found = true;
1670                                 break;
1671                         }
1672                 }
1673                 if (!found) {
1674                         // the module isn't present so must have been removed by the user
1675                         bp.addRemovedModule(*rit);
1676                 }
1677         }
1678 }
1679
1680 void GuiDocument::modulesChanged()
1681 {
1682         modulesToParams(bp_);
1683         bp_.makeDocumentClass();
1684         paramsToDialog();
1685 }
1686
1687
1688 void GuiDocument::updateModuleInfo()
1689 {
1690         selectionManager->update();
1691         
1692         //Module description
1693         bool const focus_on_selected = selectionManager->selectedFocused();
1694         QAbstractItemView * lv;
1695         if (focus_on_selected)
1696                 lv = modulesModule->selectedLV;
1697         else
1698                 lv= modulesModule->availableLV;
1699         if (lv->selectionModel()->selectedIndexes().isEmpty()) {
1700                 modulesModule->infoML->document()->clear();
1701                 return;
1702         }
1703         QModelIndex const & idx = lv->selectionModel()->currentIndex();
1704         GuiIdListModel const & id_model = 
1705                         focus_on_selected  ? modules_sel_model_ : modules_av_model_;
1706         string const modName = id_model.getIDString(idx.row());
1707         docstring desc = getModuleDescription(modName);
1708
1709         LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
1710         if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
1711                 if (!desc.empty())
1712                         desc += "\n";
1713                 desc += _("Module provided by document class.");
1714         }
1715
1716         vector<string> pkglist = getPackageList(modName);
1717         docstring pkgdesc = formatStrVec(pkglist, _("and"));
1718         if (!pkgdesc.empty()) {
1719                 if (!desc.empty())
1720                         desc += "\n";
1721                 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
1722         }
1723
1724         pkglist = getRequiredList(modName);
1725         if (!pkglist.empty()) {
1726                 vector<string> const reqdescs = idsToNames(pkglist);
1727                 pkgdesc = formatStrVec(reqdescs, _("or"));
1728                 if (!desc.empty())
1729                         desc += "\n";
1730                 desc += bformat(_("Module required: %1$s."), pkgdesc);
1731         }
1732
1733         pkglist = getExcludedList(modName);
1734         if (!pkglist.empty()) {
1735                 vector<string> const reqdescs = idsToNames(pkglist);
1736                 pkgdesc = formatStrVec(reqdescs, _( "and"));
1737                 if (!desc.empty())
1738                         desc += "\n";
1739                 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
1740         }
1741
1742         if (!isModuleAvailable(modName)) {
1743                 if (!desc.empty())
1744                         desc += "\n";
1745                 desc += _("WARNING: Some required packages are unavailable!");
1746         }
1747
1748         modulesModule->infoML->document()->setPlainText(toqstr(desc));
1749 }
1750
1751
1752 void GuiDocument::updateNumbering()
1753 {
1754         DocumentClass const & tclass = documentClass();
1755
1756         numberingModule->tocTW->setUpdatesEnabled(false);
1757         numberingModule->tocTW->clear();
1758
1759         int const depth = numberingModule->depthSL->value();
1760         int const toc = numberingModule->tocSL->value();
1761         QString const no = qt_("No");
1762         QString const yes = qt_("Yes");
1763         QTreeWidgetItem * item = 0;
1764
1765         DocumentClass::const_iterator lit = tclass.begin();
1766         DocumentClass::const_iterator len = tclass.end();
1767         for (; lit != len; ++lit) {
1768                 int const toclevel = lit->toclevel;
1769                 if (toclevel != Layout::NOT_IN_TOC && lit->labeltype == LABEL_COUNTER) {
1770                         item = new QTreeWidgetItem(numberingModule->tocTW);
1771                         item->setText(0, toqstr(translateIfPossible(lit->name())));
1772                         item->setText(1, (toclevel <= depth) ? yes : no);
1773                         item->setText(2, (toclevel <= toc) ? yes : no);
1774                 }
1775         }
1776
1777         numberingModule->tocTW->setUpdatesEnabled(true);
1778         numberingModule->tocTW->update();
1779 }
1780
1781
1782 void GuiDocument::updateDefaultFormat()
1783 {
1784         // make a copy in order to consider unapplied changes
1785         Buffer * tmpbuf = const_cast<Buffer *>(&buffer());
1786         tmpbuf->params().useXetex = outputModule->xetexCB->isChecked();
1787         int idx = latexModule->classCO->currentIndex();
1788         if (idx >= 0) {
1789                 string const classname = classes_model_.getIDString(idx);
1790                 tmpbuf->params().setBaseClass(classname);
1791                 tmpbuf->params().makeDocumentClass();
1792         }
1793         outputModule->defaultFormatCO->blockSignals(true);
1794         outputModule->defaultFormatCO->clear();
1795         outputModule->defaultFormatCO->addItem(qt_("Default"),
1796                                 QVariant(QString("default")));
1797         typedef vector<Format const *> Formats;
1798         Formats formats = tmpbuf->exportableFormats(true);
1799         Formats::const_iterator cit = formats.begin();
1800         Formats::const_iterator end = formats.end();
1801         for (; cit != end; ++cit)
1802                 outputModule->defaultFormatCO->addItem(qt_((*cit)->prettyname()),
1803                                 QVariant(toqstr((*cit)->name())));
1804         outputModule->defaultFormatCO->blockSignals(false);
1805 }
1806
1807
1808 void GuiDocument::applyView()
1809 {
1810         // preamble
1811         preambleModule->apply(bp_);
1812
1813         // date
1814         bp_.suppress_date = latexModule->suppressDateCB->isChecked();
1815
1816         // biblio
1817         bp_.setCiteEngine(ENGINE_BASIC);
1818
1819         if (biblioModule->citeNatbibRB->isChecked()) {
1820                 bool const use_numerical_citations =
1821                         biblioModule->citeStyleCO->currentIndex();
1822                 if (use_numerical_citations)
1823                         bp_.setCiteEngine(ENGINE_NATBIB_NUMERICAL);
1824                 else
1825                         bp_.setCiteEngine(ENGINE_NATBIB_AUTHORYEAR);
1826
1827         } else if (biblioModule->citeJurabibRB->isChecked())
1828                 bp_.setCiteEngine(ENGINE_JURABIB);
1829
1830         bp_.use_bibtopic =
1831                 biblioModule->bibtopicCB->isChecked();
1832
1833         string const bibtex_command =
1834                 fromqstr(biblioModule->bibtexCO->itemData(
1835                         biblioModule->bibtexCO->currentIndex()).toString());
1836         string const bibtex_options =
1837                 fromqstr(biblioModule->bibtexOptionsED->text());
1838         if (bibtex_command == "default" || bibtex_options.empty())
1839                 bp_.bibtex_command = bibtex_command;
1840         else
1841                 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
1842
1843         // Indices
1844         indicesModule->apply(bp_);
1845
1846         // language & quotes
1847         if (langModule->defaultencodingRB->isChecked()) {
1848                 bp_.inputenc = "auto";
1849         } else {
1850                 int i = langModule->encodingCO->currentIndex();
1851                 if (i == 0)
1852                         bp_.inputenc = "default";
1853                 else {
1854                         QString const enc_gui =
1855                                 langModule->encodingCO->currentText();
1856                         Encodings::const_iterator it = encodings.begin();
1857                         Encodings::const_iterator const end = encodings.end();
1858                         bool found = false;
1859                         for (; it != end; ++it) {
1860                                 if (qt_(it->guiName()) == enc_gui) {
1861                                         bp_.inputenc = it->latexName();
1862                                         found = true;
1863                                         break;
1864                                 }
1865                         }
1866                         if (!found) {
1867                                 // should not happen
1868                                 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
1869                                 bp_.inputenc = "default";
1870                         }
1871                 }
1872         }
1873
1874         InsetQuotes::QuoteLanguage lga = InsetQuotes::EnglishQuotes;
1875         switch (langModule->quoteStyleCO->currentIndex()) {
1876         case 0:
1877                 lga = InsetQuotes::EnglishQuotes;
1878                 break;
1879         case 1:
1880                 lga = InsetQuotes::SwedishQuotes;
1881                 break;
1882         case 2:
1883                 lga = InsetQuotes::GermanQuotes;
1884                 break;
1885         case 3:
1886                 lga = InsetQuotes::PolishQuotes;
1887                 break;
1888         case 4:
1889                 lga = InsetQuotes::FrenchQuotes;
1890                 break;
1891         case 5:
1892                 lga = InsetQuotes::DanishQuotes;
1893                 break;
1894         }
1895         bp_.quotes_language = lga;
1896
1897         QString const lang = langModule->languageCO->itemData(
1898                 langModule->languageCO->currentIndex()).toString();
1899         bp_.language = lyx::languages.getLanguage(fromqstr(lang));
1900
1901         // numbering
1902         if (bp_.documentClass().hasTocLevels()) {
1903                 bp_.tocdepth = numberingModule->tocSL->value();
1904                 bp_.secnumdepth = numberingModule->depthSL->value();
1905         }
1906
1907         // bullets
1908         bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
1909         bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
1910         bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
1911         bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
1912
1913         // packages
1914         bp_.graphicsDriver =
1915                 tex_graphics[latexModule->psdriverCO->currentIndex()];
1916         
1917         // text layout
1918         int idx = latexModule->classCO->currentIndex();
1919         if (idx >= 0) {
1920                 string const classname = classes_model_.getIDString(idx);
1921                 bp_.setBaseClass(classname);
1922         }
1923
1924         // Modules
1925         modulesToParams(bp_);
1926
1927         // Math
1928         if (mathsModule->amsautoCB->isChecked()) {
1929                 bp_.use_amsmath = BufferParams::package_auto;
1930         } else {
1931                 if (mathsModule->amsCB->isChecked())
1932                         bp_.use_amsmath = BufferParams::package_on;
1933                 else
1934                         bp_.use_amsmath = BufferParams::package_off;
1935         }
1936         if (mathsModule->esintautoCB->isChecked())
1937                 bp_.use_esint = BufferParams::package_auto;
1938         else {
1939                 if (mathsModule->esintCB->isChecked())
1940                         bp_.use_esint = BufferParams::package_on;
1941                 else
1942                         bp_.use_esint = BufferParams::package_off;
1943         }
1944         if (mathsModule->mhchemautoCB->isChecked())
1945                 bp_.use_mhchem = BufferParams::package_auto;
1946         else {
1947                 if (mathsModule->mhchemCB->isChecked())
1948                         bp_.use_mhchem = BufferParams::package_on;
1949                 else
1950                         bp_.use_mhchem = BufferParams::package_off;
1951         }
1952
1953         // Page Layout
1954         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
1955                 bp_.pagestyle = "default";
1956         else {
1957                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
1958                 for (size_t i = 0; i != pagestyles.size(); ++i)
1959                         if (pagestyles[i].second == style_gui)
1960                                 bp_.pagestyle = pagestyles[i].first;
1961         }
1962
1963         // Text Layout
1964         switch (textLayoutModule->lspacingCO->currentIndex()) {
1965         case 0:
1966                 bp_.spacing().set(Spacing::Single);
1967                 break;
1968         case 1:
1969                 bp_.spacing().set(Spacing::Onehalf);
1970                 break;
1971         case 2:
1972                 bp_.spacing().set(Spacing::Double);
1973                 break;
1974         case 3:
1975                 bp_.spacing().set(Spacing::Other,
1976                         widgetToDoubleStr(textLayoutModule->lspacingLE));
1977                 break;
1978         }
1979
1980         if (textLayoutModule->twoColumnCB->isChecked())
1981                 bp_.columns = 2;
1982         else
1983                 bp_.columns = 1;
1984
1985         if (textLayoutModule->indentRB->isChecked()) {
1986                 // if paragraphs are separated by an indentation
1987                 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
1988                 switch (textLayoutModule->indentCO->currentIndex()) {
1989                 case 0:
1990                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
1991                         break;
1992                 case 1: {
1993                         HSpace indent = HSpace(
1994                                 widgetsToLength(textLayoutModule->indentLE,
1995                                 textLayoutModule->indentLengthCO)
1996                                 );
1997                         bp_.setIndentation(indent);
1998                         break;
1999                         }
2000                 default:
2001                         // this should never happen
2002                         bp_.setIndentation(HSpace(HSpace::DEFAULT));
2003                         break;
2004                 }
2005         } else {
2006                 // if paragraphs are separated by a skip
2007                 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
2008                 switch (textLayoutModule->skipCO->currentIndex()) {
2009                 case 0:
2010                         bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
2011                         break;
2012                 case 1:
2013                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2014                         break;
2015                 case 2:
2016                         bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
2017                         break;
2018                 case 3:
2019                         {
2020                         VSpace vs = VSpace(
2021                                 widgetsToLength(textLayoutModule->skipLE,
2022                                 textLayoutModule->skipLengthCO)
2023                                 );
2024                         bp_.setDefSkip(vs);
2025                         break;
2026                         }
2027                 default:
2028                         // this should never happen
2029                         bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
2030                         break;
2031                 }
2032         }
2033
2034         bp_.options =
2035                 fromqstr(latexModule->optionsLE->text());
2036
2037         bp_.use_default_options =
2038                 latexModule->defaultOptionsCB->isChecked();
2039
2040         if (latexModule->childDocGB->isChecked())
2041                 bp_.master =
2042                         fromqstr(latexModule->childDocLE->text());
2043         else
2044                 bp_.master = string();
2045
2046         // Float Placement
2047         bp_.float_placement = floatModule->get();
2048
2049         // Listings
2050         // text should have passed validation
2051         bp_.listings_params =
2052                 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
2053
2054         // output
2055         bp_.defaultOutputFormat = fromqstr(outputModule->defaultFormatCO->itemData(
2056                 outputModule->defaultFormatCO->currentIndex()).toString());
2057
2058         bool const xetex = outputModule->xetexCB->isChecked();
2059         bp_.useXetex = xetex;
2060
2061         // fonts
2062         if (xetex) {
2063                 if (fontModule->fontsRomanCO->currentIndex() == 0)
2064                         bp_.fontsRoman = "default";
2065                 else
2066                         bp_.fontsRoman =
2067                                 fromqstr(fontModule->fontsRomanCO->currentText());
2068         
2069                 if (fontModule->fontsSansCO->currentIndex() == 0)
2070                         bp_.fontsSans = "default";
2071                 else
2072                         bp_.fontsSans =
2073                                 fromqstr(fontModule->fontsSansCO->currentText());
2074         
2075                 if (fontModule->fontsTypewriterCO->currentIndex() == 0)
2076                         bp_.fontsTypewriter = "default";
2077                 else
2078                         bp_.fontsTypewriter =
2079                                 fromqstr(fontModule->fontsTypewriterCO->currentText());
2080         } else {
2081                 bp_.fontsRoman =
2082                         tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
2083         
2084                 bp_.fontsSans =
2085                         tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
2086         
2087                 bp_.fontsTypewriter =
2088                         tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
2089         }
2090
2091         if (fontModule->fontencCO->currentIndex() == 0)
2092                 bp_.fontenc = "global";
2093         else if (fontModule->fontencCO->currentIndex() == 1)
2094                 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
2095         else if (fontModule->fontencCO->currentIndex() == 2)
2096                 bp_.fontenc = "default";
2097
2098         bp_.fontsCJK =
2099                 fromqstr(fontModule->cjkFontLE->text());
2100
2101         bp_.fontsSansScale = fontModule->scaleSansSB->value();
2102
2103         bp_.fontsTypewriterScale = fontModule->scaleTypewriterSB->value();
2104
2105         bp_.fontsSC = fontModule->fontScCB->isChecked();
2106
2107         bp_.fontsOSF = fontModule->fontOsfCB->isChecked();
2108
2109         if (xetex)
2110                 bp_.fontsDefaultFamily = "default";
2111         else
2112                 bp_.fontsDefaultFamily = GuiDocument::fontfamilies[
2113                         fontModule->fontsDefaultCO->currentIndex()];
2114
2115         if (fontModule->fontsizeCO->currentIndex() == 0)
2116                 bp_.fontsize = "default";
2117         else
2118                 bp_.fontsize =
2119                         fromqstr(fontModule->fontsizeCO->currentText());
2120
2121         // paper
2122         bp_.papersize = PAPER_SIZE(
2123                 pageLayoutModule->papersizeCO->currentIndex());
2124
2125         // custom, A3, B3 and B4 paper sizes need geometry
2126         int psize = pageLayoutModule->papersizeCO->currentIndex();
2127         bool geom_papersize = (psize == 1 || psize == 5 || psize == 8 || psize == 9);
2128
2129         bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
2130                 pageLayoutModule->paperwidthUnitCO);
2131
2132         bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
2133                 pageLayoutModule->paperheightUnitCO);
2134
2135         if (pageLayoutModule->facingPagesCB->isChecked())
2136                 bp_.sides = TwoSides;
2137         else
2138                 bp_.sides = OneSide;
2139
2140         if (pageLayoutModule->landscapeRB->isChecked())
2141                 bp_.orientation = ORIENTATION_LANDSCAPE;
2142         else
2143                 bp_.orientation = ORIENTATION_PORTRAIT;
2144
2145         bp_.backgroundcolor = set_backgroundcolor;
2146
2147         // margins
2148         bp_.use_geometry = !marginsModule->marginCB->isChecked()
2149                 || geom_papersize;
2150
2151         Ui::MarginsUi const * m = marginsModule;
2152
2153         bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
2154         bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
2155         bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
2156         bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
2157         bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
2158         bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
2159         bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
2160         bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
2161
2162         // branches
2163         branchesModule->apply(bp_);
2164
2165         // PDF support
2166         PDFOptions & pdf = bp_.pdfoptions();
2167         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
2168         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
2169         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
2170         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
2171         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
2172
2173         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
2174         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
2175         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
2176         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
2177
2178         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
2179         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
2180         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
2181         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
2182         pdf.backref =
2183                 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
2184         if (pdfSupportModule->fullscreenCB->isChecked())
2185                 pdf.pagemode = pdf.pagemode_fullscreen;
2186         else
2187                 pdf.pagemode.clear();
2188         pdf.quoted_options = pdf.quoted_options_check(
2189                                 fromqstr(pdfSupportModule->optionsLE->text()));
2190 }
2191
2192
2193 void GuiDocument::paramsToDialog()
2194 {
2195         // set the default unit
2196         Length::UNIT const defaultUnit = Length::defaultUnit();
2197
2198         // preamble
2199         preambleModule->update(bp_, id());
2200
2201         // date
2202         latexModule->suppressDateCB->setChecked(bp_.suppress_date);
2203
2204         // biblio
2205         biblioModule->citeDefaultRB->setChecked(
2206                 bp_.citeEngine() == ENGINE_BASIC);
2207
2208         biblioModule->citeNatbibRB->setChecked(
2209                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL ||
2210                 bp_.citeEngine() == ENGINE_NATBIB_AUTHORYEAR);
2211
2212         biblioModule->citeStyleCO->setCurrentIndex(
2213                 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL);
2214
2215         biblioModule->citeJurabibRB->setChecked(
2216                 bp_.citeEngine() == ENGINE_JURABIB);
2217
2218         biblioModule->bibtopicCB->setChecked(
2219                 bp_.use_bibtopic);
2220
2221         string command;
2222         string options =
2223                 split(bp_.bibtex_command, command, ' ');
2224
2225         int const bpos = biblioModule->bibtexCO->findData(toqstr(command));
2226         if (bpos != -1) {
2227                 biblioModule->bibtexCO->setCurrentIndex(bpos);
2228                 biblioModule->bibtexOptionsED->setText(toqstr(options).trimmed());
2229         } else {
2230                 biblioModule->bibtexCO->setCurrentIndex(0);
2231                 biblioModule->bibtexOptionsED->clear();
2232         }
2233         biblioModule->bibtexOptionsED->setEnabled(
2234                 biblioModule->bibtexCO->currentIndex() != 0);
2235
2236         // indices
2237         indicesModule->update(bp_);
2238
2239         // language & quotes
2240         int const pos = langModule->languageCO->findData(toqstr(
2241                 bp_.language->lang()));
2242         langModule->languageCO->setCurrentIndex(pos);
2243
2244         langModule->quoteStyleCO->setCurrentIndex(
2245                 bp_.quotes_language);
2246
2247         bool default_enc = true;
2248         if (bp_.inputenc != "auto") {
2249                 default_enc = false;
2250                 if (bp_.inputenc == "default") {
2251                         langModule->encodingCO->setCurrentIndex(0);
2252                 } else {
2253                         string enc_gui;
2254                         Encodings::const_iterator it = encodings.begin();
2255                         Encodings::const_iterator const end = encodings.end();
2256                         for (; it != end; ++it) {
2257                                 if (it->latexName() == bp_.inputenc) {
2258                                         enc_gui = it->guiName();
2259                                         break;
2260                                 }
2261                         }
2262                         int const i = langModule->encodingCO->findText(
2263                                         qt_(enc_gui));
2264                         if (i >= 0)
2265                                 langModule->encodingCO->setCurrentIndex(i);
2266                         else
2267                                 // unknown encoding. Set to default.
2268                                 default_enc = true;
2269                 }
2270         }
2271         langModule->defaultencodingRB->setChecked(default_enc);
2272         langModule->otherencodingRB->setChecked(!default_enc);
2273
2274         // numbering
2275         int const min_toclevel = documentClass().min_toclevel();
2276         int const max_toclevel = documentClass().max_toclevel();
2277         if (documentClass().hasTocLevels()) {
2278                 numberingModule->setEnabled(true);
2279                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
2280                 numberingModule->depthSL->setMaximum(max_toclevel);
2281                 numberingModule->depthSL->setValue(bp_.secnumdepth);
2282                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
2283                 numberingModule->tocSL->setMaximum(max_toclevel);
2284                 numberingModule->tocSL->setValue(bp_.tocdepth);
2285                 updateNumbering();
2286         } else {
2287                 numberingModule->setEnabled(false);
2288                 numberingModule->tocTW->clear();
2289         }
2290
2291         // bullets
2292         bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
2293         bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
2294         bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
2295         bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
2296         bulletsModule->init();
2297
2298         // packages
2299         int nitem = findToken(tex_graphics, bp_.graphicsDriver);
2300         if (nitem >= 0)
2301                 latexModule->psdriverCO->setCurrentIndex(nitem);
2302         updateModuleInfo();
2303         
2304         mathsModule->amsCB->setChecked(
2305                 bp_.use_amsmath == BufferParams::package_on);
2306         mathsModule->amsautoCB->setChecked(
2307                 bp_.use_amsmath == BufferParams::package_auto);
2308
2309         mathsModule->esintCB->setChecked(
2310                 bp_.use_esint == BufferParams::package_on);
2311         mathsModule->esintautoCB->setChecked(
2312                 bp_.use_esint == BufferParams::package_auto);
2313
2314         mathsModule->mhchemCB->setChecked(
2315                 bp_.use_mhchem == BufferParams::package_on);
2316         mathsModule->mhchemautoCB->setChecked(
2317                 bp_.use_mhchem == BufferParams::package_auto);
2318
2319         switch (bp_.spacing().getSpace()) {
2320                 case Spacing::Other: nitem = 3; break;
2321                 case Spacing::Double: nitem = 2; break;
2322                 case Spacing::Onehalf: nitem = 1; break;
2323                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
2324         }
2325
2326         // text layout
2327         string const & layoutID = bp_.baseClassID();
2328         setLayoutComboByIDString(layoutID);
2329
2330         updatePagestyle(documentClass().opt_pagestyle(),
2331                                  bp_.pagestyle);
2332
2333         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
2334         if (bp_.spacing().getSpace() == Spacing::Other) {
2335                 doubleToWidget(textLayoutModule->lspacingLE,
2336                         bp_.spacing().getValueAsString());
2337         }
2338         setLSpacing(nitem);
2339
2340         if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
2341                 textLayoutModule->indentRB->setChecked(true);
2342                 string indentation = bp_.getIndentation().asLyXCommand();
2343                 int indent = 0;
2344                 if (indentation != "default") {
2345                         lengthToWidgets(textLayoutModule->indentLE,
2346                         textLayoutModule->indentLengthCO,
2347                         indentation, defaultUnit);
2348                         indent = 1;
2349                 }
2350                 textLayoutModule->indentCO->setCurrentIndex(indent);
2351                 setIndent(indent);
2352         } else {
2353                 textLayoutModule->skipRB->setChecked(true);
2354                 int skip = 0;
2355                 switch (bp_.getDefSkip().kind()) {
2356                 case VSpace::SMALLSKIP:
2357                         skip = 0;
2358                         break;
2359                 case VSpace::MEDSKIP:
2360                         skip = 1;
2361                         break;
2362                 case VSpace::BIGSKIP:
2363                         skip = 2;
2364                         break;
2365                 case VSpace::LENGTH:
2366                         {
2367                         skip = 3;
2368                         string const length = bp_.getDefSkip().asLyXCommand();
2369                         lengthToWidgets(textLayoutModule->skipLE,
2370                                 textLayoutModule->skipLengthCO,
2371                                 length, defaultUnit);
2372                         break;
2373                         }
2374                 default:
2375                         skip = 0;
2376                         break;
2377                 }
2378                 textLayoutModule->skipCO->setCurrentIndex(skip);
2379                 setSkip(skip);
2380         }
2381
2382         textLayoutModule->twoColumnCB->setChecked(
2383                 bp_.columns == 2);
2384
2385         if (!bp_.options.empty()) {
2386                 latexModule->optionsLE->setText(
2387                         toqstr(bp_.options));
2388         } else {
2389                 latexModule->optionsLE->setText(QString());
2390         }
2391
2392         // latex
2393         latexModule->defaultOptionsCB->setChecked(
2394                         bp_.use_default_options);
2395         updateSelectedModules();
2396         selectionManager->updateProvidedModules(
2397                         bp_.baseClass()->providedModules());
2398         selectionManager->updateExcludedModules(
2399                         bp_.baseClass()->excludedModules());
2400
2401         if (!documentClass().options().empty()) {
2402                 latexModule->defaultOptionsLE->setText(
2403                         toqstr(documentClass().options()));
2404         } else {
2405                 latexModule->defaultOptionsLE->setText(
2406                         toqstr(_("[No options predefined]")));
2407         }
2408
2409         latexModule->defaultOptionsLE->setEnabled(
2410                 bp_.use_default_options
2411                 && !documentClass().options().empty());
2412
2413         latexModule->defaultOptionsCB->setEnabled(
2414                 !documentClass().options().empty());
2415
2416         if (!bp_.master.empty()) {
2417                 latexModule->childDocGB->setChecked(true);
2418                 latexModule->childDocLE->setText(
2419                         toqstr(bp_.master));
2420         } else {
2421                 latexModule->childDocLE->setText(QString());
2422                 latexModule->childDocGB->setChecked(false);
2423         }
2424
2425         // Float Settings
2426         floatModule->set(bp_.float_placement);
2427
2428         // ListingsSettings
2429         // break listings_params to multiple lines
2430         string lstparams =
2431                 InsetListingsParams(bp_.listings_params).separatedParams();
2432         listingsModule->listingsED->setPlainText(toqstr(lstparams));
2433
2434         // Output
2435         // update combobox with formats
2436         updateDefaultFormat();
2437         int index = outputModule->defaultFormatCO->findData(toqstr(
2438                 bp_.defaultOutputFormat));
2439         // set to default if format is not found 
2440         if (index == -1)
2441                 index = 0;
2442         outputModule->defaultFormatCO->setCurrentIndex(index);
2443         outputModule->xetexCB->setEnabled(bp_.baseClass()->outputType() == lyx::LATEX);
2444         outputModule->xetexCB->setChecked(
2445                 bp_.baseClass()->outputType() == lyx::LATEX && bp_.useXetex);
2446
2447         // Fonts
2448         updateFontsize(documentClass().opt_fontsize(),
2449                         bp_.fontsize);
2450
2451         if (bp_.useXetex) {
2452                 fontModule->fontencLA->setEnabled(false);
2453                 fontModule->fontencCO->setEnabled(false);
2454                 fontModule->fontencLE->setEnabled(false);
2455                 for (int i = 0; i < fontModule->fontsRomanCO->count(); ++i) {
2456                         if (fontModule->fontsRomanCO->itemText(i) == toqstr(bp_.fontsRoman)) {
2457                                 fontModule->fontsRomanCO->setCurrentIndex(i);
2458                                 return;
2459                         }
2460                 }
2461                 
2462                 for (int i = 0; i < fontModule->fontsSansCO->count(); ++i) {
2463                         if (fontModule->fontsSansCO->itemText(i) == toqstr(bp_.fontsSans)) {
2464                                 fontModule->fontsSansCO->setCurrentIndex(i);
2465                                 return;
2466                         }
2467                 }
2468                 for (int i = 0; i < fontModule->fontsTypewriterCO->count(); ++i) {
2469                         if (fontModule->fontsTypewriterCO->itemText(i) == 
2470                                 toqstr(bp_.fontsTypewriter)) {
2471                                 fontModule->fontsTypewriterCO->setCurrentIndex(i);
2472                                 return;
2473                         }
2474                 }
2475         } else {
2476                 fontModule->fontencLA->setEnabled(true);
2477                 fontModule->fontencCO->setEnabled(true);
2478                 fontModule->fontencLE->setEnabled(true);
2479                 int n = findToken(tex_fonts_roman, bp_.fontsRoman);
2480                 if (n >= 0) {
2481                         fontModule->fontsRomanCO->setCurrentIndex(n);
2482                         romanChanged(n);
2483                 }
2484         
2485                 n = findToken(tex_fonts_sans, bp_.fontsSans);
2486                 if (n >= 0) {
2487                         fontModule->fontsSansCO->setCurrentIndex(n);
2488                         sansChanged(n);
2489                 }
2490         
2491                 n = findToken(tex_fonts_monospaced, bp_.fontsTypewriter);
2492                 if (n >= 0) {
2493                         fontModule->fontsTypewriterCO->setCurrentIndex(n);
2494                         ttChanged(n);
2495                 }
2496         }
2497
2498         if (!bp_.fontsCJK.empty())
2499                 fontModule->cjkFontLE->setText(
2500                         toqstr(bp_.fontsCJK));
2501         else
2502                 fontModule->cjkFontLE->setText(QString());
2503
2504         fontModule->fontScCB->setChecked(bp_.fontsSC);
2505         fontModule->fontOsfCB->setChecked(bp_.fontsOSF);
2506         fontModule->scaleSansSB->setValue(bp_.fontsSansScale);
2507         fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale);
2508
2509         int nn = findToken(GuiDocument::fontfamilies, bp_.fontsDefaultFamily);
2510         if (nn >= 0)
2511                 fontModule->fontsDefaultCO->setCurrentIndex(nn);
2512
2513         if (bp_.fontenc == "global")
2514                 fontModule->fontencCO->setCurrentIndex(0);
2515         else if (bp_.fontenc == "default")
2516                 fontModule->fontencCO->setCurrentIndex(2);
2517         else {
2518                 fontModule->fontencCO->setCurrentIndex(1);
2519                 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
2520         }
2521
2522         // paper
2523         bool const extern_geometry =
2524                 documentClass().provides("geometry");
2525         int const psize = bp_.papersize;
2526         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
2527         setCustomPapersize(!extern_geometry && psize == 1);
2528         pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
2529
2530         bool const landscape =
2531                 bp_.orientation == ORIENTATION_LANDSCAPE;
2532         pageLayoutModule->landscapeRB->setChecked(landscape);
2533         pageLayoutModule->portraitRB->setChecked(!landscape);
2534         pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
2535         pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
2536
2537         pageLayoutModule->facingPagesCB->setChecked(
2538                 bp_.sides == TwoSides);
2539
2540         pageLayoutModule->backgroundPB->setStyleSheet(
2541                 colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
2542         set_backgroundcolor = bp_.backgroundcolor;
2543
2544         lengthToWidgets(pageLayoutModule->paperwidthLE,
2545                 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, defaultUnit);
2546         lengthToWidgets(pageLayoutModule->paperheightLE,
2547                 pageLayoutModule->paperheightUnitCO, bp_.paperheight, defaultUnit);
2548
2549         // margins
2550         Ui::MarginsUi * m = marginsModule;
2551
2552         setMargins(!bp_.use_geometry);
2553
2554         lengthToWidgets(m->topLE, m->topUnit,
2555                 bp_.topmargin, defaultUnit);
2556
2557         lengthToWidgets(m->bottomLE, m->bottomUnit,
2558                 bp_.bottommargin, defaultUnit);
2559
2560         lengthToWidgets(m->innerLE, m->innerUnit,
2561                 bp_.leftmargin, defaultUnit);
2562
2563         lengthToWidgets(m->outerLE, m->outerUnit,
2564                 bp_.rightmargin, defaultUnit);
2565
2566         lengthToWidgets(m->headheightLE, m->headheightUnit,
2567                 bp_.headheight, defaultUnit);
2568
2569         lengthToWidgets(m->headsepLE, m->headsepUnit,
2570                 bp_.headsep, defaultUnit);
2571
2572         lengthToWidgets(m->footskipLE, m->footskipUnit,
2573                 bp_.footskip, defaultUnit);
2574
2575         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
2576                 bp_.columnsep, defaultUnit);
2577
2578         // branches
2579         updateUnknownBranches();
2580         branchesModule->update(bp_);
2581
2582         // PDF support
2583         PDFOptions const & pdf = bp_.pdfoptions();
2584         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
2585         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
2586         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
2587         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
2588         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
2589
2590         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
2591         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
2592         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
2593
2594         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
2595
2596         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
2597         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
2598         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
2599         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
2600
2601         nn = findToken(backref_opts, pdf.backref);
2602         if (nn >= 0)
2603                 pdfSupportModule->backrefCO->setCurrentIndex(nn);
2604
2605         pdfSupportModule->fullscreenCB->setChecked
2606                 (pdf.pagemode == pdf.pagemode_fullscreen);
2607
2608         pdfSupportModule->optionsLE->setText(
2609                 toqstr(pdf.quoted_options));
2610
2611         // Make sure that the bc is in the INITIAL state
2612         if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
2613                 bc().restore();
2614
2615         // clear changed branches cache
2616         changedBranches_.clear();
2617 }
2618
2619
2620 void GuiDocument::saveDocDefault()
2621 {
2622         // we have to apply the params first
2623         applyView();
2624         saveAsDefault();
2625 }
2626
2627
2628 void GuiDocument::updateAvailableModules() 
2629 {
2630         modules_av_model_.clear();
2631         list<modInfoStruct> const & modInfoList = getModuleInfo();
2632         list<modInfoStruct>::const_iterator mit = modInfoList.begin();
2633         list<modInfoStruct>::const_iterator men = modInfoList.end();
2634         for (int i = 0; mit != men; ++mit, ++i)
2635                 modules_av_model_.insertRow(i, mit->name, mit->id, 
2636                                 mit->description);
2637 }
2638
2639
2640 void GuiDocument::updateSelectedModules() 
2641 {
2642         modules_sel_model_.clear();
2643         list<modInfoStruct> const selModList = getSelectedModules();
2644         list<modInfoStruct>::const_iterator mit = selModList.begin();
2645         list<modInfoStruct>::const_iterator men = selModList.end();
2646         for (int i = 0; mit != men; ++mit, ++i)
2647                 modules_sel_model_.insertRow(i, mit->name, mit->id, 
2648                                 mit->description);
2649 }
2650
2651
2652 void GuiDocument::updateContents()
2653 {
2654         // Nothing to do here as the document settings is not cursor dependant.
2655         return;
2656 }
2657
2658
2659 void GuiDocument::useClassDefaults()
2660 {
2661         if (applyPB->isEnabled()) {
2662                 int const ret = Alert::prompt(_("Unapplied changes"),
2663                                 _("Some changes in the dialog were not yet applied.\n"
2664                                   "If you do not apply now, they will be lost after this action."),
2665                                 1, 1, _("&Apply"), _("&Dismiss"));
2666                 if (ret == 0)
2667                         applyView();
2668         }
2669
2670         int idx = latexModule->classCO->currentIndex();
2671         string const classname = classes_model_.getIDString(idx);
2672         if (!bp_.setBaseClass(classname)) {
2673                 Alert::error(_("Error"), _("Unable to set document class."));
2674                 return;
2675         }
2676         bp_.useClassDefaults();
2677         paramsToDialog();
2678 }
2679
2680
2681 void GuiDocument::setLayoutComboByIDString(string const & idString)
2682 {
2683         int idx = classes_model_.findIDString(idString);
2684         if (idx < 0)
2685                 Alert::warning(_("Can't set layout!"), 
2686                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
2687         else 
2688                 latexModule->classCO->setCurrentIndex(idx);
2689 }
2690
2691
2692 bool GuiDocument::isValid()
2693 {
2694         return validateListingsParameters().isEmpty()
2695                 && (textLayoutModule->skipCO->currentIndex() != 3
2696                         || !textLayoutModule->skipLE->text().isEmpty()
2697                         || textLayoutModule->indentRB->isChecked())
2698                 && (textLayoutModule->indentCO->currentIndex() != 1
2699                         || !textLayoutModule->indentLE->text().isEmpty()
2700                         || textLayoutModule->skipRB->isChecked());
2701 }
2702
2703
2704 char const * const GuiDocument::fontfamilies[5] = {
2705         "default", "rmdefault", "sfdefault", "ttdefault", ""
2706 };
2707
2708
2709 char const * GuiDocument::fontfamilies_gui[5] = {
2710         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
2711 };
2712
2713
2714 bool GuiDocument::initialiseParams(string const &)
2715 {
2716         BufferView const * view = bufferview();
2717         if (!view) {
2718                 bp_ = BufferParams();
2719                 paramsToDialog();
2720                 return true;
2721         }
2722         bp_ = view->buffer().params();
2723         loadModuleInfo();
2724         updateAvailableModules();
2725         //FIXME It'd be nice to make sure here that the selected
2726         //modules are consistent: That required modules are actually
2727         //selected, and that we don't have conflicts. If so, we could
2728         //at least pop up a warning.
2729         paramsToDialog();
2730         return true;
2731 }
2732
2733
2734 void GuiDocument::clearParams()
2735 {
2736         bp_ = BufferParams();
2737 }
2738
2739
2740 BufferId GuiDocument::id() const
2741 {
2742         BufferView const * const view = bufferview();
2743         return view? &view->buffer() : 0;
2744 }
2745
2746
2747 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
2748 {
2749         return moduleNames_;
2750 }
2751
2752
2753 list<GuiDocument::modInfoStruct> const 
2754                 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
2755 {
2756         LayoutModuleList::const_iterator it =  mods.begin();
2757         LayoutModuleList::const_iterator end = mods.end();
2758         list<modInfoStruct> mInfo;
2759         for (; it != end; ++it) {
2760                 modInfoStruct m;
2761                 m.id = *it;
2762                 LyXModule const * const mod = theModuleList[*it];
2763                 if (mod)
2764                         // FIXME Unicode
2765                         m.name = toqstr(translateIfPossible(from_utf8(mod->getName())));
2766                 else 
2767                         m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
2768                 mInfo.push_back(m);
2769         }
2770         return mInfo;
2771 }
2772
2773
2774 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
2775 {
2776         return makeModuleInfo(params().getModules());
2777 }
2778
2779
2780 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
2781 {
2782         return makeModuleInfo(params().baseClass()->providedModules());
2783 }
2784
2785
2786 DocumentClass const & GuiDocument::documentClass() const
2787 {
2788         return bp_.documentClass();
2789 }
2790
2791
2792 static void dispatch_bufferparams(Dialog const & dialog,
2793         BufferParams const & bp, FuncCode lfun)
2794 {
2795         ostringstream ss;
2796         ss << "\\begin_header\n";
2797         bp.writeFile(ss);
2798         ss << "\\end_header\n";
2799         dialog.dispatch(FuncRequest(lfun, ss.str()));
2800 }
2801
2802
2803 void GuiDocument::dispatchParams()
2804 {
2805         // This must come first so that a language change is correctly noticed
2806         setLanguage();
2807
2808         // Apply the BufferParams. Note that this will set the base class
2809         // and then update the buffer's layout.
2810         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
2811
2812         if (!params().master.empty()) {
2813                 FileName const master_file = support::makeAbsPath(params().master,
2814                            support::onlyPath(buffer().absFileName()));
2815                 if (isLyXFilename(master_file.absFilename())) {
2816                         Buffer * master = checkAndLoadLyXFile(master_file);
2817                         if (master) {
2818                                 if (master->isChild(const_cast<Buffer *>(&buffer())))
2819                                         const_cast<Buffer &>(buffer()).setParent(master);
2820                                 else
2821                                         Alert::warning(_("Assigned master does not include this file"), 
2822                                                 bformat(_("You must include this file in the document\n"
2823                                                           "'%1$s' in order to use the master document\n"
2824                                                           "feature."), from_utf8(params().master)));
2825                         } else
2826                                 Alert::warning(_("Could not load master"), 
2827                                                 bformat(_("The master document '%1$s'\n"
2828                                                            "could not be loaded."),
2829                                                            from_utf8(params().master)));
2830                 }
2831         }
2832
2833         // Generate the colours requested by each new branch.
2834         BranchList & branchlist = params().branchlist();
2835         if (!branchlist.empty()) {
2836                 BranchList::const_iterator it = branchlist.begin();
2837                 BranchList::const_iterator const end = branchlist.end();
2838                 for (; it != end; ++it) {
2839                         docstring const & current_branch = it->branch();
2840                         Branch const * branch = branchlist.find(current_branch);
2841                         string const x11hexname = X11hexname(branch->color());
2842                         // display the new color
2843                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
2844                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
2845                 }
2846
2847                 // Open insets of selected branches, close deselected ones
2848                 dispatch(FuncRequest(LFUN_ALL_INSETS_TOGGLE,
2849                         "assign branch"));
2850         }
2851         // rename branches in the document
2852         executeBranchRenaming();
2853         // and clear changed branches cache
2854         changedBranches_.clear();
2855         
2856         // Generate the colours requested by indices.
2857         IndicesList & indiceslist = params().indiceslist();
2858         if (!indiceslist.empty()) {
2859                 IndicesList::const_iterator it = indiceslist.begin();
2860                 IndicesList::const_iterator const end = indiceslist.end();
2861                 for (; it != end; ++it) {
2862                         docstring const & current_index = it->shortcut();
2863                         Index const * index = indiceslist.findShortcut(current_index);
2864                         string const x11hexname = X11hexname(index->color());
2865                         // display the new color
2866                         docstring const str = current_index + ' ' + from_ascii(x11hexname);
2867                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
2868                 }
2869         }
2870         // FIXME: If we used an LFUN, we would not need those two lines:
2871         BufferView * bv = const_cast<BufferView *>(bufferview());
2872         bv->processUpdateFlags(Update::Force | Update::FitCursor);
2873 }
2874
2875
2876 void GuiDocument::setLanguage() const
2877 {
2878         Language const * const newL = bp_.language;
2879         if (buffer().params().language == newL)
2880                 return;
2881
2882         string const & lang_name = newL->lang();
2883         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
2884 }
2885
2886
2887 void GuiDocument::saveAsDefault() const
2888 {
2889         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
2890 }
2891
2892
2893 bool GuiDocument::isFontAvailable(string const & font) const
2894 {
2895         if (font == "default" || font == "cmr"
2896             || font == "cmss" || font == "cmtt")
2897                 // these are standard
2898                 return true;
2899         if (font == "lmodern" || font == "lmss" || font == "lmtt")
2900                 return LaTeXFeatures::isAvailable("lmodern");
2901         if (font == "times" || font == "palatino"
2902                  || font == "helvet" || font == "courier")
2903                 return LaTeXFeatures::isAvailable("psnfss");
2904         if (font == "cmbr" || font == "cmtl")
2905                 return LaTeXFeatures::isAvailable("cmbright");
2906         if (font == "utopia")
2907                 return LaTeXFeatures::isAvailable("utopia")
2908                         || LaTeXFeatures::isAvailable("fourier");
2909         if (font == "beraserif" || font == "berasans"
2910                 || font == "beramono")
2911                 return LaTeXFeatures::isAvailable("bera");
2912         return LaTeXFeatures::isAvailable(font);
2913 }
2914
2915
2916 bool GuiDocument::providesOSF(string const & font) const
2917 {
2918         if (outputModule->xetexCB->isChecked())
2919                 // FIXME: we should check if the fonts really
2920                 // have OSF support. But how?
2921                 return true;
2922         if (font == "cmr")
2923                 return isFontAvailable("eco");
2924         if (font == "palatino")
2925                 return isFontAvailable("mathpazo");
2926         return false;
2927 }
2928
2929
2930 bool GuiDocument::providesSC(string const & font) const
2931 {
2932         if (outputModule->xetexCB->isChecked())
2933                 return false;
2934         if (font == "palatino")
2935                 return isFontAvailable("mathpazo");
2936         if (font == "utopia")
2937                 return isFontAvailable("fourier");
2938         return false;
2939 }
2940
2941
2942 bool GuiDocument::providesScale(string const & font) const
2943 {
2944         if (outputModule->xetexCB->isChecked())
2945                 return true;
2946         return font == "helvet" || font == "luximono"
2947                 || font == "berasans"  || font == "beramono";
2948 }
2949
2950
2951 void GuiDocument::loadModuleInfo()
2952 {
2953         moduleNames_.clear();
2954         LyXModuleList::const_iterator it  = theModuleList.begin();
2955         LyXModuleList::const_iterator end = theModuleList.end();
2956         for (; it != end; ++it) {
2957                 modInfoStruct m;
2958                 m.id = it->getID();
2959                 // FIXME Unicode
2960                 m.name = toqstr(translateIfPossible(from_utf8(it->getName())));
2961                 // this is supposed to give us the first sentence of the description
2962                 // FIXME Unicode
2963                 QString desc =
2964                         toqstr(translateIfPossible(from_utf8(it->getDescription())));
2965                 int const pos = desc.indexOf(".");
2966                 if (pos > 0)
2967                         desc.truncate(pos + 1);
2968                 m.description = desc;
2969                 moduleNames_.push_back(m);
2970         }
2971 }
2972
2973
2974 void GuiDocument::updateUnknownBranches()
2975 {
2976         list<docstring> used_branches;
2977         buffer().getUsedBranches(used_branches);
2978         list<docstring>::const_iterator it = used_branches.begin();
2979         QStringList unknown_branches;
2980         for (; it != used_branches.end() ; ++it) {
2981                 if (!buffer().params().branchlist().find(*it))
2982                         unknown_branches.append(toqstr(*it));
2983         }
2984         branchesModule->setUnknownBranches(unknown_branches);
2985 }
2986
2987
2988 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
2989 {
2990         map<docstring, docstring>::iterator it = changedBranches_.begin();
2991         for (; it != changedBranches_.end() ; ++it) {
2992                 if (it->second == oldname) {
2993                         // branch has already been renamed
2994                         it->second = newname;
2995                         return;
2996                 }
2997         }
2998         // store new name
2999         changedBranches_[oldname] = newname;
3000 }
3001
3002
3003 void GuiDocument::executeBranchRenaming() const
3004 {
3005         map<docstring, docstring>::const_iterator it = changedBranches_.begin();
3006         for (; it != changedBranches_.end() ; ++it) {
3007                 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
3008                 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
3009         }
3010 }
3011
3012
3013 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
3014
3015
3016 } // namespace frontend
3017 } // namespace lyx
3018
3019 #include "moc_GuiDocument.cpp"