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