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