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