2 * \file GuiDocument.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
7 * \author Richard Heck (modules)
9 * Full author contact details are available in file CREDITS.
14 #include "GuiDocument.h"
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"
25 #include "LayoutFile.h"
26 #include "BranchList.h"
27 #include "buffer_funcs.h"
29 #include "BufferParams.h"
30 #include "BufferView.h"
32 #include "ColorCache.h"
34 #include "FloatPlacement.h"
36 #include "FuncRequest.h"
37 #include "IndicesList.h"
39 #include "LaTeXFeatures.h"
41 #include "LayoutModuleList.h"
43 #include "ModuleList.h"
44 #include "OutputParams.h"
45 #include "PDFOptions.h"
46 #include "qt_helpers.h"
49 #include "insets/InsetListingsParams.h"
51 #include "support/debug.h"
52 #include "support/FileName.h"
53 #include "support/filetools.h"
54 #include "support/gettext.h"
55 #include "support/lstrings.h"
57 #include "frontends/alert.h"
59 #include <QAbstractItemModel>
61 #include <QColorDialog>
62 #include <QCloseEvent>
63 #include <QFontDatabase>
65 #include <QTextCursor>
75 // a style sheet for buttons
76 // this is for example used for the background color setting button
77 static inline QString colorButtonStyleSheet(QColor const & bgColor)
79 if (bgColor.isValid()) {
80 QString rc = QLatin1String("background:");
89 using namespace lyx::support;
94 char const * const tex_graphics[] =
96 "default", "dvialw", "dvilaser", "dvipdf", "dvipdfm", "dvipdfmx",
97 "dvips", "dvipsone", "dvitops", "dviwin", "dviwindo", "dvi2ps", "emtex",
98 "ln", "oztex", "pctexhp", "pctexps", "pctexwin", "pctex32", "pdftex",
99 "psprint", "pubps", "tcidvi", "textures", "truetex", "vtex", "xdvi",
104 char const * const tex_graphics_gui[] =
106 N_("Default"), "dvialw", "DviLaser", "dvipdf", "DVIPDFM", "DVIPDFMx",
107 "Dvips", "DVIPSONE", "DVItoPS", "DVIWIN", "DVIWindo", "dvi2ps", "EmTeX",
108 "LN", "OzTeX", "pctexhp", "pctexps", "pctexwin", "PCTeX32", "pdfTeX",
109 "psprint", "pubps", "tcidvi", "Textures", "TrueTeX", "VTeX", "xdvi",
110 "XeTeX", N_("None"), ""
114 char const * const tex_fonts_roman[] =
116 "default", "cmr", "lmodern", "ae", "times", "palatino",
117 "charter", "newcent", "bookman", "utopia", "beraserif",
118 "ccfonts", "chancery", ""
122 char const * tex_fonts_roman_gui[] =
124 N_("Default"), N_("Computer Modern Roman"), N_("Latin Modern Roman"),
125 N_("AE (Almost European)"), N_("Times Roman"), N_("Palatino"),
126 N_("Bitstream Charter"), N_("New Century Schoolbook"), N_("Bookman"),
127 N_("Utopia"), N_("Bera Serif"), N_("Concrete Roman"), N_("Zapf Chancery"),
132 char const * const tex_fonts_sans[] =
134 "default", "cmss", "lmss", "helvet", "avant", "berasans", "cmbr", ""
138 char const * tex_fonts_sans_gui[] =
140 N_("Default"), N_("Computer Modern Sans"), N_("Latin Modern Sans"),
141 N_("Helvetica"), N_("Avant Garde"), N_("Bera Sans"), N_("CM Bright"), ""
145 char const * const tex_fonts_monospaced[] =
147 "default", "cmtt", "lmtt", "courier", "beramono", "luximono", "cmtl", ""
151 char const * tex_fonts_monospaced_gui[] =
153 N_("Default"), N_("Computer Modern Typewriter"),
154 N_("Latin Modern Typewriter"), N_("Courier"), N_("Bera Mono"),
155 N_("LuxiMono"), N_("CM Typewriter Light"), ""
159 char const * backref_opts[] =
161 "false", "section", "slide", "page", ""
165 char const * backref_opts_gui[] =
167 N_("Off"), N_("Section"), N_("Slide"), N_("Page"), ""
171 vector<pair<string, QString> > pagestyles;
174 } // anonymous namespace
178 RGBColor set_backgroundcolor;
181 // used when sorting the textclass list.
182 class less_textclass_avail_desc
183 : public binary_function<string, string, int>
186 bool operator()(string const & lhs, string const & rhs) const
188 // Ordering criteria:
189 // 1. Availability of text class
190 // 2. Description (lexicographic)
191 LayoutFile const & tc1 = LayoutFileList::get()[lhs];
192 LayoutFile const & tc2 = LayoutFileList::get()[rhs];
193 int const rel = compare_no_case(
194 translateIfPossible(from_utf8(tc1.description())),
195 translateIfPossible(from_utf8(tc2.description())));
196 return (tc1.isTeXClassAvailable() && !tc2.isTeXClassAvailable()) ||
197 (tc1.isTeXClassAvailable() == tc2.isTeXClassAvailable() && rel < 0);
206 vector<string> getRequiredList(string const & modName)
208 LyXModule const * const mod = moduleList[modName];
210 return vector<string>(); //empty such thing
211 return mod->getRequiredModules();
215 vector<string> getExcludedList(string const & modName)
217 LyXModule const * const mod = moduleList[modName];
219 return vector<string>(); //empty such thing
220 return mod->getExcludedModules();
224 docstring getModuleDescription(string const & modName)
226 LyXModule const * const mod = moduleList[modName];
228 return _("Module not found!");
230 return translateIfPossible(from_utf8(mod->getDescription()));
234 vector<string> getPackageList(string const & modName)
236 LyXModule const * const mod = moduleList[modName];
238 return vector<string>(); //empty such thing
239 return mod->getPackageList();
243 bool isModuleAvailable(string const & modName)
245 LyXModule * mod = moduleList[modName];
248 return mod->isAvailable();
251 } // anonymous namespace
254 /////////////////////////////////////////////////////////////////////
256 // ModuleSelectionManager
258 /////////////////////////////////////////////////////////////////////
260 /// SelectionManager for use with modules
261 class ModuleSelectionManager : public GuiSelectionManager
265 ModuleSelectionManager(
266 QListView * availableLV,
267 QListView * selectedLV,
271 QPushButton * downPB,
272 GuiIdListModel * availableModel,
273 GuiIdListModel * selectedModel,
274 GuiDocument const * container)
275 : GuiSelectionManager(availableLV, selectedLV, addPB, delPB,
276 upPB, downPB, availableModel, selectedModel), container_(container)
279 void updateProvidedModules(LayoutModuleList const & pm)
280 { provided_modules_ = pm.list(); }
282 void updateExcludedModules(LayoutModuleList const & em)
283 { excluded_modules_ = em.list(); }
286 virtual void updateAddPB();
288 virtual void updateUpPB();
290 virtual void updateDownPB();
292 virtual void updateDelPB();
293 /// returns availableModel as a GuiIdListModel
294 GuiIdListModel * getAvailableModel()
296 return dynamic_cast<GuiIdListModel *>(availableModel);
298 /// returns selectedModel as a GuiIdListModel
299 GuiIdListModel * getSelectedModel()
301 return dynamic_cast<GuiIdListModel *>(selectedModel);
303 /// keeps a list of the modules the text class provides
304 std::list<std::string> provided_modules_;
306 std::list<std::string> excluded_modules_;
308 GuiDocument const * container_;
311 void ModuleSelectionManager::updateAddPB()
313 int const arows = availableModel->rowCount();
314 QModelIndexList const avail_sels =
315 availableLV->selectionModel()->selectedIndexes();
317 // disable if there aren't any modules (?), if none of them is chosen
318 // in the dialog, or if the chosen one is already selected for use.
319 if (arows == 0 || avail_sels.isEmpty() || isSelected(avail_sels.first())) {
320 addPB->setEnabled(false);
324 QModelIndex const & idx = availableLV->selectionModel()->currentIndex();
325 string const modname = getAvailableModel()->getIDString(idx.row());
328 container_->params().moduleCanBeAdded(modname);
329 addPB->setEnabled(enable);
333 void ModuleSelectionManager::updateDownPB()
335 int const srows = selectedModel->rowCount();
337 downPB->setEnabled(false);
340 QModelIndex const & curidx = selectedLV->selectionModel()->currentIndex();
341 int const curRow = curidx.row();
342 if (curRow < 0 || curRow >= srows - 1) { // invalid or last item
343 downPB->setEnabled(false);
347 // determine whether immediately succeding element requires this one
348 string const curmodname = getSelectedModel()->getIDString(curRow);
349 string const nextmodname = getSelectedModel()->getIDString(curRow + 1);
351 vector<string> reqs = getRequiredList(nextmodname);
353 // if it doesn't require anything....
355 downPB->setEnabled(true);
359 // Enable it if this module isn't required.
360 // FIXME This should perhaps be more flexible and check whether, even
361 // if the next one is required, there is also an earlier one that will do.
363 find(reqs.begin(), reqs.end(), curmodname) == reqs.end());
366 void ModuleSelectionManager::updateUpPB()
368 int const srows = selectedModel->rowCount();
370 upPB->setEnabled(false);
374 QModelIndex const & curIdx = selectedLV->selectionModel()->currentIndex();
375 int curRow = curIdx.row();
376 if (curRow <= 0 || curRow > srows - 1) { // first item or invalid
377 upPB->setEnabled(false);
380 string const curmodname = getSelectedModel()->getIDString(curRow);
382 // determine whether immediately preceding element is required by this one
383 vector<string> reqs = getRequiredList(curmodname);
385 // if this one doesn't require anything....
387 upPB->setEnabled(true);
392 // Enable it if the preceding module isn't required.
393 // NOTE This is less flexible than it might be. We could check whether, even
394 // if the previous one is required, there is an earlier one that would do.
395 string const premod = getSelectedModel()->getIDString(curRow - 1);
396 upPB->setEnabled(find(reqs.begin(), reqs.end(), premod) == reqs.end());
399 void ModuleSelectionManager::updateDelPB()
401 int const srows = selectedModel->rowCount();
403 deletePB->setEnabled(false);
407 QModelIndex const & curidx =
408 selectedLV->selectionModel()->currentIndex();
409 int const curRow = curidx.row();
410 if (curRow < 0 || curRow >= srows) { // invalid index?
411 deletePB->setEnabled(false);
415 string const curmodname = getSelectedModel()->getIDString(curRow);
417 // We're looking here for a reason NOT to enable the button. If we
418 // find one, we disable it and return. If we don't, we'll end up at
419 // the end of the function, and then we enable it.
420 for (int i = curRow + 1; i < srows; ++i) {
421 string const thisMod = getSelectedModel()->getIDString(i);
422 vector<string> reqs = getRequiredList(thisMod);
423 //does this one require us?
424 if (find(reqs.begin(), reqs.end(), curmodname) == reqs.end())
428 // OK, so this module requires us
429 // is there an EARLIER module that also satisfies the require?
430 // NOTE We demand that it be earlier to keep the list of modules
431 // consistent with the rule that a module must be proceeded by a
432 // required module. There would be more flexible ways to proceed,
433 // but that would be a lot more complicated, and the logic here is
434 // already complicated. (That's why I've left the debugging code.)
435 // lyxerr << "Testing " << thisMod << std::endl;
436 bool foundone = false;
437 for (int j = 0; j < curRow; ++j) {
438 string const mod = getSelectedModel()->getIDString(j);
439 // lyxerr << "In loop: Testing " << mod << std::endl;
440 // do we satisfy the require?
441 if (find(reqs.begin(), reqs.end(), mod) != reqs.end()) {
442 // lyxerr << mod << " does the trick." << std::endl;
447 // did we find a module to satisfy the require?
449 // lyxerr << "No matching module found." << std::endl;
450 deletePB->setEnabled(false);
454 // lyxerr << "All's well that ends well." << std::endl;
455 deletePB->setEnabled(true);
459 /////////////////////////////////////////////////////////////////////
463 /////////////////////////////////////////////////////////////////////
465 PreambleModule::PreambleModule() : current_id_(0)
467 // This is not a memory leak. The object will be destroyed
469 (void) new LaTeXHighlighter(preambleTE->document());
470 setFocusProxy(preambleTE);
471 connect(preambleTE, SIGNAL(textChanged()), this, SIGNAL(changed()));
475 void PreambleModule::update(BufferParams const & params, BufferId id)
477 QString preamble = toqstr(params.preamble);
478 // Nothing to do if the params and preamble are unchanged.
479 if (id == current_id_
480 && preamble == preambleTE->document()->toPlainText())
483 QTextCursor cur = preambleTE->textCursor();
484 // Save the coords before switching to the new one.
485 preamble_coords_[current_id_] =
486 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
488 // Save the params address for further use.
490 preambleTE->document()->setPlainText(preamble);
491 Coords::const_iterator it = preamble_coords_.find(current_id_);
492 if (it == preamble_coords_.end())
493 // First time we open this one.
494 preamble_coords_[current_id_] = make_pair(0, 0);
496 // Restore saved coords.
497 QTextCursor cur = preambleTE->textCursor();
498 cur.setPosition(it->second.first);
499 preambleTE->setTextCursor(cur);
500 preambleTE->verticalScrollBar()->setValue(it->second.second);
505 void PreambleModule::apply(BufferParams & params)
507 params.preamble = fromqstr(preambleTE->document()->toPlainText());
511 void PreambleModule::closeEvent(QCloseEvent * e)
513 // Save the coords before closing.
514 QTextCursor cur = preambleTE->textCursor();
515 preamble_coords_[current_id_] =
516 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
521 /////////////////////////////////////////////////////////////////////
525 /////////////////////////////////////////////////////////////////////
528 GuiDocument::GuiDocument(GuiView & lv)
529 : GuiDialog(lv, "document", qt_("Document Settings"))
533 connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
534 connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
535 connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
536 connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore()));
538 connect(savePB, SIGNAL(clicked()), this, SLOT(saveDefaultClicked()));
539 connect(defaultPB, SIGNAL(clicked()), this, SLOT(useDefaultsClicked()));
541 // Manage the restore, ok, apply, restore and cancel/close buttons
542 bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
544 bc().setApply(applyPB);
545 bc().setCancel(closePB);
546 bc().setRestore(restorePB);
548 textLayoutModule = new UiWidget<Ui::TextLayoutUi>;
550 connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
551 this, SLOT(change_adaptor()));
552 connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
553 this, SLOT(setLSpacing(int)));
554 connect(textLayoutModule->lspacingLE, SIGNAL(textChanged(const QString &)),
555 this, SLOT(change_adaptor()));
556 connect(textLayoutModule->skipRB, SIGNAL(clicked()),
557 this, SLOT(change_adaptor()));
558 connect(textLayoutModule->indentRB, SIGNAL(clicked()),
559 this, SLOT(change_adaptor()));
560 connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
561 this, SLOT(change_adaptor()));
562 connect(textLayoutModule->skipLE, SIGNAL(textChanged(const QString &)),
563 this, SLOT(change_adaptor()));
564 connect(textLayoutModule->skipLengthCO, SIGNAL(activated(int)),
565 this, SLOT(change_adaptor()));
566 connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
567 this, SLOT(setSkip(int)));
568 connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
569 this, SLOT(enableSkip(bool)));
570 connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
571 this, SLOT(change_adaptor()));
572 connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
573 this, SLOT(setColSep()));
574 connect(textLayoutModule->listingsED, SIGNAL(textChanged()),
575 this, SLOT(change_adaptor()));
576 connect(textLayoutModule->bypassCB, SIGNAL(clicked()),
577 this, SLOT(change_adaptor()));
578 connect(textLayoutModule->bypassCB, SIGNAL(clicked()),
579 this, SLOT(setListingsMessage()));
580 connect(textLayoutModule->listingsED, SIGNAL(textChanged()),
581 this, SLOT(setListingsMessage()));
582 textLayoutModule->listingsTB->setPlainText(
583 qt_("Input listings parameters on the right. Enter ? for a list of parameters."));
584 textLayoutModule->lspacingLE->setValidator(new QDoubleValidator(
585 textLayoutModule->lspacingLE));
586 textLayoutModule->skipLE->setValidator(unsignedLengthValidator(
587 textLayoutModule->skipLE));
589 textLayoutModule->skipCO->addItem(qt_("SmallSkip"));
590 textLayoutModule->skipCO->addItem(qt_("MedSkip"));
591 textLayoutModule->skipCO->addItem(qt_("BigSkip"));
592 textLayoutModule->skipCO->addItem(qt_("Length"));
593 // remove the %-items from the unit choice
594 textLayoutModule->skipLengthCO->noPercents();
595 textLayoutModule->lspacingCO->insertItem(
596 Spacing::Single, qt_("Single"));
597 textLayoutModule->lspacingCO->insertItem(
598 Spacing::Onehalf, qt_("OneHalf"));
599 textLayoutModule->lspacingCO->insertItem(
600 Spacing::Double, qt_("Double"));
601 textLayoutModule->lspacingCO->insertItem(
602 Spacing::Other, qt_("Custom"));
604 // initialize the length validator
605 bc().addCheckedLineEdit(textLayoutModule->skipLE);
608 outputModule = new UiWidget<Ui::OutputUi>;
610 connect(outputModule->xetexCB, SIGNAL(clicked()),
611 this, SLOT(change_adaptor()));
612 connect(outputModule->xetexCB, SIGNAL(toggled(bool)),
613 this, SLOT(xetexChanged(bool)));
614 connect(outputModule->defaultFormatCO, SIGNAL(activated(int)),
615 this, SLOT(change_adaptor()));
618 fontModule = new UiWidget<Ui::FontUi>;
619 connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
620 this, SLOT(change_adaptor()));
621 connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
622 this, SLOT(romanChanged(int)));
623 connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
624 this, SLOT(change_adaptor()));
625 connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
626 this, SLOT(sansChanged(int)));
627 connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
628 this, SLOT(change_adaptor()));
629 connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
630 this, SLOT(ttChanged(int)));
631 connect(fontModule->fontsDefaultCO, SIGNAL(activated(int)),
632 this, SLOT(change_adaptor()));
633 connect(fontModule->fontsizeCO, SIGNAL(activated(int)),
634 this, SLOT(change_adaptor()));
635 connect(fontModule->cjkFontLE, SIGNAL(textChanged(const QString &)),
636 this, SLOT(change_adaptor()));
637 connect(fontModule->scaleSansSB, SIGNAL(valueChanged(int)),
638 this, SLOT(change_adaptor()));
639 connect(fontModule->scaleTypewriterSB, SIGNAL(valueChanged(int)),
640 this, SLOT(change_adaptor()));
641 connect(fontModule->fontScCB, SIGNAL(clicked()),
642 this, SLOT(change_adaptor()));
643 connect(fontModule->fontOsfCB, SIGNAL(clicked()),
644 this, SLOT(change_adaptor()));
648 fontModule->fontsizeCO->addItem(qt_("Default"));
649 fontModule->fontsizeCO->addItem(qt_("10"));
650 fontModule->fontsizeCO->addItem(qt_("11"));
651 fontModule->fontsizeCO->addItem(qt_("12"));
653 for (int n = 0; GuiDocument::fontfamilies_gui[n][0]; ++n)
654 fontModule->fontsDefaultCO->addItem(
655 qt_(GuiDocument::fontfamilies_gui[n]));
658 pageLayoutModule = new UiWidget<Ui::PageLayoutUi>;
660 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
661 this, SLOT(setCustomPapersize(int)));
662 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
663 this, SLOT(setCustomPapersize(int)));
664 connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
665 this, SLOT(portraitChanged()));
666 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
667 this, SLOT(change_adaptor()));
668 connect(pageLayoutModule->paperheightLE, SIGNAL(textChanged(const QString &)),
669 this, SLOT(change_adaptor()));
670 connect(pageLayoutModule->paperwidthLE, SIGNAL(textChanged(const QString &)),
671 this, SLOT(change_adaptor()));
672 connect(pageLayoutModule->paperwidthUnitCO, SIGNAL(activated(int)),
673 this, SLOT(change_adaptor()));
674 connect(pageLayoutModule->paperheightUnitCO, SIGNAL(activated(int)),
675 this, SLOT(change_adaptor()));
676 connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
677 this, SLOT(change_adaptor()));
678 connect(pageLayoutModule->landscapeRB, SIGNAL(clicked()),
679 this, SLOT(change_adaptor()));
680 connect(pageLayoutModule->facingPagesCB, SIGNAL(clicked()),
681 this, SLOT(change_adaptor()));
682 connect(pageLayoutModule->pagestyleCO, SIGNAL(activated(int)),
683 this, SLOT(change_adaptor()));
684 connect(pageLayoutModule->backgroundPB, SIGNAL(clicked()),
685 this, SLOT(changeBackgroundColor()));
686 connect(pageLayoutModule->delbackgroundTB, SIGNAL(clicked()),
687 this, SLOT(deleteBackgroundColor()));
689 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
690 pageLayoutModule->pagestyleCO->addItem(qt_("empty"));
691 pageLayoutModule->pagestyleCO->addItem(qt_("plain"));
692 pageLayoutModule->pagestyleCO->addItem(qt_("headings"));
693 pageLayoutModule->pagestyleCO->addItem(qt_("fancy"));
694 bc().addCheckedLineEdit(pageLayoutModule->paperheightLE,
695 pageLayoutModule->paperheightL);
696 bc().addCheckedLineEdit(pageLayoutModule->paperwidthLE,
697 pageLayoutModule->paperwidthL);
700 QComboBox * cb = pageLayoutModule->papersizeCO;
701 cb->addItem(qt_("Default"));
702 cb->addItem(qt_("Custom"));
703 cb->addItem(qt_("US letter"));
704 cb->addItem(qt_("US legal"));
705 cb->addItem(qt_("US executive"));
706 cb->addItem(qt_("A3"));
707 cb->addItem(qt_("A4"));
708 cb->addItem(qt_("A5"));
709 cb->addItem(qt_("B3"));
710 cb->addItem(qt_("B4"));
711 cb->addItem(qt_("B5"));
712 // remove the %-items from the unit choice
713 pageLayoutModule->paperwidthUnitCO->noPercents();
714 pageLayoutModule->paperheightUnitCO->noPercents();
715 pageLayoutModule->paperheightLE->setValidator(unsignedLengthValidator(
716 pageLayoutModule->paperheightLE));
717 pageLayoutModule->paperwidthLE->setValidator(unsignedLengthValidator(
718 pageLayoutModule->paperwidthLE));
721 marginsModule = new UiWidget<Ui::MarginsUi>;
723 connect(marginsModule->marginCB, SIGNAL(toggled(bool)),
724 this, SLOT(setCustomMargins(bool)));
725 connect(marginsModule->marginCB, SIGNAL(clicked()),
726 this, SLOT(change_adaptor()));
727 connect(marginsModule->topLE, SIGNAL(textChanged(QString)),
728 this, SLOT(change_adaptor()));
729 connect(marginsModule->topUnit, SIGNAL(activated(int)),
730 this, SLOT(change_adaptor()));
731 connect(marginsModule->bottomLE, SIGNAL(textChanged(QString)),
732 this, SLOT(change_adaptor()));
733 connect(marginsModule->bottomUnit, SIGNAL(activated(int)),
734 this, SLOT(change_adaptor()));
735 connect(marginsModule->innerLE, SIGNAL(textChanged(QString)),
736 this, SLOT(change_adaptor()));
737 connect(marginsModule->innerUnit, SIGNAL(activated(int)),
738 this, SLOT(change_adaptor()));
739 connect(marginsModule->outerLE, SIGNAL(textChanged(QString)),
740 this, SLOT(change_adaptor()));
741 connect(marginsModule->outerUnit, SIGNAL(activated(int)),
742 this, SLOT(change_adaptor()));
743 connect(marginsModule->headheightLE, SIGNAL(textChanged(QString)),
744 this, SLOT(change_adaptor()));
745 connect(marginsModule->headheightUnit, SIGNAL(activated(int)),
746 this, SLOT(change_adaptor()));
747 connect(marginsModule->headsepLE, SIGNAL(textChanged(QString)),
748 this, SLOT(change_adaptor()));
749 connect(marginsModule->headsepUnit, SIGNAL(activated(int)),
750 this, SLOT(change_adaptor()));
751 connect(marginsModule->footskipLE, SIGNAL(textChanged(QString)),
752 this, SLOT(change_adaptor()));
753 connect(marginsModule->footskipUnit, SIGNAL(activated(int)),
754 this, SLOT(change_adaptor()));
755 connect(marginsModule->columnsepLE, SIGNAL(textChanged(QString)),
756 this, SLOT(change_adaptor()));
757 connect(marginsModule->columnsepUnit, SIGNAL(activated(int)),
758 this, SLOT(change_adaptor()));
759 marginsModule->topLE->setValidator(unsignedLengthValidator(
760 marginsModule->topLE));
761 marginsModule->bottomLE->setValidator(unsignedLengthValidator(
762 marginsModule->bottomLE));
763 marginsModule->innerLE->setValidator(unsignedLengthValidator(
764 marginsModule->innerLE));
765 marginsModule->outerLE->setValidator(unsignedLengthValidator(
766 marginsModule->outerLE));
767 marginsModule->headsepLE->setValidator(unsignedLengthValidator(
768 marginsModule->headsepLE));
769 marginsModule->headheightLE->setValidator(unsignedLengthValidator(
770 marginsModule->headheightLE));
771 marginsModule->footskipLE->setValidator(unsignedLengthValidator(
772 marginsModule->footskipLE));
773 marginsModule->columnsepLE->setValidator(unsignedLengthValidator(
774 marginsModule->columnsepLE));
776 bc().addCheckedLineEdit(marginsModule->topLE,
777 marginsModule->topL);
778 bc().addCheckedLineEdit(marginsModule->bottomLE,
779 marginsModule->bottomL);
780 bc().addCheckedLineEdit(marginsModule->innerLE,
781 marginsModule->innerL);
782 bc().addCheckedLineEdit(marginsModule->outerLE,
783 marginsModule->outerL);
784 bc().addCheckedLineEdit(marginsModule->headsepLE,
785 marginsModule->headsepL);
786 bc().addCheckedLineEdit(marginsModule->headheightLE,
787 marginsModule->headheightL);
788 bc().addCheckedLineEdit(marginsModule->footskipLE,
789 marginsModule->footskipL);
790 bc().addCheckedLineEdit(marginsModule->columnsepLE,
791 marginsModule->columnsepL);
794 langModule = new UiWidget<Ui::LanguageUi>;
796 connect(langModule->languageCO, SIGNAL(activated(int)),
797 this, SLOT(change_adaptor()));
798 connect(langModule->defaultencodingRB, SIGNAL(clicked()),
799 this, SLOT(change_adaptor()));
800 connect(langModule->otherencodingRB, SIGNAL(clicked()),
801 this, SLOT(change_adaptor()));
802 connect(langModule->encodingCO, SIGNAL(activated(int)),
803 this, SLOT(change_adaptor()));
804 connect(langModule->quoteStyleCO, SIGNAL(activated(int)),
805 this, SLOT(change_adaptor()));
807 QAbstractItemModel * language_model = guiApp->languageModel();
808 // FIXME: it would be nice if sorting was enabled/disabled via a checkbox.
809 language_model->sort(0);
810 langModule->languageCO->setModel(language_model);
812 // Always put the default encoding in the first position.
813 langModule->encodingCO->addItem(qt_("Language Default (no inputenc)"));
814 QStringList encodinglist;
815 Encodings::const_iterator it = encodings.begin();
816 Encodings::const_iterator const end = encodings.end();
817 for (; it != end; ++it)
818 encodinglist.append(qt_(it->guiName()));
820 langModule->encodingCO->addItems(encodinglist);
822 langModule->quoteStyleCO->addItem(qt_("``text''"));
823 langModule->quoteStyleCO->addItem(qt_("''text''"));
824 langModule->quoteStyleCO->addItem(qt_(",,text``"));
825 langModule->quoteStyleCO->addItem(qt_(",,text''"));
826 langModule->quoteStyleCO->addItem(qt_("<<text>>"));
827 langModule->quoteStyleCO->addItem(qt_(">>text<<"));
830 numberingModule = new UiWidget<Ui::NumberingUi>;
832 connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
833 this, SLOT(change_adaptor()));
834 connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
835 this, SLOT(change_adaptor()));
836 connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
837 this, SLOT(updateNumbering()));
838 connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
839 this, SLOT(updateNumbering()));
840 numberingModule->tocTW->setColumnCount(3);
841 numberingModule->tocTW->headerItem()->setText(0, qt_("Example"));
842 numberingModule->tocTW->headerItem()->setText(1, qt_("Numbered"));
843 numberingModule->tocTW->headerItem()->setText(2, qt_("Appears in TOC"));
846 biblioModule = new UiWidget<Ui::BiblioUi>;
847 connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
848 biblioModule->citationStyleL, SLOT(setEnabled(bool)));
849 connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
850 biblioModule->citeStyleCO, SLOT(setEnabled(bool)));
852 connect(biblioModule->citeDefaultRB, SIGNAL(clicked()),
853 this, SLOT(change_adaptor()));
854 connect(biblioModule->citeNatbibRB, SIGNAL(clicked()),
855 this, SLOT(change_adaptor()));
856 connect(biblioModule->citeStyleCO, SIGNAL(activated(int)),
857 this, SLOT(change_adaptor()));
858 connect(biblioModule->citeJurabibRB, SIGNAL(clicked()),
859 this, SLOT(change_adaptor()));
860 connect(biblioModule->bibtopicCB, SIGNAL(clicked()),
861 this, SLOT(change_adaptor()));
863 biblioModule->citeStyleCO->addItem(qt_("Author-year"));
864 biblioModule->citeStyleCO->addItem(qt_("Numerical"));
865 biblioModule->citeStyleCO->setCurrentIndex(0);
868 indicesModule = new GuiIndices;
869 connect(indicesModule, SIGNAL(changed()),
870 this, SLOT(change_adaptor()));
873 mathsModule = new UiWidget<Ui::MathsUi>;
874 connect(mathsModule->amsautoCB, SIGNAL(toggled(bool)),
875 mathsModule->amsCB, SLOT(setDisabled(bool)));
876 connect(mathsModule->esintautoCB, SIGNAL(toggled(bool)),
877 mathsModule->esintCB, SLOT(setDisabled(bool)));
879 connect(mathsModule->amsCB, SIGNAL(clicked()),
880 this, SLOT(change_adaptor()));
881 connect(mathsModule->amsautoCB, SIGNAL(clicked()),
882 this, SLOT(change_adaptor()));
883 connect(mathsModule->esintCB, SIGNAL(clicked()),
884 this, SLOT(change_adaptor()));
885 connect(mathsModule->esintautoCB, SIGNAL(clicked()),
886 this, SLOT(change_adaptor()));
888 latexModule = new UiWidget<Ui::LaTeXUi>;
890 connect(latexModule->optionsLE, SIGNAL(textChanged(QString)),
891 this, SLOT(change_adaptor()));
892 connect(latexModule->defaultOptionsCB, SIGNAL(clicked()),
893 this, SLOT(change_adaptor()));
894 connect(latexModule->psdriverCO, SIGNAL(activated(int)),
895 this, SLOT(change_adaptor()));
896 connect(latexModule->classCO, SIGNAL(activated(int)),
897 this, SLOT(classChanged()));
898 connect(latexModule->classCO, SIGNAL(activated(int)),
899 this, SLOT(change_adaptor()));
900 connect(latexModule->layoutPB, SIGNAL(clicked()),
901 this, SLOT(browseLayout()));
902 connect(latexModule->layoutPB, SIGNAL(clicked()),
903 this, SLOT(change_adaptor()));
904 connect(latexModule->childDocGB, SIGNAL(clicked()),
905 this, SLOT(change_adaptor()));
906 connect(latexModule->childDocLE, SIGNAL(textChanged(QString)),
907 this, SLOT(change_adaptor()));
908 connect(latexModule->childDocPB, SIGNAL(clicked()),
909 this, SLOT(browseMaster()));
911 // postscript drivers
912 for (int n = 0; tex_graphics[n][0]; ++n) {
913 QString enc = qt_(tex_graphics_gui[n]);
914 latexModule->psdriverCO->addItem(enc);
917 latexModule->classCO->setModel(&classes_model_);
918 LayoutFileList const & bcl = LayoutFileList::get();
919 vector<LayoutFileIndex> classList = bcl.classList();
920 sort(classList.begin(), classList.end(), less_textclass_avail_desc());
922 vector<LayoutFileIndex>::const_iterator cit = classList.begin();
923 vector<LayoutFileIndex>::const_iterator cen = classList.end();
924 for (int i = 0; cit != cen; ++cit, ++i) {
925 LayoutFile const & tc = bcl[*cit];
926 docstring item = (tc.isTeXClassAvailable()) ?
927 from_utf8(tc.description()) :
928 bformat(_("Unavailable: %1$s"), from_utf8(tc.description()));
929 classes_model_.insertRow(i, toqstr(item), *cit);
933 branchesModule = new GuiBranches;
934 connect(branchesModule, SIGNAL(changed()),
935 this, SLOT(change_adaptor()));
938 preambleModule = new PreambleModule;
939 connect(preambleModule, SIGNAL(changed()),
940 this, SLOT(change_adaptor()));
943 bulletsModule = new BulletsModule;
944 connect(bulletsModule, SIGNAL(changed()),
945 this, SLOT(change_adaptor()));
948 modulesModule = new UiWidget<Ui::ModulesUi>;
951 new ModuleSelectionManager(modulesModule->availableLV,
952 modulesModule->selectedLV,
953 modulesModule->addPB, modulesModule->deletePB,
954 modulesModule->upPB, modulesModule->downPB,
955 availableModel(), selectedModel(), this);
956 connect(selectionManager, SIGNAL(updateHook()),
957 this, SLOT(updateModuleInfo()));
958 connect(selectionManager, SIGNAL(updateHook()),
959 this, SLOT(change_adaptor()));
960 connect(selectionManager, SIGNAL(selectionChanged()),
961 this, SLOT(modulesChanged()));
964 pdfSupportModule = new UiWidget<Ui::PDFSupportUi>;
966 connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
967 this, SLOT(change_adaptor()));
968 connect(pdfSupportModule->titleLE, SIGNAL(textChanged(QString)),
969 this, SLOT(change_adaptor()));
970 connect(pdfSupportModule->authorLE, SIGNAL(textChanged(QString)),
971 this, SLOT(change_adaptor()));
972 connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(QString)),
973 this, SLOT(change_adaptor()));
974 connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(QString)),
975 this, SLOT(change_adaptor()));
976 connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
977 this, SLOT(change_adaptor()));
978 connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
979 this, SLOT(change_adaptor()));
980 connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
981 this, SLOT(change_adaptor()));
982 connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
983 this, SLOT(change_adaptor()));
984 connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
985 this, SLOT(change_adaptor()));
986 connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
987 this, SLOT(change_adaptor()));
988 connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
989 this, SLOT(change_adaptor()));
990 connect(pdfSupportModule->backrefCO, SIGNAL(activated(int)),
991 this, SLOT(change_adaptor()));
992 connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
993 this, SLOT(change_adaptor()));
994 connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
995 this, SLOT(change_adaptor()));
996 connect(pdfSupportModule->optionsLE, SIGNAL(textChanged(QString)),
997 this, SLOT(change_adaptor()));
999 for (int i = 0; backref_opts[i][0]; ++i)
1000 pdfSupportModule->backrefCO->addItem(qt_(backref_opts_gui[i]));
1003 floatModule = new FloatPlacement;
1004 connect(floatModule, SIGNAL(changed()),
1005 this, SLOT(change_adaptor()));
1007 docPS->addPanel(latexModule, qt_("Document Class"));
1008 docPS->addPanel(modulesModule, qt_("Modules"));
1009 docPS->addPanel(fontModule, qt_("Fonts"));
1010 docPS->addPanel(textLayoutModule, qt_("Text Layout"));
1011 docPS->addPanel(pageLayoutModule, qt_("Page Layout"));
1012 docPS->addPanel(marginsModule, qt_("Page Margins"));
1013 docPS->addPanel(langModule, qt_("Language"));
1014 docPS->addPanel(numberingModule, qt_("Numbering & TOC"));
1015 docPS->addPanel(biblioModule, qt_("Bibliography"));
1016 docPS->addPanel(indicesModule, qt_("Indexes"));
1017 docPS->addPanel(pdfSupportModule, qt_("PDF Properties"));
1018 docPS->addPanel(mathsModule, qt_("Math Options"));
1019 docPS->addPanel(floatModule, qt_("Float Placement"));
1020 docPS->addPanel(bulletsModule, qt_("Bullets"));
1021 docPS->addPanel(branchesModule, qt_("Branches"));
1022 docPS->addPanel(outputModule, qt_("Output"));
1023 docPS->addPanel(preambleModule, qt_("LaTeX Preamble"));
1024 docPS->setCurrentPanel(qt_("Document Class"));
1025 // FIXME: hack to work around resizing bug in Qt >= 4.2
1026 // bug verified with Qt 4.2.{0-3} (JSpitzm)
1027 #if QT_VERSION >= 0x040200
1028 docPS->updateGeometry();
1033 void GuiDocument::showPreamble()
1035 docPS->setCurrentPanel(qt_("LaTeX Preamble"));
1039 void GuiDocument::saveDefaultClicked()
1045 void GuiDocument::useDefaultsClicked()
1051 void GuiDocument::change_adaptor()
1057 QString GuiDocument::validateListingsParameters()
1059 // use a cache here to avoid repeated validation
1060 // of the same parameters
1061 static string param_cache;
1062 static QString msg_cache;
1064 if (textLayoutModule->bypassCB->isChecked())
1067 string params = fromqstr(textLayoutModule->listingsED->toPlainText());
1068 if (params != param_cache) {
1069 param_cache = params;
1070 msg_cache = toqstr(InsetListingsParams(params).validate());
1076 void GuiDocument::setListingsMessage()
1078 static bool isOK = true;
1079 QString msg = validateListingsParameters();
1080 if (msg.isEmpty()) {
1084 // listingsTB->setTextColor("black");
1085 textLayoutModule->listingsTB->setPlainText(
1086 qt_("Input listings parameters on the right. "
1087 "Enter ? for a list of parameters."));
1090 // listingsTB->setTextColor("red");
1091 textLayoutModule->listingsTB->setPlainText(msg);
1096 void GuiDocument::setLSpacing(int item)
1098 textLayoutModule->lspacingLE->setEnabled(item == 3);
1102 void GuiDocument::setSkip(int item)
1104 bool const enable = (item == 3);
1105 textLayoutModule->skipLE->setEnabled(enable);
1106 textLayoutModule->skipLengthCO->setEnabled(enable);
1110 void GuiDocument::enableSkip(bool skip)
1112 textLayoutModule->skipCO->setEnabled(skip);
1113 textLayoutModule->skipLE->setEnabled(skip);
1114 textLayoutModule->skipLengthCO->setEnabled(skip);
1116 setSkip(textLayoutModule->skipCO->currentIndex());
1120 void GuiDocument::portraitChanged()
1122 setMargins(pageLayoutModule->papersizeCO->currentIndex());
1126 void GuiDocument::setMargins(bool custom)
1128 bool const extern_geometry =
1129 documentClass().provides("geometry");
1130 marginsModule->marginCB->setEnabled(!extern_geometry);
1131 if (extern_geometry) {
1132 marginsModule->marginCB->setChecked(false);
1133 setCustomMargins(true);
1136 marginsModule->marginCB->setChecked(custom);
1137 setCustomMargins(custom);
1141 void GuiDocument::setCustomPapersize(int papersize)
1143 bool const custom = (papersize == 1);
1145 pageLayoutModule->paperwidthL->setEnabled(custom);
1146 pageLayoutModule->paperwidthLE->setEnabled(custom);
1147 pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
1148 pageLayoutModule->paperheightL->setEnabled(custom);
1149 pageLayoutModule->paperheightLE->setEnabled(custom);
1150 pageLayoutModule->paperheightLE->setFocus();
1151 pageLayoutModule->paperheightUnitCO->setEnabled(custom);
1155 void GuiDocument::setColSep()
1157 setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
1161 void GuiDocument::setCustomMargins(bool custom)
1163 marginsModule->topL->setEnabled(!custom);
1164 marginsModule->topLE->setEnabled(!custom);
1165 marginsModule->topUnit->setEnabled(!custom);
1167 marginsModule->bottomL->setEnabled(!custom);
1168 marginsModule->bottomLE->setEnabled(!custom);
1169 marginsModule->bottomUnit->setEnabled(!custom);
1171 marginsModule->innerL->setEnabled(!custom);
1172 marginsModule->innerLE->setEnabled(!custom);
1173 marginsModule->innerUnit->setEnabled(!custom);
1175 marginsModule->outerL->setEnabled(!custom);
1176 marginsModule->outerLE->setEnabled(!custom);
1177 marginsModule->outerUnit->setEnabled(!custom);
1179 marginsModule->headheightL->setEnabled(!custom);
1180 marginsModule->headheightLE->setEnabled(!custom);
1181 marginsModule->headheightUnit->setEnabled(!custom);
1183 marginsModule->headsepL->setEnabled(!custom);
1184 marginsModule->headsepLE->setEnabled(!custom);
1185 marginsModule->headsepUnit->setEnabled(!custom);
1187 marginsModule->footskipL->setEnabled(!custom);
1188 marginsModule->footskipLE->setEnabled(!custom);
1189 marginsModule->footskipUnit->setEnabled(!custom);
1191 bool const enableColSep = !custom &&
1192 textLayoutModule->twoColumnCB->checkState() == Qt::Checked;
1193 marginsModule->columnsepL->setEnabled(enableColSep);
1194 marginsModule->columnsepLE->setEnabled(enableColSep);
1195 marginsModule->columnsepUnit->setEnabled(enableColSep);
1198 void GuiDocument::changeBackgroundColor()
1200 QColor const & newColor = QColorDialog::getColor(
1201 rgb2qcolor(set_backgroundcolor), asQWidget());
1202 if (!newColor.isValid())
1204 // set the button color
1205 pageLayoutModule->backgroundPB->setStyleSheet(
1206 colorButtonStyleSheet(newColor));
1208 set_backgroundcolor = rgbFromHexName(fromqstr(newColor.name()));
1213 void GuiDocument::deleteBackgroundColor()
1215 // set the button color back to white
1216 pageLayoutModule->backgroundPB->setStyleSheet(
1217 colorButtonStyleSheet(QColor(Qt::white)));
1218 // save white as the set color
1219 set_backgroundcolor = rgbFromHexName("#ffffff");
1224 void GuiDocument::xetexChanged(bool xetex)
1227 updateDefaultFormat();
1228 langModule->encodingCO->setEnabled(!xetex &&
1229 !langModule->defaultencodingRB->isChecked());
1230 langModule->defaultencodingRB->setEnabled(!xetex);
1231 langModule->otherencodingRB->setEnabled(!xetex);
1233 fontModule->fontsDefaultCO->setEnabled(!xetex);
1234 fontModule->fontsDefaultLA->setEnabled(!xetex);
1235 fontModule->cjkFontLE->setEnabled(!xetex);
1236 fontModule->cjkFontLA->setEnabled(!xetex);
1239 font = tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1240 bool scaleable = providesScale(font);
1241 fontModule->scaleSansSB->setEnabled(scaleable);
1242 fontModule->scaleSansLA->setEnabled(scaleable);
1244 font = tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1245 scaleable = providesScale(font);
1246 fontModule->scaleTypewriterSB->setEnabled(scaleable);
1247 fontModule->scaleTypewriterLA->setEnabled(scaleable);
1249 font = tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1250 fontModule->fontScCB->setEnabled(providesSC(font));
1251 fontModule->fontOsfCB->setEnabled(providesOSF(font));
1255 void GuiDocument::updateFontsize(string const & items, string const & sel)
1257 fontModule->fontsizeCO->clear();
1258 fontModule->fontsizeCO->addItem(qt_("Default"));
1260 for (int n = 0; !token(items,'|',n).empty(); ++n)
1261 fontModule->fontsizeCO->
1262 addItem(toqstr(token(items,'|',n)));
1264 for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
1265 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
1266 fontModule->fontsizeCO->setCurrentIndex(n);
1273 void GuiDocument::updateFontlist()
1275 fontModule->fontsRomanCO->clear();
1276 fontModule->fontsSansCO->clear();
1277 fontModule->fontsTypewriterCO->clear();
1279 // With XeTeX, we have access to all system fonts, but not the LaTeX fonts
1280 if (outputModule->xetexCB->isChecked()) {
1281 fontModule->fontsRomanCO->addItem(qt_("Default"));
1282 fontModule->fontsSansCO->addItem(qt_("Default"));
1283 fontModule->fontsTypewriterCO->addItem(qt_("Default"));
1285 QFontDatabase fontdb;
1286 QStringList families(fontdb.families());
1287 for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
1288 fontModule->fontsRomanCO->addItem(*it);
1289 fontModule->fontsSansCO->addItem(*it);
1290 fontModule->fontsTypewriterCO->addItem(*it);
1295 for (int n = 0; tex_fonts_roman[n][0]; ++n) {
1296 QString font = qt_(tex_fonts_roman_gui[n]);
1297 if (!isFontAvailable(tex_fonts_roman[n]))
1298 font += qt_(" (not installed)");
1299 fontModule->fontsRomanCO->addItem(font);
1301 for (int n = 0; tex_fonts_sans[n][0]; ++n) {
1302 QString font = qt_(tex_fonts_sans_gui[n]);
1303 if (!isFontAvailable(tex_fonts_sans[n]))
1304 font += qt_(" (not installed)");
1305 fontModule->fontsSansCO->addItem(font);
1307 for (int n = 0; tex_fonts_monospaced[n][0]; ++n) {
1308 QString font = qt_(tex_fonts_monospaced_gui[n]);
1309 if (!isFontAvailable(tex_fonts_monospaced[n]))
1310 font += qt_(" (not installed)");
1311 fontModule->fontsTypewriterCO->addItem(font);
1316 void GuiDocument::romanChanged(int item)
1318 if (outputModule->xetexCB->isChecked())
1320 string const font = tex_fonts_roman[item];
1321 fontModule->fontScCB->setEnabled(providesSC(font));
1322 fontModule->fontOsfCB->setEnabled(providesOSF(font));
1326 void GuiDocument::sansChanged(int item)
1328 if (outputModule->xetexCB->isChecked())
1330 string const font = tex_fonts_sans[item];
1331 bool scaleable = providesScale(font);
1332 fontModule->scaleSansSB->setEnabled(scaleable);
1333 fontModule->scaleSansLA->setEnabled(scaleable);
1337 void GuiDocument::ttChanged(int item)
1339 if (outputModule->xetexCB->isChecked())
1341 string const font = tex_fonts_monospaced[item];
1342 bool scaleable = providesScale(font);
1343 fontModule->scaleTypewriterSB->setEnabled(scaleable);
1344 fontModule->scaleTypewriterLA->setEnabled(scaleable);
1348 void GuiDocument::updatePagestyle(string const & items, string const & sel)
1351 pageLayoutModule->pagestyleCO->clear();
1352 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1354 for (int n = 0; !token(items, '|', n).empty(); ++n) {
1355 string style = token(items, '|', n);
1356 QString style_gui = qt_(style);
1357 pagestyles.push_back(pair<string, QString>(style, style_gui));
1358 pageLayoutModule->pagestyleCO->addItem(style_gui);
1361 if (sel == "default") {
1362 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
1368 for (size_t i = 0; i < pagestyles.size(); ++i)
1369 if (pagestyles[i].first == sel)
1370 nn = pageLayoutModule->pagestyleCO->findText(pagestyles[i].second);
1373 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
1377 void GuiDocument::browseLayout()
1379 QString const label1 = qt_("Layouts|#o#O");
1380 QString const dir1 = toqstr(lyxrc.document_path);
1381 QStringList const filter(qt_("LyX Layout (*.layout)"));
1382 QString file = browseRelFile(QString(), bufferFilepath(),
1383 qt_("Local layout file"), filter, false,
1386 if (!file.endsWith(".layout"))
1389 FileName layoutFile = support::makeAbsPath(fromqstr(file),
1390 fromqstr(bufferFilepath()));
1392 int const ret = Alert::prompt(_("Local layout file"),
1393 _("The layout file you have selected is a local layout\n"
1394 "file, not one in the system or user directory. Your\n"
1395 "document may not work with this layout if you do not\n"
1396 "keep the layout file in the document directory."),
1397 1, 1, _("&Set Layout"), _("&Cancel"));
1401 // load the layout file
1402 LayoutFileList & bcl = LayoutFileList::get();
1403 string classname = layoutFile.onlyFileName();
1404 // this will update an existing layout if that layout has been loaded before.
1405 LayoutFileIndex name = bcl.addLocalLayout(
1406 classname.substr(0, classname.size() - 7),
1407 layoutFile.onlyPath().absFilename());
1410 Alert::error(_("Error"),
1411 _("Unable to read local layout file."));
1415 // do not trigger classChanged if there is no change.
1416 if (latexModule->classCO->currentText() == toqstr(name))
1420 int idx = latexModule->classCO->findText(toqstr(name));
1422 classes_model_.insertRow(0, toqstr(name), name);
1423 latexModule->classCO->setCurrentIndex(0);
1425 latexModule->classCO->setCurrentIndex(idx);
1431 void GuiDocument::browseMaster()
1433 QString const title = qt_("Select master document");
1434 QString const dir1 = toqstr(lyxrc.document_path);
1435 QString const old = latexModule->childDocLE->text();
1436 QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
1437 QStringList const filter(qt_("LyX Files (*.lyx)"));
1438 QString file = browseRelFile(old, docpath, title, filter, false,
1439 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
1441 latexModule->childDocLE->setText(file);
1445 void GuiDocument::classChanged()
1447 int idx = latexModule->classCO->currentIndex();
1450 string const classname = classes_model_.getIDString(idx);
1452 // check whether the selected modules have changed.
1453 bool modules_changed = false;
1454 unsigned int const srows = selectedModel()->rowCount();
1455 if (srows != bp_.getModules().size())
1456 modules_changed = true;
1458 list<string>::const_iterator mit = bp_.getModules().begin();
1459 list<string>::const_iterator men = bp_.getModules().end();
1460 for (unsigned int i = 0; i < srows && mit != men; ++i, ++mit)
1461 if (selectedModel()->getIDString(i) != *mit) {
1462 modules_changed = true;
1467 if (modules_changed || lyxrc.auto_reset_options) {
1468 if (applyPB->isEnabled()) {
1469 int const ret = Alert::prompt(_("Unapplied changes"),
1470 _("Some changes in the dialog were not yet applied.\n"
1471 "If you do not apply now, they will be lost after this action."),
1472 1, 1, _("&Apply"), _("&Dismiss"));
1478 // We load the TextClass as soon as it is selected. This is
1479 // necessary so that other options in the dialog can be updated
1480 // according to the new class. Note, however, that, if you use
1481 // the scroll wheel when sitting on the combo box, we'll load a
1482 // lot of TextClass objects very quickly....
1483 if (!bp_.setBaseClass(classname)) {
1484 Alert::error(_("Error"), _("Unable to set document class."));
1487 if (lyxrc.auto_reset_options)
1488 bp_.useClassDefaults();
1490 // With the introduction of modules came a distinction between the base
1491 // class and the document class. The former corresponds to the main layout
1492 // file; the latter is that plus the modules (or the document-specific layout,
1493 // or whatever else there could be). Our parameters come from the document
1494 // class. So when we set the base class, we also need to recreate the document
1495 // class. Otherwise, we still have the old one.
1496 bp_.makeDocumentClass();
1502 // This is an insanely complicated attempt to make this sort of thing
1503 // work with RTL languages.
1504 docstring formatStrVec(vector<string> const & v, docstring const & s)
1506 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
1510 return from_utf8(v[0]);
1511 if (v.size() == 2) {
1512 docstring retval = _("%1$s and %2$s");
1513 retval = subst(retval, _("and"), s);
1514 return bformat(retval, from_utf8(v[0]), from_utf8(v[1]));
1516 // The idea here is to format all but the last two items...
1517 int const vSize = v.size();
1518 docstring t2 = _("%1$s, %2$s");
1519 docstring retval = from_utf8(v[0]);
1520 for (int i = 1; i < vSize - 2; ++i)
1521 retval = bformat(t2, retval, from_utf8(v[i]));
1522 //...and then to plug them, and the last two, into this schema
1523 docstring t = _("%1$s, %2$s, and %3$s");
1524 t = subst(t, _("and"), s);
1525 return bformat(t, retval, from_utf8(v[vSize - 2]), from_utf8(v[vSize - 1]));
1528 vector<string> idsToNames(vector<string> const & idList)
1530 vector<string> retval;
1531 vector<string>::const_iterator it = idList.begin();
1532 vector<string>::const_iterator end = idList.end();
1533 for (; it != end; ++it) {
1534 LyXModule const * const mod = moduleList[*it];
1536 retval.push_back(*it + " (Unavailable)");
1538 retval.push_back(mod->getName());
1545 void GuiDocument::modulesToParams(BufferParams & bp)
1547 // update list of loaded modules
1548 bp.clearLayoutModules();
1549 int const srows = modules_sel_model_.rowCount();
1550 for (int i = 0; i < srows; ++i)
1551 bp.addLayoutModule(modules_sel_model_.getIDString(i));
1553 // update the list of removed modules
1554 bp.clearRemovedModules();
1555 LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
1556 list<string>::const_iterator rit = reqmods.begin();
1557 list<string>::const_iterator ren = reqmods.end();
1559 // check each of the default modules
1560 for (; rit != ren; rit++) {
1561 list<string>::const_iterator mit = bp.getModules().begin();
1562 list<string>::const_iterator men = bp.getModules().end();
1564 for (; mit != men; mit++) {
1571 // the module isn't present so must have been removed by the user
1572 bp.addRemovedModule(*rit);
1577 void GuiDocument::modulesChanged()
1579 modulesToParams(bp_);
1580 bp_.makeDocumentClass();
1585 void GuiDocument::updateModuleInfo()
1587 selectionManager->update();
1589 //Module description
1590 bool const focus_on_selected = selectionManager->selectedFocused();
1591 QListView const * const lv =
1592 focus_on_selected ? modulesModule->selectedLV : modulesModule->availableLV;
1593 if (lv->selectionModel()->selectedIndexes().isEmpty()) {
1594 modulesModule->infoML->document()->clear();
1597 QModelIndex const & idx = lv->selectionModel()->currentIndex();
1598 GuiIdListModel const & id_model =
1599 focus_on_selected ? modules_sel_model_ : modules_av_model_;
1600 string const modName = id_model.getIDString(idx.row());
1601 docstring desc = getModuleDescription(modName);
1603 LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
1604 if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
1607 desc += _("Module provided by document class.");
1610 vector<string> pkglist = getPackageList(modName);
1611 docstring pkgdesc = formatStrVec(pkglist, _("and"));
1612 if (!pkgdesc.empty()) {
1615 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
1618 pkglist = getRequiredList(modName);
1619 if (!pkglist.empty()) {
1620 vector<string> const reqdescs = idsToNames(pkglist);
1621 pkgdesc = formatStrVec(reqdescs, _("or"));
1624 desc += bformat(_("Module required: %1$s."), pkgdesc);
1627 pkglist = getExcludedList(modName);
1628 if (!pkglist.empty()) {
1629 vector<string> const reqdescs = idsToNames(pkglist);
1630 pkgdesc = formatStrVec(reqdescs, _( "and"));
1633 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
1636 if (!isModuleAvailable(modName)) {
1639 desc += _("WARNING: Some required packages are unavailable!");
1642 modulesModule->infoML->document()->setPlainText(toqstr(desc));
1646 void GuiDocument::updateNumbering()
1648 DocumentClass const & tclass = documentClass();
1650 numberingModule->tocTW->setUpdatesEnabled(false);
1651 numberingModule->tocTW->clear();
1653 int const depth = numberingModule->depthSL->value();
1654 int const toc = numberingModule->tocSL->value();
1655 QString const no = qt_("No");
1656 QString const yes = qt_("Yes");
1657 QTreeWidgetItem * item = 0;
1659 DocumentClass::const_iterator lit = tclass.begin();
1660 DocumentClass::const_iterator len = tclass.end();
1661 for (; lit != len; ++lit) {
1662 int const toclevel = lit->toclevel;
1663 if (toclevel != Layout::NOT_IN_TOC && lit->labeltype == LABEL_COUNTER) {
1664 item = new QTreeWidgetItem(numberingModule->tocTW);
1665 item->setText(0, toqstr(translateIfPossible(lit->name())));
1666 item->setText(1, (toclevel <= depth) ? yes : no);
1667 item->setText(2, (toclevel <= toc) ? yes : no);
1671 numberingModule->tocTW->setUpdatesEnabled(true);
1672 numberingModule->tocTW->update();
1676 void GuiDocument::updateDefaultFormat()
1678 // make a copy in order to consider unapplied changes
1679 Buffer * tmpbuf = const_cast<Buffer *>(&buffer());
1680 tmpbuf->params().useXetex = outputModule->xetexCB->isChecked();
1681 int idx = latexModule->classCO->currentIndex();
1683 string const classname = classes_model_.getIDString(idx);
1684 tmpbuf->params().setBaseClass(classname);
1685 tmpbuf->params().makeDocumentClass();
1687 outputModule->defaultFormatCO->blockSignals(true);
1688 outputModule->defaultFormatCO->clear();
1689 outputModule->defaultFormatCO->addItem(qt_("Default"),
1690 QVariant(QString("default")));
1691 typedef vector<Format const *> Formats;
1692 Formats formats = tmpbuf->exportableFormats(true);
1693 Formats::const_iterator cit = formats.begin();
1694 Formats::const_iterator end = formats.end();
1695 for (; cit != end; ++cit)
1696 outputModule->defaultFormatCO->addItem(qt_((*cit)->prettyname()),
1697 QVariant(toqstr((*cit)->name())));
1698 outputModule->defaultFormatCO->blockSignals(false);
1702 void GuiDocument::applyView()
1705 preambleModule->apply(bp_);
1708 bp_.setCiteEngine(ENGINE_BASIC);
1710 if (biblioModule->citeNatbibRB->isChecked()) {
1711 bool const use_numerical_citations =
1712 biblioModule->citeStyleCO->currentIndex();
1713 if (use_numerical_citations)
1714 bp_.setCiteEngine(ENGINE_NATBIB_NUMERICAL);
1716 bp_.setCiteEngine(ENGINE_NATBIB_AUTHORYEAR);
1718 } else if (biblioModule->citeJurabibRB->isChecked())
1719 bp_.setCiteEngine(ENGINE_JURABIB);
1722 biblioModule->bibtopicCB->isChecked();
1725 indicesModule->apply(bp_);
1727 // language & quotes
1728 if (langModule->defaultencodingRB->isChecked()) {
1729 bp_.inputenc = "auto";
1731 int i = langModule->encodingCO->currentIndex();
1733 bp_.inputenc = "default";
1735 QString const enc_gui =
1736 langModule->encodingCO->currentText();
1737 Encodings::const_iterator it = encodings.begin();
1738 Encodings::const_iterator const end = encodings.end();
1740 for (; it != end; ++it) {
1741 if (qt_(it->guiName()) == enc_gui) {
1742 bp_.inputenc = it->latexName();
1748 // should not happen
1749 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
1750 bp_.inputenc = "default";
1755 InsetQuotes::QuoteLanguage lga = InsetQuotes::EnglishQuotes;
1756 switch (langModule->quoteStyleCO->currentIndex()) {
1758 lga = InsetQuotes::EnglishQuotes;
1761 lga = InsetQuotes::SwedishQuotes;
1764 lga = InsetQuotes::GermanQuotes;
1767 lga = InsetQuotes::PolishQuotes;
1770 lga = InsetQuotes::FrenchQuotes;
1773 lga = InsetQuotes::DanishQuotes;
1776 bp_.quotes_language = lga;
1778 QString const lang = langModule->languageCO->itemData(
1779 langModule->languageCO->currentIndex()).toString();
1780 bp_.language = languages.getLanguage(fromqstr(lang));
1783 if (bp_.documentClass().hasTocLevels()) {
1784 bp_.tocdepth = numberingModule->tocSL->value();
1785 bp_.secnumdepth = numberingModule->depthSL->value();
1789 bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
1790 bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
1791 bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
1792 bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
1795 bp_.graphicsDriver =
1796 tex_graphics[latexModule->psdriverCO->currentIndex()];
1799 int idx = latexModule->classCO->currentIndex();
1801 string const classname = classes_model_.getIDString(idx);
1802 bp_.setBaseClass(classname);
1806 modulesToParams(bp_);
1808 if (mathsModule->amsautoCB->isChecked()) {
1809 bp_.use_amsmath = BufferParams::package_auto;
1811 if (mathsModule->amsCB->isChecked())
1812 bp_.use_amsmath = BufferParams::package_on;
1814 bp_.use_amsmath = BufferParams::package_off;
1817 if (mathsModule->esintautoCB->isChecked())
1818 bp_.use_esint = BufferParams::package_auto;
1820 if (mathsModule->esintCB->isChecked())
1821 bp_.use_esint = BufferParams::package_on;
1823 bp_.use_esint = BufferParams::package_off;
1826 if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
1827 bp_.pagestyle = "default";
1829 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
1830 for (size_t i = 0; i != pagestyles.size(); ++i)
1831 if (pagestyles[i].second == style_gui)
1832 bp_.pagestyle = pagestyles[i].first;
1835 switch (textLayoutModule->lspacingCO->currentIndex()) {
1837 bp_.spacing().set(Spacing::Single);
1840 bp_.spacing().set(Spacing::Onehalf);
1843 bp_.spacing().set(Spacing::Double);
1846 bp_.spacing().set(Spacing::Other,
1847 fromqstr(textLayoutModule->lspacingLE->text()));
1851 if (textLayoutModule->twoColumnCB->isChecked())
1856 // text should have passed validation
1857 bp_.listings_params =
1858 InsetListingsParams(fromqstr(textLayoutModule->listingsED->toPlainText())).params();
1860 if (textLayoutModule->indentRB->isChecked())
1861 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
1863 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
1865 switch (textLayoutModule->skipCO->currentIndex()) {
1867 bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
1870 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
1873 bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
1878 widgetsToLength(textLayoutModule->skipLE,
1879 textLayoutModule->skipLengthCO)
1885 // DocumentDefskipCB assures that this never happens
1886 // so Assert then !!! - jbl
1887 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
1892 fromqstr(latexModule->optionsLE->text());
1894 bp_.use_default_options =
1895 latexModule->defaultOptionsCB->isChecked();
1897 if (latexModule->childDocGB->isChecked())
1899 fromqstr(latexModule->childDocLE->text());
1901 bp_.master = string();
1903 bp_.float_placement = floatModule->get();
1906 bp_.defaultOutputFormat = fromqstr(outputModule->defaultFormatCO->itemData(
1907 outputModule->defaultFormatCO->currentIndex()).toString());
1909 bool const xetex = outputModule->xetexCB->isChecked();
1910 bp_.useXetex = xetex;
1914 if (fontModule->fontsRomanCO->currentIndex() == 0)
1915 bp_.fontsRoman = "default";
1918 fromqstr(fontModule->fontsRomanCO->currentText());
1920 if (fontModule->fontsSansCO->currentIndex() == 0)
1921 bp_.fontsSans = "default";
1924 fromqstr(fontModule->fontsSansCO->currentText());
1926 if (fontModule->fontsTypewriterCO->currentIndex() == 0)
1927 bp_.fontsTypewriter = "default";
1929 bp_.fontsTypewriter =
1930 fromqstr(fontModule->fontsTypewriterCO->currentText());
1933 tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1936 tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1938 bp_.fontsTypewriter =
1939 tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1943 fromqstr(fontModule->cjkFontLE->text());
1945 bp_.fontsSansScale = fontModule->scaleSansSB->value();
1947 bp_.fontsTypewriterScale = fontModule->scaleTypewriterSB->value();
1949 bp_.fontsSC = fontModule->fontScCB->isChecked();
1951 bp_.fontsOSF = fontModule->fontOsfCB->isChecked();
1954 bp_.fontsDefaultFamily = "default";
1956 bp_.fontsDefaultFamily = GuiDocument::fontfamilies[
1957 fontModule->fontsDefaultCO->currentIndex()];
1959 if (fontModule->fontsizeCO->currentIndex() == 0)
1960 bp_.fontsize = "default";
1963 fromqstr(fontModule->fontsizeCO->currentText());
1966 bp_.papersize = PAPER_SIZE(
1967 pageLayoutModule->papersizeCO->currentIndex());
1969 // custom, A3, B3 and B4 paper sizes need geometry
1970 int psize = pageLayoutModule->papersizeCO->currentIndex();
1971 bool geom_papersize = (psize == 1 || psize == 5 || psize == 8 || psize == 9);
1973 bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
1974 pageLayoutModule->paperwidthUnitCO);
1976 bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
1977 pageLayoutModule->paperheightUnitCO);
1979 if (pageLayoutModule->facingPagesCB->isChecked())
1980 bp_.sides = TwoSides;
1982 bp_.sides = OneSide;
1984 if (pageLayoutModule->landscapeRB->isChecked())
1985 bp_.orientation = ORIENTATION_LANDSCAPE;
1987 bp_.orientation = ORIENTATION_PORTRAIT;
1989 bp_.backgroundcolor = set_backgroundcolor;
1992 bp_.use_geometry = !marginsModule->marginCB->isChecked()
1995 Ui::MarginsUi const * m = marginsModule;
1997 bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
1998 bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
1999 bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
2000 bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
2001 bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
2002 bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
2003 bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
2004 bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
2006 branchesModule->apply(bp_);
2009 PDFOptions & pdf = bp_.pdfoptions();
2010 pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
2011 pdf.title = fromqstr(pdfSupportModule->titleLE->text());
2012 pdf.author = fromqstr(pdfSupportModule->authorLE->text());
2013 pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
2014 pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
2016 pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
2017 pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
2018 pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
2019 pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
2021 pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
2022 pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
2023 pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
2024 pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
2026 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
2027 if (pdfSupportModule->fullscreenCB->isChecked())
2028 pdf.pagemode = pdf.pagemode_fullscreen;
2030 pdf.pagemode.clear();
2031 pdf.quoted_options = pdf.quoted_options_check(
2032 fromqstr(pdfSupportModule->optionsLE->text()));
2036 void GuiDocument::paramsToDialog()
2038 // set the default unit
2039 Length::UNIT const defaultUnit = Length::defaultUnit();
2042 preambleModule->update(bp_, id());
2045 biblioModule->citeDefaultRB->setChecked(
2046 bp_.citeEngine() == ENGINE_BASIC);
2048 biblioModule->citeNatbibRB->setChecked(
2049 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL ||
2050 bp_.citeEngine() == ENGINE_NATBIB_AUTHORYEAR);
2052 biblioModule->citeStyleCO->setCurrentIndex(
2053 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL);
2055 biblioModule->citeJurabibRB->setChecked(
2056 bp_.citeEngine() == ENGINE_JURABIB);
2058 biblioModule->bibtopicCB->setChecked(
2062 indicesModule->update(bp_);
2064 // language & quotes
2065 int const pos = langModule->languageCO->findData(toqstr(
2066 bp_.language->lang()));
2067 langModule->languageCO->setCurrentIndex(pos);
2069 langModule->quoteStyleCO->setCurrentIndex(
2070 bp_.quotes_language);
2072 bool default_enc = true;
2073 if (bp_.inputenc != "auto") {
2074 default_enc = false;
2075 if (bp_.inputenc == "default") {
2076 langModule->encodingCO->setCurrentIndex(0);
2079 Encodings::const_iterator it = encodings.begin();
2080 Encodings::const_iterator const end = encodings.end();
2081 for (; it != end; ++it) {
2082 if (it->latexName() == bp_.inputenc) {
2083 enc_gui = it->guiName();
2087 int const i = langModule->encodingCO->findText(
2090 langModule->encodingCO->setCurrentIndex(i);
2092 // unknown encoding. Set to default.
2096 langModule->defaultencodingRB->setChecked(default_enc);
2097 langModule->otherencodingRB->setChecked(!default_enc);
2100 int const min_toclevel = documentClass().min_toclevel();
2101 int const max_toclevel = documentClass().max_toclevel();
2102 if (documentClass().hasTocLevels()) {
2103 numberingModule->setEnabled(true);
2104 numberingModule->depthSL->setMinimum(min_toclevel - 1);
2105 numberingModule->depthSL->setMaximum(max_toclevel);
2106 numberingModule->depthSL->setValue(bp_.secnumdepth);
2107 numberingModule->tocSL->setMaximum(min_toclevel - 1);
2108 numberingModule->tocSL->setMaximum(max_toclevel);
2109 numberingModule->tocSL->setValue(bp_.tocdepth);
2112 numberingModule->setEnabled(false);
2113 numberingModule->tocTW->clear();
2117 bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
2118 bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
2119 bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
2120 bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
2121 bulletsModule->init();
2124 int nitem = findToken(tex_graphics, bp_.graphicsDriver);
2126 latexModule->psdriverCO->setCurrentIndex(nitem);
2129 mathsModule->amsCB->setChecked(
2130 bp_.use_amsmath == BufferParams::package_on);
2131 mathsModule->amsautoCB->setChecked(
2132 bp_.use_amsmath == BufferParams::package_auto);
2134 mathsModule->esintCB->setChecked(
2135 bp_.use_esint == BufferParams::package_on);
2136 mathsModule->esintautoCB->setChecked(
2137 bp_.use_esint == BufferParams::package_auto);
2139 switch (bp_.spacing().getSpace()) {
2140 case Spacing::Other: nitem = 3; break;
2141 case Spacing::Double: nitem = 2; break;
2142 case Spacing::Onehalf: nitem = 1; break;
2143 case Spacing::Default: case Spacing::Single: nitem = 0; break;
2147 string const & layoutID = bp_.baseClassID();
2148 setLayoutComboByIDString(layoutID);
2150 updatePagestyle(documentClass().opt_pagestyle(),
2153 textLayoutModule->lspacingCO->setCurrentIndex(nitem);
2154 if (bp_.spacing().getSpace() == Spacing::Other) {
2155 textLayoutModule->lspacingLE->setText(
2156 toqstr(bp_.spacing().getValueAsString()));
2160 if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation)
2161 textLayoutModule->indentRB->setChecked(true);
2163 textLayoutModule->skipRB->setChecked(true);
2166 switch (bp_.getDefSkip().kind()) {
2167 case VSpace::SMALLSKIP:
2170 case VSpace::MEDSKIP:
2173 case VSpace::BIGSKIP:
2176 case VSpace::LENGTH:
2179 string const length = bp_.getDefSkip().asLyXCommand();
2180 lengthToWidgets(textLayoutModule->skipLE,
2181 textLayoutModule->skipLengthCO,
2182 length, defaultUnit);
2189 textLayoutModule->skipCO->setCurrentIndex(skip);
2192 textLayoutModule->twoColumnCB->setChecked(
2195 // break listings_params to multiple lines
2197 InsetListingsParams(bp_.listings_params).separatedParams();
2198 textLayoutModule->listingsED->setPlainText(toqstr(lstparams));
2200 if (!bp_.options.empty()) {
2201 latexModule->optionsLE->setText(
2202 toqstr(bp_.options));
2204 latexModule->optionsLE->setText(QString());
2208 latexModule->defaultOptionsCB->setChecked(
2209 bp_.use_default_options);
2210 updateSelectedModules();
2211 selectionManager->updateProvidedModules(
2212 bp_.baseClass()->providedModules());
2213 selectionManager->updateExcludedModules(
2214 bp_.baseClass()->excludedModules());
2216 if (!documentClass().options().empty()) {
2217 latexModule->defaultOptionsLE->setText(
2218 toqstr(documentClass().options()));
2220 latexModule->defaultOptionsLE->setText(
2221 toqstr(_("[No options predefined]")));
2224 latexModule->defaultOptionsLE->setEnabled(
2225 bp_.use_default_options
2226 && !documentClass().options().empty());
2228 latexModule->defaultOptionsCB->setEnabled(
2229 !documentClass().options().empty());
2231 if (!bp_.master.empty()) {
2232 latexModule->childDocGB->setChecked(true);
2233 latexModule->childDocLE->setText(
2234 toqstr(bp_.master));
2236 latexModule->childDocLE->setText(QString());
2237 latexModule->childDocGB->setChecked(false);
2240 floatModule->set(bp_.float_placement);
2243 // update combobox with formats
2244 updateDefaultFormat();
2245 int index = outputModule->defaultFormatCO->findData(toqstr(
2246 bp_.defaultOutputFormat));
2247 // set to default if format is not found
2250 outputModule->defaultFormatCO->setCurrentIndex(index);
2251 outputModule->xetexCB->setEnabled(bp_.baseClass()->outputType() == lyx::LATEX);
2252 outputModule->xetexCB->setChecked(
2253 bp_.baseClass()->outputType() == lyx::LATEX && bp_.useXetex);
2256 updateFontsize(documentClass().opt_fontsize(),
2260 for (int i = 0; i < fontModule->fontsRomanCO->count(); ++i) {
2261 if (fontModule->fontsRomanCO->itemText(i) == toqstr(bp_.fontsRoman)) {
2262 fontModule->fontsRomanCO->setCurrentIndex(i);
2267 for (int i = 0; i < fontModule->fontsSansCO->count(); ++i) {
2268 if (fontModule->fontsSansCO->itemText(i) == toqstr(bp_.fontsSans)) {
2269 fontModule->fontsSansCO->setCurrentIndex(i);
2273 for (int i = 0; i < fontModule->fontsTypewriterCO->count(); ++i) {
2274 if (fontModule->fontsTypewriterCO->itemText(i) ==
2275 toqstr(bp_.fontsTypewriter)) {
2276 fontModule->fontsTypewriterCO->setCurrentIndex(i);
2281 int n = findToken(tex_fonts_roman, bp_.fontsRoman);
2283 fontModule->fontsRomanCO->setCurrentIndex(n);
2287 n = findToken(tex_fonts_sans, bp_.fontsSans);
2289 fontModule->fontsSansCO->setCurrentIndex(n);
2293 n = findToken(tex_fonts_monospaced, bp_.fontsTypewriter);
2295 fontModule->fontsTypewriterCO->setCurrentIndex(n);
2300 if (!bp_.fontsCJK.empty())
2301 fontModule->cjkFontLE->setText(
2302 toqstr(bp_.fontsCJK));
2304 fontModule->cjkFontLE->setText(QString());
2306 fontModule->fontScCB->setChecked(bp_.fontsSC);
2307 fontModule->fontOsfCB->setChecked(bp_.fontsOSF);
2308 fontModule->scaleSansSB->setValue(bp_.fontsSansScale);
2309 fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale);
2311 int nn = findToken(GuiDocument::fontfamilies, bp_.fontsDefaultFamily);
2313 fontModule->fontsDefaultCO->setCurrentIndex(nn);
2316 bool const extern_geometry =
2317 documentClass().provides("geometry");
2318 int const psize = bp_.papersize;
2319 pageLayoutModule->papersizeCO->setCurrentIndex(psize);
2320 setCustomPapersize(!extern_geometry && psize);
2321 pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
2323 bool const landscape =
2324 bp_.orientation == ORIENTATION_LANDSCAPE;
2325 pageLayoutModule->landscapeRB->setChecked(landscape);
2326 pageLayoutModule->portraitRB->setChecked(!landscape);
2327 pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
2328 pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
2330 pageLayoutModule->facingPagesCB->setChecked(
2331 bp_.sides == TwoSides);
2333 pageLayoutModule->backgroundPB->setStyleSheet(
2334 colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
2335 set_backgroundcolor = bp_.backgroundcolor;
2337 lengthToWidgets(pageLayoutModule->paperwidthLE,
2338 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, defaultUnit);
2339 lengthToWidgets(pageLayoutModule->paperheightLE,
2340 pageLayoutModule->paperheightUnitCO, bp_.paperheight, defaultUnit);
2343 Ui::MarginsUi * m = marginsModule;
2345 setMargins(!bp_.use_geometry);
2347 lengthToWidgets(m->topLE, m->topUnit,
2348 bp_.topmargin, defaultUnit);
2350 lengthToWidgets(m->bottomLE, m->bottomUnit,
2351 bp_.bottommargin, defaultUnit);
2353 lengthToWidgets(m->innerLE, m->innerUnit,
2354 bp_.leftmargin, defaultUnit);
2356 lengthToWidgets(m->outerLE, m->outerUnit,
2357 bp_.rightmargin, defaultUnit);
2359 lengthToWidgets(m->headheightLE, m->headheightUnit,
2360 bp_.headheight, defaultUnit);
2362 lengthToWidgets(m->headsepLE, m->headsepUnit,
2363 bp_.headsep, defaultUnit);
2365 lengthToWidgets(m->footskipLE, m->footskipUnit,
2366 bp_.footskip, defaultUnit);
2368 lengthToWidgets(m->columnsepLE, m->columnsepUnit,
2369 bp_.columnsep, defaultUnit);
2371 branchesModule->update(bp_);
2374 PDFOptions const & pdf = bp_.pdfoptions();
2375 pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
2376 pdfSupportModule->titleLE->setText(toqstr(pdf.title));
2377 pdfSupportModule->authorLE->setText(toqstr(pdf.author));
2378 pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
2379 pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
2381 pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
2382 pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
2383 pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
2385 pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
2387 pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
2388 pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
2389 pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
2390 pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
2392 nn = findToken(backref_opts, pdf.backref);
2394 pdfSupportModule->backrefCO->setCurrentIndex(nn);
2396 pdfSupportModule->fullscreenCB->setChecked
2397 (pdf.pagemode == pdf.pagemode_fullscreen);
2399 pdfSupportModule->optionsLE->setText(
2400 toqstr(pdf.quoted_options));
2402 // Make sure that the bc is in the INITIAL state
2403 if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
2408 void GuiDocument::saveDocDefault()
2410 // we have to apply the params first
2416 void GuiDocument::updateAvailableModules()
2418 modules_av_model_.clear();
2419 list<modInfoStruct> const & modInfoList = getModuleInfo();
2420 list<modInfoStruct>::const_iterator mit = modInfoList.begin();
2421 list<modInfoStruct>::const_iterator men = modInfoList.end();
2422 for (int i = 0; mit != men; ++mit, ++i)
2423 modules_av_model_.insertRow(i, mit->name, mit->id,
2428 void GuiDocument::updateSelectedModules()
2430 modules_sel_model_.clear();
2431 list<modInfoStruct> const selModList = getSelectedModules();
2432 list<modInfoStruct>::const_iterator mit = selModList.begin();
2433 list<modInfoStruct>::const_iterator men = selModList.end();
2434 for (int i = 0; mit != men; ++mit, ++i)
2435 modules_sel_model_.insertRow(i, mit->name, mit->id,
2440 void GuiDocument::updateContents()
2442 // Nothing to do here as the document settings is not cursor dependant.
2447 void GuiDocument::useClassDefaults()
2449 if (applyPB->isEnabled()) {
2450 int const ret = Alert::prompt(_("Unapplied changes"),
2451 _("Some changes in the dialog were not yet applied.\n"
2452 "If you do not apply now, they will be lost after this action."),
2453 1, 1, _("&Apply"), _("&Dismiss"));
2458 int idx = latexModule->classCO->currentIndex();
2459 string const classname = classes_model_.getIDString(idx);
2460 if (!bp_.setBaseClass(classname)) {
2461 Alert::error(_("Error"), _("Unable to set document class."));
2464 bp_.useClassDefaults();
2469 void GuiDocument::setLayoutComboByIDString(string const & idString)
2471 int idx = classes_model_.findIDString(idString);
2473 Alert::warning(_("Can't set layout!"),
2474 bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
2476 latexModule->classCO->setCurrentIndex(idx);
2480 bool GuiDocument::isValid()
2482 return validateListingsParameters().isEmpty()
2483 && (textLayoutModule->skipCO->currentIndex() != 3
2484 || !textLayoutModule->skipLE->text().isEmpty());
2488 char const * const GuiDocument::fontfamilies[5] = {
2489 "default", "rmdefault", "sfdefault", "ttdefault", ""
2493 char const * GuiDocument::fontfamilies_gui[5] = {
2494 N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
2498 bool GuiDocument::initialiseParams(string const &)
2500 BufferView const * view = bufferview();
2502 bp_ = BufferParams();
2506 bp_ = view->buffer().params();
2508 updateAvailableModules();
2509 //FIXME It'd be nice to make sure here that the selected
2510 //modules are consistent: That required modules are actually
2511 //selected, and that we don't have conflicts. If so, we could
2512 //at least pop up a warning.
2518 void GuiDocument::clearParams()
2520 bp_ = BufferParams();
2524 BufferId GuiDocument::id() const
2526 BufferView const * const view = bufferview();
2527 return view? &view->buffer() : 0;
2531 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
2533 return moduleNames_;
2537 list<GuiDocument::modInfoStruct> const
2538 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
2540 LayoutModuleList::const_iterator it = mods.begin();
2541 LayoutModuleList::const_iterator end = mods.end();
2542 list<modInfoStruct> mInfo;
2543 for (; it != end; ++it) {
2546 LyXModule * mod = moduleList[*it];
2549 m.name = toqstr(translateIfPossible(from_utf8(mod->getName())));
2551 m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
2558 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
2560 return makeModuleInfo(params().getModules());
2564 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
2566 return makeModuleInfo(params().baseClass()->providedModules());
2570 DocumentClass const & GuiDocument::documentClass() const
2572 return bp_.documentClass();
2576 static void dispatch_bufferparams(Dialog const & dialog,
2577 BufferParams const & bp, FuncCode lfun)
2580 ss << "\\begin_header\n";
2582 ss << "\\end_header\n";
2583 dialog.dispatch(FuncRequest(lfun, ss.str()));
2587 void GuiDocument::dispatchParams()
2589 // This must come first so that a language change is correctly noticed
2592 // Apply the BufferParams. Note that this will set the base class
2593 // and then update the buffer's layout.
2594 dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
2596 if (!params().master.empty()) {
2597 FileName const master_file = support::makeAbsPath(params().master,
2598 support::onlyPath(buffer().absFileName()));
2599 if (isLyXFilename(master_file.absFilename())) {
2600 Buffer * master = checkAndLoadLyXFile(master_file);
2602 if (master->isChild(const_cast<Buffer *>(&buffer())))
2603 const_cast<Buffer &>(buffer()).setParent(master);
2605 Alert::warning(_("Assigned master does not include this file"),
2606 bformat(_("You must include this file in the document\n"
2607 "'%1$s' in order to use the master document\n"
2608 "feature."), from_utf8(params().master)));
2610 Alert::warning(_("Could not load master"),
2611 bformat(_("The master document '%1$s'\n"
2612 "could not be loaded."),
2613 from_utf8(params().master)));
2617 // Generate the colours requested by each new branch.
2618 BranchList & branchlist = params().branchlist();
2619 if (!branchlist.empty()) {
2620 BranchList::const_iterator it = branchlist.begin();
2621 BranchList::const_iterator const end = branchlist.end();
2622 for (; it != end; ++it) {
2623 docstring const & current_branch = it->branch();
2624 Branch const * branch = branchlist.find(current_branch);
2625 string const x11hexname = X11hexname(branch->color());
2626 // display the new color
2627 docstring const str = current_branch + ' ' + from_ascii(x11hexname);
2628 dispatch(FuncRequest(LFUN_SET_COLOR, str));
2631 // Open insets of selected branches, close deselected ones
2632 dispatch(FuncRequest(LFUN_ALL_INSETS_TOGGLE,
2635 // Generate the colours requested by indices.
2636 IndicesList & indiceslist = params().indiceslist();
2637 if (!indiceslist.empty()) {
2638 IndicesList::const_iterator it = indiceslist.begin();
2639 IndicesList::const_iterator const end = indiceslist.end();
2640 for (; it != end; ++it) {
2641 docstring const & current_index = it->index();
2642 Index const * index = indiceslist.find(current_index);
2643 string const x11hexname = X11hexname(index->color());
2644 // display the new color
2645 docstring const str = current_index + ' ' + from_ascii(x11hexname);
2646 dispatch(FuncRequest(LFUN_SET_COLOR, str));
2649 // FIXME: If we used an LFUN, we would not need those two lines:
2650 BufferView * bv = const_cast<BufferView *>(bufferview());
2651 bv->processUpdateFlags(Update::Force | Update::FitCursor);
2655 void GuiDocument::setLanguage() const
2657 Language const * const newL = bp_.language;
2658 if (buffer().params().language == newL)
2661 string const & lang_name = newL->lang();
2662 dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
2666 void GuiDocument::saveAsDefault() const
2668 dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
2672 bool GuiDocument::isFontAvailable(string const & font) const
2674 if (font == "default" || font == "cmr"
2675 || font == "cmss" || font == "cmtt")
2676 // these are standard
2678 if (font == "lmodern" || font == "lmss" || font == "lmtt")
2679 return LaTeXFeatures::isAvailable("lmodern");
2680 if (font == "times" || font == "palatino"
2681 || font == "helvet" || font == "courier")
2682 return LaTeXFeatures::isAvailable("psnfss");
2683 if (font == "cmbr" || font == "cmtl")
2684 return LaTeXFeatures::isAvailable("cmbright");
2685 if (font == "utopia")
2686 return LaTeXFeatures::isAvailable("utopia")
2687 || LaTeXFeatures::isAvailable("fourier");
2688 if (font == "beraserif" || font == "berasans"
2689 || font == "beramono")
2690 return LaTeXFeatures::isAvailable("bera");
2691 return LaTeXFeatures::isAvailable(font);
2695 bool GuiDocument::providesOSF(string const & font) const
2697 if (outputModule->xetexCB->isChecked())
2698 // FIXME: we should check if the fonts really
2699 // have OSF support. But how?
2702 return isFontAvailable("eco");
2703 if (font == "palatino")
2704 return isFontAvailable("mathpazo");
2709 bool GuiDocument::providesSC(string const & font) const
2711 if (outputModule->xetexCB->isChecked())
2713 if (font == "palatino")
2714 return isFontAvailable("mathpazo");
2715 if (font == "utopia")
2716 return isFontAvailable("fourier");
2721 bool GuiDocument::providesScale(string const & font) const
2723 if (outputModule->xetexCB->isChecked())
2725 return font == "helvet" || font == "luximono"
2726 || font == "berasans" || font == "beramono";
2730 void GuiDocument::loadModuleInfo()
2732 moduleNames_.clear();
2733 LyXModuleList::const_iterator it = moduleList.begin();
2734 LyXModuleList::const_iterator end = moduleList.end();
2735 for (; it != end; ++it) {
2739 m.name = toqstr(translateIfPossible(from_utf8(it->getName())));
2740 // this is supposed to give us the first sentence of the description
2743 toqstr(translateIfPossible(from_utf8(it->getDescription())));
2744 int const pos = desc.indexOf(".");
2746 desc.truncate(pos + 1);
2747 m.description = desc;
2748 moduleNames_.push_back(m);
2753 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
2756 } // namespace frontend
2759 #include "moc_GuiDocument.cpp"