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