]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiDocument.cpp
6a9cdf79e4b59b379b715ed562994d8418cff108
[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 "GuiSelectionManager.h"
19 #include "LaTeXHighlighter.h"
20 #include "LengthCombo.h"
21 #include "PanelStack.h"
22 #include "Validator.h"
23
24 #include "LayoutFile.h"
25 #include "BranchList.h"
26 #include "buffer_funcs.h"
27 #include "Buffer.h"
28 #include "BufferParams.h"
29 #include "BufferView.h"
30 #include "Color.h"
31 #include "Encoding.h"
32 #include "FloatPlacement.h"
33 #include "FuncRequest.h"
34 #include "Language.h"
35 #include "LaTeXFeatures.h"
36 #include "Layout.h"
37 #include "LyXRC.h" // defaultUnit
38 #include "ModuleList.h"
39 #include "OutputParams.h"
40 #include "PDFOptions.h"
41 #include "qt_helpers.h"
42 #include "Spacing.h"
43
44 #include "insets/InsetListingsParams.h"
45
46 #include "support/debug.h"
47 #include "support/FileName.h"
48 #include "support/filetools.h"
49 #include "support/gettext.h"
50 #include "support/lstrings.h"
51
52 #include "frontends/alert.h"
53
54 #include <QAbstractItemModel>
55 #include <QCloseEvent>
56 #include <QScrollBar>
57 #include <QTextCursor>
58
59 #include <sstream>
60
61 #ifdef IN
62 #undef IN
63 #endif
64
65
66 using namespace std;
67 using namespace lyx::support;
68
69
70 namespace {
71
72 char const * const tex_graphics[] =
73 {
74         "default", "dvialw", "dvilaser", "dvipdf", "dvipdfm", "dvipdfmx",
75         "dvips", "dvipsone", "dvitops", "dviwin", "dviwindo", "dvi2ps", "emtex",
76         "ln", "oztex", "pctexhp", "pctexps", "pctexwin", "pctex32", "pdftex",
77         "psprint", "pubps", "tcidvi", "textures", "truetex", "vtex", "xdvi",
78         "xetex", "none", ""
79 };
80
81
82 char const * const tex_graphics_gui[] =
83 {
84         N_("Default"), "dvialw", "DviLaser", "dvipdf", "DVIPDFM", "DVIPDFMx",
85         "Dvips", "DVIPSONE", "DVItoPS", "DVIWIN", "DVIWindo", "dvi2ps", "EmTeX",
86         "LN", "OzTeX", "pctexhp", "pctexps", "pctexwin", "PCTeX32", "pdfTeX",
87         "psprint", "pubps", "tcidvi", "Textures", "TrueTeX", "VTeX", "xdvi",
88         "XeTeX", N_("None"), ""
89 };
90
91
92 char const * const tex_fonts_roman[] =
93 {
94         "default", "cmr", "lmodern", "ae", "times", "palatino",
95         "charter", "newcent", "bookman", "utopia", "beraserif",
96         "ccfonts", "chancery", ""
97 };
98
99
100 char const * tex_fonts_roman_gui[] =
101 {
102         N_("Default"), N_("Computer Modern Roman"), N_("Latin Modern Roman"),
103         N_("AE (Almost European)"), N_("Times Roman"), N_("Palatino"),
104         N_("Bitstream Charter"), N_("New Century Schoolbook"), N_("Bookman"),
105         N_("Utopia"),  N_("Bera Serif"), N_("Concrete Roman"), N_("Zapf Chancery"),
106         ""
107 };
108
109
110 char const * const tex_fonts_sans[] =
111 {
112         "default", "cmss", "lmss", "helvet", "avant", "berasans", "cmbr", ""
113 };
114
115
116 char const * tex_fonts_sans_gui[] =
117 {
118         N_("Default"), N_("Computer Modern Sans"), N_("Latin Modern Sans"),
119         N_("Helvetica"), N_("Avant Garde"), N_("Bera Sans"), N_("CM Bright"), ""
120 };
121
122
123 char const * const tex_fonts_monospaced[] =
124 {
125         "default", "cmtt", "lmtt", "courier", "beramono", "luximono", "cmtl", ""
126 };
127
128
129 char const * tex_fonts_monospaced_gui[] =
130 {
131         N_("Default"), N_("Computer Modern Typewriter"),
132         N_("Latin Modern Typewriter"), N_("Courier"), N_("Bera Mono"),
133         N_("LuxiMono"), N_("CM Typewriter Light"), ""
134 };
135
136
137 vector<pair<string, QString> > pagestyles;
138
139
140 } // anonymous namespace
141
142 namespace lyx {
143
144 namespace {
145 // used when sorting the textclass list.
146 class less_textclass_avail_desc
147         : public binary_function<string, string, int>
148 {
149 public:
150         bool operator()(string const & lhs, string const & rhs) const
151         {
152                 // Ordering criteria:
153                 //   1. Availability of text class
154                 //   2. Description (lexicographic)
155                 LayoutFile const & tc1 = LayoutFileList::get()[lhs];
156                 LayoutFile const & tc2 = LayoutFileList::get()[rhs];
157                 return (tc1.isTeXClassAvailable() && !tc2.isTeXClassAvailable()) ||
158                         (tc1.isTeXClassAvailable() == tc2.isTeXClassAvailable() &&
159                          _(tc1.description()) < _(tc2.description()));
160         }
161 };
162
163 }
164
165 namespace frontend {
166 namespace {
167
168 vector<string> getRequiredList(string const & modName) 
169 {
170         LyXModule const * const mod = moduleList[modName];
171         if (!mod)
172                 return vector<string>(); //empty such thing
173         return mod->getRequiredModules();
174 }
175
176
177 vector<string> getExcludedList(string const & modName)
178 {
179         LyXModule const * const mod = moduleList[modName];
180         if (!mod)
181                 return vector<string>(); //empty such thing
182         return mod->getExcludedModules();
183 }
184
185
186 docstring getModuleDescription(string const & modName)
187 {
188         LyXModule const * const mod = moduleList[modName];
189         if (!mod)
190                 return _("Module not found!");
191         return _(mod->getDescription());
192 }
193
194
195 vector<string> getPackageList(string const & modName)
196 {
197         LyXModule const * const mod = moduleList[modName];
198         if (!mod)
199                 return vector<string>(); //empty such thing
200         return mod->getPackageList();
201 }
202
203
204 bool isModuleAvailable(string const & modName)
205 {
206         LyXModule * mod = moduleList[modName];
207         if (!mod)
208                 return false;
209         return mod->isAvailable();
210 }
211
212 } // anonymous namespace
213
214
215 /////////////////////////////////////////////////////////////////////
216 //
217 // ModuleSelectionManager
218 //
219 /////////////////////////////////////////////////////////////////////
220
221 /// SelectionManager for use with modules
222 class ModuleSelectionManager : public GuiSelectionManager 
223 {
224 public:
225         ModuleSelectionManager(
226                 QListView * availableLV, 
227                 QListView * selectedLV,
228                 QPushButton * addPB, 
229                 QPushButton * delPB, 
230                 QPushButton * upPB, 
231                 QPushButton * downPB,
232                 GuiIdListModel * availableModel,
233                 GuiIdListModel * selectedModel)
234         : GuiSelectionManager(availableLV, selectedLV, addPB, delPB,
235                     upPB, downPB, availableModel, selectedModel) 
236                 {}
237         
238
239 private:
240         ///
241         virtual void updateAddPB();
242         ///
243         virtual void updateUpPB();
244         ///
245         virtual void updateDownPB();
246         ///
247         virtual void updateDelPB();
248         /// returns availableModel as a GuiIdListModel
249         GuiIdListModel * getAvailableModel() 
250         {
251                 return dynamic_cast<GuiIdListModel *>(availableModel);
252         }
253         /// returns selectedModel as a GuiIdListModel
254         GuiIdListModel * getSelectedModel() 
255         {
256                 return dynamic_cast<GuiIdListModel *>(selectedModel);
257         }
258 };
259
260 void ModuleSelectionManager::updateAddPB() 
261 {
262         int const arows = availableModel->rowCount();
263         QModelIndexList const availSels = 
264                         availableLV->selectionModel()->selectedIndexes();
265         if (arows == 0 || availSels.isEmpty()  || isSelected(availSels.first())) {
266                 addPB->setEnabled(false);
267                 return;
268         }
269         
270         QModelIndex const & idx = availableLV->selectionModel()->currentIndex();
271         string const modName = getAvailableModel()->getIDString(idx.row());
272         vector<string> reqs = getRequiredList(modName);
273         vector<string> excl = getExcludedList(modName);
274         
275         if (reqs.empty() && excl.empty()) {
276                 addPB->setEnabled(true);
277                 return;
278         }
279
280         int const srows = selectedModel->rowCount();
281         vector<string> selModList;
282         for (int i = 0; i < srows; ++i)
283                 selModList.push_back(getSelectedModel()->getIDString(i));
284
285         vector<string>::const_iterator selModStart = selModList.begin();
286         vector<string>::const_iterator selModEnd   = selModList.end();
287         
288         //Check whether some required module is available
289         if (!reqs.empty()) {
290                 bool foundOne = false;
291                 vector<string>::const_iterator it  = reqs.begin();
292                 vector<string>::const_iterator end = reqs.end();
293                 for (; it != end; ++it) {
294                         if (find(selModStart, selModEnd, *it) != selModEnd) {
295                                 foundOne = true;
296                                 break;
297                         }
298                 }
299                 if (!foundOne) {
300                         addPB->setEnabled(false);
301                         return;
302                 }
303         }
304         
305         //Check whether any excluded module is being used
306         if (!excl.empty()) {
307                 vector<string>::const_iterator it  = excl.begin();
308                 vector<string>::const_iterator end = excl.end();
309                 for (; it != end; ++it) {
310                         if (find(selModStart, selModEnd, *it) != selModEnd) {
311                                 addPB->setEnabled(false);
312                                 return;
313                         }
314                 }
315         }
316
317         addPB->setEnabled(true);
318 }
319
320
321 void ModuleSelectionManager::updateDownPB()
322 {
323         int const srows = selectedModel->rowCount();
324         if (srows == 0) {
325                 downPB->setEnabled(false);
326                 return;
327         }
328         QModelIndexList const selSels = 
329                         selectedLV->selectionModel()->selectedIndexes();
330         //disable if empty or last item is selected
331         if (selSels.empty() || selSels.first().row() == srows - 1) {
332                 downPB->setEnabled(false);
333                 return;
334         }
335         //determine whether immediately succeding element requires this one
336         QModelIndex const & curIdx = selectedLV->selectionModel()->currentIndex();
337         int curRow = curIdx.row();
338         if (curRow < 0 || curRow >= srows - 1) { //this shouldn't happen...
339                 downPB->setEnabled(false);
340                 return;
341         }
342         string const curModName = getSelectedModel()->getIDString(curRow);
343         string const nextModName = getSelectedModel()->getIDString(curRow + 1);
344
345         vector<string> reqs = getRequiredList(nextModName);
346
347         //if it doesn't require anything....
348         if (reqs.empty()) {
349                 downPB->setEnabled(true);
350                 return;
351         }
352
353         //FIXME This should perhaps be more flexible and check whether, even 
354         //if this one is required, there is also an earlier one that is required.
355         //enable it if this module isn't required
356         downPB->setEnabled(
357                         find(reqs.begin(), reqs.end(), curModName) == reqs.end());
358 }
359
360 void ModuleSelectionManager::updateUpPB() 
361 {
362         int const srows = selectedModel->rowCount();
363         if (srows == 0) {
364                 upPB->setEnabled(false);
365                 return;
366         }
367         QModelIndexList const selSels = 
368                         selectedLV->selectionModel()->selectedIndexes();
369         //disable if empty or first item is selected
370         if (selSels.empty() || selSels.first().row() == 0) {
371                 upPB->setEnabled(false);
372                 return;
373         }
374
375         //determine whether immediately preceding element is required by this one
376         QModelIndex const & curIdx = selectedLV->selectionModel()->currentIndex();
377         int curRow = curIdx.row();
378         if (curRow <= -1 || curRow > srows - 1) { //sanity check
379                 downPB->setEnabled(false);
380                 return;
381         }
382         string const curModName = getSelectedModel()->getIDString(curRow);
383         vector<string> reqs = getRequiredList(curModName);
384         
385         //if this one doesn't require anything....
386         if (reqs.empty()) {
387                 upPB->setEnabled(true);
388                 return;
389         }
390
391         string preModName = getSelectedModel()->getIDString(curRow - 1);
392
393         //NOTE This is less flexible than it might be. You could check whether, even 
394         //if this one is required, there is also an earlier one that is required.
395         //enable it if the preceding module isn't required
396         upPB->setEnabled(find(reqs.begin(), reqs.end(), preModName) == reqs.end());
397 }
398
399 void ModuleSelectionManager::updateDelPB() 
400 {
401         int const srows = selectedModel->rowCount();
402         if (srows == 0) {
403                 deletePB->setEnabled(false);
404                 return;
405         }
406         QModelIndexList const selSels = 
407                         selectedLV->selectionModel()->selectedIndexes();
408         if (selSels.empty() || selSels.first().row() < 0) {
409                 deletePB->setEnabled(false);
410                 return;
411         }
412         
413         //determine whether some LATER module requires this one
414         //NOTE Things are arranged so that this is the only way there
415         //can be a problem. At least, we hope so.
416         QModelIndex const & curIdx = 
417                 selectedLV->selectionModel()->currentIndex();
418         int const curRow = curIdx.row();
419         if (curRow < 0 || curRow >= srows) { //this shouldn't happen
420                 deletePB->setEnabled(false);
421                 return;
422         }
423                 
424         QString const curModName = curIdx.data().toString();
425         
426         //We're looking here for a reason NOT to enable the button. If we
427         //find one, we disable it and return. If we don't, we'll end up at
428         //the end of the function, and then we enable it.
429         for (int i = curRow + 1; i < srows; ++i) {
430                 string const thisMod = getSelectedModel()->getIDString(i);
431                 vector<string> reqs = getRequiredList(thisMod);
432                 //does this one require us?
433                 if (find(reqs.begin(), reqs.end(), fromqstr(curModName)) == reqs.end())
434                         //no...
435                         continue;
436
437                 //OK, so this module requires us
438                 //is there an EARLIER module that also satisfies the require?
439                 //NOTE We demand that it be earlier to keep the list of modules
440                 //consistent with the rule that a module must be proceeded by a
441                 //required module. There would be more flexible ways to proceed,
442                 //but that would be a lot more complicated, and the logic here is
443                 //already complicated. (That's why I've left the debugging code.)
444                 //lyxerr << "Testing " << thisMod << std::endl;
445                 bool foundOne = false;
446                 for (int j = 0; j < curRow; ++j) {
447                         string const mod = getSelectedModel()->getIDString(j);
448                         //lyxerr << "In loop: Testing " << mod << std::endl;
449                         //do we satisfy the require? 
450                         if (find(reqs.begin(), reqs.end(), mod) != reqs.end()) {
451                                 //lyxerr << mod << " does the trick." << std::endl;
452                                 foundOne = true;
453                                 break;
454                         }
455                 }
456                 //did we find a module to satisfy the require?
457                 if (!foundOne) {
458                         //lyxerr << "No matching module found." << std::endl;
459                         deletePB->setEnabled(false);
460                         return;
461                 }
462         }
463         //lyxerr << "All's well that ends well." << std::endl;  
464         deletePB->setEnabled(true);
465 }
466
467
468 /////////////////////////////////////////////////////////////////////
469 //
470 // PreambleModule
471 //
472 /////////////////////////////////////////////////////////////////////
473
474 PreambleModule::PreambleModule() : current_id_(0)
475 {
476         // This is not a memory leak. The object will be destroyed
477         // with this.
478         (void) new LaTeXHighlighter(preambleTE->document());
479         setFocusProxy(preambleTE);
480         connect(preambleTE, SIGNAL(textChanged()), this, SIGNAL(changed()));
481 }
482
483
484 void PreambleModule::update(BufferParams const & params, BufferId id)
485 {
486         QString preamble = toqstr(params.preamble);
487         // Nothing to do if the params and preamble are unchanged.
488         if (id == current_id_
489                 && preamble == preambleTE->document()->toPlainText())
490                 return;
491
492         QTextCursor cur = preambleTE->textCursor();
493         // Save the coords before switching to the new one.
494         preamble_coords_[current_id_] =
495                 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
496
497         // Save the params address for further use.
498         current_id_ = id;
499         preambleTE->document()->setPlainText(preamble);
500         Coords::const_iterator it = preamble_coords_.find(current_id_);
501         if (it == preamble_coords_.end())
502                 // First time we open this one.
503                 preamble_coords_[current_id_] = make_pair(0, 0);
504         else {
505                 // Restore saved coords.
506                 QTextCursor cur = preambleTE->textCursor();
507                 cur.setPosition(it->second.first);
508                 preambleTE->setTextCursor(cur);
509                 preambleTE->verticalScrollBar()->setValue(it->second.second);
510         }
511 }
512
513
514 void PreambleModule::apply(BufferParams & params)
515 {
516         params.preamble = fromqstr(preambleTE->document()->toPlainText());
517 }
518
519
520 void PreambleModule::closeEvent(QCloseEvent * e)
521 {
522         // Save the coords before closing.
523         QTextCursor cur = preambleTE->textCursor();
524         preamble_coords_[current_id_] =
525                 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
526         e->accept();
527 }
528
529
530 /////////////////////////////////////////////////////////////////////
531 //
532 // DocumentDialog
533 //
534 /////////////////////////////////////////////////////////////////////
535
536
537 GuiDocument::GuiDocument(GuiView & lv)
538         : GuiDialog(lv, "document", qt_("Document Settings"))
539 {
540         setupUi(this);
541
542         connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
543         connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
544         connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
545         connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore()));
546
547         connect(savePB, SIGNAL(clicked()), this, SLOT(saveDefaultClicked()));
548         connect(defaultPB, SIGNAL(clicked()), this, SLOT(useDefaultsClicked()));
549
550         // Manage the restore, ok, apply, restore and cancel/close buttons
551         bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
552         bc().setOK(okPB);
553         bc().setApply(applyPB);
554         bc().setCancel(closePB);
555         bc().setRestore(restorePB);
556
557         textLayoutModule = new UiWidget<Ui::TextLayoutUi>;
558         // text layout
559         connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
560                 this, SLOT(change_adaptor()));
561         connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
562                 this, SLOT(setLSpacing(int)));
563         connect(textLayoutModule->lspacingLE, SIGNAL(textChanged(const QString &)),
564                 this, SLOT(change_adaptor()));
565         connect(textLayoutModule->skipRB, SIGNAL(clicked()),
566                 this, SLOT(change_adaptor()));
567         connect(textLayoutModule->indentRB, SIGNAL(clicked()),
568                 this, SLOT(change_adaptor()));
569         connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
570                 this, SLOT(change_adaptor()));
571         connect(textLayoutModule->skipLE, SIGNAL(textChanged(const QString &)),
572                 this, SLOT(change_adaptor()));
573         connect(textLayoutModule->skipLengthCO, SIGNAL(activated(int)),
574                 this, SLOT(change_adaptor()));
575         connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
576                 this, SLOT(setSkip(int)));
577         connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
578                 this, SLOT(enableSkip(bool)));
579         connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
580                 this, SLOT(change_adaptor()));
581         connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
582                 this, SLOT(setColSep()));
583         connect(textLayoutModule->listingsED, SIGNAL(textChanged()),
584                 this, SLOT(change_adaptor()));
585         connect(textLayoutModule->bypassCB, SIGNAL(clicked()), 
586                 this, SLOT(change_adaptor()));
587         connect(textLayoutModule->bypassCB, SIGNAL(clicked()), 
588                 this, SLOT(setListingsMessage()));
589         connect(textLayoutModule->listingsED, SIGNAL(textChanged()),
590                 this, SLOT(setListingsMessage()));
591         textLayoutModule->listingsTB->setPlainText(
592                 qt_("Input listings parameters on the right. Enter ? for a list of parameters."));
593         textLayoutModule->lspacingLE->setValidator(new QDoubleValidator(
594                 textLayoutModule->lspacingLE));
595         textLayoutModule->skipLE->setValidator(unsignedLengthValidator(
596                 textLayoutModule->skipLE));
597
598         textLayoutModule->skipCO->addItem(qt_("SmallSkip"));
599         textLayoutModule->skipCO->addItem(qt_("MedSkip"));
600         textLayoutModule->skipCO->addItem(qt_("BigSkip"));
601         textLayoutModule->skipCO->addItem(qt_("Length"));
602         // remove the %-items from the unit choice
603         textLayoutModule->skipLengthCO->noPercents();
604         textLayoutModule->lspacingCO->insertItem(
605                 Spacing::Single, qt_("Single"));
606         textLayoutModule->lspacingCO->insertItem(
607                 Spacing::Onehalf, qt_("OneHalf"));
608         textLayoutModule->lspacingCO->insertItem(
609                 Spacing::Double, qt_("Double"));
610         textLayoutModule->lspacingCO->insertItem(
611                 Spacing::Other, qt_("Custom"));
612
613         // initialize the length validator
614         bc().addCheckedLineEdit(textLayoutModule->skipLE);
615
616         fontModule = new UiWidget<Ui::FontUi>;
617         // fonts
618         connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
619                 this, SLOT(change_adaptor()));
620         connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
621                 this, SLOT(romanChanged(int)));
622         connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
623                 this, SLOT(change_adaptor()));
624         connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
625                 this, SLOT(sansChanged(int)));
626         connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
627                 this, SLOT(change_adaptor()));
628         connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
629                 this, SLOT(ttChanged(int)));
630         connect(fontModule->fontsDefaultCO, SIGNAL(activated(int)),
631                 this, SLOT(change_adaptor()));
632         connect(fontModule->fontsizeCO, SIGNAL(activated(int)),
633                 this, SLOT(change_adaptor()));
634         connect(fontModule->cjkFontLE, SIGNAL(textChanged(const QString &)),
635                 this, SLOT(change_adaptor()));
636         connect(fontModule->scaleSansSB, SIGNAL(valueChanged(int)),
637                 this, SLOT(change_adaptor()));
638         connect(fontModule->scaleTypewriterSB, SIGNAL(valueChanged(int)),
639                 this, SLOT(change_adaptor()));
640         connect(fontModule->fontScCB, SIGNAL(clicked()),
641                 this, SLOT(change_adaptor()));
642         connect(fontModule->fontOsfCB, SIGNAL(clicked()),
643                 this, SLOT(change_adaptor()));
644
645         for (int n = 0; tex_fonts_roman[n][0]; ++n) {
646                 QString font = qt_(tex_fonts_roman_gui[n]);
647                 if (!isFontAvailable(tex_fonts_roman[n]))
648                         font += qt_(" (not installed)");
649                 fontModule->fontsRomanCO->addItem(font);
650         }
651         for (int n = 0; tex_fonts_sans[n][0]; ++n) {
652                 QString font = qt_(tex_fonts_sans_gui[n]);
653                 if (!isFontAvailable(tex_fonts_sans[n]))
654                         font += qt_(" (not installed)");
655                 fontModule->fontsSansCO->addItem(font);
656         }
657         for (int n = 0; tex_fonts_monospaced[n][0]; ++n) {
658                 QString font = qt_(tex_fonts_monospaced_gui[n]);
659                 if (!isFontAvailable(tex_fonts_monospaced[n]))
660                         font += qt_(" (not installed)");
661                 fontModule->fontsTypewriterCO->addItem(font);
662         }
663
664         fontModule->fontsizeCO->addItem(qt_("Default"));
665         fontModule->fontsizeCO->addItem(qt_("10"));
666         fontModule->fontsizeCO->addItem(qt_("11"));
667         fontModule->fontsizeCO->addItem(qt_("12"));
668
669         for (int n = 0; GuiDocument::fontfamilies_gui[n][0]; ++n)
670                 fontModule->fontsDefaultCO->addItem(
671                         qt_(GuiDocument::fontfamilies_gui[n]));
672
673
674         pageLayoutModule = new UiWidget<Ui::PageLayoutUi>;
675         // page layout
676         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
677                 this, SLOT(setCustomPapersize(int)));
678         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
679                 this, SLOT(setCustomPapersize(int)));
680         connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
681                 this, SLOT(portraitChanged()));
682         connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
683                 this, SLOT(change_adaptor()));
684         connect(pageLayoutModule->paperheightLE, SIGNAL(textChanged(const QString &)),
685                 this, SLOT(change_adaptor()));
686         connect(pageLayoutModule->paperwidthLE, SIGNAL(textChanged(const QString &)),
687                 this, SLOT(change_adaptor()));
688         connect(pageLayoutModule->paperwidthUnitCO, SIGNAL(activated(int)),
689                 this, SLOT(change_adaptor()));
690         connect(pageLayoutModule->paperheightUnitCO, SIGNAL(activated(int)),
691                 this, SLOT(change_adaptor()));
692         connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
693                 this, SLOT(change_adaptor()));
694         connect(pageLayoutModule->landscapeRB, SIGNAL(clicked()),
695                 this, SLOT(change_adaptor()));
696         connect(pageLayoutModule->facingPagesCB, SIGNAL(clicked()),
697                 this, SLOT(change_adaptor()));
698         connect(pageLayoutModule->pagestyleCO, SIGNAL(activated(int)),
699                 this, SLOT(change_adaptor()));
700
701         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
702         pageLayoutModule->pagestyleCO->addItem(qt_("empty"));
703         pageLayoutModule->pagestyleCO->addItem(qt_("plain"));
704         pageLayoutModule->pagestyleCO->addItem(qt_("headings"));
705         pageLayoutModule->pagestyleCO->addItem(qt_("fancy"));
706         bc().addCheckedLineEdit(pageLayoutModule->paperheightLE,
707                 pageLayoutModule->paperheightL);
708         bc().addCheckedLineEdit(pageLayoutModule->paperwidthLE,
709                 pageLayoutModule->paperwidthL);
710
711         // paper
712         QComboBox * cb = pageLayoutModule->papersizeCO;
713         cb->addItem(qt_("Default"));
714         cb->addItem(qt_("Custom"));
715         cb->addItem(qt_("US letter"));
716         cb->addItem(qt_("US legal"));
717         cb->addItem(qt_("US executive"));
718         cb->addItem(qt_("A3"));
719         cb->addItem(qt_("A4"));
720         cb->addItem(qt_("A5"));
721         cb->addItem(qt_("B3"));
722         cb->addItem(qt_("B4"));
723         cb->addItem(qt_("B5"));
724         // remove the %-items from the unit choice
725         pageLayoutModule->paperwidthUnitCO->noPercents();
726         pageLayoutModule->paperheightUnitCO->noPercents();
727         pageLayoutModule->paperheightLE->setValidator(unsignedLengthValidator(
728                 pageLayoutModule->paperheightLE));
729         pageLayoutModule->paperwidthLE->setValidator(unsignedLengthValidator(
730                 pageLayoutModule->paperwidthLE));
731
732
733         marginsModule = new UiWidget<Ui::MarginsUi>;
734         // margins
735         connect(marginsModule->marginCB, SIGNAL(toggled(bool)),
736                 this, SLOT(setCustomMargins(bool)));
737         connect(marginsModule->marginCB, SIGNAL(clicked()),
738                 this, SLOT(change_adaptor()));
739         connect(marginsModule->topLE, SIGNAL(textChanged(QString)),
740                 this, SLOT(change_adaptor()));
741         connect(marginsModule->topUnit, SIGNAL(activated(int)),
742                 this, SLOT(change_adaptor()));
743         connect(marginsModule->bottomLE, SIGNAL(textChanged(QString)),
744                 this, SLOT(change_adaptor()));
745         connect(marginsModule->bottomUnit, SIGNAL(activated(int)),
746                 this, SLOT(change_adaptor()));
747         connect(marginsModule->innerLE, SIGNAL(textChanged(QString)),
748                 this, SLOT(change_adaptor()));
749         connect(marginsModule->innerUnit, SIGNAL(activated(int)),
750                 this, SLOT(change_adaptor()));
751         connect(marginsModule->outerLE, SIGNAL(textChanged(QString)),
752                 this, SLOT(change_adaptor()));
753         connect(marginsModule->outerUnit, SIGNAL(activated(int)),
754                 this, SLOT(change_adaptor()));
755         connect(marginsModule->headheightLE, SIGNAL(textChanged(QString)),
756                 this, SLOT(change_adaptor()));
757         connect(marginsModule->headheightUnit, SIGNAL(activated(int)),
758                 this, SLOT(change_adaptor()));
759         connect(marginsModule->headsepLE, SIGNAL(textChanged(QString)),
760                 this, SLOT(change_adaptor()));
761         connect(marginsModule->headsepUnit, SIGNAL(activated(int)),
762                 this, SLOT(change_adaptor()));
763         connect(marginsModule->footskipLE, SIGNAL(textChanged(QString)),
764                 this, SLOT(change_adaptor()));
765         connect(marginsModule->footskipUnit, SIGNAL(activated(int)),
766                 this, SLOT(change_adaptor()));
767         connect(marginsModule->columnsepLE, SIGNAL(textChanged(QString)),
768                 this, SLOT(change_adaptor()));
769         connect(marginsModule->columnsepUnit, SIGNAL(activated(int)),
770                 this, SLOT(change_adaptor()));
771         marginsModule->topLE->setValidator(unsignedLengthValidator(
772                 marginsModule->topLE));
773         marginsModule->bottomLE->setValidator(unsignedLengthValidator(
774                 marginsModule->bottomLE));
775         marginsModule->innerLE->setValidator(unsignedLengthValidator(
776                 marginsModule->innerLE));
777         marginsModule->outerLE->setValidator(unsignedLengthValidator(
778                 marginsModule->outerLE));
779         marginsModule->headsepLE->setValidator(unsignedLengthValidator(
780                 marginsModule->headsepLE));
781         marginsModule->headheightLE->setValidator(unsignedLengthValidator(
782                 marginsModule->headheightLE));
783         marginsModule->footskipLE->setValidator(unsignedLengthValidator(
784                 marginsModule->footskipLE));
785         marginsModule->columnsepLE->setValidator(unsignedLengthValidator(
786                 marginsModule->columnsepLE));
787
788         bc().addCheckedLineEdit(marginsModule->topLE,
789                 marginsModule->topL);
790         bc().addCheckedLineEdit(marginsModule->bottomLE,
791                 marginsModule->bottomL);
792         bc().addCheckedLineEdit(marginsModule->innerLE,
793                 marginsModule->innerL);
794         bc().addCheckedLineEdit(marginsModule->outerLE,
795                 marginsModule->outerL);
796         bc().addCheckedLineEdit(marginsModule->headsepLE,
797                 marginsModule->headsepL);
798         bc().addCheckedLineEdit(marginsModule->headheightLE,
799                 marginsModule->headheightL);
800         bc().addCheckedLineEdit(marginsModule->footskipLE,
801                 marginsModule->footskipL);
802         bc().addCheckedLineEdit(marginsModule->columnsepLE,
803                 marginsModule->columnsepL);
804
805
806         langModule = new UiWidget<Ui::LanguageUi>;
807         // language & quote
808         connect(langModule->languageCO, SIGNAL(activated(int)),
809                 this, SLOT(change_adaptor()));
810         connect(langModule->defaultencodingRB, SIGNAL(clicked()),
811                 this, SLOT(change_adaptor()));
812         connect(langModule->otherencodingRB, SIGNAL(clicked()),
813                 this, SLOT(change_adaptor()));
814         connect(langModule->encodingCO, SIGNAL(activated(int)),
815                 this, SLOT(change_adaptor()));
816         connect(langModule->quoteStyleCO, SIGNAL(activated(int)),
817                 this, SLOT(change_adaptor()));
818         // language & quotes
819         QAbstractItemModel * language_model = guiApp->languageModel();
820         // FIXME: it would be nice if sorting was enabled/disabled via a checkbox.
821         language_model->sort(0);
822         langModule->languageCO->setModel(language_model);
823
824         // Always put the default encoding in the first position.
825         langModule->encodingCO->addItem(qt_("Language Default (no inputenc)"));
826         QStringList encodinglist;
827         Encodings::const_iterator it = encodings.begin();
828         Encodings::const_iterator const end = encodings.end();
829         for (; it != end; ++it)
830                 encodinglist.append(qt_(it->guiName()));
831         encodinglist.sort();
832         langModule->encodingCO->addItems(encodinglist);
833
834         langModule->quoteStyleCO->addItem(qt_("``text''"));
835         langModule->quoteStyleCO->addItem(qt_("''text''"));
836         langModule->quoteStyleCO->addItem(qt_(",,text``"));
837         langModule->quoteStyleCO->addItem(qt_(",,text''"));
838         langModule->quoteStyleCO->addItem(qt_("<<text>>"));
839         langModule->quoteStyleCO->addItem(qt_(">>text<<"));
840
841
842         numberingModule = new UiWidget<Ui::NumberingUi>;
843         // numbering
844         connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
845                 this, SLOT(change_adaptor()));
846         connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
847                 this, SLOT(change_adaptor()));
848         connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
849                 this, SLOT(updateNumbering()));
850         connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
851                 this, SLOT(updateNumbering()));
852         numberingModule->tocTW->setColumnCount(3);
853         numberingModule->tocTW->headerItem()->setText(0, qt_("Example"));
854         numberingModule->tocTW->headerItem()->setText(1, qt_("Numbered"));
855         numberingModule->tocTW->headerItem()->setText(2, qt_("Appears in TOC"));
856
857
858         biblioModule = new UiWidget<Ui::BiblioUi>;
859         connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
860                 biblioModule->citationStyleL, SLOT(setEnabled(bool)));
861         connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
862                 biblioModule->citeStyleCO, SLOT(setEnabled(bool)));
863         // biblio
864         connect(biblioModule->citeDefaultRB, SIGNAL(clicked()),
865                 this, SLOT(change_adaptor()));
866         connect(biblioModule->citeNatbibRB, SIGNAL(clicked()),
867                 this, SLOT(change_adaptor()));
868         connect(biblioModule->citeStyleCO, SIGNAL(activated(int)),
869                 this, SLOT(change_adaptor()));
870         connect(biblioModule->citeJurabibRB, SIGNAL(clicked()),
871                 this, SLOT(change_adaptor()));
872         connect(biblioModule->bibtopicCB, SIGNAL(clicked()),
873                 this, SLOT(change_adaptor()));
874         // biblio
875         biblioModule->citeStyleCO->addItem(qt_("Author-year"));
876         biblioModule->citeStyleCO->addItem(qt_("Numerical"));
877         biblioModule->citeStyleCO->setCurrentIndex(0);
878
879
880         mathsModule = new UiWidget<Ui::MathsUi>;
881         connect(mathsModule->amsautoCB, SIGNAL(toggled(bool)),
882                 mathsModule->amsCB, SLOT(setDisabled(bool)));
883         connect(mathsModule->esintautoCB, SIGNAL(toggled(bool)),
884                 mathsModule->esintCB, SLOT(setDisabled(bool)));
885         // maths
886         connect(mathsModule->amsCB, SIGNAL(clicked()),
887                 this, SLOT(change_adaptor()));
888         connect(mathsModule->amsautoCB, SIGNAL(clicked()),
889                 this, SLOT(change_adaptor()));
890         connect(mathsModule->esintCB, SIGNAL(clicked()),
891                 this, SLOT(change_adaptor()));
892         connect(mathsModule->esintautoCB, SIGNAL(clicked()),
893                 this, SLOT(change_adaptor()));
894
895         latexModule = new UiWidget<Ui::LaTeXUi>;
896         // latex class
897         connect(latexModule->optionsLE, SIGNAL(textChanged(QString)),
898                 this, SLOT(change_adaptor()));
899         connect(latexModule->psdriverCO, SIGNAL(activated(int)),
900                 this, SLOT(change_adaptor()));
901         connect(latexModule->classCO, SIGNAL(activated(int)),
902                 this, SLOT(classChanged()));
903         connect(latexModule->classCO, SIGNAL(activated(int)),
904                 this, SLOT(change_adaptor()));
905         connect(latexModule->layoutPB, SIGNAL(clicked()),
906                 this, SLOT(browseLayout()));
907         connect(latexModule->layoutPB, SIGNAL(clicked()),
908                 this, SLOT(change_adaptor()));
909         connect(latexModule->childDocGB, SIGNAL(clicked()),
910                 this, SLOT(change_adaptor()));
911         connect(latexModule->childDocLE, SIGNAL(textChanged(QString)),
912                 this, SLOT(change_adaptor()));
913         connect(latexModule->childDocPB, SIGNAL(clicked()),
914                 this, SLOT(browseMaster()));
915         
916         selectionManager = 
917                 new ModuleSelectionManager(latexModule->availableLV,
918                         latexModule->selectedLV, 
919                         latexModule->addPB, latexModule->deletePB, 
920                         latexModule->upPB, latexModule->downPB, 
921                         availableModel(), selectedModel());
922         connect(selectionManager, SIGNAL(updateHook()),
923                 this, SLOT(updateModuleInfo()));
924         connect(selectionManager, SIGNAL(updateHook()),
925                 this, SLOT(change_adaptor()));
926         
927         // postscript drivers
928         for (int n = 0; tex_graphics[n][0]; ++n) {
929                 QString enc = qt_(tex_graphics_gui[n]);
930                 latexModule->psdriverCO->addItem(enc);
931         }
932         // latex classes
933         latexModule->classCO->setModel(&classes_model_);
934         LayoutFileList const & bcl = LayoutFileList::get();
935         vector<LayoutFileIndex> classList = bcl.classList();
936         sort(classList.begin(), classList.end(), less_textclass_avail_desc());
937
938         vector<LayoutFileIndex>::const_iterator cit  = classList.begin();
939         vector<LayoutFileIndex>::const_iterator cen = classList.end();
940         for (int i = 0; cit != cen; ++cit, ++i) {
941                 LayoutFile const & tc = bcl[*cit];
942                 docstring item = (tc.isTeXClassAvailable()) ?
943                         from_utf8(tc.description()) :
944                         bformat(_("Unavailable: %1$s"), from_utf8(tc.description()));
945                 classes_model_.insertRow(i, toqstr(item), *cit);
946         }
947
948         // branches
949         branchesModule = new GuiBranches;
950         connect(branchesModule, SIGNAL(changed()),
951                 this, SLOT(change_adaptor()));
952
953         // preamble
954         preambleModule = new PreambleModule;
955         connect(preambleModule, SIGNAL(changed()),
956                 this, SLOT(change_adaptor()));
957
958         // bullets
959         bulletsModule = new BulletsModule;
960         connect(bulletsModule, SIGNAL(changed()),
961                 this, SLOT(change_adaptor()));
962
963         // PDF support
964         pdfSupportModule = new UiWidget<Ui::PDFSupportUi>;
965
966         connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
967                 this, SLOT(change_adaptor()));
968         connect(pdfSupportModule->titleLE, SIGNAL(textChanged(QString)),
969                 this, SLOT(change_adaptor()));
970         connect(pdfSupportModule->authorLE, SIGNAL(textChanged(QString)),
971                 this, SLOT(change_adaptor()));
972         connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(QString)),
973                 this, SLOT(change_adaptor()));
974         connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(QString)),
975                 this, SLOT(change_adaptor()));
976         connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
977                 this, SLOT(change_adaptor()));
978         connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
979                 this, SLOT(change_adaptor()));
980         connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
981                 this, SLOT(change_adaptor()));
982         connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
983                 this, SLOT(change_adaptor()));
984         connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
985                 this, SLOT(change_adaptor()));
986         connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
987                 this, SLOT(change_adaptor()));
988         connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
989                 this, SLOT(change_adaptor()));
990         connect(pdfSupportModule->backrefCB, SIGNAL(toggled(bool)),
991                 this, SLOT(change_adaptor()));
992         connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
993                 this, SLOT(change_adaptor()));
994         connect(pdfSupportModule->pagebackrefCB, SIGNAL(toggled(bool)),
995                 this, SLOT(change_adaptor()));
996         connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
997                 this, SLOT(change_adaptor()));
998         connect(pdfSupportModule->optionsLE, SIGNAL(textChanged(QString)),
999                 this, SLOT(change_adaptor()));
1000
1001         // float
1002         floatModule = new FloatPlacement;
1003         connect(floatModule, SIGNAL(changed()),
1004                 this, SLOT(change_adaptor()));
1005
1006         docPS->addPanel(latexModule, qt_("Document Class"));
1007         docPS->addPanel(fontModule, qt_("Fonts"));
1008         docPS->addPanel(textLayoutModule, qt_("Text Layout"));
1009         docPS->addPanel(pageLayoutModule, qt_("Page Layout"));
1010         docPS->addPanel(marginsModule, qt_("Page Margins"));
1011         docPS->addPanel(langModule, qt_("Language"));
1012         docPS->addPanel(numberingModule, qt_("Numbering & TOC"));
1013         docPS->addPanel(biblioModule, qt_("Bibliography"));
1014         docPS->addPanel(pdfSupportModule, qt_("PDF Properties"));
1015         docPS->addPanel(mathsModule, qt_("Math Options"));
1016         docPS->addPanel(floatModule, qt_("Float Placement"));
1017         docPS->addPanel(bulletsModule, qt_("Bullets"));
1018         docPS->addPanel(branchesModule, qt_("Branches"));
1019         docPS->addPanel(preambleModule, qt_("LaTeX Preamble"));
1020         docPS->setCurrentPanel(qt_("Document Class"));
1021 // FIXME: hack to work around resizing bug in Qt >= 4.2
1022 // bug verified with Qt 4.2.{0-3} (JSpitzm)
1023 #if QT_VERSION >= 0x040200
1024         docPS->updateGeometry();
1025 #endif
1026 }
1027
1028
1029 void GuiDocument::showPreamble()
1030 {
1031         docPS->setCurrentPanel(qt_("LaTeX Preamble"));
1032 }
1033
1034
1035 void GuiDocument::saveDefaultClicked()
1036 {
1037         saveDocDefault();
1038 }
1039
1040
1041 void GuiDocument::useDefaultsClicked()
1042 {
1043         useClassDefaults();
1044 }
1045
1046
1047 void GuiDocument::change_adaptor()
1048 {
1049         changed();
1050 }
1051
1052
1053 QString GuiDocument::validateListingsParameters()
1054 {
1055         // use a cache here to avoid repeated validation
1056         // of the same parameters
1057         static string param_cache;
1058         static QString msg_cache;
1059         
1060         if (textLayoutModule->bypassCB->isChecked())
1061                 return QString();
1062
1063         string params = fromqstr(textLayoutModule->listingsED->toPlainText());
1064         if (params != param_cache) {
1065                 param_cache = params;
1066                 msg_cache = toqstr(InsetListingsParams(params).validate());
1067         }
1068         return msg_cache;
1069 }
1070
1071
1072 void GuiDocument::setListingsMessage()
1073 {
1074         static bool isOK = true;
1075         QString msg = validateListingsParameters();
1076         if (msg.isEmpty()) {
1077                 if (isOK)
1078                         return;
1079                 isOK = true;
1080                 // listingsTB->setTextColor("black");
1081                 textLayoutModule->listingsTB->setPlainText(
1082                         qt_("Input listings parameters on the right. "
1083                 "Enter ? for a list of parameters."));
1084         } else {
1085                 isOK = false;
1086                 // listingsTB->setTextColor("red");
1087                 textLayoutModule->listingsTB->setPlainText(msg);
1088         }
1089 }
1090
1091
1092 void GuiDocument::setLSpacing(int item)
1093 {
1094         textLayoutModule->lspacingLE->setEnabled(item == 3);
1095 }
1096
1097
1098 void GuiDocument::setSkip(int item)
1099 {
1100         bool const enable = (item == 3);
1101         textLayoutModule->skipLE->setEnabled(enable);
1102         textLayoutModule->skipLengthCO->setEnabled(enable);
1103 }
1104
1105
1106 void GuiDocument::enableSkip(bool skip)
1107 {
1108         textLayoutModule->skipCO->setEnabled(skip);
1109         textLayoutModule->skipLE->setEnabled(skip);
1110         textLayoutModule->skipLengthCO->setEnabled(skip);
1111         if (skip)
1112                 setSkip(textLayoutModule->skipCO->currentIndex());
1113 }
1114
1115 void GuiDocument::portraitChanged()
1116 {
1117         setMargins(pageLayoutModule->papersizeCO->currentIndex());
1118 }
1119
1120 void GuiDocument::setMargins(bool custom)
1121 {
1122         marginsModule->marginCB->setChecked(custom);
1123         setCustomMargins(custom);
1124 }
1125
1126
1127 void GuiDocument::setCustomPapersize(int papersize)
1128 {
1129         bool const custom = (papersize == 1);
1130
1131         pageLayoutModule->paperwidthL->setEnabled(custom);
1132         pageLayoutModule->paperwidthLE->setEnabled(custom);
1133         pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
1134         pageLayoutModule->paperheightL->setEnabled(custom);
1135         pageLayoutModule->paperheightLE->setEnabled(custom);
1136         pageLayoutModule->paperheightLE->setFocus();
1137         pageLayoutModule->paperheightUnitCO->setEnabled(custom);
1138 }
1139
1140
1141 void GuiDocument::setColSep()
1142 {
1143         setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
1144 }
1145
1146
1147 void GuiDocument::setCustomMargins(bool custom)
1148 {
1149         marginsModule->topL->setEnabled(!custom);
1150         marginsModule->topLE->setEnabled(!custom);
1151         marginsModule->topUnit->setEnabled(!custom);
1152
1153         marginsModule->bottomL->setEnabled(!custom);
1154         marginsModule->bottomLE->setEnabled(!custom);
1155         marginsModule->bottomUnit->setEnabled(!custom);
1156
1157         marginsModule->innerL->setEnabled(!custom);
1158         marginsModule->innerLE->setEnabled(!custom);
1159         marginsModule->innerUnit->setEnabled(!custom);
1160
1161         marginsModule->outerL->setEnabled(!custom);
1162         marginsModule->outerLE->setEnabled(!custom);
1163         marginsModule->outerUnit->setEnabled(!custom);
1164
1165         marginsModule->headheightL->setEnabled(!custom);
1166         marginsModule->headheightLE->setEnabled(!custom);
1167         marginsModule->headheightUnit->setEnabled(!custom);
1168
1169         marginsModule->headsepL->setEnabled(!custom);
1170         marginsModule->headsepLE->setEnabled(!custom);
1171         marginsModule->headsepUnit->setEnabled(!custom);
1172
1173         marginsModule->footskipL->setEnabled(!custom);
1174         marginsModule->footskipLE->setEnabled(!custom);
1175         marginsModule->footskipUnit->setEnabled(!custom);
1176
1177         bool const enableColSep = !custom && 
1178                         textLayoutModule->twoColumnCB->checkState() == Qt::Checked;
1179         marginsModule->columnsepL->setEnabled(enableColSep);
1180         marginsModule->columnsepLE->setEnabled(enableColSep);
1181         marginsModule->columnsepUnit->setEnabled(enableColSep);
1182 }
1183
1184
1185 void GuiDocument::updateFontsize(string const & items, string const & sel)
1186 {
1187         fontModule->fontsizeCO->clear();
1188         fontModule->fontsizeCO->addItem(qt_("Default"));
1189
1190         for (int n = 0; !token(items,'|',n).empty(); ++n)
1191                 fontModule->fontsizeCO->
1192                         addItem(toqstr(token(items,'|',n)));
1193
1194         for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
1195                 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
1196                         fontModule->fontsizeCO->setCurrentIndex(n);
1197                         break;
1198                 }
1199         }
1200 }
1201
1202
1203 void GuiDocument::romanChanged(int item)
1204 {
1205         string const font = tex_fonts_roman[item];
1206         fontModule->fontScCB->setEnabled(providesSC(font));
1207         fontModule->fontOsfCB->setEnabled(providesOSF(font));
1208 }
1209
1210
1211 void GuiDocument::sansChanged(int item)
1212 {
1213         string const font = tex_fonts_sans[item];
1214         bool scaleable = providesScale(font);
1215         fontModule->scaleSansSB->setEnabled(scaleable);
1216         fontModule->scaleSansLA->setEnabled(scaleable);
1217 }
1218
1219
1220 void GuiDocument::ttChanged(int item)
1221 {
1222         string const font = tex_fonts_monospaced[item];
1223         bool scaleable = providesScale(font);
1224         fontModule->scaleTypewriterSB->setEnabled(scaleable);
1225         fontModule->scaleTypewriterLA->setEnabled(scaleable);
1226 }
1227
1228
1229 void GuiDocument::updatePagestyle(string const & items, string const & sel)
1230 {
1231         pagestyles.clear();
1232         pageLayoutModule->pagestyleCO->clear();
1233         pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1234
1235         for (int n = 0; !token(items, '|', n).empty(); ++n) {
1236                 string style = token(items, '|', n);
1237                 QString style_gui = qt_(style);
1238                 pagestyles.push_back(pair<string, QString>(style, style_gui));
1239                 pageLayoutModule->pagestyleCO->addItem(style_gui);
1240         }
1241
1242         if (sel == "default") {
1243                 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
1244                 return;
1245         }
1246
1247         int nn = 0;
1248
1249         for (size_t i = 0; i < pagestyles.size(); ++i)
1250                 if (pagestyles[i].first == sel)
1251                         nn = pageLayoutModule->pagestyleCO->findText(pagestyles[i].second);
1252
1253         if (nn > 0)
1254                 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
1255 }
1256
1257
1258 void GuiDocument::browseLayout()
1259 {
1260         QString const label1 = qt_("Layouts|#o#O");
1261         QString const dir1 = toqstr(lyxrc.document_path);
1262         QStringList const filter(qt_("LyX Layout (*.layout)"));
1263         QString file = browseRelFile(QString(), bufferFilepath(),
1264                 qt_("Local layout file"), filter, false,
1265                 label1, dir1);
1266
1267         if (!file.endsWith(".layout"))
1268                 return;
1269
1270         FileName layoutFile = support::makeAbsPath(fromqstr(file),
1271                 fromqstr(bufferFilepath()));
1272         
1273         int const ret = Alert::prompt(_("Local layout file"),
1274                 _("The layout file you have selected is a local layout\n"
1275                   "file, not one in the system or user directory. Your\n"
1276                   "document may not work with this layout if you do not\n"
1277                   "keep the layout file in the document directory."),
1278                   1, 1, _("&Set Layout"), _("&Cancel"));
1279         if (ret == 1)
1280                 return;
1281
1282         // load the layout file
1283         LayoutFileList & bcl = LayoutFileList::get();
1284         string classname = layoutFile.onlyFileName();
1285         // this will update an existing layout if that layout has been loaded before.
1286         LayoutFileIndex name = bcl.addLocalLayout(
1287                 classname.substr(0, classname.size() - 7),
1288                 layoutFile.onlyPath().absFilename());
1289
1290         if (name.empty()) {
1291                 Alert::error(_("Error"),
1292                         _("Unable to read local layout file."));                
1293                 return;
1294         }
1295
1296         // do not trigger classChanged if there is no change.
1297         if (latexModule->classCO->currentText() == toqstr(name))
1298                 return;
1299                 
1300         // add to combo box
1301         int idx = latexModule->classCO->findText(toqstr(name));
1302         if (idx == -1) {
1303                 classes_model_.insertRow(0, toqstr(name), name);
1304                 latexModule->classCO->setCurrentIndex(0);
1305         } else
1306                 latexModule->classCO->setCurrentIndex(idx);
1307         
1308         classChanged();
1309 }
1310
1311
1312 void GuiDocument::browseMaster()
1313 {
1314         QString const title = qt_("Select master document");
1315         QString const dir1 = toqstr(lyxrc.document_path);
1316         QString const old = latexModule->childDocLE->text();
1317         QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
1318         QStringList const filter(qt_("LyX Files (*.lyx)"));
1319         QString file = browseRelFile(old, docpath, title, filter, false,
1320                 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
1321
1322         latexModule->childDocLE->setText(file);
1323 }
1324
1325
1326 void GuiDocument::classChanged()
1327 {
1328         int idx = latexModule->classCO->currentIndex();
1329         if (idx < 0) 
1330                 return;
1331         string const classname = classes_model_.getIDString(idx);
1332
1333         // FIXME Note that by doing things this way, we load the TextClass
1334         // as soon as it is selected. So, if you use the scroll wheel when
1335         // sitting on the combo box, we'll load a lot of TextClass objects
1336         // very quickly. This could be changed.
1337         if (!bp_.setBaseClass(classname)) {
1338                 Alert::error(_("Error"), _("Unable to set document class."));
1339                 return;
1340         }
1341         if (lyxrc.auto_reset_options) {
1342                 if (applyPB->isEnabled()) {
1343                         int const ret = Alert::prompt(_("Unapplied changes"),
1344                                         _("Some changes in the dialog were not yet applied.\n"
1345                                         "If you do not apply now, they will be lost after this action."),
1346                                         1, 1, _("&Apply"), _("&Dismiss"));
1347                         if (ret == 0)
1348                                 applyView();
1349                 }
1350                 bp_.useClassDefaults();
1351                 paramsToDialog(bp_);
1352         }
1353         // FIXME There's a little bug here connected with auto_reset, namely,
1354         // that, if the preceding is skipped and the user has changed the
1355         // modules before changing the class, those changes will be lost on
1356         // update. But maybe that's what we want?
1357         updateSelectedModules();
1358 }
1359
1360
1361 namespace {
1362         // This is an insanely complicated attempt to make this sort of thing
1363         // work with RTL languages.
1364         docstring formatStrVec(vector<string> const & v, docstring const & s) 
1365         {
1366                 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
1367                 if (v.size() == 0)
1368                         return docstring();
1369                 if (v.size() == 1) 
1370                         return from_ascii(v[0]);
1371                 if (v.size() == 2) {
1372                         docstring retval = _("%1$s and %2$s");
1373                         retval = subst(retval, _("and"), s);
1374                         return bformat(retval, from_ascii(v[0]), from_ascii(v[1]));
1375                 }
1376                 // The idea here is to format all but the last two items...
1377                 int const vSize = v.size();
1378                 docstring t2 = _("%1$s, %2$s");
1379                 docstring retval = from_ascii(v[0]);
1380                 for (int i = 1; i < vSize - 2; ++i)
1381                         retval = bformat(t2, retval, from_ascii(v[i])); 
1382                 //...and then to  plug them, and the last two, into this schema
1383                 docstring t = _("%1$s, %2$s, and %3$s");
1384                 t = subst(t, _("and"), s);
1385                 return bformat(t, retval, from_ascii(v[vSize - 2]), from_ascii(v[vSize - 1]));
1386         }
1387         
1388         vector<string> idsToNames(vector<string> const & idList)
1389         {
1390                 vector<string> retval;
1391                 vector<string>::const_iterator it  = idList.begin();
1392                 vector<string>::const_iterator end = idList.end();
1393                 for (; it != end; ++it) {
1394                         LyXModule const * const mod = moduleList[*it];
1395                         if (!mod)
1396                                 retval.push_back(*it + " (Unavailable)");
1397                         else
1398                                 retval.push_back(mod->getName());
1399                 }
1400                 return retval;
1401         }
1402 }
1403
1404
1405 void GuiDocument::updateModuleInfo()
1406 {
1407         selectionManager->update();
1408         
1409         //Module description
1410         bool const focusOnSelected = selectionManager->selectedFocused();
1411         QListView const * const lv = 
1412                         focusOnSelected ? latexModule->selectedLV : latexModule->availableLV;
1413         if (lv->selectionModel()->selectedIndexes().isEmpty()) {
1414                 latexModule->infoML->document()->clear();
1415                 return;
1416         }
1417         QModelIndex const & idx = lv->selectionModel()->currentIndex();
1418         GuiIdListModel const & idModel = 
1419                         focusOnSelected  ? modules_sel_model_ : modules_av_model_;
1420         string const modName = idModel.getIDString(idx.row());
1421         docstring desc = getModuleDescription(modName);
1422
1423         vector<string> pkgList = getPackageList(modName);
1424         docstring pkgdesc = formatStrVec(pkgList, _("and"));
1425         if (!pkgdesc.empty()) {
1426                 if (!desc.empty())
1427                         desc += "\n";
1428                 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
1429         }
1430
1431         pkgList = getRequiredList(modName);
1432         if (!pkgList.empty()) {
1433                 vector<string> const reqDescs = idsToNames(pkgList);
1434                 pkgdesc = formatStrVec(reqDescs, _("or"));
1435                 if (!desc.empty())
1436                         desc += "\n";
1437                 desc += bformat(_("Module required: %1$s."), pkgdesc);
1438         }
1439
1440         pkgList = getExcludedList(modName);
1441         if (!pkgList.empty()) {
1442                 vector<string> const reqDescs = idsToNames(pkgList);
1443                 pkgdesc = formatStrVec(reqDescs, _( "and"));
1444                 if (!desc.empty())
1445                         desc += "\n";
1446                 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
1447         }
1448
1449         if (!isModuleAvailable(modName)) {
1450                 if (!desc.empty())
1451                         desc += "\n";
1452                 desc += _("WARNING: Some packages are unavailable!");
1453         }
1454
1455         latexModule->infoML->document()->setPlainText(toqstr(desc));
1456 }
1457
1458
1459 void GuiDocument::updateNumbering()
1460 {
1461         DocumentClass const & tclass = bp_.documentClass();
1462
1463         numberingModule->tocTW->setUpdatesEnabled(false);
1464         numberingModule->tocTW->clear();
1465
1466         int const depth = numberingModule->depthSL->value();
1467         int const toc = numberingModule->tocSL->value();
1468         QString const no = qt_("No");
1469         QString const yes = qt_("Yes");
1470         QTreeWidgetItem * item = 0;
1471
1472         DocumentClass::const_iterator lit = tclass.begin();
1473         DocumentClass::const_iterator len = tclass.end();
1474         for (; lit != len; ++lit) {
1475                 int const toclevel = lit->toclevel;
1476                 if (toclevel != Layout::NOT_IN_TOC && lit->labeltype == LABEL_COUNTER) {
1477                         item = new QTreeWidgetItem(numberingModule->tocTW);
1478                         item->setText(0, toqstr(translateIfPossible(lit->name())));
1479                         item->setText(1, (toclevel <= depth) ? yes : no);
1480                         item->setText(2, (toclevel <= toc) ? yes : no);
1481                 }
1482         }
1483
1484         numberingModule->tocTW->setUpdatesEnabled(true);
1485         numberingModule->tocTW->update();
1486 }
1487
1488
1489 void GuiDocument::apply(BufferParams & params)
1490 {
1491         // preamble
1492         preambleModule->apply(params);
1493
1494         // biblio
1495         params.setCiteEngine(ENGINE_BASIC);
1496
1497         if (biblioModule->citeNatbibRB->isChecked()) {
1498                 bool const use_numerical_citations =
1499                         biblioModule->citeStyleCO->currentIndex();
1500                 if (use_numerical_citations)
1501                         params.setCiteEngine(ENGINE_NATBIB_NUMERICAL);
1502                 else
1503                         params.setCiteEngine(ENGINE_NATBIB_AUTHORYEAR);
1504
1505         } else if (biblioModule->citeJurabibRB->isChecked())
1506                 params.setCiteEngine(ENGINE_JURABIB);
1507
1508         params.use_bibtopic =
1509                 biblioModule->bibtopicCB->isChecked();
1510
1511         // language & quotes
1512         if (langModule->defaultencodingRB->isChecked()) {
1513                 params.inputenc = "auto";
1514         } else {
1515                 int i = langModule->encodingCO->currentIndex();
1516                 if (i == 0)
1517                         params.inputenc = "default";
1518                 else {
1519                         QString const enc_gui =
1520                                 langModule->encodingCO->currentText();
1521                         Encodings::const_iterator it = encodings.begin();
1522                         Encodings::const_iterator const end = encodings.end();
1523                         bool found = false;
1524                         for (; it != end; ++it) {
1525                                 if (qt_(it->guiName()) == enc_gui) {
1526                                         params.inputenc = it->latexName();
1527                                         found = true;
1528                                         break;
1529                                 }
1530                         }
1531                         if (!found) {
1532                                 // should not happen
1533                                 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
1534                                 params.inputenc = "default";
1535                         }
1536                 }
1537         }
1538
1539         InsetQuotes::QuoteLanguage lga = InsetQuotes::EnglishQuotes;
1540         switch (langModule->quoteStyleCO->currentIndex()) {
1541         case 0:
1542                 lga = InsetQuotes::EnglishQuotes;
1543                 break;
1544         case 1:
1545                 lga = InsetQuotes::SwedishQuotes;
1546                 break;
1547         case 2:
1548                 lga = InsetQuotes::GermanQuotes;
1549                 break;
1550         case 3:
1551                 lga = InsetQuotes::PolishQuotes;
1552                 break;
1553         case 4:
1554                 lga = InsetQuotes::FrenchQuotes;
1555                 break;
1556         case 5:
1557                 lga = InsetQuotes::DanishQuotes;
1558                 break;
1559         }
1560         params.quotes_language = lga;
1561
1562         QString const lang = langModule->languageCO->itemData(
1563                 langModule->languageCO->currentIndex()).toString();
1564         params.language = lyx::languages.getLanguage(fromqstr(lang));
1565
1566         // numbering
1567         if (params.documentClass().hasTocLevels()) {
1568                 params.tocdepth = numberingModule->tocSL->value();
1569                 params.secnumdepth = numberingModule->depthSL->value();
1570         }
1571
1572         // bullets
1573         params.user_defined_bullet(0) = bulletsModule->bullet(0);
1574         params.user_defined_bullet(1) = bulletsModule->bullet(1);
1575         params.user_defined_bullet(2) = bulletsModule->bullet(2);
1576         params.user_defined_bullet(3) = bulletsModule->bullet(3);
1577
1578         // packages
1579         params.graphicsDriver =
1580                 tex_graphics[latexModule->psdriverCO->currentIndex()];
1581         
1582         // text layout
1583         int idx = latexModule->classCO->currentIndex();
1584         if (idx >= 0) {
1585                 string const classname = classes_model_.getIDString(idx);
1586                 params.setBaseClass(classname);
1587         }
1588
1589         // Modules
1590         params.clearLayoutModules();
1591         int const srows = modules_sel_model_.rowCount();
1592         vector<string> selModList;
1593         for (int i = 0; i < srows; ++i)
1594                 params.addLayoutModule(modules_sel_model_.getIDString(i));
1595         // update the list of removed modules
1596         params.clearRemovedModules();
1597         list<string> const & reqmods = params.baseClass()->defaultModules();
1598         list<string>::const_iterator rit = reqmods.begin();
1599         list<string>::const_iterator ren = reqmods.end();
1600         // check each of the required modules
1601         for (; rit != ren; rit++) {
1602                 vector<string>::const_iterator mit = params.getModules().begin();
1603                 vector<string>::const_iterator men = params.getModules().end();
1604                 bool found = false;
1605                 for (; mit != men; mit++) {
1606                         if (*rit == *mit) {
1607                                 found = true;
1608                                 break;
1609                         }
1610                 }
1611                 if (!found) {
1612                         // the module isn't present so must have been removed by the user
1613                         params.addRemovedModule(*rit);
1614                 }
1615         }
1616
1617         if (mathsModule->amsautoCB->isChecked()) {
1618                 params.use_amsmath = BufferParams::package_auto;
1619         } else {
1620                 if (mathsModule->amsCB->isChecked())
1621                         params.use_amsmath = BufferParams::package_on;
1622                 else
1623                         params.use_amsmath = BufferParams::package_off;
1624         }
1625
1626         if (mathsModule->esintautoCB->isChecked())
1627                 params.use_esint = BufferParams::package_auto;
1628         else {
1629                 if (mathsModule->esintCB->isChecked())
1630                         params.use_esint = BufferParams::package_on;
1631                 else
1632                         params.use_esint = BufferParams::package_off;
1633         }
1634
1635         if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
1636                 params.pagestyle = "default";
1637         else {
1638                 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
1639                 for (size_t i = 0; i != pagestyles.size(); ++i)
1640                         if (pagestyles[i].second == style_gui)
1641                                 params.pagestyle = pagestyles[i].first;
1642         }
1643
1644         switch (textLayoutModule->lspacingCO->currentIndex()) {
1645         case 0:
1646                 params.spacing().set(Spacing::Single);
1647                 break;
1648         case 1:
1649                 params.spacing().set(Spacing::Onehalf);
1650                 break;
1651         case 2:
1652                 params.spacing().set(Spacing::Double);
1653                 break;
1654         case 3:
1655                 params.spacing().set(Spacing::Other,
1656                         fromqstr(textLayoutModule->lspacingLE->text()));
1657                 break;
1658         }
1659
1660         if (textLayoutModule->twoColumnCB->isChecked())
1661                 params.columns = 2;
1662         else
1663                 params.columns = 1;
1664
1665         // text should have passed validation
1666         params.listings_params =
1667                 InsetListingsParams(fromqstr(textLayoutModule->listingsED->toPlainText())).params();
1668
1669         if (textLayoutModule->indentRB->isChecked())
1670                 params.paragraph_separation = BufferParams::ParagraphIndentSeparation;
1671         else
1672                 params.paragraph_separation = BufferParams::ParagraphSkipSeparation;
1673
1674         switch (textLayoutModule->skipCO->currentIndex()) {
1675         case 0:
1676                 params.setDefSkip(VSpace(VSpace::SMALLSKIP));
1677                 break;
1678         case 1:
1679                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
1680                 break;
1681         case 2:
1682                 params.setDefSkip(VSpace(VSpace::BIGSKIP));
1683                 break;
1684         case 3:
1685         {
1686                 VSpace vs = VSpace(
1687                         widgetsToLength(textLayoutModule->skipLE,
1688                                 textLayoutModule->skipLengthCO)
1689                         );
1690                 params.setDefSkip(vs);
1691                 break;
1692         }
1693         default:
1694                 // DocumentDefskipCB assures that this never happens
1695                 // so Assert then !!!  - jbl
1696                 params.setDefSkip(VSpace(VSpace::MEDSKIP));
1697                 break;
1698         }
1699
1700         params.options =
1701                 fromqstr(latexModule->optionsLE->text());
1702
1703         if (latexModule->childDocGB->isChecked())
1704                 params.master =
1705                         fromqstr(latexModule->childDocLE->text());
1706         else
1707                 params.master = string();
1708
1709         params.float_placement = floatModule->get();
1710
1711         // fonts
1712         params.fontsRoman =
1713                 tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1714
1715         params.fontsSans =
1716                 tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1717
1718         params.fontsTypewriter =
1719                 tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1720
1721         params.fontsCJK =
1722                 fromqstr(fontModule->cjkFontLE->text());
1723
1724         params.fontsSansScale = fontModule->scaleSansSB->value();
1725
1726         params.fontsTypewriterScale = fontModule->scaleTypewriterSB->value();
1727
1728         params.fontsSC = fontModule->fontScCB->isChecked();
1729
1730         params.fontsOSF = fontModule->fontOsfCB->isChecked();
1731
1732         params.fontsDefaultFamily = GuiDocument::fontfamilies[
1733                 fontModule->fontsDefaultCO->currentIndex()];
1734
1735         if (fontModule->fontsizeCO->currentIndex() == 0)
1736                 params.fontsize = "default";
1737         else
1738                 params.fontsize =
1739                         fromqstr(fontModule->fontsizeCO->currentText());
1740
1741         // paper
1742         params.papersize = PAPER_SIZE(
1743                 pageLayoutModule->papersizeCO->currentIndex());
1744
1745         // custom, A3, B3 and B4 paper sizes need geometry
1746         int psize = pageLayoutModule->papersizeCO->currentIndex();
1747         bool geom_papersize = (psize == 1 || psize == 5 || psize == 8 || psize == 9);
1748
1749         params.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
1750                 pageLayoutModule->paperwidthUnitCO);
1751
1752         params.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
1753                 pageLayoutModule->paperheightUnitCO);
1754
1755         if (pageLayoutModule->facingPagesCB->isChecked())
1756                 params.sides = TwoSides;
1757         else
1758                 params.sides = OneSide;
1759
1760         if (pageLayoutModule->landscapeRB->isChecked())
1761                 params.orientation = ORIENTATION_LANDSCAPE;
1762         else
1763                 params.orientation = ORIENTATION_PORTRAIT;
1764
1765         // margins
1766         params.use_geometry = !marginsModule->marginCB->isChecked()
1767                 || geom_papersize;
1768
1769         Ui::MarginsUi const * m = marginsModule;
1770
1771         params.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
1772         params.topmargin = widgetsToLength(m->topLE, m->topUnit);
1773         params.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
1774         params.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
1775         params.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
1776         params.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
1777         params.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
1778         params.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
1779
1780         branchesModule->apply(params);
1781
1782         // PDF support
1783         PDFOptions & pdf = params.pdfoptions();
1784         pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
1785         pdf.title = fromqstr(pdfSupportModule->titleLE->text());
1786         pdf.author = fromqstr(pdfSupportModule->authorLE->text());
1787         pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
1788         pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
1789
1790         pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
1791         pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
1792         pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
1793         pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
1794
1795         pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
1796         pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
1797         pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
1798         pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
1799         pdf.backref = pdfSupportModule->backrefCB->isChecked();
1800         pdf.pagebackref = pdfSupportModule->pagebackrefCB->isChecked();
1801         if (pdfSupportModule->fullscreenCB->isChecked())
1802                 pdf.pagemode = pdf.pagemode_fullscreen;
1803         else
1804                 pdf.pagemode.clear();
1805         pdf.quoted_options = pdf.quoted_options_check(
1806                                 fromqstr(pdfSupportModule->optionsLE->text()));
1807 }
1808
1809
1810 void GuiDocument::paramsToDialog(BufferParams const & params)
1811 {
1812         // set the default unit
1813         Length::UNIT defaultUnit = Length::CM;
1814         switch (lyxrc.default_papersize) {
1815                 case PAPER_DEFAULT: break;
1816
1817                 case PAPER_USLETTER:
1818                 case PAPER_USLEGAL:
1819                 case PAPER_USEXECUTIVE:
1820                         defaultUnit = Length::IN;
1821                         break;
1822
1823                 case PAPER_A3:
1824                 case PAPER_A4:
1825                 case PAPER_A5:
1826                 case PAPER_B3:
1827                 case PAPER_B4:
1828                 case PAPER_B5:
1829                         defaultUnit = Length::CM;
1830                         break;
1831                 case PAPER_CUSTOM:
1832                         break;
1833         }
1834
1835         // preamble
1836         preambleModule->update(params, id());
1837
1838         // biblio
1839         biblioModule->citeDefaultRB->setChecked(
1840                 params.citeEngine() == ENGINE_BASIC);
1841
1842         biblioModule->citeNatbibRB->setChecked(
1843                 params.citeEngine() == ENGINE_NATBIB_NUMERICAL ||
1844                 params.citeEngine() == ENGINE_NATBIB_AUTHORYEAR);
1845
1846         biblioModule->citeStyleCO->setCurrentIndex(
1847                 params.citeEngine() == ENGINE_NATBIB_NUMERICAL);
1848
1849         biblioModule->citeJurabibRB->setChecked(
1850                 params.citeEngine() == ENGINE_JURABIB);
1851
1852         biblioModule->bibtopicCB->setChecked(
1853                 params.use_bibtopic);
1854
1855         // language & quotes
1856         int const pos = langModule->languageCO->findData(toqstr(
1857                 params.language->lang()));
1858         langModule->languageCO->setCurrentIndex(pos);
1859
1860         langModule->quoteStyleCO->setCurrentIndex(
1861                 params.quotes_language);
1862
1863         bool default_enc = true;
1864         if (params.inputenc != "auto") {
1865                 default_enc = false;
1866                 if (params.inputenc == "default") {
1867                         langModule->encodingCO->setCurrentIndex(0);
1868                 } else {
1869                         string enc_gui;
1870                         Encodings::const_iterator it = encodings.begin();
1871                         Encodings::const_iterator const end = encodings.end();
1872                         for (; it != end; ++it) {
1873                                 if (it->latexName() == params.inputenc) {
1874                                         enc_gui = it->guiName();
1875                                         break;
1876                                 }
1877                         }
1878                         int const i = langModule->encodingCO->findText(
1879                                         qt_(enc_gui));
1880                         if (i >= 0)
1881                                 langModule->encodingCO->setCurrentIndex(i);
1882                         else
1883                                 // unknown encoding. Set to default.
1884                                 default_enc = true;
1885                 }
1886         }
1887         langModule->defaultencodingRB->setChecked(default_enc);
1888         langModule->otherencodingRB->setChecked(!default_enc);
1889
1890         // numbering
1891         int const min_toclevel = documentClass().min_toclevel();
1892         int const max_toclevel = documentClass().max_toclevel();
1893         if (documentClass().hasTocLevels()) {
1894                 numberingModule->setEnabled(true);
1895                 numberingModule->depthSL->setMinimum(min_toclevel - 1);
1896                 numberingModule->depthSL->setMaximum(max_toclevel);
1897                 numberingModule->depthSL->setValue(params.secnumdepth);
1898                 numberingModule->tocSL->setMaximum(min_toclevel - 1);
1899                 numberingModule->tocSL->setMaximum(max_toclevel);
1900                 numberingModule->tocSL->setValue(params.tocdepth);
1901                 updateNumbering();
1902         } else {
1903                 numberingModule->setEnabled(false);
1904                 numberingModule->tocTW->clear();
1905         }
1906
1907         // bullets
1908         bulletsModule->setBullet(0, params.user_defined_bullet(0));
1909         bulletsModule->setBullet(1, params.user_defined_bullet(1));
1910         bulletsModule->setBullet(2, params.user_defined_bullet(2));
1911         bulletsModule->setBullet(3, params.user_defined_bullet(3));
1912         bulletsModule->init();
1913
1914         // packages
1915         int nitem = findToken(tex_graphics, params.graphicsDriver);
1916         if (nitem >= 0)
1917                 latexModule->psdriverCO->setCurrentIndex(nitem);
1918         updateModuleInfo();
1919         
1920         mathsModule->amsCB->setChecked(
1921                 params.use_amsmath == BufferParams::package_on);
1922         mathsModule->amsautoCB->setChecked(
1923                 params.use_amsmath == BufferParams::package_auto);
1924
1925         mathsModule->esintCB->setChecked(
1926                 params.use_esint == BufferParams::package_on);
1927         mathsModule->esintautoCB->setChecked(
1928                 params.use_esint == BufferParams::package_auto);
1929
1930         switch (params.spacing().getSpace()) {
1931                 case Spacing::Other: nitem = 3; break;
1932                 case Spacing::Double: nitem = 2; break;
1933                 case Spacing::Onehalf: nitem = 1; break;
1934                 case Spacing::Default: case Spacing::Single: nitem = 0; break;
1935         }
1936
1937         // text layout
1938         string const & layoutID = params.baseClassID();
1939         setLayoutComboByIDString(layoutID);
1940
1941         updatePagestyle(documentClass().opt_pagestyle(),
1942                                  params.pagestyle);
1943
1944         textLayoutModule->lspacingCO->setCurrentIndex(nitem);
1945         if (params.spacing().getSpace() == Spacing::Other) {
1946                 textLayoutModule->lspacingLE->setText(
1947                         toqstr(params.spacing().getValueAsString()));
1948         }
1949         setLSpacing(nitem);
1950
1951         if (params.paragraph_separation == BufferParams::ParagraphIndentSeparation)
1952                 textLayoutModule->indentRB->setChecked(true);
1953         else
1954                 textLayoutModule->skipRB->setChecked(true);
1955
1956         int skip = 0;
1957         switch (params.getDefSkip().kind()) {
1958         case VSpace::SMALLSKIP:
1959                 skip = 0;
1960                 break;
1961         case VSpace::MEDSKIP:
1962                 skip = 1;
1963                 break;
1964         case VSpace::BIGSKIP:
1965                 skip = 2;
1966                 break;
1967         case VSpace::LENGTH:
1968         {
1969                 skip = 3;
1970                 string const length = params.getDefSkip().asLyXCommand();
1971                 lengthToWidgets(textLayoutModule->skipLE,
1972                         textLayoutModule->skipLengthCO,
1973                         length, defaultUnit);
1974                 break;
1975         }
1976         default:
1977                 skip = 0;
1978                 break;
1979         }
1980         textLayoutModule->skipCO->setCurrentIndex(skip);
1981         setSkip(skip);
1982
1983         textLayoutModule->twoColumnCB->setChecked(
1984                 params.columns == 2);
1985
1986         // break listings_params to multiple lines
1987         string lstparams =
1988                 InsetListingsParams(params.listings_params).separatedParams();
1989         textLayoutModule->listingsED->setPlainText(toqstr(lstparams));
1990
1991         if (!params.options.empty()) {
1992                 latexModule->optionsLE->setText(
1993                         toqstr(params.options));
1994         } else {
1995                 latexModule->optionsLE->setText(QString());
1996         }
1997
1998         if (!params.master.empty()) {
1999                 latexModule->childDocGB->setChecked(true);
2000                 latexModule->childDocLE->setText(
2001                         toqstr(params.master));
2002         } else {
2003                 latexModule->childDocLE->setText(QString());
2004                 latexModule->childDocGB->setChecked(false);
2005         }
2006
2007         floatModule->set(params.float_placement);
2008
2009         // Fonts
2010         updateFontsize(documentClass().opt_fontsize(),
2011                         params.fontsize);
2012
2013         int n = findToken(tex_fonts_roman, params.fontsRoman);
2014         if (n >= 0) {
2015                 fontModule->fontsRomanCO->setCurrentIndex(n);
2016                 romanChanged(n);
2017         }
2018
2019         n = findToken(tex_fonts_sans, params.fontsSans);
2020         if (n >= 0)     {
2021                 fontModule->fontsSansCO->setCurrentIndex(n);
2022                 sansChanged(n);
2023         }
2024
2025         n = findToken(tex_fonts_monospaced, params.fontsTypewriter);
2026         if (n >= 0) {
2027                 fontModule->fontsTypewriterCO->setCurrentIndex(n);
2028                 ttChanged(n);
2029         }
2030
2031         if (!params.fontsCJK.empty())
2032                 fontModule->cjkFontLE->setText(
2033                         toqstr(params.fontsCJK));
2034         else
2035                 fontModule->cjkFontLE->setText(QString());
2036
2037         fontModule->fontScCB->setChecked(params.fontsSC);
2038         fontModule->fontOsfCB->setChecked(params.fontsOSF);
2039         fontModule->scaleSansSB->setValue(params.fontsSansScale);
2040         fontModule->scaleTypewriterSB->setValue(params.fontsTypewriterScale);
2041         n = findToken(GuiDocument::fontfamilies, params.fontsDefaultFamily);
2042         if (n >= 0)
2043                 fontModule->fontsDefaultCO->setCurrentIndex(n);
2044
2045         // paper
2046         int const psize = params.papersize;
2047         pageLayoutModule->papersizeCO->setCurrentIndex(psize);
2048         setCustomPapersize(psize);
2049
2050         bool const landscape =
2051                 params.orientation == ORIENTATION_LANDSCAPE;
2052         pageLayoutModule->landscapeRB->setChecked(landscape);
2053         pageLayoutModule->portraitRB->setChecked(!landscape);
2054
2055         pageLayoutModule->facingPagesCB->setChecked(
2056                 params.sides == TwoSides);
2057
2058
2059         lengthToWidgets(pageLayoutModule->paperwidthLE,
2060                 pageLayoutModule->paperwidthUnitCO, params.paperwidth, defaultUnit);
2061
2062         lengthToWidgets(pageLayoutModule->paperheightLE,
2063                 pageLayoutModule->paperheightUnitCO, params.paperheight, defaultUnit);
2064
2065         // margins
2066         Ui::MarginsUi * m = marginsModule;
2067
2068         setMargins(!params.use_geometry);
2069
2070         lengthToWidgets(m->topLE, m->topUnit,
2071                 params.topmargin, defaultUnit);
2072
2073         lengthToWidgets(m->bottomLE, m->bottomUnit,
2074                 params.bottommargin, defaultUnit);
2075
2076         lengthToWidgets(m->innerLE, m->innerUnit,
2077                 params.leftmargin, defaultUnit);
2078
2079         lengthToWidgets(m->outerLE, m->outerUnit,
2080                 params.rightmargin, defaultUnit);
2081
2082         lengthToWidgets(m->headheightLE, m->headheightUnit,
2083                 params.headheight, defaultUnit);
2084
2085         lengthToWidgets(m->headsepLE, m->headsepUnit,
2086                 params.headsep, defaultUnit);
2087
2088         lengthToWidgets(m->footskipLE, m->footskipUnit,
2089                 params.footskip, defaultUnit);
2090
2091         lengthToWidgets(m->columnsepLE, m->columnsepUnit,
2092                 params.columnsep, defaultUnit);
2093
2094         branchesModule->update(params);
2095
2096         // PDF support
2097         PDFOptions const & pdf = params.pdfoptions();
2098         pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
2099         pdfSupportModule->titleLE->setText(toqstr(pdf.title));
2100         pdfSupportModule->authorLE->setText(toqstr(pdf.author));
2101         pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
2102         pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
2103
2104         pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
2105         pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
2106         pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
2107
2108         pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
2109
2110         pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
2111         pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
2112         pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
2113         pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
2114         pdfSupportModule->backrefCB->setChecked(pdf.backref);
2115         pdfSupportModule->pagebackrefCB->setChecked(pdf.pagebackref);
2116         pdfSupportModule->fullscreenCB->setChecked
2117                 (pdf.pagemode == pdf.pagemode_fullscreen);
2118
2119         pdfSupportModule->optionsLE->setText(
2120                 toqstr(pdf.quoted_options));
2121 }
2122
2123
2124 void GuiDocument::applyView()
2125 {
2126         apply(params());
2127 }
2128
2129
2130 void GuiDocument::saveDocDefault()
2131 {
2132         // we have to apply the params first
2133         applyView();
2134         saveAsDefault();
2135 }
2136
2137
2138 void GuiDocument::updateAvailableModules() 
2139 {
2140         modules_av_model_.clear();
2141         vector<modInfoStruct> const & modInfoList = getModuleInfo();
2142         int const mSize = modInfoList.size();
2143         for (int i = 0; i != mSize; ++i) {
2144                 modInfoStruct const & modInfo = modInfoList[i];
2145                 modules_av_model_.insertRow(i, modInfo.name, modInfo.id, 
2146                                 modInfo.description);
2147         }
2148 }
2149
2150
2151 void GuiDocument::updateSelectedModules() 
2152 {
2153         // and selected ones, too
2154         modules_sel_model_.clear();
2155         vector<modInfoStruct> const selModList = getSelectedModules();
2156         int const sSize = selModList.size();
2157         for (int i = 0; i != sSize; ++i) {
2158                 modInfoStruct const & modInfo = selModList[i];
2159                 modules_sel_model_.insertRow(i, modInfo.name, modInfo.id,
2160                                 modInfo.description);
2161         }
2162 }
2163
2164
2165 void GuiDocument::updateContents()
2166 {
2167         // Nothing to do here as the document settings is not cursor dependant.
2168         return;
2169 }
2170
2171
2172 void GuiDocument::useClassDefaults()
2173 {
2174         if (applyPB->isEnabled()) {
2175                 int const ret = Alert::prompt(_("Unapplied changes"),
2176                                 _("Some changes in the dialog were not yet applied.\n"
2177                                   "If you do not apply now, they will be lost after this action."),
2178                                 1, 1, _("&Apply"), _("&Dismiss"));
2179                 if (ret == 0)
2180                         applyView();
2181         }
2182
2183         int idx = latexModule->classCO->currentIndex();
2184         string const classname = classes_model_.getIDString(idx);
2185         if (!bp_.setBaseClass(classname)) {
2186                 Alert::error(_("Error"), _("Unable to set document class."));
2187                 return;
2188         }
2189         bp_.useClassDefaults();
2190         paramsToDialog(bp_);
2191 }
2192
2193
2194 void GuiDocument::setLayoutComboByIDString(std::string const & idString)
2195 {
2196         int idx = classes_model_.findIDString(idString);
2197         if (idx < 0)
2198                 Alert::warning(_("Can't set layout!"), 
2199                         bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
2200         else 
2201                 latexModule->classCO->setCurrentIndex(idx);
2202 }
2203
2204
2205 bool GuiDocument::isValid()
2206 {
2207         return validateListingsParameters().isEmpty()
2208                 && (textLayoutModule->skipCO->currentIndex() != 3
2209                         || !textLayoutModule->skipLE->text().isEmpty());
2210 }
2211
2212
2213 char const * const GuiDocument::fontfamilies[5] = {
2214         "default", "rmdefault", "sfdefault", "ttdefault", ""
2215 };
2216
2217
2218 char const * GuiDocument::fontfamilies_gui[5] = {
2219         N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
2220 };
2221
2222
2223 bool GuiDocument::initialiseParams(string const &)
2224 {
2225         BufferView const * view = bufferview();
2226         if (!view) {
2227                 bp_ = BufferParams();
2228                 paramsToDialog(bp_);
2229                 return true;
2230         }
2231         bp_ = view->buffer().params();
2232         loadModuleInfo();
2233         updateAvailableModules();
2234         updateSelectedModules();
2235         //FIXME It'd be nice to make sure here that the selected
2236         //modules are consistent: That required modules are actually
2237         //selected, and that we don't have conflicts. If so, we could
2238         //at least pop up a warning.
2239         paramsToDialog(bp_);
2240         return true;
2241 }
2242
2243
2244 void GuiDocument::clearParams()
2245 {
2246         bp_ = BufferParams();
2247 }
2248
2249
2250 BufferId GuiDocument::id() const
2251 {
2252         BufferView const * const view = bufferview();
2253         return view? &view->buffer() : 0;
2254 }
2255
2256
2257 vector<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
2258 {
2259         return moduleNames_;
2260 }
2261
2262
2263 vector<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
2264 {
2265         vector<string> const & mods = params().getModules();
2266         vector<string>::const_iterator it =  mods.begin();
2267         vector<string>::const_iterator end = mods.end();
2268         vector<modInfoStruct> mInfo;
2269         for (; it != end; ++it) {
2270                 modInfoStruct m;
2271                 m.id = *it;
2272                 LyXModule * mod = moduleList[*it];
2273                 if (mod)
2274                         m.name = qt_(mod->getName());
2275                 else 
2276                         m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
2277                 mInfo.push_back(m);
2278         }
2279         return mInfo;
2280 }
2281
2282
2283 DocumentClass const & GuiDocument::documentClass() const
2284 {
2285         return bp_.documentClass();
2286 }
2287
2288
2289 static void dispatch_bufferparams(Dialog const & dialog,
2290         BufferParams const & bp, FuncCode lfun)
2291 {
2292         ostringstream ss;
2293         ss << "\\begin_header\n";
2294         bp.writeFile(ss);
2295         ss << "\\end_header\n";
2296         dialog.dispatch(FuncRequest(lfun, ss.str()));
2297 }
2298
2299
2300 void GuiDocument::dispatchParams()
2301 {
2302         // This must come first so that a language change is correctly noticed
2303         setLanguage();
2304
2305         // Apply the BufferParams. Note that this will set the base class
2306         // and then update the buffer's layout.
2307         dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
2308
2309         if (!params().master.empty()) {
2310                 FileName const master_file = support::makeAbsPath(params().master,
2311                            support::onlyPath(buffer().absFileName()));
2312                 if (isLyXFilename(master_file.absFilename())) {
2313                         Buffer * master = checkAndLoadLyXFile(master_file);
2314                         const_cast<Buffer &>(buffer()).setParent(master);
2315                 }
2316         }
2317
2318         // Generate the colours requested by each new branch.
2319         BranchList & branchlist = params().branchlist();
2320         if (!branchlist.empty()) {
2321                 BranchList::const_iterator it = branchlist.begin();
2322                 BranchList::const_iterator const end = branchlist.end();
2323                 for (; it != end; ++it) {
2324                         docstring const & current_branch = it->branch();
2325                         Branch const * branch = branchlist.find(current_branch);
2326                         string const x11hexname = X11hexname(branch->color());
2327                         // display the new color
2328                         docstring const str = current_branch + ' ' + from_ascii(x11hexname);
2329                         dispatch(FuncRequest(LFUN_SET_COLOR, str));
2330                 }
2331
2332                 // Open insets of selected branches, close deselected ones
2333                 dispatch(FuncRequest(LFUN_ALL_INSETS_TOGGLE,
2334                         "assign branch"));
2335         }
2336         // FIXME: If we used an LFUN, we would not need those two lines:
2337         BufferView * bv = const_cast<BufferView *>(bufferview());
2338         bv->processUpdateFlags(Update::Force | Update::FitCursor);
2339 }
2340
2341
2342 void GuiDocument::setLanguage() const
2343 {
2344         Language const * const newL = bp_.language;
2345         if (buffer().params().language == newL)
2346                 return;
2347
2348         string const & lang_name = newL->lang();
2349         dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
2350 }
2351
2352
2353 void GuiDocument::saveAsDefault() const
2354 {
2355         dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
2356 }
2357
2358
2359 bool GuiDocument::isFontAvailable(string const & font) const
2360 {
2361         if (font == "default" || font == "cmr"
2362             || font == "cmss" || font == "cmtt")
2363                 // these are standard
2364                 return true;
2365         if (font == "lmodern" || font == "lmss" || font == "lmtt")
2366                 return LaTeXFeatures::isAvailable("lmodern");
2367         if (font == "times" || font == "palatino"
2368                  || font == "helvet" || font == "courier")
2369                 return LaTeXFeatures::isAvailable("psnfss");
2370         if (font == "cmbr" || font == "cmtl")
2371                 return LaTeXFeatures::isAvailable("cmbright");
2372         if (font == "utopia")
2373                 return LaTeXFeatures::isAvailable("utopia")
2374                         || LaTeXFeatures::isAvailable("fourier");
2375         if (font == "beraserif" || font == "berasans"
2376                 || font == "beramono")
2377                 return LaTeXFeatures::isAvailable("bera");
2378         return LaTeXFeatures::isAvailable(font);
2379 }
2380
2381
2382 bool GuiDocument::providesOSF(string const & font) const
2383 {
2384         if (font == "cmr")
2385                 return isFontAvailable("eco");
2386         if (font == "palatino")
2387                 return isFontAvailable("mathpazo");
2388         return false;
2389 }
2390
2391
2392 bool GuiDocument::providesSC(string const & font) const
2393 {
2394         if (font == "palatino")
2395                 return isFontAvailable("mathpazo");
2396         if (font == "utopia")
2397                 return isFontAvailable("fourier");
2398         return false;
2399 }
2400
2401
2402 bool GuiDocument::providesScale(string const & font) const
2403 {
2404         return font == "helvet" || font == "luximono"
2405                 || font == "berasans"  || font == "beramono";
2406 }
2407
2408
2409 void GuiDocument::loadModuleInfo()
2410 {
2411         moduleNames_.clear();
2412         LyXModuleList::const_iterator it  = moduleList.begin();
2413         LyXModuleList::const_iterator end = moduleList.end();
2414         for (; it != end; ++it) {
2415                 modInfoStruct m;
2416                 m.id = it->getID();
2417                 m.name = qt_(it->getName());
2418                 // this is supposed to give us the first sentence of the description
2419                 QString desc = qt_(it->getDescription());
2420                 int const pos = desc.indexOf(".");
2421                 if (pos > 0)
2422                         desc.truncate(pos + 1);
2423                 m.description = desc;
2424                 moduleNames_.push_back(m);
2425         }
2426 }
2427
2428
2429 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
2430
2431
2432 } // namespace frontend
2433 } // namespace lyx
2434
2435 #include "GuiDocument_moc.cpp"