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