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