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