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