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 "GuiSelectionManager.h"
19 #include "LaTeXHighlighter.h"
20 #include "LengthCombo.h"
21 #include "PanelStack.h"
22 #include "Validator.h"
24 #include "LayoutFile.h"
25 #include "BranchList.h"
26 #include "buffer_funcs.h"
28 #include "BufferParams.h"
29 #include "BufferView.h"
31 #include "ColorCache.h"
33 #include "FloatPlacement.h"
35 #include "FuncRequest.h"
37 #include "LaTeXFeatures.h"
39 #include "LayoutModuleList.h"
41 #include "ModuleList.h"
42 #include "OutputParams.h"
43 #include "PDFOptions.h"
44 #include "qt_helpers.h"
47 #include "insets/InsetListingsParams.h"
49 #include "support/debug.h"
50 #include "support/FileName.h"
51 #include "support/filetools.h"
52 #include "support/gettext.h"
53 #include "support/lstrings.h"
55 #include "frontends/alert.h"
57 #include <QAbstractItemModel>
59 #include <QColorDialog>
60 #include <QCloseEvent>
61 #include <QFontDatabase>
63 #include <QTextCursor>
73 // a style sheet for buttons
74 // this is for example used for the background color setting button
75 static inline QString colorButtonStyleSheet(const QColor &bgColor)
77 if (bgColor.isValid()) {
78 QString rc = QLatin1String("background:");
82 return QLatin1String("");
87 using namespace lyx::support;
92 char const * const tex_graphics[] =
94 "default", "dvialw", "dvilaser", "dvipdf", "dvipdfm", "dvipdfmx",
95 "dvips", "dvipsone", "dvitops", "dviwin", "dviwindo", "dvi2ps", "emtex",
96 "ln", "oztex", "pctexhp", "pctexps", "pctexwin", "pctex32", "pdftex",
97 "psprint", "pubps", "tcidvi", "textures", "truetex", "vtex", "xdvi",
102 char const * const tex_graphics_gui[] =
104 N_("Default"), "dvialw", "DviLaser", "dvipdf", "DVIPDFM", "DVIPDFMx",
105 "Dvips", "DVIPSONE", "DVItoPS", "DVIWIN", "DVIWindo", "dvi2ps", "EmTeX",
106 "LN", "OzTeX", "pctexhp", "pctexps", "pctexwin", "PCTeX32", "pdfTeX",
107 "psprint", "pubps", "tcidvi", "Textures", "TrueTeX", "VTeX", "xdvi",
108 "XeTeX", N_("None"), ""
112 char const * const tex_fonts_roman[] =
114 "default", "cmr", "lmodern", "ae", "times", "palatino",
115 "charter", "newcent", "bookman", "utopia", "beraserif",
116 "ccfonts", "chancery", ""
120 char const * tex_fonts_roman_gui[] =
122 N_("Default"), N_("Computer Modern Roman"), N_("Latin Modern Roman"),
123 N_("AE (Almost European)"), N_("Times Roman"), N_("Palatino"),
124 N_("Bitstream Charter"), N_("New Century Schoolbook"), N_("Bookman"),
125 N_("Utopia"), N_("Bera Serif"), N_("Concrete Roman"), N_("Zapf Chancery"),
130 char const * const tex_fonts_sans[] =
132 "default", "cmss", "lmss", "helvet", "avant", "berasans", "cmbr", ""
136 char const * tex_fonts_sans_gui[] =
138 N_("Default"), N_("Computer Modern Sans"), N_("Latin Modern Sans"),
139 N_("Helvetica"), N_("Avant Garde"), N_("Bera Sans"), N_("CM Bright"), ""
143 char const * const tex_fonts_monospaced[] =
145 "default", "cmtt", "lmtt", "courier", "beramono", "luximono", "cmtl", ""
149 char const * tex_fonts_monospaced_gui[] =
151 N_("Default"), N_("Computer Modern Typewriter"),
152 N_("Latin Modern Typewriter"), N_("Courier"), N_("Bera Mono"),
153 N_("LuxiMono"), N_("CM Typewriter Light"), ""
157 char const * backref_opts[] =
159 "false", "section", "slide", "page", ""
163 char const * backref_opts_gui[] =
165 N_("Off"), N_("Section"), N_("Slide"), N_("Page"), ""
169 vector<pair<string, QString> > pagestyles;
172 } // anonymous namespace
176 RGBColor set_backgroundcolor;
179 // used when sorting the textclass list.
180 class less_textclass_avail_desc
181 : public binary_function<string, string, int>
184 bool operator()(string const & lhs, string const & rhs) const
186 // Ordering criteria:
187 // 1. Availability of text class
188 // 2. Description (lexicographic)
189 LayoutFile const & tc1 = LayoutFileList::get()[lhs];
190 LayoutFile const & tc2 = LayoutFileList::get()[rhs];
191 int const rel = compare_no_case(
192 translateIfPossible(from_utf8(tc1.description())),
193 translateIfPossible(from_utf8(tc2.description())));
194 return (tc1.isTeXClassAvailable() && !tc2.isTeXClassAvailable()) ||
195 (tc1.isTeXClassAvailable() == tc2.isTeXClassAvailable() && rel < 0);
204 vector<string> getRequiredList(string const & modName)
206 LyXModule const * const mod = moduleList[modName];
208 return vector<string>(); //empty such thing
209 return mod->getRequiredModules();
213 vector<string> getExcludedList(string const & modName)
215 LyXModule const * const mod = moduleList[modName];
217 return vector<string>(); //empty such thing
218 return mod->getExcludedModules();
222 docstring getModuleDescription(string const & modName)
224 LyXModule const * const mod = moduleList[modName];
226 return _("Module not found!");
228 return translateIfPossible(from_utf8(mod->getDescription()));
232 vector<string> getPackageList(string const & modName)
234 LyXModule const * const mod = moduleList[modName];
236 return vector<string>(); //empty such thing
237 return mod->getPackageList();
241 bool isModuleAvailable(string const & modName)
243 LyXModule * mod = moduleList[modName];
246 return mod->isAvailable();
249 } // anonymous namespace
252 /////////////////////////////////////////////////////////////////////
254 // ModuleSelectionManager
256 /////////////////////////////////////////////////////////////////////
258 /// SelectionManager for use with modules
259 class ModuleSelectionManager : public GuiSelectionManager
263 ModuleSelectionManager(
264 QListView * availableLV,
265 QListView * selectedLV,
269 QPushButton * downPB,
270 GuiIdListModel * availableModel,
271 GuiIdListModel * selectedModel,
272 GuiDocument const * container)
273 : GuiSelectionManager(availableLV, selectedLV, addPB, delPB,
274 upPB, downPB, availableModel, selectedModel), container_(container)
277 void updateProvidedModules(LayoutModuleList const & pm)
278 { provided_modules_ = pm.list(); }
280 void updateExcludedModules(LayoutModuleList const & em)
281 { excluded_modules_ = em.list(); }
284 virtual void updateAddPB();
286 virtual void updateUpPB();
288 virtual void updateDownPB();
290 virtual void updateDelPB();
291 /// returns availableModel as a GuiIdListModel
292 GuiIdListModel * getAvailableModel()
294 return dynamic_cast<GuiIdListModel *>(availableModel);
296 /// returns selectedModel as a GuiIdListModel
297 GuiIdListModel * getSelectedModel()
299 return dynamic_cast<GuiIdListModel *>(selectedModel);
301 /// keeps a list of the modules the text class provides
302 std::list<std::string> provided_modules_;
304 std::list<std::string> excluded_modules_;
306 GuiDocument const * container_;
309 void ModuleSelectionManager::updateAddPB()
311 int const arows = availableModel->rowCount();
312 QModelIndexList const avail_sels =
313 availableLV->selectionModel()->selectedIndexes();
315 // disable if there aren't any modules (?), if none of them is chosen
316 // in the dialog, or if the chosen one is already selected for use.
317 if (arows == 0 || avail_sels.isEmpty() || isSelected(avail_sels.first())) {
318 addPB->setEnabled(false);
322 QModelIndex const & idx = availableLV->selectionModel()->currentIndex();
323 string const modname = getAvailableModel()->getIDString(idx.row());
326 container_->params().moduleCanBeAdded(modname);
327 addPB->setEnabled(enable);
331 void ModuleSelectionManager::updateDownPB()
333 int const srows = selectedModel->rowCount();
335 downPB->setEnabled(false);
338 QModelIndex const & curidx = selectedLV->selectionModel()->currentIndex();
339 int const curRow = curidx.row();
340 if (curRow < 0 || curRow >= srows - 1) { // invalid or last item
341 downPB->setEnabled(false);
345 // determine whether immediately succeding element requires this one
346 string const curmodname = getSelectedModel()->getIDString(curRow);
347 string const nextmodname = getSelectedModel()->getIDString(curRow + 1);
349 vector<string> reqs = getRequiredList(nextmodname);
351 // if it doesn't require anything....
353 downPB->setEnabled(true);
357 // Enable it if this module isn't required.
358 // FIXME This should perhaps be more flexible and check whether, even
359 // if the next one is required, there is also an earlier one that will do.
361 find(reqs.begin(), reqs.end(), curmodname) == reqs.end());
364 void ModuleSelectionManager::updateUpPB()
366 int const srows = selectedModel->rowCount();
368 upPB->setEnabled(false);
372 QModelIndex const & curIdx = selectedLV->selectionModel()->currentIndex();
373 int curRow = curIdx.row();
374 if (curRow <= 0 || curRow > srows - 1) { // first item or invalid
375 upPB->setEnabled(false);
378 string const curmodname = getSelectedModel()->getIDString(curRow);
380 // determine whether immediately preceding element is required by this one
381 vector<string> reqs = getRequiredList(curmodname);
383 // if this one doesn't require anything....
385 upPB->setEnabled(true);
390 // Enable it if the preceding module isn't required.
391 // NOTE This is less flexible than it might be. We could check whether, even
392 // if the previous one is required, there is an earlier one that would do.
393 string const premod = getSelectedModel()->getIDString(curRow - 1);
394 upPB->setEnabled(find(reqs.begin(), reqs.end(), premod) == reqs.end());
397 void ModuleSelectionManager::updateDelPB()
399 int const srows = selectedModel->rowCount();
401 deletePB->setEnabled(false);
405 QModelIndex const & curidx =
406 selectedLV->selectionModel()->currentIndex();
407 int const curRow = curidx.row();
408 if (curRow < 0 || curRow >= srows) { // invalid index?
409 deletePB->setEnabled(false);
413 string const curmodname = getSelectedModel()->getIDString(curRow);
415 // We're looking here for a reason NOT to enable the button. If we
416 // find one, we disable it and return. If we don't, we'll end up at
417 // the end of the function, and then we enable it.
418 for (int i = curRow + 1; i < srows; ++i) {
419 string const thisMod = getSelectedModel()->getIDString(i);
420 vector<string> reqs = getRequiredList(thisMod);
421 //does this one require us?
422 if (find(reqs.begin(), reqs.end(), curmodname) == reqs.end())
426 // OK, so this module requires us
427 // is there an EARLIER module that also satisfies the require?
428 // NOTE We demand that it be earlier to keep the list of modules
429 // consistent with the rule that a module must be proceeded by a
430 // required module. There would be more flexible ways to proceed,
431 // but that would be a lot more complicated, and the logic here is
432 // already complicated. (That's why I've left the debugging code.)
433 // lyxerr << "Testing " << thisMod << std::endl;
434 bool foundone = false;
435 for (int j = 0; j < curRow; ++j) {
436 string const mod = getSelectedModel()->getIDString(j);
437 // lyxerr << "In loop: Testing " << mod << std::endl;
438 // do we satisfy the require?
439 if (find(reqs.begin(), reqs.end(), mod) != reqs.end()) {
440 // lyxerr << mod << " does the trick." << std::endl;
445 // did we find a module to satisfy the require?
447 // lyxerr << "No matching module found." << std::endl;
448 deletePB->setEnabled(false);
452 // lyxerr << "All's well that ends well." << std::endl;
453 deletePB->setEnabled(true);
457 /////////////////////////////////////////////////////////////////////
461 /////////////////////////////////////////////////////////////////////
463 PreambleModule::PreambleModule() : current_id_(0)
465 // This is not a memory leak. The object will be destroyed
467 (void) new LaTeXHighlighter(preambleTE->document());
468 setFocusProxy(preambleTE);
469 connect(preambleTE, SIGNAL(textChanged()), this, SIGNAL(changed()));
473 void PreambleModule::update(BufferParams const & params, BufferId id)
475 QString preamble = toqstr(params.preamble);
476 // Nothing to do if the params and preamble are unchanged.
477 if (id == current_id_
478 && preamble == preambleTE->document()->toPlainText())
481 QTextCursor cur = preambleTE->textCursor();
482 // Save the coords before switching to the new one.
483 preamble_coords_[current_id_] =
484 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
486 // Save the params address for further use.
488 preambleTE->document()->setPlainText(preamble);
489 Coords::const_iterator it = preamble_coords_.find(current_id_);
490 if (it == preamble_coords_.end())
491 // First time we open this one.
492 preamble_coords_[current_id_] = make_pair(0, 0);
494 // Restore saved coords.
495 QTextCursor cur = preambleTE->textCursor();
496 cur.setPosition(it->second.first);
497 preambleTE->setTextCursor(cur);
498 preambleTE->verticalScrollBar()->setValue(it->second.second);
503 void PreambleModule::apply(BufferParams & params)
505 params.preamble = fromqstr(preambleTE->document()->toPlainText());
509 void PreambleModule::closeEvent(QCloseEvent * e)
511 // Save the coords before closing.
512 QTextCursor cur = preambleTE->textCursor();
513 preamble_coords_[current_id_] =
514 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
519 /////////////////////////////////////////////////////////////////////
523 /////////////////////////////////////////////////////////////////////
526 GuiDocument::GuiDocument(GuiView & lv)
527 : GuiDialog(lv, "document", qt_("Document Settings"))
531 connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
532 connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
533 connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
534 connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore()));
536 connect(savePB, SIGNAL(clicked()), this, SLOT(saveDefaultClicked()));
537 connect(defaultPB, SIGNAL(clicked()), this, SLOT(useDefaultsClicked()));
539 // Manage the restore, ok, apply, restore and cancel/close buttons
540 bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
542 bc().setApply(applyPB);
543 bc().setCancel(closePB);
544 bc().setRestore(restorePB);
546 textLayoutModule = new UiWidget<Ui::TextLayoutUi>;
548 connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
549 this, SLOT(change_adaptor()));
550 connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
551 this, SLOT(setLSpacing(int)));
552 connect(textLayoutModule->lspacingLE, SIGNAL(textChanged(const QString &)),
553 this, SLOT(change_adaptor()));
554 connect(textLayoutModule->skipRB, SIGNAL(clicked()),
555 this, SLOT(change_adaptor()));
556 connect(textLayoutModule->indentRB, SIGNAL(clicked()),
557 this, SLOT(change_adaptor()));
558 connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
559 this, SLOT(change_adaptor()));
560 connect(textLayoutModule->skipLE, SIGNAL(textChanged(const QString &)),
561 this, SLOT(change_adaptor()));
562 connect(textLayoutModule->skipLengthCO, SIGNAL(activated(int)),
563 this, SLOT(change_adaptor()));
564 connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
565 this, SLOT(setSkip(int)));
566 connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
567 this, SLOT(enableSkip(bool)));
568 connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
569 this, SLOT(change_adaptor()));
570 connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
571 this, SLOT(setColSep()));
572 connect(textLayoutModule->listingsED, SIGNAL(textChanged()),
573 this, SLOT(change_adaptor()));
574 connect(textLayoutModule->bypassCB, SIGNAL(clicked()),
575 this, SLOT(change_adaptor()));
576 connect(textLayoutModule->bypassCB, SIGNAL(clicked()),
577 this, SLOT(setListingsMessage()));
578 connect(textLayoutModule->listingsED, SIGNAL(textChanged()),
579 this, SLOT(setListingsMessage()));
580 textLayoutModule->listingsTB->setPlainText(
581 qt_("Input listings parameters on the right. Enter ? for a list of parameters."));
582 textLayoutModule->lspacingLE->setValidator(new QDoubleValidator(
583 textLayoutModule->lspacingLE));
584 textLayoutModule->skipLE->setValidator(unsignedLengthValidator(
585 textLayoutModule->skipLE));
587 textLayoutModule->skipCO->addItem(qt_("SmallSkip"));
588 textLayoutModule->skipCO->addItem(qt_("MedSkip"));
589 textLayoutModule->skipCO->addItem(qt_("BigSkip"));
590 textLayoutModule->skipCO->addItem(qt_("Length"));
591 // remove the %-items from the unit choice
592 textLayoutModule->skipLengthCO->noPercents();
593 textLayoutModule->lspacingCO->insertItem(
594 Spacing::Single, qt_("Single"));
595 textLayoutModule->lspacingCO->insertItem(
596 Spacing::Onehalf, qt_("OneHalf"));
597 textLayoutModule->lspacingCO->insertItem(
598 Spacing::Double, qt_("Double"));
599 textLayoutModule->lspacingCO->insertItem(
600 Spacing::Other, qt_("Custom"));
602 // initialize the length validator
603 bc().addCheckedLineEdit(textLayoutModule->skipLE);
606 outputModule = new UiWidget<Ui::OutputUi>;
608 connect(outputModule->xetexCB, SIGNAL(clicked()),
609 this, SLOT(change_adaptor()));
610 connect(outputModule->xetexCB, SIGNAL(toggled(bool)),
611 this, SLOT(xetexChanged(bool)));
612 connect(outputModule->defaultFormatCO, SIGNAL(activated(int)),
613 this, SLOT(change_adaptor()));
616 fontModule = new UiWidget<Ui::FontUi>;
617 connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
618 this, SLOT(change_adaptor()));
619 connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
620 this, SLOT(romanChanged(int)));
621 connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
622 this, SLOT(change_adaptor()));
623 connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
624 this, SLOT(sansChanged(int)));
625 connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
626 this, SLOT(change_adaptor()));
627 connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
628 this, SLOT(ttChanged(int)));
629 connect(fontModule->fontsDefaultCO, SIGNAL(activated(int)),
630 this, SLOT(change_adaptor()));
631 connect(fontModule->fontsizeCO, SIGNAL(activated(int)),
632 this, SLOT(change_adaptor()));
633 connect(fontModule->cjkFontLE, SIGNAL(textChanged(const QString &)),
634 this, SLOT(change_adaptor()));
635 connect(fontModule->scaleSansSB, SIGNAL(valueChanged(int)),
636 this, SLOT(change_adaptor()));
637 connect(fontModule->scaleTypewriterSB, SIGNAL(valueChanged(int)),
638 this, SLOT(change_adaptor()));
639 connect(fontModule->fontScCB, SIGNAL(clicked()),
640 this, SLOT(change_adaptor()));
641 connect(fontModule->fontOsfCB, SIGNAL(clicked()),
642 this, SLOT(change_adaptor()));
646 fontModule->fontsizeCO->addItem(qt_("Default"));
647 fontModule->fontsizeCO->addItem(qt_("10"));
648 fontModule->fontsizeCO->addItem(qt_("11"));
649 fontModule->fontsizeCO->addItem(qt_("12"));
651 for (int n = 0; GuiDocument::fontfamilies_gui[n][0]; ++n)
652 fontModule->fontsDefaultCO->addItem(
653 qt_(GuiDocument::fontfamilies_gui[n]));
656 pageLayoutModule = new UiWidget<Ui::PageLayoutUi>;
658 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
659 this, SLOT(setCustomPapersize(int)));
660 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
661 this, SLOT(setCustomPapersize(int)));
662 connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
663 this, SLOT(portraitChanged()));
664 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
665 this, SLOT(change_adaptor()));
666 connect(pageLayoutModule->paperheightLE, SIGNAL(textChanged(const QString &)),
667 this, SLOT(change_adaptor()));
668 connect(pageLayoutModule->paperwidthLE, SIGNAL(textChanged(const QString &)),
669 this, SLOT(change_adaptor()));
670 connect(pageLayoutModule->paperwidthUnitCO, SIGNAL(activated(int)),
671 this, SLOT(change_adaptor()));
672 connect(pageLayoutModule->paperheightUnitCO, SIGNAL(activated(int)),
673 this, SLOT(change_adaptor()));
674 connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
675 this, SLOT(change_adaptor()));
676 connect(pageLayoutModule->landscapeRB, SIGNAL(clicked()),
677 this, SLOT(change_adaptor()));
678 connect(pageLayoutModule->facingPagesCB, SIGNAL(clicked()),
679 this, SLOT(change_adaptor()));
680 connect(pageLayoutModule->pagestyleCO, SIGNAL(activated(int)),
681 this, SLOT(change_adaptor()));
682 connect(pageLayoutModule->backgroundTB, SIGNAL(clicked()),
683 this, SLOT(changeBackgroundColor()));
684 connect(pageLayoutModule->delbackgroundTB, SIGNAL(clicked()),
685 this, SLOT(deleteBackgroundColor()));
687 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
688 pageLayoutModule->pagestyleCO->addItem(qt_("empty"));
689 pageLayoutModule->pagestyleCO->addItem(qt_("plain"));
690 pageLayoutModule->pagestyleCO->addItem(qt_("headings"));
691 pageLayoutModule->pagestyleCO->addItem(qt_("fancy"));
692 bc().addCheckedLineEdit(pageLayoutModule->paperheightLE,
693 pageLayoutModule->paperheightL);
694 bc().addCheckedLineEdit(pageLayoutModule->paperwidthLE,
695 pageLayoutModule->paperwidthL);
698 QComboBox * cb = pageLayoutModule->papersizeCO;
699 cb->addItem(qt_("Default"));
700 cb->addItem(qt_("Custom"));
701 cb->addItem(qt_("US letter"));
702 cb->addItem(qt_("US legal"));
703 cb->addItem(qt_("US executive"));
704 cb->addItem(qt_("A3"));
705 cb->addItem(qt_("A4"));
706 cb->addItem(qt_("A5"));
707 cb->addItem(qt_("B3"));
708 cb->addItem(qt_("B4"));
709 cb->addItem(qt_("B5"));
710 // remove the %-items from the unit choice
711 pageLayoutModule->paperwidthUnitCO->noPercents();
712 pageLayoutModule->paperheightUnitCO->noPercents();
713 pageLayoutModule->paperheightLE->setValidator(unsignedLengthValidator(
714 pageLayoutModule->paperheightLE));
715 pageLayoutModule->paperwidthLE->setValidator(unsignedLengthValidator(
716 pageLayoutModule->paperwidthLE));
719 marginsModule = new UiWidget<Ui::MarginsUi>;
721 connect(marginsModule->marginCB, SIGNAL(toggled(bool)),
722 this, SLOT(setCustomMargins(bool)));
723 connect(marginsModule->marginCB, SIGNAL(clicked()),
724 this, SLOT(change_adaptor()));
725 connect(marginsModule->topLE, SIGNAL(textChanged(QString)),
726 this, SLOT(change_adaptor()));
727 connect(marginsModule->topUnit, SIGNAL(activated(int)),
728 this, SLOT(change_adaptor()));
729 connect(marginsModule->bottomLE, SIGNAL(textChanged(QString)),
730 this, SLOT(change_adaptor()));
731 connect(marginsModule->bottomUnit, SIGNAL(activated(int)),
732 this, SLOT(change_adaptor()));
733 connect(marginsModule->innerLE, SIGNAL(textChanged(QString)),
734 this, SLOT(change_adaptor()));
735 connect(marginsModule->innerUnit, SIGNAL(activated(int)),
736 this, SLOT(change_adaptor()));
737 connect(marginsModule->outerLE, SIGNAL(textChanged(QString)),
738 this, SLOT(change_adaptor()));
739 connect(marginsModule->outerUnit, SIGNAL(activated(int)),
740 this, SLOT(change_adaptor()));
741 connect(marginsModule->headheightLE, SIGNAL(textChanged(QString)),
742 this, SLOT(change_adaptor()));
743 connect(marginsModule->headheightUnit, SIGNAL(activated(int)),
744 this, SLOT(change_adaptor()));
745 connect(marginsModule->headsepLE, SIGNAL(textChanged(QString)),
746 this, SLOT(change_adaptor()));
747 connect(marginsModule->headsepUnit, SIGNAL(activated(int)),
748 this, SLOT(change_adaptor()));
749 connect(marginsModule->footskipLE, SIGNAL(textChanged(QString)),
750 this, SLOT(change_adaptor()));
751 connect(marginsModule->footskipUnit, SIGNAL(activated(int)),
752 this, SLOT(change_adaptor()));
753 connect(marginsModule->columnsepLE, SIGNAL(textChanged(QString)),
754 this, SLOT(change_adaptor()));
755 connect(marginsModule->columnsepUnit, SIGNAL(activated(int)),
756 this, SLOT(change_adaptor()));
757 marginsModule->topLE->setValidator(unsignedLengthValidator(
758 marginsModule->topLE));
759 marginsModule->bottomLE->setValidator(unsignedLengthValidator(
760 marginsModule->bottomLE));
761 marginsModule->innerLE->setValidator(unsignedLengthValidator(
762 marginsModule->innerLE));
763 marginsModule->outerLE->setValidator(unsignedLengthValidator(
764 marginsModule->outerLE));
765 marginsModule->headsepLE->setValidator(unsignedLengthValidator(
766 marginsModule->headsepLE));
767 marginsModule->headheightLE->setValidator(unsignedLengthValidator(
768 marginsModule->headheightLE));
769 marginsModule->footskipLE->setValidator(unsignedLengthValidator(
770 marginsModule->footskipLE));
771 marginsModule->columnsepLE->setValidator(unsignedLengthValidator(
772 marginsModule->columnsepLE));
774 bc().addCheckedLineEdit(marginsModule->topLE,
775 marginsModule->topL);
776 bc().addCheckedLineEdit(marginsModule->bottomLE,
777 marginsModule->bottomL);
778 bc().addCheckedLineEdit(marginsModule->innerLE,
779 marginsModule->innerL);
780 bc().addCheckedLineEdit(marginsModule->outerLE,
781 marginsModule->outerL);
782 bc().addCheckedLineEdit(marginsModule->headsepLE,
783 marginsModule->headsepL);
784 bc().addCheckedLineEdit(marginsModule->headheightLE,
785 marginsModule->headheightL);
786 bc().addCheckedLineEdit(marginsModule->footskipLE,
787 marginsModule->footskipL);
788 bc().addCheckedLineEdit(marginsModule->columnsepLE,
789 marginsModule->columnsepL);
792 langModule = new UiWidget<Ui::LanguageUi>;
794 connect(langModule->languageCO, SIGNAL(activated(int)),
795 this, SLOT(change_adaptor()));
796 connect(langModule->defaultencodingRB, SIGNAL(clicked()),
797 this, SLOT(change_adaptor()));
798 connect(langModule->otherencodingRB, SIGNAL(clicked()),
799 this, SLOT(change_adaptor()));
800 connect(langModule->encodingCO, SIGNAL(activated(int)),
801 this, SLOT(change_adaptor()));
802 connect(langModule->quoteStyleCO, SIGNAL(activated(int)),
803 this, SLOT(change_adaptor()));
805 QAbstractItemModel * language_model = guiApp->languageModel();
806 // FIXME: it would be nice if sorting was enabled/disabled via a checkbox.
807 language_model->sort(0);
808 langModule->languageCO->setModel(language_model);
810 // Always put the default encoding in the first position.
811 langModule->encodingCO->addItem(qt_("Language Default (no inputenc)"));
812 QStringList encodinglist;
813 Encodings::const_iterator it = encodings.begin();
814 Encodings::const_iterator const end = encodings.end();
815 for (; it != end; ++it)
816 encodinglist.append(qt_(it->guiName()));
818 langModule->encodingCO->addItems(encodinglist);
820 langModule->quoteStyleCO->addItem(qt_("``text''"));
821 langModule->quoteStyleCO->addItem(qt_("''text''"));
822 langModule->quoteStyleCO->addItem(qt_(",,text``"));
823 langModule->quoteStyleCO->addItem(qt_(",,text''"));
824 langModule->quoteStyleCO->addItem(qt_("<<text>>"));
825 langModule->quoteStyleCO->addItem(qt_(">>text<<"));
828 numberingModule = new UiWidget<Ui::NumberingUi>;
830 connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
831 this, SLOT(change_adaptor()));
832 connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
833 this, SLOT(change_adaptor()));
834 connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
835 this, SLOT(updateNumbering()));
836 connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
837 this, SLOT(updateNumbering()));
838 numberingModule->tocTW->setColumnCount(3);
839 numberingModule->tocTW->headerItem()->setText(0, qt_("Example"));
840 numberingModule->tocTW->headerItem()->setText(1, qt_("Numbered"));
841 numberingModule->tocTW->headerItem()->setText(2, qt_("Appears in TOC"));
844 biblioModule = new UiWidget<Ui::BiblioUi>;
845 connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
846 biblioModule->citationStyleL, SLOT(setEnabled(bool)));
847 connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
848 biblioModule->citeStyleCO, SLOT(setEnabled(bool)));
850 connect(biblioModule->citeDefaultRB, SIGNAL(clicked()),
851 this, SLOT(change_adaptor()));
852 connect(biblioModule->citeNatbibRB, SIGNAL(clicked()),
853 this, SLOT(change_adaptor()));
854 connect(biblioModule->citeStyleCO, SIGNAL(activated(int)),
855 this, SLOT(change_adaptor()));
856 connect(biblioModule->citeJurabibRB, SIGNAL(clicked()),
857 this, SLOT(change_adaptor()));
858 connect(biblioModule->bibtopicCB, SIGNAL(clicked()),
859 this, SLOT(change_adaptor()));
861 biblioModule->citeStyleCO->addItem(qt_("Author-year"));
862 biblioModule->citeStyleCO->addItem(qt_("Numerical"));
863 biblioModule->citeStyleCO->setCurrentIndex(0);
866 mathsModule = new UiWidget<Ui::MathsUi>;
867 connect(mathsModule->amsautoCB, SIGNAL(toggled(bool)),
868 mathsModule->amsCB, SLOT(setDisabled(bool)));
869 connect(mathsModule->esintautoCB, SIGNAL(toggled(bool)),
870 mathsModule->esintCB, SLOT(setDisabled(bool)));
872 connect(mathsModule->amsCB, SIGNAL(clicked()),
873 this, SLOT(change_adaptor()));
874 connect(mathsModule->amsautoCB, SIGNAL(clicked()),
875 this, SLOT(change_adaptor()));
876 connect(mathsModule->esintCB, SIGNAL(clicked()),
877 this, SLOT(change_adaptor()));
878 connect(mathsModule->esintautoCB, SIGNAL(clicked()),
879 this, SLOT(change_adaptor()));
881 latexModule = new UiWidget<Ui::LaTeXUi>;
883 connect(latexModule->optionsLE, SIGNAL(textChanged(QString)),
884 this, SLOT(change_adaptor()));
885 connect(latexModule->defaultOptionsCB, SIGNAL(clicked()),
886 this, SLOT(change_adaptor()));
887 connect(latexModule->psdriverCO, SIGNAL(activated(int)),
888 this, SLOT(change_adaptor()));
889 connect(latexModule->classCO, SIGNAL(activated(int)),
890 this, SLOT(classChanged()));
891 connect(latexModule->classCO, SIGNAL(activated(int)),
892 this, SLOT(change_adaptor()));
893 connect(latexModule->layoutPB, SIGNAL(clicked()),
894 this, SLOT(browseLayout()));
895 connect(latexModule->layoutPB, SIGNAL(clicked()),
896 this, SLOT(change_adaptor()));
897 connect(latexModule->childDocGB, SIGNAL(clicked()),
898 this, SLOT(change_adaptor()));
899 connect(latexModule->childDocLE, SIGNAL(textChanged(QString)),
900 this, SLOT(change_adaptor()));
901 connect(latexModule->childDocPB, SIGNAL(clicked()),
902 this, SLOT(browseMaster()));
904 // postscript drivers
905 for (int n = 0; tex_graphics[n][0]; ++n) {
906 QString enc = qt_(tex_graphics_gui[n]);
907 latexModule->psdriverCO->addItem(enc);
910 latexModule->classCO->setModel(&classes_model_);
911 LayoutFileList const & bcl = LayoutFileList::get();
912 vector<LayoutFileIndex> classList = bcl.classList();
913 sort(classList.begin(), classList.end(), less_textclass_avail_desc());
915 vector<LayoutFileIndex>::const_iterator cit = classList.begin();
916 vector<LayoutFileIndex>::const_iterator cen = classList.end();
917 for (int i = 0; cit != cen; ++cit, ++i) {
918 LayoutFile const & tc = bcl[*cit];
919 docstring item = (tc.isTeXClassAvailable()) ?
920 from_utf8(tc.description()) :
921 bformat(_("Unavailable: %1$s"), from_utf8(tc.description()));
922 classes_model_.insertRow(i, toqstr(item), *cit);
926 branchesModule = new GuiBranches;
927 connect(branchesModule, SIGNAL(changed()),
928 this, SLOT(change_adaptor()));
931 preambleModule = new PreambleModule;
932 connect(preambleModule, SIGNAL(changed()),
933 this, SLOT(change_adaptor()));
936 bulletsModule = new BulletsModule;
937 connect(bulletsModule, SIGNAL(changed()),
938 this, SLOT(change_adaptor()));
941 modulesModule = new UiWidget<Ui::ModulesUi>;
944 new ModuleSelectionManager(modulesModule->availableLV,
945 modulesModule->selectedLV,
946 modulesModule->addPB, modulesModule->deletePB,
947 modulesModule->upPB, modulesModule->downPB,
948 availableModel(), selectedModel(), this);
949 connect(selectionManager, SIGNAL(updateHook()),
950 this, SLOT(updateModuleInfo()));
951 connect(selectionManager, SIGNAL(updateHook()),
952 this, SLOT(change_adaptor()));
953 connect(selectionManager, SIGNAL(selectionChanged()),
954 this, SLOT(modulesChanged()));
957 pdfSupportModule = new UiWidget<Ui::PDFSupportUi>;
959 connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
960 this, SLOT(change_adaptor()));
961 connect(pdfSupportModule->titleLE, SIGNAL(textChanged(QString)),
962 this, SLOT(change_adaptor()));
963 connect(pdfSupportModule->authorLE, SIGNAL(textChanged(QString)),
964 this, SLOT(change_adaptor()));
965 connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(QString)),
966 this, SLOT(change_adaptor()));
967 connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(QString)),
968 this, SLOT(change_adaptor()));
969 connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
970 this, SLOT(change_adaptor()));
971 connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
972 this, SLOT(change_adaptor()));
973 connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
974 this, SLOT(change_adaptor()));
975 connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
976 this, SLOT(change_adaptor()));
977 connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
978 this, SLOT(change_adaptor()));
979 connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
980 this, SLOT(change_adaptor()));
981 connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
982 this, SLOT(change_adaptor()));
983 connect(pdfSupportModule->backrefCO, SIGNAL(activated(int)),
984 this, SLOT(change_adaptor()));
985 connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
986 this, SLOT(change_adaptor()));
987 connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
988 this, SLOT(change_adaptor()));
989 connect(pdfSupportModule->optionsLE, SIGNAL(textChanged(QString)),
990 this, SLOT(change_adaptor()));
992 for (int i = 0; backref_opts[i][0]; ++i)
993 pdfSupportModule->backrefCO->addItem(qt_(backref_opts_gui[i]));
996 floatModule = new FloatPlacement;
997 connect(floatModule, SIGNAL(changed()),
998 this, SLOT(change_adaptor()));
1000 docPS->addPanel(latexModule, qt_("Document Class"));
1001 docPS->addPanel(modulesModule, qt_("Modules"));
1002 docPS->addPanel(fontModule, qt_("Fonts"));
1003 docPS->addPanel(textLayoutModule, qt_("Text Layout"));
1004 docPS->addPanel(pageLayoutModule, qt_("Page Layout"));
1005 docPS->addPanel(marginsModule, qt_("Page Margins"));
1006 docPS->addPanel(langModule, qt_("Language"));
1007 docPS->addPanel(numberingModule, qt_("Numbering & TOC"));
1008 docPS->addPanel(biblioModule, qt_("Bibliography"));
1009 docPS->addPanel(pdfSupportModule, qt_("PDF Properties"));
1010 docPS->addPanel(mathsModule, qt_("Math Options"));
1011 docPS->addPanel(floatModule, qt_("Float Placement"));
1012 docPS->addPanel(bulletsModule, qt_("Bullets"));
1013 docPS->addPanel(branchesModule, qt_("Branches"));
1014 docPS->addPanel(outputModule, qt_("Output"));
1015 docPS->addPanel(preambleModule, qt_("LaTeX Preamble"));
1016 docPS->setCurrentPanel(qt_("Document Class"));
1017 // FIXME: hack to work around resizing bug in Qt >= 4.2
1018 // bug verified with Qt 4.2.{0-3} (JSpitzm)
1019 #if QT_VERSION >= 0x040200
1020 docPS->updateGeometry();
1025 void GuiDocument::showPreamble()
1027 docPS->setCurrentPanel(qt_("LaTeX Preamble"));
1031 void GuiDocument::saveDefaultClicked()
1037 void GuiDocument::useDefaultsClicked()
1043 void GuiDocument::change_adaptor()
1049 QString GuiDocument::validateListingsParameters()
1051 // use a cache here to avoid repeated validation
1052 // of the same parameters
1053 static string param_cache;
1054 static QString msg_cache;
1056 if (textLayoutModule->bypassCB->isChecked())
1059 string params = fromqstr(textLayoutModule->listingsED->toPlainText());
1060 if (params != param_cache) {
1061 param_cache = params;
1062 msg_cache = toqstr(InsetListingsParams(params).validate());
1068 void GuiDocument::setListingsMessage()
1070 static bool isOK = true;
1071 QString msg = validateListingsParameters();
1072 if (msg.isEmpty()) {
1076 // listingsTB->setTextColor("black");
1077 textLayoutModule->listingsTB->setPlainText(
1078 qt_("Input listings parameters on the right. "
1079 "Enter ? for a list of parameters."));
1082 // listingsTB->setTextColor("red");
1083 textLayoutModule->listingsTB->setPlainText(msg);
1088 void GuiDocument::setLSpacing(int item)
1090 textLayoutModule->lspacingLE->setEnabled(item == 3);
1094 void GuiDocument::setSkip(int item)
1096 bool const enable = (item == 3);
1097 textLayoutModule->skipLE->setEnabled(enable);
1098 textLayoutModule->skipLengthCO->setEnabled(enable);
1102 void GuiDocument::enableSkip(bool skip)
1104 textLayoutModule->skipCO->setEnabled(skip);
1105 textLayoutModule->skipLE->setEnabled(skip);
1106 textLayoutModule->skipLengthCO->setEnabled(skip);
1108 setSkip(textLayoutModule->skipCO->currentIndex());
1112 void GuiDocument::portraitChanged()
1114 setMargins(pageLayoutModule->papersizeCO->currentIndex());
1118 void GuiDocument::setMargins(bool custom)
1120 bool const extern_geometry =
1121 documentClass().provides("geometry");
1122 marginsModule->marginCB->setEnabled(!extern_geometry);
1123 if (extern_geometry) {
1124 marginsModule->marginCB->setChecked(false);
1125 setCustomMargins(true);
1128 marginsModule->marginCB->setChecked(custom);
1129 setCustomMargins(custom);
1133 void GuiDocument::setCustomPapersize(int papersize)
1135 bool const custom = (papersize == 1);
1137 pageLayoutModule->paperwidthL->setEnabled(custom);
1138 pageLayoutModule->paperwidthLE->setEnabled(custom);
1139 pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
1140 pageLayoutModule->paperheightL->setEnabled(custom);
1141 pageLayoutModule->paperheightLE->setEnabled(custom);
1142 pageLayoutModule->paperheightLE->setFocus();
1143 pageLayoutModule->paperheightUnitCO->setEnabled(custom);
1147 void GuiDocument::setColSep()
1149 setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
1153 void GuiDocument::setCustomMargins(bool custom)
1155 marginsModule->topL->setEnabled(!custom);
1156 marginsModule->topLE->setEnabled(!custom);
1157 marginsModule->topUnit->setEnabled(!custom);
1159 marginsModule->bottomL->setEnabled(!custom);
1160 marginsModule->bottomLE->setEnabled(!custom);
1161 marginsModule->bottomUnit->setEnabled(!custom);
1163 marginsModule->innerL->setEnabled(!custom);
1164 marginsModule->innerLE->setEnabled(!custom);
1165 marginsModule->innerUnit->setEnabled(!custom);
1167 marginsModule->outerL->setEnabled(!custom);
1168 marginsModule->outerLE->setEnabled(!custom);
1169 marginsModule->outerUnit->setEnabled(!custom);
1171 marginsModule->headheightL->setEnabled(!custom);
1172 marginsModule->headheightLE->setEnabled(!custom);
1173 marginsModule->headheightUnit->setEnabled(!custom);
1175 marginsModule->headsepL->setEnabled(!custom);
1176 marginsModule->headsepLE->setEnabled(!custom);
1177 marginsModule->headsepUnit->setEnabled(!custom);
1179 marginsModule->footskipL->setEnabled(!custom);
1180 marginsModule->footskipLE->setEnabled(!custom);
1181 marginsModule->footskipUnit->setEnabled(!custom);
1183 bool const enableColSep = !custom &&
1184 textLayoutModule->twoColumnCB->checkState() == Qt::Checked;
1185 marginsModule->columnsepL->setEnabled(enableColSep);
1186 marginsModule->columnsepLE->setEnabled(enableColSep);
1187 marginsModule->columnsepUnit->setEnabled(enableColSep);
1190 void GuiDocument::changeBackgroundColor()
1192 const QColor newColor = QColorDialog::getColor(
1193 rgb2qcolor(set_backgroundcolor), qApp->focusWidget());
1194 if (!newColor.isValid())
1196 // set the button color
1197 pageLayoutModule->backgroundTB->setStyleSheet(
1198 colorButtonStyleSheet(newColor));
1199 // save white as the set color
1200 set_backgroundcolor = rgbFromHexName(fromqstr(newColor.name()));
1205 void GuiDocument::deleteBackgroundColor()
1207 // set the button color back to white
1208 pageLayoutModule->backgroundTB->setStyleSheet(
1209 colorButtonStyleSheet(QColor(Qt::white)));
1210 // save white as the set color
1211 set_backgroundcolor = rgbFromHexName("#ffffff");
1216 void GuiDocument::xetexChanged(bool xetex)
1219 updateDefaultFormat();
1220 langModule->encodingCO->setEnabled(!xetex &&
1221 !langModule->defaultencodingRB->isChecked());
1222 langModule->defaultencodingRB->setEnabled(!xetex);
1223 langModule->otherencodingRB->setEnabled(!xetex);
1225 fontModule->fontsDefaultCO->setEnabled(!xetex);
1226 fontModule->fontsDefaultLA->setEnabled(!xetex);
1227 fontModule->cjkFontLE->setEnabled(!xetex);
1228 fontModule->cjkFontLA->setEnabled(!xetex);
1231 font = tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1232 bool scaleable = providesScale(font);
1233 fontModule->scaleSansSB->setEnabled(scaleable);
1234 fontModule->scaleSansLA->setEnabled(scaleable);
1236 font = tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1237 scaleable = providesScale(font);
1238 fontModule->scaleTypewriterSB->setEnabled(scaleable);
1239 fontModule->scaleTypewriterLA->setEnabled(scaleable);
1241 font = tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1242 fontModule->fontScCB->setEnabled(providesSC(font));
1243 fontModule->fontOsfCB->setEnabled(providesOSF(font));
1247 void GuiDocument::updateFontsize(string const & items, string const & sel)
1249 fontModule->fontsizeCO->clear();
1250 fontModule->fontsizeCO->addItem(qt_("Default"));
1252 for (int n = 0; !token(items,'|',n).empty(); ++n)
1253 fontModule->fontsizeCO->
1254 addItem(toqstr(token(items,'|',n)));
1256 for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
1257 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
1258 fontModule->fontsizeCO->setCurrentIndex(n);
1265 void GuiDocument::updateFontlist()
1267 fontModule->fontsRomanCO->clear();
1268 fontModule->fontsSansCO->clear();
1269 fontModule->fontsTypewriterCO->clear();
1271 // With XeTeX, we have access to all system fonts, but not the LaTeX fonts
1272 if (outputModule->xetexCB->isChecked()) {
1273 fontModule->fontsRomanCO->addItem(qt_("Default"));
1274 fontModule->fontsSansCO->addItem(qt_("Default"));
1275 fontModule->fontsTypewriterCO->addItem(qt_("Default"));
1277 QFontDatabase fontdb;
1278 QStringList families(fontdb.families());
1279 for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
1280 fontModule->fontsRomanCO->addItem(*it);
1281 fontModule->fontsSansCO->addItem(*it);
1282 fontModule->fontsTypewriterCO->addItem(*it);
1287 for (int n = 0; tex_fonts_roman[n][0]; ++n) {
1288 QString font = qt_(tex_fonts_roman_gui[n]);
1289 if (!isFontAvailable(tex_fonts_roman[n]))
1290 font += qt_(" (not installed)");
1291 fontModule->fontsRomanCO->addItem(font);
1293 for (int n = 0; tex_fonts_sans[n][0]; ++n) {
1294 QString font = qt_(tex_fonts_sans_gui[n]);
1295 if (!isFontAvailable(tex_fonts_sans[n]))
1296 font += qt_(" (not installed)");
1297 fontModule->fontsSansCO->addItem(font);
1299 for (int n = 0; tex_fonts_monospaced[n][0]; ++n) {
1300 QString font = qt_(tex_fonts_monospaced_gui[n]);
1301 if (!isFontAvailable(tex_fonts_monospaced[n]))
1302 font += qt_(" (not installed)");
1303 fontModule->fontsTypewriterCO->addItem(font);
1308 void GuiDocument::romanChanged(int item)
1310 if (outputModule->xetexCB->isChecked())
1312 string const font = tex_fonts_roman[item];
1313 fontModule->fontScCB->setEnabled(providesSC(font));
1314 fontModule->fontOsfCB->setEnabled(providesOSF(font));
1318 void GuiDocument::sansChanged(int item)
1320 if (outputModule->xetexCB->isChecked())
1322 string const font = tex_fonts_sans[item];
1323 bool scaleable = providesScale(font);
1324 fontModule->scaleSansSB->setEnabled(scaleable);
1325 fontModule->scaleSansLA->setEnabled(scaleable);
1329 void GuiDocument::ttChanged(int item)
1331 if (outputModule->xetexCB->isChecked())
1333 string const font = tex_fonts_monospaced[item];
1334 bool scaleable = providesScale(font);
1335 fontModule->scaleTypewriterSB->setEnabled(scaleable);
1336 fontModule->scaleTypewriterLA->setEnabled(scaleable);
1340 void GuiDocument::updatePagestyle(string const & items, string const & sel)
1343 pageLayoutModule->pagestyleCO->clear();
1344 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1346 for (int n = 0; !token(items, '|', n).empty(); ++n) {
1347 string style = token(items, '|', n);
1348 QString style_gui = qt_(style);
1349 pagestyles.push_back(pair<string, QString>(style, style_gui));
1350 pageLayoutModule->pagestyleCO->addItem(style_gui);
1353 if (sel == "default") {
1354 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
1360 for (size_t i = 0; i < pagestyles.size(); ++i)
1361 if (pagestyles[i].first == sel)
1362 nn = pageLayoutModule->pagestyleCO->findText(pagestyles[i].second);
1365 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
1369 void GuiDocument::browseLayout()
1371 QString const label1 = qt_("Layouts|#o#O");
1372 QString const dir1 = toqstr(lyxrc.document_path);
1373 QStringList const filter(qt_("LyX Layout (*.layout)"));
1374 QString file = browseRelFile(QString(), bufferFilepath(),
1375 qt_("Local layout file"), filter, false,
1378 if (!file.endsWith(".layout"))
1381 FileName layoutFile = support::makeAbsPath(fromqstr(file),
1382 fromqstr(bufferFilepath()));
1384 int const ret = Alert::prompt(_("Local layout file"),
1385 _("The layout file you have selected is a local layout\n"
1386 "file, not one in the system or user directory. Your\n"
1387 "document may not work with this layout if you do not\n"
1388 "keep the layout file in the document directory."),
1389 1, 1, _("&Set Layout"), _("&Cancel"));
1393 // load the layout file
1394 LayoutFileList & bcl = LayoutFileList::get();
1395 string classname = layoutFile.onlyFileName();
1396 // this will update an existing layout if that layout has been loaded before.
1397 LayoutFileIndex name = bcl.addLocalLayout(
1398 classname.substr(0, classname.size() - 7),
1399 layoutFile.onlyPath().absFilename());
1402 Alert::error(_("Error"),
1403 _("Unable to read local layout file."));
1407 // do not trigger classChanged if there is no change.
1408 if (latexModule->classCO->currentText() == toqstr(name))
1412 int idx = latexModule->classCO->findText(toqstr(name));
1414 classes_model_.insertRow(0, toqstr(name), name);
1415 latexModule->classCO->setCurrentIndex(0);
1417 latexModule->classCO->setCurrentIndex(idx);
1423 void GuiDocument::browseMaster()
1425 QString const title = qt_("Select master document");
1426 QString const dir1 = toqstr(lyxrc.document_path);
1427 QString const old = latexModule->childDocLE->text();
1428 QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
1429 QStringList const filter(qt_("LyX Files (*.lyx)"));
1430 QString file = browseRelFile(old, docpath, title, filter, false,
1431 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
1433 latexModule->childDocLE->setText(file);
1437 void GuiDocument::classChanged()
1439 int idx = latexModule->classCO->currentIndex();
1442 string const classname = classes_model_.getIDString(idx);
1444 // check whether the selected modules have changed.
1445 bool modules_changed = false;
1446 unsigned int const srows = selectedModel()->rowCount();
1447 if (srows != bp_.getModules().size())
1448 modules_changed = true;
1450 list<string>::const_iterator mit = bp_.getModules().begin();
1451 list<string>::const_iterator men = bp_.getModules().end();
1452 for (unsigned int i = 0; i < srows && mit != men; ++i, ++mit)
1453 if (selectedModel()->getIDString(i) != *mit) {
1454 modules_changed = true;
1459 if (modules_changed || lyxrc.auto_reset_options) {
1460 if (applyPB->isEnabled()) {
1461 int const ret = Alert::prompt(_("Unapplied changes"),
1462 _("Some changes in the dialog were not yet applied.\n"
1463 "If you do not apply now, they will be lost after this action."),
1464 1, 1, _("&Apply"), _("&Dismiss"));
1470 // We load the TextClass as soon as it is selected. This is
1471 // necessary so that other options in the dialog can be updated
1472 // according to the new class. Note, however, that, if you use
1473 // the scroll wheel when sitting on the combo box, we'll load a
1474 // lot of TextClass objects very quickly....
1475 if (!bp_.setBaseClass(classname)) {
1476 Alert::error(_("Error"), _("Unable to set document class."));
1479 if (lyxrc.auto_reset_options)
1480 bp_.useClassDefaults();
1482 // With the introduction of modules came a distinction between the base
1483 // class and the document class. The former corresponds to the main layout
1484 // file; the latter is that plus the modules (or the document-specific layout,
1485 // or whatever else there could be). Our parameters come from the document
1486 // class. So when we set the base class, we also need to recreate the document
1487 // class. Otherwise, we still have the old one.
1488 bp_.makeDocumentClass();
1494 // This is an insanely complicated attempt to make this sort of thing
1495 // work with RTL languages.
1496 docstring formatStrVec(vector<string> const & v, docstring const & s)
1498 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
1502 return from_utf8(v[0]);
1503 if (v.size() == 2) {
1504 docstring retval = _("%1$s and %2$s");
1505 retval = subst(retval, _("and"), s);
1506 return bformat(retval, from_utf8(v[0]), from_utf8(v[1]));
1508 // The idea here is to format all but the last two items...
1509 int const vSize = v.size();
1510 docstring t2 = _("%1$s, %2$s");
1511 docstring retval = from_utf8(v[0]);
1512 for (int i = 1; i < vSize - 2; ++i)
1513 retval = bformat(t2, retval, from_utf8(v[i]));
1514 //...and then to plug them, and the last two, into this schema
1515 docstring t = _("%1$s, %2$s, and %3$s");
1516 t = subst(t, _("and"), s);
1517 return bformat(t, retval, from_utf8(v[vSize - 2]), from_utf8(v[vSize - 1]));
1520 vector<string> idsToNames(vector<string> const & idList)
1522 vector<string> retval;
1523 vector<string>::const_iterator it = idList.begin();
1524 vector<string>::const_iterator end = idList.end();
1525 for (; it != end; ++it) {
1526 LyXModule const * const mod = moduleList[*it];
1528 retval.push_back(*it + " (Unavailable)");
1530 retval.push_back(mod->getName());
1537 void GuiDocument::modulesToParams(BufferParams & bp)
1539 // update list of loaded modules
1540 bp.clearLayoutModules();
1541 int const srows = modules_sel_model_.rowCount();
1542 for (int i = 0; i < srows; ++i)
1543 bp.addLayoutModule(modules_sel_model_.getIDString(i));
1545 // update the list of removed modules
1546 bp.clearRemovedModules();
1547 LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
1548 list<string>::const_iterator rit = reqmods.begin();
1549 list<string>::const_iterator ren = reqmods.end();
1551 // check each of the default modules
1552 for (; rit != ren; rit++) {
1553 list<string>::const_iterator mit = bp.getModules().begin();
1554 list<string>::const_iterator men = bp.getModules().end();
1556 for (; mit != men; mit++) {
1563 // the module isn't present so must have been removed by the user
1564 bp.addRemovedModule(*rit);
1569 void GuiDocument::modulesChanged()
1571 modulesToParams(bp_);
1572 bp_.makeDocumentClass();
1577 void GuiDocument::updateModuleInfo()
1579 selectionManager->update();
1581 //Module description
1582 bool const focus_on_selected = selectionManager->selectedFocused();
1583 QListView const * const lv =
1584 focus_on_selected ? modulesModule->selectedLV : modulesModule->availableLV;
1585 if (lv->selectionModel()->selectedIndexes().isEmpty()) {
1586 modulesModule->infoML->document()->clear();
1589 QModelIndex const & idx = lv->selectionModel()->currentIndex();
1590 GuiIdListModel const & id_model =
1591 focus_on_selected ? modules_sel_model_ : modules_av_model_;
1592 string const modName = id_model.getIDString(idx.row());
1593 docstring desc = getModuleDescription(modName);
1595 LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
1596 if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
1599 desc += _("Module provided by document class.");
1602 vector<string> pkglist = getPackageList(modName);
1603 docstring pkgdesc = formatStrVec(pkglist, _("and"));
1604 if (!pkgdesc.empty()) {
1607 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
1610 pkglist = getRequiredList(modName);
1611 if (!pkglist.empty()) {
1612 vector<string> const reqdescs = idsToNames(pkglist);
1613 pkgdesc = formatStrVec(reqdescs, _("or"));
1616 desc += bformat(_("Module required: %1$s."), pkgdesc);
1619 pkglist = getExcludedList(modName);
1620 if (!pkglist.empty()) {
1621 vector<string> const reqdescs = idsToNames(pkglist);
1622 pkgdesc = formatStrVec(reqdescs, _( "and"));
1625 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
1628 if (!isModuleAvailable(modName)) {
1631 desc += _("WARNING: Some required packages are unavailable!");
1634 modulesModule->infoML->document()->setPlainText(toqstr(desc));
1638 void GuiDocument::updateNumbering()
1640 DocumentClass const & tclass = documentClass();
1642 numberingModule->tocTW->setUpdatesEnabled(false);
1643 numberingModule->tocTW->clear();
1645 int const depth = numberingModule->depthSL->value();
1646 int const toc = numberingModule->tocSL->value();
1647 QString const no = qt_("No");
1648 QString const yes = qt_("Yes");
1649 QTreeWidgetItem * item = 0;
1651 DocumentClass::const_iterator lit = tclass.begin();
1652 DocumentClass::const_iterator len = tclass.end();
1653 for (; lit != len; ++lit) {
1654 int const toclevel = lit->toclevel;
1655 if (toclevel != Layout::NOT_IN_TOC && lit->labeltype == LABEL_COUNTER) {
1656 item = new QTreeWidgetItem(numberingModule->tocTW);
1657 item->setText(0, toqstr(translateIfPossible(lit->name())));
1658 item->setText(1, (toclevel <= depth) ? yes : no);
1659 item->setText(2, (toclevel <= toc) ? yes : no);
1663 numberingModule->tocTW->setUpdatesEnabled(true);
1664 numberingModule->tocTW->update();
1668 void GuiDocument::updateDefaultFormat()
1670 // make a copy in order to consider unapplied changes
1671 Buffer * tmpbuf = const_cast<Buffer *>(&buffer());
1672 tmpbuf->params().useXetex = outputModule->xetexCB->isChecked();
1673 int idx = latexModule->classCO->currentIndex();
1675 string const classname = classes_model_.getIDString(idx);
1676 tmpbuf->params().setBaseClass(classname);
1677 tmpbuf->params().makeDocumentClass();
1679 outputModule->defaultFormatCO->blockSignals(true);
1680 outputModule->defaultFormatCO->clear();
1681 outputModule->defaultFormatCO->addItem(qt_("Default"),
1682 QVariant(QString("default")));
1683 typedef vector<Format const *> Formats;
1684 Formats formats = tmpbuf->exportableFormats(true);
1685 Formats::const_iterator cit = formats.begin();
1686 Formats::const_iterator end = formats.end();
1687 for (; cit != end; ++cit)
1688 outputModule->defaultFormatCO->addItem(qt_((*cit)->prettyname()),
1689 QVariant(toqstr((*cit)->name())));
1690 outputModule->defaultFormatCO->blockSignals(false);
1694 void GuiDocument::applyView()
1697 preambleModule->apply(bp_);
1700 bp_.setCiteEngine(ENGINE_BASIC);
1702 if (biblioModule->citeNatbibRB->isChecked()) {
1703 bool const use_numerical_citations =
1704 biblioModule->citeStyleCO->currentIndex();
1705 if (use_numerical_citations)
1706 bp_.setCiteEngine(ENGINE_NATBIB_NUMERICAL);
1708 bp_.setCiteEngine(ENGINE_NATBIB_AUTHORYEAR);
1710 } else if (biblioModule->citeJurabibRB->isChecked())
1711 bp_.setCiteEngine(ENGINE_JURABIB);
1714 biblioModule->bibtopicCB->isChecked();
1716 // language & quotes
1717 if (langModule->defaultencodingRB->isChecked()) {
1718 bp_.inputenc = "auto";
1720 int i = langModule->encodingCO->currentIndex();
1722 bp_.inputenc = "default";
1724 QString const enc_gui =
1725 langModule->encodingCO->currentText();
1726 Encodings::const_iterator it = encodings.begin();
1727 Encodings::const_iterator const end = encodings.end();
1729 for (; it != end; ++it) {
1730 if (qt_(it->guiName()) == enc_gui) {
1731 bp_.inputenc = it->latexName();
1737 // should not happen
1738 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
1739 bp_.inputenc = "default";
1744 InsetQuotes::QuoteLanguage lga = InsetQuotes::EnglishQuotes;
1745 switch (langModule->quoteStyleCO->currentIndex()) {
1747 lga = InsetQuotes::EnglishQuotes;
1750 lga = InsetQuotes::SwedishQuotes;
1753 lga = InsetQuotes::GermanQuotes;
1756 lga = InsetQuotes::PolishQuotes;
1759 lga = InsetQuotes::FrenchQuotes;
1762 lga = InsetQuotes::DanishQuotes;
1765 bp_.quotes_language = lga;
1767 QString const lang = langModule->languageCO->itemData(
1768 langModule->languageCO->currentIndex()).toString();
1769 bp_.language = languages.getLanguage(fromqstr(lang));
1772 if (bp_.documentClass().hasTocLevels()) {
1773 bp_.tocdepth = numberingModule->tocSL->value();
1774 bp_.secnumdepth = numberingModule->depthSL->value();
1778 bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
1779 bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
1780 bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
1781 bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
1784 bp_.graphicsDriver =
1785 tex_graphics[latexModule->psdriverCO->currentIndex()];
1788 int idx = latexModule->classCO->currentIndex();
1790 string const classname = classes_model_.getIDString(idx);
1791 bp_.setBaseClass(classname);
1795 modulesToParams(bp_);
1797 if (mathsModule->amsautoCB->isChecked()) {
1798 bp_.use_amsmath = BufferParams::package_auto;
1800 if (mathsModule->amsCB->isChecked())
1801 bp_.use_amsmath = BufferParams::package_on;
1803 bp_.use_amsmath = BufferParams::package_off;
1806 if (mathsModule->esintautoCB->isChecked())
1807 bp_.use_esint = BufferParams::package_auto;
1809 if (mathsModule->esintCB->isChecked())
1810 bp_.use_esint = BufferParams::package_on;
1812 bp_.use_esint = BufferParams::package_off;
1815 if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
1816 bp_.pagestyle = "default";
1818 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
1819 for (size_t i = 0; i != pagestyles.size(); ++i)
1820 if (pagestyles[i].second == style_gui)
1821 bp_.pagestyle = pagestyles[i].first;
1824 switch (textLayoutModule->lspacingCO->currentIndex()) {
1826 bp_.spacing().set(Spacing::Single);
1829 bp_.spacing().set(Spacing::Onehalf);
1832 bp_.spacing().set(Spacing::Double);
1835 bp_.spacing().set(Spacing::Other,
1836 fromqstr(textLayoutModule->lspacingLE->text()));
1840 if (textLayoutModule->twoColumnCB->isChecked())
1845 // text should have passed validation
1846 bp_.listings_params =
1847 InsetListingsParams(fromqstr(textLayoutModule->listingsED->toPlainText())).params();
1849 if (textLayoutModule->indentRB->isChecked())
1850 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
1852 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
1854 switch (textLayoutModule->skipCO->currentIndex()) {
1856 bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
1859 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
1862 bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
1867 widgetsToLength(textLayoutModule->skipLE,
1868 textLayoutModule->skipLengthCO)
1874 // DocumentDefskipCB assures that this never happens
1875 // so Assert then !!! - jbl
1876 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
1881 fromqstr(latexModule->optionsLE->text());
1883 bp_.use_default_options =
1884 latexModule->defaultOptionsCB->isChecked();
1886 if (latexModule->childDocGB->isChecked())
1888 fromqstr(latexModule->childDocLE->text());
1890 bp_.master = string();
1892 bp_.float_placement = floatModule->get();
1895 bp_.defaultOutputFormat = fromqstr(outputModule->defaultFormatCO->itemData(
1896 outputModule->defaultFormatCO->currentIndex()).toString());
1898 bool const xetex = outputModule->xetexCB->isChecked();
1899 bp_.useXetex = xetex;
1903 if (fontModule->fontsRomanCO->currentIndex() == 0)
1904 bp_.fontsRoman = "default";
1907 fromqstr(fontModule->fontsRomanCO->currentText());
1909 if (fontModule->fontsSansCO->currentIndex() == 0)
1910 bp_.fontsSans = "default";
1913 fromqstr(fontModule->fontsSansCO->currentText());
1915 if (fontModule->fontsTypewriterCO->currentIndex() == 0)
1916 bp_.fontsTypewriter = "default";
1918 bp_.fontsTypewriter =
1919 fromqstr(fontModule->fontsTypewriterCO->currentText());
1922 tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1925 tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1927 bp_.fontsTypewriter =
1928 tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1932 fromqstr(fontModule->cjkFontLE->text());
1934 bp_.fontsSansScale = fontModule->scaleSansSB->value();
1936 bp_.fontsTypewriterScale = fontModule->scaleTypewriterSB->value();
1938 bp_.fontsSC = fontModule->fontScCB->isChecked();
1940 bp_.fontsOSF = fontModule->fontOsfCB->isChecked();
1943 bp_.fontsDefaultFamily = "default";
1945 bp_.fontsDefaultFamily = GuiDocument::fontfamilies[
1946 fontModule->fontsDefaultCO->currentIndex()];
1948 if (fontModule->fontsizeCO->currentIndex() == 0)
1949 bp_.fontsize = "default";
1952 fromqstr(fontModule->fontsizeCO->currentText());
1955 bp_.papersize = PAPER_SIZE(
1956 pageLayoutModule->papersizeCO->currentIndex());
1958 // custom, A3, B3 and B4 paper sizes need geometry
1959 int psize = pageLayoutModule->papersizeCO->currentIndex();
1960 bool geom_papersize = (psize == 1 || psize == 5 || psize == 8 || psize == 9);
1962 bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
1963 pageLayoutModule->paperwidthUnitCO);
1965 bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
1966 pageLayoutModule->paperheightUnitCO);
1968 if (pageLayoutModule->facingPagesCB->isChecked())
1969 bp_.sides = TwoSides;
1971 bp_.sides = OneSide;
1973 if (pageLayoutModule->landscapeRB->isChecked())
1974 bp_.orientation = ORIENTATION_LANDSCAPE;
1976 bp_.orientation = ORIENTATION_PORTRAIT;
1978 bp_.backgroundcolor = set_backgroundcolor;
1981 bp_.use_geometry = !marginsModule->marginCB->isChecked()
1984 Ui::MarginsUi const * m = marginsModule;
1986 bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
1987 bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
1988 bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
1989 bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
1990 bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
1991 bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
1992 bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
1993 bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
1995 branchesModule->apply(bp_);
1998 PDFOptions & pdf = bp_.pdfoptions();
1999 pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
2000 pdf.title = fromqstr(pdfSupportModule->titleLE->text());
2001 pdf.author = fromqstr(pdfSupportModule->authorLE->text());
2002 pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
2003 pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
2005 pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
2006 pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
2007 pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
2008 pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
2010 pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
2011 pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
2012 pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
2013 pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
2015 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
2016 if (pdfSupportModule->fullscreenCB->isChecked())
2017 pdf.pagemode = pdf.pagemode_fullscreen;
2019 pdf.pagemode.clear();
2020 pdf.quoted_options = pdf.quoted_options_check(
2021 fromqstr(pdfSupportModule->optionsLE->text()));
2025 void GuiDocument::paramsToDialog()
2027 // set the default unit
2028 Length::UNIT const defaultUnit = Length::defaultUnit();
2031 preambleModule->update(bp_, id());
2034 biblioModule->citeDefaultRB->setChecked(
2035 bp_.citeEngine() == ENGINE_BASIC);
2037 biblioModule->citeNatbibRB->setChecked(
2038 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL ||
2039 bp_.citeEngine() == ENGINE_NATBIB_AUTHORYEAR);
2041 biblioModule->citeStyleCO->setCurrentIndex(
2042 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL);
2044 biblioModule->citeJurabibRB->setChecked(
2045 bp_.citeEngine() == ENGINE_JURABIB);
2047 biblioModule->bibtopicCB->setChecked(
2050 // language & quotes
2051 int const pos = langModule->languageCO->findData(toqstr(
2052 bp_.language->lang()));
2053 langModule->languageCO->setCurrentIndex(pos);
2055 langModule->quoteStyleCO->setCurrentIndex(
2056 bp_.quotes_language);
2058 bool default_enc = true;
2059 if (bp_.inputenc != "auto") {
2060 default_enc = false;
2061 if (bp_.inputenc == "default") {
2062 langModule->encodingCO->setCurrentIndex(0);
2065 Encodings::const_iterator it = encodings.begin();
2066 Encodings::const_iterator const end = encodings.end();
2067 for (; it != end; ++it) {
2068 if (it->latexName() == bp_.inputenc) {
2069 enc_gui = it->guiName();
2073 int const i = langModule->encodingCO->findText(
2076 langModule->encodingCO->setCurrentIndex(i);
2078 // unknown encoding. Set to default.
2082 langModule->defaultencodingRB->setChecked(default_enc);
2083 langModule->otherencodingRB->setChecked(!default_enc);
2086 int const min_toclevel = documentClass().min_toclevel();
2087 int const max_toclevel = documentClass().max_toclevel();
2088 if (documentClass().hasTocLevels()) {
2089 numberingModule->setEnabled(true);
2090 numberingModule->depthSL->setMinimum(min_toclevel - 1);
2091 numberingModule->depthSL->setMaximum(max_toclevel);
2092 numberingModule->depthSL->setValue(bp_.secnumdepth);
2093 numberingModule->tocSL->setMaximum(min_toclevel - 1);
2094 numberingModule->tocSL->setMaximum(max_toclevel);
2095 numberingModule->tocSL->setValue(bp_.tocdepth);
2098 numberingModule->setEnabled(false);
2099 numberingModule->tocTW->clear();
2103 bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
2104 bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
2105 bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
2106 bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
2107 bulletsModule->init();
2110 int nitem = findToken(tex_graphics, bp_.graphicsDriver);
2112 latexModule->psdriverCO->setCurrentIndex(nitem);
2115 mathsModule->amsCB->setChecked(
2116 bp_.use_amsmath == BufferParams::package_on);
2117 mathsModule->amsautoCB->setChecked(
2118 bp_.use_amsmath == BufferParams::package_auto);
2120 mathsModule->esintCB->setChecked(
2121 bp_.use_esint == BufferParams::package_on);
2122 mathsModule->esintautoCB->setChecked(
2123 bp_.use_esint == BufferParams::package_auto);
2125 switch (bp_.spacing().getSpace()) {
2126 case Spacing::Other: nitem = 3; break;
2127 case Spacing::Double: nitem = 2; break;
2128 case Spacing::Onehalf: nitem = 1; break;
2129 case Spacing::Default: case Spacing::Single: nitem = 0; break;
2133 string const & layoutID = bp_.baseClassID();
2134 setLayoutComboByIDString(layoutID);
2136 updatePagestyle(documentClass().opt_pagestyle(),
2139 textLayoutModule->lspacingCO->setCurrentIndex(nitem);
2140 if (bp_.spacing().getSpace() == Spacing::Other) {
2141 textLayoutModule->lspacingLE->setText(
2142 toqstr(bp_.spacing().getValueAsString()));
2146 if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation)
2147 textLayoutModule->indentRB->setChecked(true);
2149 textLayoutModule->skipRB->setChecked(true);
2152 switch (bp_.getDefSkip().kind()) {
2153 case VSpace::SMALLSKIP:
2156 case VSpace::MEDSKIP:
2159 case VSpace::BIGSKIP:
2162 case VSpace::LENGTH:
2165 string const length = bp_.getDefSkip().asLyXCommand();
2166 lengthToWidgets(textLayoutModule->skipLE,
2167 textLayoutModule->skipLengthCO,
2168 length, defaultUnit);
2175 textLayoutModule->skipCO->setCurrentIndex(skip);
2178 textLayoutModule->twoColumnCB->setChecked(
2181 // break listings_params to multiple lines
2183 InsetListingsParams(bp_.listings_params).separatedParams();
2184 textLayoutModule->listingsED->setPlainText(toqstr(lstparams));
2186 if (!bp_.options.empty()) {
2187 latexModule->optionsLE->setText(
2188 toqstr(bp_.options));
2190 latexModule->optionsLE->setText(QString());
2194 latexModule->defaultOptionsCB->setChecked(
2195 bp_.use_default_options);
2196 updateSelectedModules();
2197 selectionManager->updateProvidedModules(
2198 bp_.baseClass()->providedModules());
2199 selectionManager->updateExcludedModules(
2200 bp_.baseClass()->excludedModules());
2202 if (!documentClass().options().empty()) {
2203 latexModule->defaultOptionsLE->setText(
2204 toqstr(documentClass().options()));
2206 latexModule->defaultOptionsLE->setText(
2207 toqstr(_("[No options predefined]")));
2210 latexModule->defaultOptionsLE->setEnabled(
2211 bp_.use_default_options
2212 && !documentClass().options().empty());
2214 latexModule->defaultOptionsCB->setEnabled(
2215 !documentClass().options().empty());
2217 if (!bp_.master.empty()) {
2218 latexModule->childDocGB->setChecked(true);
2219 latexModule->childDocLE->setText(
2220 toqstr(bp_.master));
2222 latexModule->childDocLE->setText(QString());
2223 latexModule->childDocGB->setChecked(false);
2226 floatModule->set(bp_.float_placement);
2229 // update combobox with formats
2230 updateDefaultFormat();
2231 int index = outputModule->defaultFormatCO->findData(toqstr(
2232 bp_.defaultOutputFormat));
2233 // set to default if format is not found
2236 outputModule->defaultFormatCO->setCurrentIndex(index);
2237 outputModule->xetexCB->setEnabled(bp_.baseClass()->outputType() == lyx::LATEX);
2238 outputModule->xetexCB->setChecked(
2239 bp_.baseClass()->outputType() == lyx::LATEX && bp_.useXetex);
2242 updateFontsize(documentClass().opt_fontsize(),
2246 for (int i = 0; i < fontModule->fontsRomanCO->count(); ++i) {
2247 if (fontModule->fontsRomanCO->itemText(i) == toqstr(bp_.fontsRoman)) {
2248 fontModule->fontsRomanCO->setCurrentIndex(i);
2253 for (int i = 0; i < fontModule->fontsSansCO->count(); ++i) {
2254 if (fontModule->fontsSansCO->itemText(i) == toqstr(bp_.fontsSans)) {
2255 fontModule->fontsSansCO->setCurrentIndex(i);
2259 for (int i = 0; i < fontModule->fontsTypewriterCO->count(); ++i) {
2260 if (fontModule->fontsTypewriterCO->itemText(i) ==
2261 toqstr(bp_.fontsTypewriter)) {
2262 fontModule->fontsTypewriterCO->setCurrentIndex(i);
2267 int n = findToken(tex_fonts_roman, bp_.fontsRoman);
2269 fontModule->fontsRomanCO->setCurrentIndex(n);
2273 n = findToken(tex_fonts_sans, bp_.fontsSans);
2275 fontModule->fontsSansCO->setCurrentIndex(n);
2279 n = findToken(tex_fonts_monospaced, bp_.fontsTypewriter);
2281 fontModule->fontsTypewriterCO->setCurrentIndex(n);
2286 if (!bp_.fontsCJK.empty())
2287 fontModule->cjkFontLE->setText(
2288 toqstr(bp_.fontsCJK));
2290 fontModule->cjkFontLE->setText(QString());
2292 fontModule->fontScCB->setChecked(bp_.fontsSC);
2293 fontModule->fontOsfCB->setChecked(bp_.fontsOSF);
2294 fontModule->scaleSansSB->setValue(bp_.fontsSansScale);
2295 fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale);
2297 int nn = findToken(GuiDocument::fontfamilies, bp_.fontsDefaultFamily);
2299 fontModule->fontsDefaultCO->setCurrentIndex(nn);
2302 bool const extern_geometry =
2303 documentClass().provides("geometry");
2304 int const psize = bp_.papersize;
2305 pageLayoutModule->papersizeCO->setCurrentIndex(psize);
2306 setCustomPapersize(!extern_geometry && psize);
2307 pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
2309 bool const landscape =
2310 bp_.orientation == ORIENTATION_LANDSCAPE;
2311 pageLayoutModule->landscapeRB->setChecked(landscape);
2312 pageLayoutModule->portraitRB->setChecked(!landscape);
2313 pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
2314 pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
2316 pageLayoutModule->facingPagesCB->setChecked(
2317 bp_.sides == TwoSides);
2319 pageLayoutModule->backgroundTB->setStyleSheet(
2320 colorButtonStyleSheet(QColor(rgb2qcolor(bp_.backgroundcolor))));
2321 set_backgroundcolor = bp_.backgroundcolor;
2323 lengthToWidgets(pageLayoutModule->paperwidthLE,
2324 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, defaultUnit);
2325 lengthToWidgets(pageLayoutModule->paperheightLE,
2326 pageLayoutModule->paperheightUnitCO, bp_.paperheight, defaultUnit);
2329 Ui::MarginsUi * m = marginsModule;
2331 setMargins(!bp_.use_geometry);
2333 lengthToWidgets(m->topLE, m->topUnit,
2334 bp_.topmargin, defaultUnit);
2336 lengthToWidgets(m->bottomLE, m->bottomUnit,
2337 bp_.bottommargin, defaultUnit);
2339 lengthToWidgets(m->innerLE, m->innerUnit,
2340 bp_.leftmargin, defaultUnit);
2342 lengthToWidgets(m->outerLE, m->outerUnit,
2343 bp_.rightmargin, defaultUnit);
2345 lengthToWidgets(m->headheightLE, m->headheightUnit,
2346 bp_.headheight, defaultUnit);
2348 lengthToWidgets(m->headsepLE, m->headsepUnit,
2349 bp_.headsep, defaultUnit);
2351 lengthToWidgets(m->footskipLE, m->footskipUnit,
2352 bp_.footskip, defaultUnit);
2354 lengthToWidgets(m->columnsepLE, m->columnsepUnit,
2355 bp_.columnsep, defaultUnit);
2357 branchesModule->update(bp_);
2360 PDFOptions const & pdf = bp_.pdfoptions();
2361 pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
2362 pdfSupportModule->titleLE->setText(toqstr(pdf.title));
2363 pdfSupportModule->authorLE->setText(toqstr(pdf.author));
2364 pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
2365 pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
2367 pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
2368 pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
2369 pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
2371 pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
2373 pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
2374 pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
2375 pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
2376 pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
2378 nn = findToken(backref_opts, pdf.backref);
2380 pdfSupportModule->backrefCO->setCurrentIndex(nn);
2382 pdfSupportModule->fullscreenCB->setChecked
2383 (pdf.pagemode == pdf.pagemode_fullscreen);
2385 pdfSupportModule->optionsLE->setText(
2386 toqstr(pdf.quoted_options));
2388 // Make sure that the bc is in the INITIAL state
2389 if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
2394 void GuiDocument::saveDocDefault()
2396 // we have to apply the params first
2402 void GuiDocument::updateAvailableModules()
2404 modules_av_model_.clear();
2405 list<modInfoStruct> const & modInfoList = getModuleInfo();
2406 list<modInfoStruct>::const_iterator mit = modInfoList.begin();
2407 list<modInfoStruct>::const_iterator men = modInfoList.end();
2408 for (int i = 0; mit != men; ++mit, ++i)
2409 modules_av_model_.insertRow(i, mit->name, mit->id,
2414 void GuiDocument::updateSelectedModules()
2416 modules_sel_model_.clear();
2417 list<modInfoStruct> const selModList = getSelectedModules();
2418 list<modInfoStruct>::const_iterator mit = selModList.begin();
2419 list<modInfoStruct>::const_iterator men = selModList.end();
2420 for (int i = 0; mit != men; ++mit, ++i)
2421 modules_sel_model_.insertRow(i, mit->name, mit->id,
2426 void GuiDocument::updateContents()
2428 // Nothing to do here as the document settings is not cursor dependant.
2433 void GuiDocument::useClassDefaults()
2435 if (applyPB->isEnabled()) {
2436 int const ret = Alert::prompt(_("Unapplied changes"),
2437 _("Some changes in the dialog were not yet applied.\n"
2438 "If you do not apply now, they will be lost after this action."),
2439 1, 1, _("&Apply"), _("&Dismiss"));
2444 int idx = latexModule->classCO->currentIndex();
2445 string const classname = classes_model_.getIDString(idx);
2446 if (!bp_.setBaseClass(classname)) {
2447 Alert::error(_("Error"), _("Unable to set document class."));
2450 bp_.useClassDefaults();
2455 void GuiDocument::setLayoutComboByIDString(string const & idString)
2457 int idx = classes_model_.findIDString(idString);
2459 Alert::warning(_("Can't set layout!"),
2460 bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
2462 latexModule->classCO->setCurrentIndex(idx);
2466 bool GuiDocument::isValid()
2468 return validateListingsParameters().isEmpty()
2469 && (textLayoutModule->skipCO->currentIndex() != 3
2470 || !textLayoutModule->skipLE->text().isEmpty());
2474 char const * const GuiDocument::fontfamilies[5] = {
2475 "default", "rmdefault", "sfdefault", "ttdefault", ""
2479 char const * GuiDocument::fontfamilies_gui[5] = {
2480 N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
2484 bool GuiDocument::initialiseParams(string const &)
2486 BufferView const * view = bufferview();
2488 bp_ = BufferParams();
2492 bp_ = view->buffer().params();
2494 updateAvailableModules();
2495 //FIXME It'd be nice to make sure here that the selected
2496 //modules are consistent: That required modules are actually
2497 //selected, and that we don't have conflicts. If so, we could
2498 //at least pop up a warning.
2504 void GuiDocument::clearParams()
2506 bp_ = BufferParams();
2510 BufferId GuiDocument::id() const
2512 BufferView const * const view = bufferview();
2513 return view? &view->buffer() : 0;
2517 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
2519 return moduleNames_;
2523 list<GuiDocument::modInfoStruct> const
2524 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
2526 LayoutModuleList::const_iterator it = mods.begin();
2527 LayoutModuleList::const_iterator end = mods.end();
2528 list<modInfoStruct> mInfo;
2529 for (; it != end; ++it) {
2532 LyXModule * mod = moduleList[*it];
2535 m.name = toqstr(translateIfPossible(from_utf8(mod->getName())));
2537 m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
2544 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
2546 return makeModuleInfo(params().getModules());
2550 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
2552 return makeModuleInfo(params().baseClass()->providedModules());
2556 DocumentClass const & GuiDocument::documentClass() const
2558 return bp_.documentClass();
2562 static void dispatch_bufferparams(Dialog const & dialog,
2563 BufferParams const & bp, FuncCode lfun)
2566 ss << "\\begin_header\n";
2568 ss << "\\end_header\n";
2569 dialog.dispatch(FuncRequest(lfun, ss.str()));
2573 void GuiDocument::dispatchParams()
2575 // This must come first so that a language change is correctly noticed
2578 // Apply the BufferParams. Note that this will set the base class
2579 // and then update the buffer's layout.
2580 dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
2582 if (!params().master.empty()) {
2583 FileName const master_file = support::makeAbsPath(params().master,
2584 support::onlyPath(buffer().absFileName()));
2585 if (isLyXFilename(master_file.absFilename())) {
2586 Buffer * master = checkAndLoadLyXFile(master_file);
2588 if (master->isChild(const_cast<Buffer *>(&buffer())))
2589 const_cast<Buffer &>(buffer()).setParent(master);
2591 Alert::warning(_("Assigned master does not include this file"),
2592 bformat(_("You must include this file in the document\n"
2593 "'%1$s' in order to use the master document\n"
2594 "feature."), from_utf8(params().master)));
2596 Alert::warning(_("Could not load master"),
2597 bformat(_("The master document '%1$s'\n"
2598 "could not be loaded."),
2599 from_utf8(params().master)));
2603 // Generate the colours requested by each new branch.
2604 BranchList & branchlist = params().branchlist();
2605 if (!branchlist.empty()) {
2606 BranchList::const_iterator it = branchlist.begin();
2607 BranchList::const_iterator const end = branchlist.end();
2608 for (; it != end; ++it) {
2609 docstring const & current_branch = it->branch();
2610 Branch const * branch = branchlist.find(current_branch);
2611 string const x11hexname = X11hexname(branch->color());
2612 // display the new color
2613 docstring const str = current_branch + ' ' + from_ascii(x11hexname);
2614 dispatch(FuncRequest(LFUN_SET_COLOR, str));
2617 // Open insets of selected branches, close deselected ones
2618 dispatch(FuncRequest(LFUN_ALL_INSETS_TOGGLE,
2621 // FIXME: If we used an LFUN, we would not need those two lines:
2622 BufferView * bv = const_cast<BufferView *>(bufferview());
2623 bv->processUpdateFlags(Update::Force | Update::FitCursor);
2627 void GuiDocument::setLanguage() const
2629 Language const * const newL = bp_.language;
2630 if (buffer().params().language == newL)
2633 string const & lang_name = newL->lang();
2634 dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
2638 void GuiDocument::saveAsDefault() const
2640 dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
2644 bool GuiDocument::isFontAvailable(string const & font) const
2646 if (font == "default" || font == "cmr"
2647 || font == "cmss" || font == "cmtt")
2648 // these are standard
2650 if (font == "lmodern" || font == "lmss" || font == "lmtt")
2651 return LaTeXFeatures::isAvailable("lmodern");
2652 if (font == "times" || font == "palatino"
2653 || font == "helvet" || font == "courier")
2654 return LaTeXFeatures::isAvailable("psnfss");
2655 if (font == "cmbr" || font == "cmtl")
2656 return LaTeXFeatures::isAvailable("cmbright");
2657 if (font == "utopia")
2658 return LaTeXFeatures::isAvailable("utopia")
2659 || LaTeXFeatures::isAvailable("fourier");
2660 if (font == "beraserif" || font == "berasans"
2661 || font == "beramono")
2662 return LaTeXFeatures::isAvailable("bera");
2663 return LaTeXFeatures::isAvailable(font);
2667 bool GuiDocument::providesOSF(string const & font) const
2669 if (outputModule->xetexCB->isChecked())
2670 // FIXME: we should check if the fonts really
2671 // have OSF support. But how?
2674 return isFontAvailable("eco");
2675 if (font == "palatino")
2676 return isFontAvailable("mathpazo");
2681 bool GuiDocument::providesSC(string const & font) const
2683 if (outputModule->xetexCB->isChecked())
2685 if (font == "palatino")
2686 return isFontAvailable("mathpazo");
2687 if (font == "utopia")
2688 return isFontAvailable("fourier");
2693 bool GuiDocument::providesScale(string const & font) const
2695 if (outputModule->xetexCB->isChecked())
2697 return font == "helvet" || font == "luximono"
2698 || font == "berasans" || font == "beramono";
2702 void GuiDocument::loadModuleInfo()
2704 moduleNames_.clear();
2705 LyXModuleList::const_iterator it = moduleList.begin();
2706 LyXModuleList::const_iterator end = moduleList.end();
2707 for (; it != end; ++it) {
2711 m.name = toqstr(translateIfPossible(from_utf8(it->getName())));
2712 // this is supposed to give us the first sentence of the description
2715 toqstr(translateIfPossible(from_utf8(it->getDescription())));
2716 int const pos = desc.indexOf(".");
2718 desc.truncate(pos + 1);
2719 m.description = desc;
2720 moduleNames_.push_back(m);
2725 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
2728 } // namespace frontend
2731 #include "moc_GuiDocument.cpp"