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