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 Kimberly Heck (modules)
9 * Full author contact details are available in file CREDITS.
14 #include "GuiDocument.h"
16 #include "BulletsModule.h"
17 #include "CategorizedCombo.h"
18 #include "FancyLineEdit.h"
19 #include "GuiApplication.h"
20 #include "GuiBranches.h"
21 #include "GuiIndices.h"
23 #include "GuiSelectionManager.h"
24 #include "Validator.h"
26 #include "LayoutFile.h"
27 #include "BranchList.h"
28 #include "buffer_funcs.h"
30 #include "BufferView.h"
31 #include "CiteEnginesList.h"
33 #include "ColorCache.h"
34 #include "Converter.h"
37 #include "FloatPlacement.h"
39 #include "FuncRequest.h"
40 #include "IndicesList.h"
42 #include "LaTeXFeatures.h"
43 #include "LaTeXFonts.h"
45 #include "LayoutEnums.h"
46 #include "LayoutModuleList.h"
48 #include "ModuleList.h"
49 #include "PDFOptions.h"
50 #include "qt_helpers.h"
53 #include "TextClass.h"
57 #include "insets/InsetListingsParams.h"
58 #include "insets/InsetQuotes.h"
60 #include "support/debug.h"
61 #include "support/docstream.h"
62 #include "support/FileName.h"
63 #include "support/filetools.h"
64 #include "support/gettext.h"
65 #include "support/lassert.h"
66 #include "support/lstrings.h"
67 #include "support/Package.h"
68 #include "support/TempFile.h"
70 #include "frontends/alert.h"
72 #include <QAbstractItemModel>
73 #include <QButtonGroup>
75 #include <QCloseEvent>
76 #include <QDirIterator>
77 #include <QFontDatabase>
78 #include <QHeaderView>
81 #include <QTextBoundaryFinder>
82 #include <QTextCursor>
88 // a style sheet for color frame widgets
89 static inline QString colorFrameStyleSheet(QColor const & bgColor)
91 if (bgColor.isValid()) {
92 QString rc = QLatin1String("background-color:");
101 using namespace lyx::support;
106 char const * const tex_graphics[] =
108 "default", "dvialw", "dvilaser", "dvipdf", "dvipdfm", "dvipdfmx",
109 "dvips", "dvipsone", "dvitops", "dviwin", "dviwindo", "dvi2ps", "emtex",
110 "ln", "oztex", "pctexhp", "pctexps", "pctexwin", "pctex32", "pdftex",
111 "psprint", "pubps", "tcidvi", "textures", "truetex", "vtex", "xdvi",
116 char const * const tex_graphics_gui[] =
118 N_("Default"), "dvialw", "DviLaser", "dvipdf", "DVIPDFM", "DVIPDFMx",
119 "Dvips", "DVIPSONE", "DVItoPS", "DVIWIN", "DVIWindo", "dvi2ps", "EmTeX",
120 "LN", "OzTeX", "pctexhp", "pctexps", "pctexwin", "PCTeX32", "pdfTeX",
121 "psprint", "pubps", "tcidvi", "Textures", "TrueTeX", "VTeX", "xdvi",
122 "XeTeX", N_("None"), ""
126 char const * backref_opts[] =
128 "false", "section", "slide", "page", ""
132 char const * backref_opts_gui[] =
134 N_("Off"), N_("Section"), N_("Slide"), N_("Page"), ""
138 char const * lst_packages[] =
140 "Listings", "Minted", ""
144 vector<string> engine_types_;
145 vector<pair<string, QString> > pagestyles;
147 QMap<QString, QString> rmfonts_;
148 QMap<QString, QString> sffonts_;
149 QMap<QString, QString> ttfonts_;
150 QMap<QString, QString> mathfonts_;
158 lyx::RGBColor set_backgroundcolor;
159 bool is_backgroundcolor;
160 lyx::RGBColor set_fontcolor;
162 lyx::RGBColor set_notefontcolor;
163 bool is_notefontcolor;
164 lyx::RGBColor set_boxbgcolor;
166 bool forced_fontspec_activation;
168 } // anonymous namespace
173 // used when sorting the textclass list.
174 class less_textclass_avail_desc
177 bool operator()(string const & lhs, string const & rhs) const
179 // Ordering criteria:
180 // 1. Availability of text class
181 // 2. Description (lexicographic)
182 LayoutFile const & tc1 = LayoutFileList::get()[lhs];
183 LayoutFile const & tc2 = LayoutFileList::get()[rhs];
184 int const order = compare_no_case(
185 translateIfPossible(from_utf8(tc1.description())),
186 translateIfPossible(from_utf8(tc2.description())));
187 return (tc1.isTeXClassAvailable() && !tc2.isTeXClassAvailable()) ||
188 (tc1.isTeXClassAvailable() == tc2.isTeXClassAvailable() && order < 0);
197 vector<string> getRequiredList(string const & modName)
199 LyXModule const * const mod = theModuleList[modName];
201 return vector<string>(); //empty such thing
202 return mod->getRequiredModules();
206 vector<string> getExcludedList(string const & modName)
208 LyXModule const * const mod = theModuleList[modName];
210 return vector<string>(); //empty such thing
211 return mod->getExcludedModules();
215 docstring getModuleCategory(string const & modName)
217 LyXModule const * const mod = theModuleList[modName];
220 return from_utf8(mod->category());
224 docstring getModuleDescription(string const & modName)
226 LyXModule const * const mod = theModuleList[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 = theModuleList[modName];
238 return vector<string>(); //empty such thing
239 return mod->getPackageList();
243 bool isModuleAvailable(string const & modName)
245 LyXModule const * const mod = theModuleList[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(QObject * parent,
266 QTreeView * availableLVarg,
267 QTreeView * selectedLVarg,
268 QPushButton * addPBarg,
269 QPushButton * delPBarg,
270 QPushButton * upPBarg,
271 QPushButton * downPBarg,
272 QStandardItemModel * availableModelarg,
273 GuiIdListModel * selectedModelarg,
274 GuiDocument const * container)
275 : GuiSelectionManager(parent, availableLVarg, selectedLVarg, addPBarg, delPBarg,
276 upPBarg, downPBarg, availableModelarg, selectedModelarg),
277 container_(container)
280 void updateProvidedModules(LayoutModuleList const & pm)
281 { provided_modules_ = pm.list(); }
283 void updateExcludedModules(LayoutModuleList const & em)
284 { excluded_modules_ = em.list(); }
287 void updateAddPB() override;
289 void updateUpPB() override;
291 void updateDownPB() override;
293 void updateDelPB() override;
294 /// returns availableModel as a GuiIdListModel
295 QStandardItemModel * getAvailableModel()
297 return dynamic_cast<QStandardItemModel *>(availableModel);
299 /// returns selectedModel as a GuiIdListModel
300 GuiIdListModel * getSelectedModel()
302 return dynamic_cast<GuiIdListModel *>(selectedModel);
304 /// keeps a list of the modules the text class provides
305 list<string> provided_modules_;
307 list<string> excluded_modules_;
309 GuiDocument const * container_;
312 void ModuleSelectionManager::updateAddPB()
314 int const arows = availableModel->rowCount();
315 QModelIndexList const avail_sels =
316 availableLV->selectionModel()->selectedRows(0);
318 // disable if there aren't any modules (?), if none of them is chosen
319 // in the dialog, or if the chosen one is already selected for use.
320 if (arows == 0 || avail_sels.isEmpty() || isSelected(avail_sels.first())) {
321 addPB->setEnabled(false);
325 QModelIndex const & idx = availableLV->selectionModel()->currentIndex();
330 if (getAvailableModel()->itemFromIndex(idx)->hasChildren()) {
331 // This is a category header
332 addPB->setEnabled(false);
336 string const modname = fromqstr(getAvailableModel()->data(idx, Qt::UserRole).toString());
339 container_->params().layoutModuleCanBeAdded(modname);
340 addPB->setEnabled(enable);
344 void ModuleSelectionManager::updateDownPB()
346 int const srows = selectedModel->rowCount();
348 downPB->setEnabled(false);
351 QModelIndex const & curidx = selectedLV->selectionModel()->currentIndex();
352 int const curRow = curidx.row();
353 if (curRow < 0 || curRow >= srows - 1) { // invalid or last item
354 downPB->setEnabled(false);
358 // determine whether immediately succeeding element requires this one
359 string const curmodname = getSelectedModel()->getIDString(curRow);
360 string const nextmodname = getSelectedModel()->getIDString(curRow + 1);
362 vector<string> reqs = getRequiredList(nextmodname);
364 // if it doesn't require anything....
366 downPB->setEnabled(true);
370 // Enable it if this module isn't required.
371 // FIXME This should perhaps be more flexible and check whether, even
372 // if the next one is required, there is also an earlier one that will do.
374 find(reqs.begin(), reqs.end(), curmodname) == reqs.end());
377 void ModuleSelectionManager::updateUpPB()
379 int const srows = selectedModel->rowCount();
381 upPB->setEnabled(false);
385 QModelIndex const & curIdx = selectedLV->selectionModel()->currentIndex();
386 int curRow = curIdx.row();
387 if (curRow <= 0 || curRow > srows - 1) { // first item or invalid
388 upPB->setEnabled(false);
391 string const curmodname = getSelectedModel()->getIDString(curRow);
393 // determine whether immediately preceding element is required by this one
394 vector<string> reqs = getRequiredList(curmodname);
396 // if this one doesn't require anything....
398 upPB->setEnabled(true);
403 // Enable it if the preceding module isn't required.
404 // NOTE This is less flexible than it might be. We could check whether, even
405 // if the previous one is required, there is an earlier one that would do.
406 string const premod = getSelectedModel()->getIDString(curRow - 1);
407 upPB->setEnabled(find(reqs.begin(), reqs.end(), premod) == reqs.end());
410 void ModuleSelectionManager::updateDelPB()
412 int const srows = selectedModel->rowCount();
414 deletePB->setEnabled(false);
418 QModelIndex const & curidx =
419 selectedLV->selectionModel()->currentIndex();
420 int const curRow = curidx.row();
421 if (curRow < 0 || curRow >= srows) { // invalid index?
422 deletePB->setEnabled(false);
426 string const curmodname = getSelectedModel()->getIDString(curRow);
428 // We're looking here for a reason NOT to enable the button. If we
429 // find one, we disable it and return. If we don't, we'll end up at
430 // the end of the function, and then we enable it.
431 for (int i = curRow + 1; i < srows; ++i) {
432 string const thisMod = getSelectedModel()->getIDString(i);
433 vector<string> reqs = getRequiredList(thisMod);
434 //does this one require us?
435 if (find(reqs.begin(), reqs.end(), curmodname) == reqs.end())
439 // OK, so this module requires us
440 // is there an EARLIER module that also satisfies the require?
441 // NOTE We demand that it be earlier to keep the list of modules
442 // consistent with the rule that a module must be proceeded by a
443 // required module. There would be more flexible ways to proceed,
444 // but that would be a lot more complicated, and the logic here is
445 // already complicated. (That's why I've left the debugging code.)
446 // lyxerr << "Testing " << thisMod << endl;
447 bool foundone = false;
448 for (int j = 0; j < curRow; ++j) {
449 string const mod = getSelectedModel()->getIDString(j);
450 // lyxerr << "In loop: Testing " << mod << endl;
451 // do we satisfy the require?
452 if (find(reqs.begin(), reqs.end(), mod) != reqs.end()) {
453 // lyxerr << mod << " does the trick." << endl;
458 // did we find a module to satisfy the require?
460 // lyxerr << "No matching module found." << endl;
461 deletePB->setEnabled(false);
465 // lyxerr << "All's well that ends well." << endl;
466 deletePB->setEnabled(true);
470 /////////////////////////////////////////////////////////////////////
474 /////////////////////////////////////////////////////////////////////
476 PreambleModule::PreambleModule(QWidget * parent)
477 : UiWidget<Ui::PreambleUi>(parent), current_id_(nullptr),
478 highlighter_(new LaTeXHighlighter(preambleTE->document(), true))
480 // This is not a memory leak. The object will be destroyed
482 // @ is letter in the LyX user preamble
483 preambleTE->setFont(guiApp->typewriterSystemFont());
484 preambleTE->setWordWrapMode(QTextOption::NoWrap);
485 setFocusProxy(preambleTE);
486 // Install event filter on find line edit to capture return/enter key
487 findLE->installEventFilter(this);
488 connect(preambleTE, SIGNAL(textChanged()), this, SIGNAL(changed()));
489 connect(findLE, SIGNAL(textEdited(const QString &)), this, SLOT(checkFindButton()));
490 connect(findButtonPB, SIGNAL(clicked()), this, SLOT(findText()));
491 connect(editPB, SIGNAL(clicked()), this, SLOT(editExternal()));
492 connect(findLE, SIGNAL(returnPressed()), this, SLOT(findText()));
494 int const tabStop = 4;
495 QFontMetrics metrics(preambleTE->currentFont());
496 #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
497 // horizontalAdvance() is available starting in 5.11.0
498 // setTabStopDistance() is available starting in 5.10.0
499 preambleTE->setTabStopDistance(tabStop * metrics.horizontalAdvance(' '));
501 preambleTE->setTabStopWidth(tabStop * metrics.width(' '));
506 bool PreambleModule::eventFilter(QObject * sender, QEvent * event)
508 if (sender == findLE) {
509 if (event->type()==QEvent::KeyPress) {
510 QKeyEvent * key = static_cast<QKeyEvent *>(event);
511 if ((key->key() == Qt::Key_Enter) || (key->key() == Qt::Key_Return)) {
513 // Return true to filter out the event
518 if (event->type() == QEvent::ApplicationPaletteChange) {
519 // mode switch: colors need to be updated
520 // and the highlighting redone
522 highlighter_->setupColors();
523 highlighter_->rehighlight();
526 return QWidget::eventFilter(sender, event);
531 void PreambleModule::checkFindButton()
533 findButtonPB->setEnabled(!findLE->text().isEmpty());
537 void PreambleModule::findText()
539 bool const found = preambleTE->find(findLE->text());
542 QTextCursor qtcur = preambleTE->textCursor();
543 qtcur.movePosition(QTextCursor::Start);
544 preambleTE->setTextCursor(qtcur);
545 preambleTE->find(findLE->text());
550 void PreambleModule::update(BufferParams const & params, BufferId id)
552 QString preamble = toqstr(params.preamble);
553 // Nothing to do if the params and preamble are unchanged.
554 if (id == current_id_
555 && preamble == preambleTE->document()->toPlainText())
558 QTextCursor cur = preambleTE->textCursor();
559 // Save the coords before switching to the new one.
560 preamble_coords_[current_id_] =
561 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
563 // Save the params address for further use.
565 preambleTE->document()->setPlainText(preamble);
566 Coords::const_iterator it = preamble_coords_.find(current_id_);
567 if (it == preamble_coords_.end())
568 // First time we open this one.
569 preamble_coords_[current_id_] = make_pair(0, 0);
571 // Restore saved coords.
572 cur = preambleTE->textCursor();
573 cur.setPosition(it->second.first);
574 preambleTE->setTextCursor(cur);
575 preambleTE->verticalScrollBar()->setValue(it->second.second);
580 void PreambleModule::apply(BufferParams & params)
582 params.preamble = qstring_to_ucs4(preambleTE->document()->toPlainText());
586 void PreambleModule::closeEvent(QCloseEvent * e)
588 // Save the coords before closing.
589 QTextCursor cur = preambleTE->textCursor();
590 preamble_coords_[current_id_] =
591 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
596 void PreambleModule::editExternal() {
601 preambleTE->setReadOnly(false);
602 FileName const tempfilename = tempfile_->name();
603 docstring const s = tempfilename.fileContents("UTF-8");
604 preambleTE->document()->setPlainText(toqstr(s));
606 editPB->setText(qt_("&Edit Externally"));
607 editPB->setIcon(QIcon());
612 string const format =
613 current_id_->params().documentClass().outputFormat();
614 string const ext = theFormats().extension(format);
615 tempfile_.reset(new TempFile("preamble_editXXXXXX." + ext));
616 FileName const tempfilename = tempfile_->name();
617 string const name = tempfilename.toFilesystemEncoding();
618 ofdocstream os(name.c_str());
619 os << qstring_to_ucs4(preambleTE->document()->toPlainText());
621 preambleTE->setReadOnly(true);
622 theFormats().edit(*current_id_, tempfilename, format);
623 editPB->setText(qt_("&End Edit"));
624 QIcon warn(guiApp ? guiApp->getScaledPixmap("images/", "emblem-shellescape-user")
625 : getPixmap("images/", "emblem-shellescape", "svgz,png"));
626 editPB->setIcon(warn);
630 /////////////////////////////////////////////////////////////////////
634 /////////////////////////////////////////////////////////////////////
637 LocalLayout::LocalLayout(QWidget * parent)
638 : UiWidget<Ui::LocalLayoutUi>(parent), current_id_(nullptr), validated_(false)
640 locallayoutTE->setFont(guiApp->typewriterSystemFont());
641 locallayoutTE->setWordWrapMode(QTextOption::NoWrap);
642 connect(locallayoutTE, SIGNAL(textChanged()), this, SLOT(textChanged()));
643 connect(validatePB, SIGNAL(clicked()), this, SLOT(validatePressed()));
644 connect(convertPB, SIGNAL(clicked()), this, SLOT(convertPressed()));
645 connect(editPB, SIGNAL(clicked()), this, SLOT(editExternal()));
646 int const tabStop = 4;
647 QFontMetrics metrics(locallayoutTE->currentFont());
648 #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
649 // horizontalAdvance() is available starting in 5.11.0
650 // setTabStopDistance() is available starting in 5.10.0
651 locallayoutTE->setTabStopDistance(tabStop * metrics.horizontalAdvance(' '));
653 locallayoutTE->setTabStopWidth(tabStop * metrics.width(' '));
658 void LocalLayout::update(BufferParams const & params, BufferId id)
660 QString layout = toqstr(params.getLocalLayout(false));
661 // Nothing to do if the params and preamble are unchanged.
662 if (id == current_id_
663 && layout == locallayoutTE->document()->toPlainText())
666 // Save the params address for further use.
668 locallayoutTE->document()->setPlainText(layout);
673 void LocalLayout::apply(BufferParams & params)
675 docstring const layout =
676 qstring_to_ucs4(locallayoutTE->document()->toPlainText());
677 params.setLocalLayout(layout, false);
681 void LocalLayout::hideConvert()
683 convertPB->setEnabled(false);
684 convertLB->setText("");
690 void LocalLayout::textChanged()
692 validLB->setText("");
693 string const layout =
694 fromqstr(locallayoutTE->document()->toPlainText().trimmed());
696 if (layout.empty()) {
698 validatePB->setEnabled(false);
701 } else if (!validatePB->isEnabled()) {
702 // if that's already enabled, we shouldn't need to do anything.
704 validatePB->setEnabled(true);
711 void LocalLayout::convert() {
712 string const layout =
713 fromqstr(locallayoutTE->document()->toPlainText().trimmed());
714 string const newlayout = TextClass::convert(layout);
715 if (!newlayout.empty())
716 locallayoutTE->setPlainText(toqstr(newlayout));
721 void LocalLayout::convertPressed() {
728 void LocalLayout::validate() {
730 static const QString vpar("<p style=\"font-weight: bold; text-align:left\">%1</p>");
731 // Flashy red bold text
732 static const QString ivpar("<p style=\"color: #c00000; font-weight: bold; text-align:left\">"
734 string const layout =
735 fromqstr(locallayoutTE->document()->toPlainText().trimmed());
736 if (!layout.empty()) {
737 TextClass::ReturnValues const ret = TextClass::validate(layout);
738 validated_ = (ret == TextClass::OK) || (ret == TextClass::OK_OLDFORMAT);
739 validatePB->setEnabled(false);
740 validLB->setText(validated_ ? vpar.arg(qt_("Layout is valid!"))
741 : ivpar.arg(qt_("Layout is invalid!")));
742 if (ret == TextClass::OK_OLDFORMAT) {
744 // Testing conversion to LYXFILE_LAYOUT_FORMAT at this point
746 if (TextClass::convert(layout).empty()) {
747 // Conversion failed. If LAYOUT_FORMAT > LYXFILE_LAYOUT_FORMAT,
748 // then maybe the layout is still valid, but its format is more
749 // recent than LYXFILE_LAYOUT_FORMAT. However, if LAYOUT_FORMAT
750 // == LYXFILE_LAYOUT_FORMAT then something is definitely wrong.
751 convertPB->setEnabled(false);
752 const QString text = (LAYOUT_FORMAT == LYXFILE_LAYOUT_FORMAT)
753 ? ivpar.arg(qt_("Conversion to current format impossible!"))
754 : vpar.arg(qt_("Conversion to current stable format "
756 convertLB->setText(text);
758 convertPB->setEnabled(true);
759 convertLB->setText(qt_("Convert to current format"));
770 void LocalLayout::validatePressed() {
776 void LocalLayout::editExternal() {
781 locallayoutTE->setReadOnly(false);
782 FileName const tempfilename = tempfile_->name();
783 docstring const s = tempfilename.fileContents("UTF-8");
784 locallayoutTE->document()->setPlainText(toqstr(s));
786 editPB->setText(qt_("&Edit Externally"));
787 editPB->setIcon(QIcon());
792 string const format =
793 current_id_->params().documentClass().outputFormat();
794 string const ext = theFormats().extension(format);
795 tempfile_.reset(new TempFile("preamble_editXXXXXX." + ext));
796 FileName const tempfilename = tempfile_->name();
797 string const name = tempfilename.toFilesystemEncoding();
798 ofdocstream os(name.c_str());
799 os << qstring_to_ucs4(locallayoutTE->document()->toPlainText());
801 locallayoutTE->setReadOnly(true);
802 theFormats().edit(*current_id_, tempfilename, format);
803 editPB->setText(qt_("&End Edit"));
804 QIcon warn(guiApp ? guiApp->getScaledPixmap("images/", "emblem-shellescape-user")
805 : getPixmap("images/", "emblem-shellescape", "svgz,png"));
806 editPB->setIcon(warn);
807 validatePB->setEnabled(false);
812 /////////////////////////////////////////////////////////////////////
816 /////////////////////////////////////////////////////////////////////
819 GuiDocument::GuiDocument(GuiView & lv)
820 : GuiDialog(lv, "document", qt_("Document Settings")),
821 biblioChanged_(false), nonModuleChanged_(false),
822 modulesChanged_(false), shellescapeChanged_(false),
823 switchback_(false), prompted_(false)
827 connect(buttonBox, SIGNAL(clicked(QAbstractButton *)),
828 this, SLOT(slotButtonBox(QAbstractButton *)));
830 connect(savePB, SIGNAL(clicked()), this, SLOT(saveDefaultClicked()));
831 connect(defaultPB, SIGNAL(clicked()), this, SLOT(useDefaultsClicked()));
833 // Manage the restore, ok, apply, restore and cancel/close buttons
834 bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
835 bc().setOK(buttonBox->button(QDialogButtonBox::Ok));
836 bc().setApply(buttonBox->button(QDialogButtonBox::Apply));
837 bc().setCancel(buttonBox->button(QDialogButtonBox::Cancel));
838 bc().setRestore(buttonBox->button(QDialogButtonBox::Reset));
842 textLayoutModule = new UiWidget<Ui::TextLayoutUi>(this);
843 connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
844 this, SLOT(change_adaptor()));
845 connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
846 this, SLOT(setLSpacing(int)));
847 connect(textLayoutModule->lspacingLE, SIGNAL(textChanged(const QString &)),
848 this, SLOT(change_adaptor()));
850 connect(textLayoutModule->indentRB, SIGNAL(clicked()),
851 this, SLOT(change_adaptor()));
852 connect(textLayoutModule->indentRB, SIGNAL(toggled(bool)),
853 textLayoutModule->indentCO, SLOT(setEnabled(bool)));
854 connect(textLayoutModule->indentCO, SIGNAL(activated(int)),
855 this, SLOT(change_adaptor()));
856 connect(textLayoutModule->indentCO, SIGNAL(activated(int)),
857 this, SLOT(setIndent(int)));
858 connect(textLayoutModule->indentLE, SIGNAL(textChanged(const QString &)),
859 this, SLOT(change_adaptor()));
860 connect(textLayoutModule->indentLengthCO, SIGNAL(activated(int)),
861 this, SLOT(change_adaptor()));
863 connect(textLayoutModule->skipRB, SIGNAL(clicked()),
864 this, SLOT(change_adaptor()));
865 connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
866 textLayoutModule->skipCO, SLOT(setEnabled(bool)));
867 connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
868 this, SLOT(change_adaptor()));
869 connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
870 this, SLOT(setSkip(int)));
871 connect(textLayoutModule->skipLE, SIGNAL(textChanged(const QString &)),
872 this, SLOT(change_adaptor()));
873 connect(textLayoutModule->skipLengthCO, SIGNAL(activated(int)),
874 this, SLOT(change_adaptor()));
876 connect(textLayoutModule->indentRB, SIGNAL(toggled(bool)),
877 this, SLOT(enableIndent(bool)));
878 connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
879 this, SLOT(enableSkip(bool)));
881 connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
882 this, SLOT(change_adaptor()));
883 connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
884 this, SLOT(setColSep()));
885 connect(textLayoutModule->justCB, SIGNAL(clicked()),
886 this, SLOT(change_adaptor()));
888 connect(textLayoutModule->tableStyleCO, SIGNAL(activated(int)),
889 this, SLOT(change_adaptor()));
891 textLayoutModule->lspacingLE->setValidator(new QDoubleValidator(
892 textLayoutModule->lspacingLE));
893 textLayoutModule->indentLE->setValidator(new LengthValidator(
894 textLayoutModule->indentLE, false));
895 textLayoutModule->skipLE->setValidator(new LengthValidator(
896 textLayoutModule->skipLE, false));
898 textLayoutModule->indentCO->addItem(qt_("Default"), toqstr("default"));
899 textLayoutModule->indentCO->addItem(qt_("Custom"), toqstr("custom"));
900 textLayoutModule->skipCO->addItem(qt_("Half line height"), VSpace::HALFLINE);
901 textLayoutModule->skipCO->addItem(qt_("Line height"), VSpace::FULLLINE);
902 textLayoutModule->skipCO->addItem(qt_("Small Skip"), VSpace::SMALLSKIP);
903 textLayoutModule->skipCO->addItem(qt_("Medium Skip"), VSpace::MEDSKIP);
904 textLayoutModule->skipCO->addItem(qt_("Big Skip"), VSpace::BIGSKIP);
905 textLayoutModule->skipCO->addItem(qt_("Custom"), VSpace::LENGTH);
906 textLayoutModule->lspacingCO->insertItem(
907 Spacing::Single, qt_("Single"));
908 textLayoutModule->lspacingCO->insertItem(
909 Spacing::Onehalf, qt_("OneHalf"));
910 textLayoutModule->lspacingCO->insertItem(
911 Spacing::Double, qt_("Double"));
912 textLayoutModule->lspacingCO->insertItem(
913 Spacing::Other, qt_("Custom"));
914 // initialize the length validator
915 bc().addCheckedLineEdit(textLayoutModule->indentLE, textLayoutModule->indentRB);
916 bc().addCheckedLineEditPanel(textLayoutModule->indentLE, docPS, N_("Text Layout"));
917 bc().addCheckedLineEdit(textLayoutModule->skipLE, textLayoutModule->skipRB);
918 bc().addCheckedLineEditPanel(textLayoutModule->skipLE, docPS, N_("Text Layout"));
920 textLayoutModule->tableStyleCO->addItem(qt_("Default"), toqstr("default"));
924 // master/child handling
925 masterChildModule = new UiWidget<Ui::MasterChildUi>(this);
927 connect(masterChildModule->childrenTW, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),
928 this, SLOT(includeonlyClicked(QTreeWidgetItem *, int)));
929 connect(masterChildModule->includeonlyRB, SIGNAL(toggled(bool)),
930 masterChildModule->childrenTW, SLOT(setEnabled(bool)));
931 connect(masterChildModule->includeonlyRB, SIGNAL(toggled(bool)),
932 masterChildModule->maintainGB, SLOT(setEnabled(bool)));
933 connect(masterChildModule->includeallRB, SIGNAL(clicked()),
934 this, SLOT(change_adaptor()));
935 connect(masterChildModule->includeonlyRB, SIGNAL(clicked()),
936 this, SLOT(change_adaptor()));
937 connect(masterChildModule->maintainCRNoneRB, SIGNAL(clicked()),
938 this, SLOT(change_adaptor()));
939 connect(masterChildModule->maintainCRMostlyRB, SIGNAL(clicked()),
940 this, SLOT(change_adaptor()));
941 connect(masterChildModule->maintainCRStrictRB, SIGNAL(clicked()),
942 this, SLOT(change_adaptor()));
943 masterChildModule->childrenTW->setColumnCount(2);
944 masterChildModule->childrenTW->headerItem()->setText(0, qt_("Child Document"));
945 masterChildModule->childrenTW->headerItem()->setText(1, qt_("Include to Output"));
946 masterChildModule->childrenTW->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
947 masterChildModule->childrenTW->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
950 outputModule = new UiWidget<Ui::OutputUi>(this);
952 connect(outputModule->defaultFormatCO, SIGNAL(activated(int)),
953 this, SLOT(change_adaptor()));
954 connect(outputModule->mathimgSB, SIGNAL(valueChanged(double)),
955 this, SLOT(change_adaptor()));
956 connect(outputModule->strictCB, SIGNAL(stateChanged(int)),
957 this, SLOT(change_adaptor()));
958 connect(outputModule->cssCB, SIGNAL(stateChanged(int)),
959 this, SLOT(change_adaptor()));
960 connect(outputModule->mathoutCB, SIGNAL(currentIndexChanged(int)),
961 this, SLOT(change_adaptor()));
962 connect(outputModule->tableoutCB, SIGNAL(currentIndexChanged(int)),
963 this, SLOT(change_adaptor()));
964 connect(outputModule->mathmlprefixCB, SIGNAL(currentIndexChanged(int)),
965 this, SLOT(change_adaptor()));
967 connect(outputModule->shellescapeCB, SIGNAL(stateChanged(int)),
968 this, SLOT(shellescapeChanged()));
969 connect(outputModule->outputsyncCB, SIGNAL(toggled(bool)),
970 this, SLOT(setOutputSync(bool)));
971 connect(outputModule->synccustomCB, SIGNAL(editTextChanged(QString)),
972 this, SLOT(change_adaptor()));
973 outputModule->synccustomCB->addItem("");
974 outputModule->synccustomCB->addItem("\\synctex=1");
975 outputModule->synccustomCB->addItem("\\synctex=-1");
976 outputModule->synccustomCB->addItem("\\usepackage[active]{srcltx}");
978 outputModule->synccustomCB->lineEdit()->setValidator(new NoNewLineValidator(
979 outputModule->synccustomCB));
981 connect(outputModule->saveTransientPropertiesCB, SIGNAL(clicked()),
982 this, SLOT(change_adaptor()));
983 connect(outputModule->postponeFragileCB, SIGNAL(clicked()),
984 this, SLOT(change_adaptor()));
988 // this must precede font, since fonts depend on this
989 langModule = new UiWidget<Ui::LanguageUi>(this);
990 connect(langModule->languageCO, SIGNAL(activated(int)),
991 this, SLOT(change_adaptor()));
992 connect(langModule->languageCO, SIGNAL(activated(int)),
993 this, SLOT(languageChanged(int)));
994 connect(langModule->encodingCO, SIGNAL(activated(int)),
995 this, SLOT(change_adaptor()));
996 connect(langModule->encodingCO, SIGNAL(activated(int)),
997 this, SLOT(encodingSwitched(int)));
998 connect(langModule->unicodeEncodingCO, SIGNAL(activated(int)),
999 this, SLOT(change_adaptor()));
1000 connect(langModule->autoEncodingCO, SIGNAL(activated(int)),
1001 this, SLOT(change_adaptor()));
1002 connect(langModule->customEncodingCO, SIGNAL(activated(int)),
1003 this, SLOT(change_adaptor()));
1004 connect(langModule->quoteStyleCO, SIGNAL(activated(int)),
1005 this, SLOT(change_adaptor()));
1006 connect(langModule->languagePackageCO, SIGNAL(activated(int)),
1007 this, SLOT(change_adaptor()));
1008 connect(langModule->languagePackageLE, SIGNAL(textChanged(QString)),
1009 this, SLOT(change_adaptor()));
1010 connect(langModule->languagePackageCO, SIGNAL(currentIndexChanged(int)),
1011 this, SLOT(languagePackageChanged(int)));
1012 connect(langModule->dynamicQuotesCB, SIGNAL(clicked()),
1013 this, SLOT(change_adaptor()));
1015 langModule->languagePackageLE->setValidator(new NoNewLineValidator(
1016 langModule->languagePackageLE));
1018 QAbstractItemModel * language_model = guiApp->languageModel();
1019 // FIXME: it would be nice if sorting was enabled/disabled via a checkbox.
1020 language_model->sort(0);
1021 langModule->languageCO->setModel(language_model);
1022 langModule->languageCO->setModelColumn(0);
1024 langModule->encodingCO->addItem(qt_("Unicode (utf8)"));
1025 langModule->encodingCO->addItem(qt_("Traditional (auto-selected)"));
1026 langModule->encodingCO->addItem(qt_("Custom"));
1027 langModule->encodingCO->setItemData(EncodingSets::unicode,
1028 qt_("Select Unicode (utf8) encoding."), Qt::ToolTipRole);
1029 langModule->encodingCO->setItemData(EncodingSets::legacy,
1030 qt_("Use language-dependent traditional encodings."), Qt::ToolTipRole);
1031 langModule->encodingCO->setItemData(EncodingSets::custom,
1032 qt_("Select a custom, document-wide encoding."), Qt::ToolTipRole);
1034 // basic Unicode encodings: keep order
1035 const QStringList utf8_base_encodings = {"utf8", "utf8-plain", "utf8x"};
1036 for (auto const & i : utf8_base_encodings) {
1037 langModule->unicodeEncodingCO->addItem(
1038 qt_(encodings.fromLyXName(fromqstr(i))->guiName()), i);
1040 langModule->unicodeEncodingCO->setItemData(0,
1041 qt_("Standard Unicode support by the ``inputenc'' package."),
1043 langModule->unicodeEncodingCO->setItemData(1,
1044 qt_("Use UTF-8 'as-is': do not load any supporting packages, "
1045 "do not convert any characters to LaTeX macros. "
1046 "For use with non-TeX fonts (XeTeX/LuaTeX) or custom preamble code."),
1048 langModule->unicodeEncodingCO->setItemData(2,
1049 qt_("Load ``inputenc'' with option 'utf8x' "
1050 "for extended Unicode support by the ``ucs'' package."),
1052 langModule->autoEncodingCO->addItem(qt_("Language Default"), toqstr("auto-legacy"));
1053 langModule->autoEncodingCO->addItem(qt_("Language Default (no inputenc)"), toqstr("auto-legacy-plain"));
1054 langModule->autoEncodingCO->setItemData(0,
1055 qt_("Use the traditional default encoding of the text language. Switch encoding "
1056 "if a text part is set to a language with different default."),
1058 langModule->autoEncodingCO->setItemData(1,
1059 qt_("Do not load the 'inputenc' package. Switch encoding if required "
1060 "but do not write input encoding switch commands to the source."),
1063 QMap<QString,QString> encodingmap;
1064 QMap<QString,QString> encodingmap_utf8;
1065 for (auto const & encvar : encodings) {
1066 if (encvar.unsafe() ||encvar.guiName().empty()
1067 || utf8_base_encodings.contains(toqstr(encvar.name())))
1069 if (encvar.name().find("utf8") == 0)
1070 encodingmap_utf8.insert(qt_(encvar.guiName()), toqstr(encvar.name()));
1072 encodingmap.insert(qt_(encvar.guiName()), toqstr(encvar.name()));
1074 for (auto const & i : encodingmap_utf8.keys()) {
1075 langModule->unicodeEncodingCO->addItem(i, encodingmap_utf8.value(i));
1077 for (auto const & i : encodingmap.keys()) {
1078 langModule->customEncodingCO->addItem(i, encodingmap.value(i));
1080 // equalise the width of encoding selectors
1081 langModule->autoEncodingCO->setMinimumSize(
1082 langModule->unicodeEncodingCO->minimumSizeHint());
1083 langModule->customEncodingCO->setMinimumSize(
1084 langModule->unicodeEncodingCO->minimumSizeHint());
1086 langModule->languagePackageCO->addItem(
1087 qt_("Default"), toqstr("default"));
1088 langModule->languagePackageCO->addItem(
1089 qt_("Automatic"), toqstr("auto"));
1090 langModule->languagePackageCO->addItem(
1091 qt_("Always Babel"), toqstr("babel"));
1092 langModule->languagePackageCO->addItem(
1093 qt_("Custom"), toqstr("custom"));
1094 langModule->languagePackageCO->addItem(
1095 qt_("None[[language package]]"), toqstr("none"));
1099 fontModule = new FontModule(this);
1100 connect(fontModule->osFontsCB, SIGNAL(clicked()),
1101 this, SLOT(change_adaptor()));
1102 connect(fontModule->osFontsCB, SIGNAL(toggled(bool)),
1103 this, SLOT(osFontsChanged(bool)));
1104 connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
1105 this, SLOT(change_adaptor()));
1106 connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
1107 this, SLOT(romanChanged(int)));
1108 connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
1109 this, SLOT(change_adaptor()));
1110 connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
1111 this, SLOT(sansChanged(int)));
1112 connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
1113 this, SLOT(change_adaptor()));
1114 connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
1115 this, SLOT(ttChanged(int)));
1116 connect(fontModule->fontsMathCO, SIGNAL(activated(int)),
1117 this, SLOT(change_adaptor()));
1118 connect(fontModule->fontsMathCO, SIGNAL(activated(int)),
1119 this, SLOT(mathFontChanged(int)));
1120 connect(fontModule->fontsDefaultCO, SIGNAL(activated(int)),
1121 this, SLOT(change_adaptor()));
1122 connect(fontModule->fontencCO, SIGNAL(activated(int)),
1123 this, SLOT(change_adaptor()));
1124 connect(fontModule->fontencCO, SIGNAL(activated(int)),
1125 this, SLOT(fontencChanged(int)));
1126 connect(fontModule->fontencLE, SIGNAL(textChanged(const QString &)),
1127 this, SLOT(change_adaptor()));
1128 connect(fontModule->fontsizeCO, SIGNAL(activated(int)),
1129 this, SLOT(change_adaptor()));
1130 connect(fontModule->cjkFontLE, SIGNAL(textChanged(const QString &)),
1131 this, SLOT(change_adaptor()));
1132 connect(fontModule->microtypeCB, SIGNAL(clicked()),
1133 this, SLOT(change_adaptor()));
1134 connect(fontModule->dashesCB, SIGNAL(clicked()),
1135 this, SLOT(change_adaptor()));
1136 connect(fontModule->scaleSansSB, SIGNAL(valueChanged(int)),
1137 this, SLOT(change_adaptor()));
1138 connect(fontModule->scaleTypewriterSB, SIGNAL(valueChanged(int)),
1139 this, SLOT(change_adaptor()));
1140 connect(fontModule->fontScCB, SIGNAL(clicked()),
1141 this, SLOT(change_adaptor()));
1142 connect(fontModule->fontScCB, SIGNAL(toggled(bool)),
1143 this, SLOT(fontScToggled(bool)));
1144 connect(fontModule->fontOsfCB, SIGNAL(clicked()),
1145 this, SLOT(change_adaptor()));
1146 connect(fontModule->fontOsfCB, SIGNAL(toggled(bool)),
1147 this, SLOT(fontOsfToggled(bool)));
1148 connect(fontModule->fontSansOsfCB, SIGNAL(clicked()),
1149 this, SLOT(change_adaptor()));
1150 connect(fontModule->fontTypewriterOsfCB, SIGNAL(clicked()),
1151 this, SLOT(change_adaptor()));
1152 connect(fontModule->fontspecRomanLE, SIGNAL(textChanged(const QString &)),
1153 this, SLOT(change_adaptor()));
1154 connect(fontModule->fontspecSansLE, SIGNAL(textChanged(const QString &)),
1155 this, SLOT(change_adaptor()));
1156 connect(fontModule->fontspecTypewriterLE, SIGNAL(textChanged(const QString &)),
1157 this, SLOT(change_adaptor()));
1159 fontModule->fontencLE->setValidator(new NoNewLineValidator(
1160 fontModule->fontencLE));
1161 fontModule->cjkFontLE->setValidator(new NoNewLineValidator(
1162 fontModule->cjkFontLE));
1163 fontModule->fontspecRomanLE->setValidator(new NoNewLineValidator(
1164 fontModule->fontspecRomanLE));
1165 fontModule->fontspecSansLE->setValidator(new NoNewLineValidator(
1166 fontModule->fontspecSansLE));
1167 fontModule->fontspecTypewriterLE->setValidator(new NoNewLineValidator(
1168 fontModule->fontspecTypewriterLE));
1172 fontModule->fontsizeCO->addItem(qt_("Default"));
1173 fontModule->fontsizeCO->addItem(qt_("10"));
1174 fontModule->fontsizeCO->addItem(qt_("11"));
1175 fontModule->fontsizeCO->addItem(qt_("12"));
1177 fontModule->fontencCO->addItem(qt_("Automatic[[encoding]]"), QString("auto"));
1178 fontModule->fontencCO->addItem(qt_("Class Default"), QString("default"));
1179 fontModule->fontencCO->addItem(qt_("Custom"), QString("custom"));
1181 for (int n = 0; GuiDocument::fontfamilies_gui[n][0]; ++n)
1182 fontModule->fontsDefaultCO->addItem(
1183 qt_(GuiDocument::fontfamilies_gui[n]));
1185 if (!LaTeXFeatures::isAvailable("fontspec"))
1186 fontModule->osFontsCB->setToolTip(
1187 qt_("Use OpenType and TrueType fonts directly (requires XeTeX or LuaTeX)\n"
1188 "You need to install the package \"fontspec\" to use this feature"));
1192 pageLayoutModule = new UiWidget<Ui::PageLayoutUi>(this);
1193 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
1194 this, SLOT(papersizeChanged(int)));
1195 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
1196 this, SLOT(papersizeChanged(int)));
1197 connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
1198 this, SLOT(change_adaptor()));
1199 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
1200 this, SLOT(change_adaptor()));
1201 connect(pageLayoutModule->paperheightLE, SIGNAL(textChanged(const QString &)),
1202 this, SLOT(change_adaptor()));
1203 connect(pageLayoutModule->paperwidthLE, SIGNAL(textChanged(const QString &)),
1204 this, SLOT(change_adaptor()));
1205 connect(pageLayoutModule->paperwidthUnitCO, SIGNAL(activated(int)),
1206 this, SLOT(change_adaptor()));
1207 connect(pageLayoutModule->paperheightUnitCO, SIGNAL(activated(int)),
1208 this, SLOT(change_adaptor()));
1209 connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
1210 this, SLOT(change_adaptor()));
1211 connect(pageLayoutModule->landscapeRB, SIGNAL(clicked()),
1212 this, SLOT(change_adaptor()));
1213 connect(pageLayoutModule->facingPagesCB, SIGNAL(clicked()),
1214 this, SLOT(change_adaptor()));
1215 connect(pageLayoutModule->pagestyleCO, SIGNAL(activated(int)),
1216 this, SLOT(change_adaptor()));
1218 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1219 pageLayoutModule->pagestyleCO->addItem(qt_("empty"));
1220 pageLayoutModule->pagestyleCO->addItem(qt_("plain"));
1221 pageLayoutModule->pagestyleCO->addItem(qt_("headings"));
1222 pageLayoutModule->pagestyleCO->addItem(qt_("fancy"));
1223 bc().addCheckedLineEdit(pageLayoutModule->paperheightLE,
1224 pageLayoutModule->paperheightL);
1225 bc().addCheckedLineEditPanel(pageLayoutModule->paperheightLE, docPS, N_("Page Layout"));
1226 bc().addCheckedLineEdit(pageLayoutModule->paperwidthLE,
1227 pageLayoutModule->paperwidthL);
1228 bc().addCheckedLineEditPanel(pageLayoutModule->paperwidthLE, docPS, N_("Page Layout"));
1230 QComboBox * cb = pageLayoutModule->papersizeCO;
1231 cb->addItem(qt_("Default"));
1232 cb->addItem(qt_("Custom"));
1233 cb->addItem(qt_("US letter"));
1234 cb->addItem(qt_("US legal"));
1235 cb->addItem(qt_("US executive"));
1236 cb->addItem(qt_("A0"));
1237 cb->addItem(qt_("A1"));
1238 cb->addItem(qt_("A2"));
1239 cb->addItem(qt_("A3"));
1240 cb->addItem(qt_("A4"));
1241 cb->addItem(qt_("A5"));
1242 cb->addItem(qt_("A6"));
1243 cb->addItem(qt_("B0"));
1244 cb->addItem(qt_("B1"));
1245 cb->addItem(qt_("B2"));
1246 cb->addItem(qt_("B3"));
1247 cb->addItem(qt_("B4"));
1248 cb->addItem(qt_("B5"));
1249 cb->addItem(qt_("B6"));
1250 cb->addItem(qt_("C0"));
1251 cb->addItem(qt_("C1"));
1252 cb->addItem(qt_("C2"));
1253 cb->addItem(qt_("C3"));
1254 cb->addItem(qt_("C4"));
1255 cb->addItem(qt_("C5"));
1256 cb->addItem(qt_("C6"));
1257 cb->addItem(qt_("JIS B0"));
1258 cb->addItem(qt_("JIS B1"));
1259 cb->addItem(qt_("JIS B2"));
1260 cb->addItem(qt_("JIS B3"));
1261 cb->addItem(qt_("JIS B4"));
1262 cb->addItem(qt_("JIS B5"));
1263 cb->addItem(qt_("JIS B6"));
1264 // remove the %-items from the unit choice
1265 pageLayoutModule->paperwidthUnitCO->noPercents();
1266 pageLayoutModule->paperheightUnitCO->noPercents();
1267 pageLayoutModule->paperheightLE->setValidator(unsignedLengthValidator(
1268 pageLayoutModule->paperheightLE));
1269 pageLayoutModule->paperwidthLE->setValidator(unsignedLengthValidator(
1270 pageLayoutModule->paperwidthLE));
1274 marginsModule = new UiWidget<Ui::MarginsUi>(this);
1275 connect(marginsModule->marginCB, SIGNAL(toggled(bool)),
1276 this, SLOT(setCustomMargins(bool)));
1277 connect(marginsModule->marginCB, SIGNAL(clicked()),
1278 this, SLOT(change_adaptor()));
1279 connect(marginsModule->topLE, SIGNAL(textChanged(QString)),
1280 this, SLOT(change_adaptor()));
1281 connect(marginsModule->topUnit, SIGNAL(activated(int)),
1282 this, SLOT(change_adaptor()));
1283 connect(marginsModule->bottomLE, SIGNAL(textChanged(QString)),
1284 this, SLOT(change_adaptor()));
1285 connect(marginsModule->bottomUnit, SIGNAL(activated(int)),
1286 this, SLOT(change_adaptor()));
1287 connect(marginsModule->innerLE, SIGNAL(textChanged(QString)),
1288 this, SLOT(change_adaptor()));
1289 connect(marginsModule->innerUnit, SIGNAL(activated(int)),
1290 this, SLOT(change_adaptor()));
1291 connect(marginsModule->outerLE, SIGNAL(textChanged(QString)),
1292 this, SLOT(change_adaptor()));
1293 connect(marginsModule->outerUnit, SIGNAL(activated(int)),
1294 this, SLOT(change_adaptor()));
1295 connect(marginsModule->headheightLE, SIGNAL(textChanged(QString)),
1296 this, SLOT(change_adaptor()));
1297 connect(marginsModule->headheightUnit, SIGNAL(activated(int)),
1298 this, SLOT(change_adaptor()));
1299 connect(marginsModule->headsepLE, SIGNAL(textChanged(QString)),
1300 this, SLOT(change_adaptor()));
1301 connect(marginsModule->headsepUnit, SIGNAL(activated(int)),
1302 this, SLOT(change_adaptor()));
1303 connect(marginsModule->footskipLE, SIGNAL(textChanged(QString)),
1304 this, SLOT(change_adaptor()));
1305 connect(marginsModule->footskipUnit, SIGNAL(activated(int)),
1306 this, SLOT(change_adaptor()));
1307 connect(marginsModule->columnsepLE, SIGNAL(textChanged(QString)),
1308 this, SLOT(change_adaptor()));
1309 connect(marginsModule->columnsepUnit, SIGNAL(activated(int)),
1310 this, SLOT(change_adaptor()));
1311 marginsModule->topLE->setValidator(new LengthValidator(
1312 marginsModule->topLE));
1313 marginsModule->bottomLE->setValidator(new LengthValidator(
1314 marginsModule->bottomLE));
1315 marginsModule->innerLE->setValidator(new LengthValidator(
1316 marginsModule->innerLE));
1317 marginsModule->outerLE->setValidator(new LengthValidator(
1318 marginsModule->outerLE));
1319 marginsModule->headsepLE->setValidator(new LengthValidator(
1320 marginsModule->headsepLE));
1321 marginsModule->headheightLE->setValidator(new LengthValidator(
1322 marginsModule->headheightLE));
1323 marginsModule->footskipLE->setValidator(new LengthValidator(
1324 marginsModule->footskipLE));
1325 marginsModule->columnsepLE->setValidator(new LengthValidator(
1326 marginsModule->columnsepLE));
1328 bc().addCheckedLineEdit(marginsModule->topLE,
1329 marginsModule->topL);
1330 bc().addCheckedLineEditPanel(marginsModule->topLE,
1331 docPS, N_("Page Margins"));
1332 bc().addCheckedLineEdit(marginsModule->bottomLE,
1333 marginsModule->bottomL);
1334 bc().addCheckedLineEditPanel(marginsModule->bottomLE,
1335 docPS, N_("Page Margins"));
1336 bc().addCheckedLineEdit(marginsModule->innerLE,
1337 marginsModule->innerL);
1338 bc().addCheckedLineEditPanel(marginsModule->innerLE,
1339 docPS, N_("Page Margins"));
1340 bc().addCheckedLineEdit(marginsModule->outerLE,
1341 marginsModule->outerL);
1342 bc().addCheckedLineEditPanel(marginsModule->outerLE,
1343 docPS, N_("Page Margins"));
1344 bc().addCheckedLineEdit(marginsModule->headsepLE,
1345 marginsModule->headsepL);
1346 bc().addCheckedLineEditPanel(marginsModule->headsepLE,
1347 docPS, N_("Page Margins"));
1348 bc().addCheckedLineEdit(marginsModule->headheightLE,
1349 marginsModule->headheightL);
1350 bc().addCheckedLineEditPanel(marginsModule->headheightLE,
1351 docPS, N_("Page Margins"));
1352 bc().addCheckedLineEdit(marginsModule->footskipLE,
1353 marginsModule->footskipL);
1354 bc().addCheckedLineEditPanel(marginsModule->footskipLE,
1355 docPS, N_("Page Margins"));
1356 bc().addCheckedLineEdit(marginsModule->columnsepLE,
1357 marginsModule->columnsepL);
1358 bc().addCheckedLineEditPanel(marginsModule->columnsepLE,
1359 docPS, N_("Page Margins"));
1363 colorModule = new UiWidget<Ui::ColorUi>(this);
1364 connect(colorModule->fontColorPB, SIGNAL(clicked()),
1365 this, SLOT(changeFontColor()));
1366 connect(colorModule->delFontColorTB, SIGNAL(clicked()),
1367 this, SLOT(deleteFontColor()));
1368 connect(colorModule->noteFontColorPB, SIGNAL(clicked()),
1369 this, SLOT(changeNoteFontColor()));
1370 connect(colorModule->delNoteFontColorTB, SIGNAL(clicked()),
1371 this, SLOT(deleteNoteFontColor()));
1372 connect(colorModule->backgroundPB, SIGNAL(clicked()),
1373 this, SLOT(changeBackgroundColor()));
1374 connect(colorModule->delBackgroundTB, SIGNAL(clicked()),
1375 this, SLOT(deleteBackgroundColor()));
1376 connect(colorModule->boxBackgroundPB, SIGNAL(clicked()),
1377 this, SLOT(changeBoxBackgroundColor()));
1378 connect(colorModule->delBoxBackgroundTB, SIGNAL(clicked()),
1379 this, SLOT(deleteBoxBackgroundColor()));
1383 changesModule = new UiWidget<Ui::ChangeTrackingUi>(this);
1384 connect(changesModule->trackChangesCB, SIGNAL(clicked()),
1385 this, SLOT(change_adaptor()));
1386 connect(changesModule->outputChangesCB, SIGNAL(toggled(bool)),
1387 this, SLOT(outputChangesToggled(bool)));
1388 connect(changesModule->changeBarsCB, SIGNAL(clicked()),
1389 this, SLOT(change_adaptor()));
1390 connect(&lv, SIGNAL(changeTrackingToggled(bool)),
1391 this, SLOT(changeTrackingChanged(bool)));
1395 numberingModule = new UiWidget<Ui::NumberingUi>(this);
1396 connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
1397 this, SLOT(change_adaptor()));
1398 connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
1399 this, SLOT(change_adaptor()));
1400 connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
1401 this, SLOT(updateNumbering()));
1402 connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
1403 this, SLOT(updateNumbering()));
1404 numberingModule->tocTW->setColumnCount(3);
1405 numberingModule->tocTW->headerItem()->setText(0, qt_("Example"));
1406 numberingModule->tocTW->headerItem()->setText(1, qt_("Numbered"));
1407 numberingModule->tocTW->headerItem()->setText(2, qt_("Appears in TOC"));
1408 numberingModule->tocTW->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
1409 connect(numberingModule->linenoCB, SIGNAL(toggled(bool)),
1410 this, SLOT(linenoToggled(bool)));
1411 connect(numberingModule->linenoCB, SIGNAL(clicked()),
1412 this, SLOT(change_adaptor()));
1413 connect(numberingModule->linenoLE, SIGNAL(textChanged(QString)),
1414 this, SLOT(change_adaptor()));
1418 biblioModule = new UiWidget<Ui::BiblioUi>(this);
1419 connect(biblioModule->citeEngineCO, SIGNAL(activated(int)),
1420 this, SLOT(citeEngineChanged(int)));
1421 connect(biblioModule->citeStyleCO, SIGNAL(activated(int)),
1422 this, SLOT(citeStyleChanged()));
1423 connect(biblioModule->bibtopicCB, SIGNAL(clicked()),
1424 this, SLOT(biblioChanged()));
1425 connect(biblioModule->bibunitsCO, SIGNAL(activated(int)),
1426 this, SLOT(biblioChanged()));
1427 connect(biblioModule->bibtexCO, SIGNAL(activated(int)),
1428 this, SLOT(bibtexChanged(int)));
1429 connect(biblioModule->bibtexOptionsLE, SIGNAL(textChanged(QString)),
1430 this, SLOT(biblioChanged()));
1431 connect(biblioModule->citePackageOptionsLE, SIGNAL(textChanged(QString)),
1432 this, SLOT(biblioChanged()));
1433 connect(biblioModule->defaultBiblioCO, SIGNAL(activated(int)),
1434 this, SLOT(biblioChanged()));
1435 connect(biblioModule->defaultBiblioCO, SIGNAL(editTextChanged(QString)),
1436 this, SLOT(biblioChanged()));
1437 connect(biblioModule->defaultBiblioCO, SIGNAL(editTextChanged(QString)),
1438 this, SLOT(updateResetDefaultBiblio()));
1439 connect(biblioModule->biblatexBbxCO, SIGNAL(activated(int)),
1440 this, SLOT(biblioChanged()));
1441 connect(biblioModule->biblatexBbxCO, SIGNAL(editTextChanged(QString)),
1442 this, SLOT(biblioChanged()));
1443 connect(biblioModule->biblatexBbxCO, SIGNAL(editTextChanged(QString)),
1444 this, SLOT(updateResetDefaultBiblio()));
1445 connect(biblioModule->biblatexCbxCO, SIGNAL(activated(int)),
1446 this, SLOT(biblioChanged()));
1447 connect(biblioModule->biblatexCbxCO, SIGNAL(editTextChanged(QString)),
1448 this, SLOT(biblioChanged()));
1449 connect(biblioModule->biblatexCbxCO, SIGNAL(editTextChanged(QString)),
1450 this, SLOT(updateResetDefaultBiblio()));
1451 connect(biblioModule->rescanBibliosPB, SIGNAL(clicked()),
1452 this, SLOT(rescanBibFiles()));
1453 connect(biblioModule->resetDefaultBiblioPB, SIGNAL(clicked()),
1454 this, SLOT(resetDefaultBibfile()));
1455 connect(biblioModule->resetCbxPB, SIGNAL(clicked()),
1456 this, SLOT(resetDefaultCbxBibfile()));
1457 connect(biblioModule->resetBbxPB, SIGNAL(clicked()),
1458 this, SLOT(resetDefaultBbxBibfile()));
1459 connect(biblioModule->matchBbxPB, SIGNAL(clicked()),
1460 this, SLOT(matchBiblatexStyles()));
1462 biblioModule->citeEngineCO->clear();
1463 for (LyXCiteEngine const & cet : theCiteEnginesList) {
1464 biblioModule->citeEngineCO->addItem(qt_(cet.getName()), toqstr(cet.getID()));
1465 int const i = biblioModule->citeEngineCO->findData(toqstr(cet.getID()));
1466 biblioModule->citeEngineCO->setItemData(i, qt_(cet.getDescription()),
1470 biblioModule->bibtexOptionsLE->setValidator(new NoNewLineValidator(
1471 biblioModule->bibtexOptionsLE));
1472 biblioModule->defaultBiblioCO->lineEdit()->setValidator(new NoNewLineValidator(
1473 biblioModule->defaultBiblioCO->lineEdit()));
1474 biblioModule->citePackageOptionsLE->setValidator(new NoNewLineValidator(
1475 biblioModule->citePackageOptionsLE));
1477 // NOTE: we do not provide "custom" here for security reasons!
1478 biblioModule->bibtexCO->clear();
1479 biblioModule->bibtexCO->addItem(qt_("Default"), QString("default"));
1480 for (auto const & alts : lyxrc.bibtex_alternatives) {
1481 QString const command = toqstr(alts).left(toqstr(alts).indexOf(" "));
1482 biblioModule->bibtexCO->addItem(command, command);
1487 indicesModule = new GuiIndices;
1488 connect(indicesModule, SIGNAL(changed()),
1489 this, SLOT(change_adaptor()));
1493 mathsModule = new UiWidget<Ui::MathsUi>(this);
1494 QStringList headers;
1495 headers << qt_("Package") << qt_("Load automatically")
1496 << qt_("Load always") << qt_("Do not load");
1497 mathsModule->packagesTW->setHorizontalHeaderLabels(headers);
1498 mathsModule->packagesTW->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
1499 map<string, string> const & packages = BufferParams::auto_packages();
1500 mathsModule->packagesTW->setRowCount(packages.size());
1502 for (auto const & pkgvar : packages) {
1503 docstring const package = from_ascii(pkgvar.first);
1504 QString autoTooltip = qt_(pkgvar.second);
1505 QString alwaysTooltip;
1506 if (package == "amsmath")
1508 qt_("The AMS LaTeX packages are always used");
1510 alwaysTooltip = toqstr(bformat(
1511 _("The LaTeX package %1$s is always used"),
1513 QString neverTooltip;
1514 if (package == "amsmath")
1516 qt_("The AMS LaTeX packages are never used");
1518 neverTooltip = toqstr(bformat(
1519 _("The LaTeX package %1$s is never used"),
1521 QRadioButton * autoRB = new QRadioButton(mathsModule);
1522 QRadioButton * alwaysRB = new QRadioButton(mathsModule);
1523 QRadioButton * neverRB = new QRadioButton(mathsModule);
1524 QButtonGroup * packageGroup = new QButtonGroup(mathsModule);
1525 packageGroup->addButton(autoRB);
1526 packageGroup->addButton(alwaysRB);
1527 packageGroup->addButton(neverRB);
1528 autoRB->setToolTip(autoTooltip);
1529 alwaysRB->setToolTip(alwaysTooltip);
1530 neverRB->setToolTip(neverTooltip);
1532 // Pack the buttons in a layout in order to get proper alignment
1533 QWidget * autoRBWidget = new QWidget();
1534 QHBoxLayout * autoRBLayout = new QHBoxLayout(autoRBWidget);
1535 autoRBLayout->addWidget(autoRB);
1536 autoRBLayout->setAlignment(Qt::AlignCenter);
1537 autoRBLayout->setContentsMargins(0, 0, 0, 0);
1538 autoRBWidget->setLayout(autoRBLayout);
1540 QWidget * alwaysRBWidget = new QWidget();
1541 QHBoxLayout * alwaysRBLayout = new QHBoxLayout(alwaysRBWidget);
1542 alwaysRBLayout->addWidget(alwaysRB);
1543 alwaysRBLayout->setAlignment(Qt::AlignCenter);
1544 alwaysRBLayout->setContentsMargins(0, 0, 0, 0);
1545 alwaysRBWidget->setLayout(alwaysRBLayout);
1547 QWidget * neverRBWidget = new QWidget();
1548 QHBoxLayout * neverRBLayout = new QHBoxLayout(neverRBWidget);
1549 neverRBLayout->addWidget(neverRB);
1550 neverRBLayout->setAlignment(Qt::AlignCenter);
1551 neverRBLayout->setContentsMargins(0, 0, 0, 0);
1552 neverRBWidget->setLayout(neverRBLayout);
1554 QTableWidgetItem * pack = new QTableWidgetItem(toqstr(package));
1555 mathsModule->packagesTW->setItem(packnum, 0, pack);
1556 mathsModule->packagesTW->setCellWidget(packnum, 1, autoRBWidget);
1557 mathsModule->packagesTW->setCellWidget(packnum, 2, alwaysRBWidget);
1558 mathsModule->packagesTW->setCellWidget(packnum, 3, neverRBWidget);
1560 connect(autoRB, SIGNAL(clicked()),
1561 this, SLOT(change_adaptor()));
1562 connect(alwaysRB, SIGNAL(clicked()),
1563 this, SLOT(change_adaptor()));
1564 connect(neverRB, SIGNAL(clicked()),
1565 this, SLOT(change_adaptor()));
1568 connect(mathsModule->allPackagesAutoPB, SIGNAL(clicked()),
1569 this, SLOT(allPackagesAuto()));
1570 connect(mathsModule->allPackagesAlwaysPB, SIGNAL(clicked()),
1571 this, SLOT(allPackagesAlways()));
1572 connect(mathsModule->allPackagesNotPB, SIGNAL(clicked()),
1573 this, SLOT(allPackagesNot()));
1574 connect(mathsModule->allPackagesAutoPB, SIGNAL(clicked()),
1575 this, SLOT(change_adaptor()));
1576 connect(mathsModule->allPackagesAlwaysPB, SIGNAL(clicked()),
1577 this, SLOT(change_adaptor()));
1578 connect(mathsModule->allPackagesNotPB, SIGNAL(clicked()),
1579 this, SLOT(change_adaptor()));
1580 connect(mathsModule->MathNumberingPosCO, SIGNAL(activated(int)),
1581 this, SLOT(change_adaptor()));
1583 connect(mathsModule->MathIndentCB, SIGNAL(toggled(bool)),
1584 this, SLOT(allowMathIndent()));
1585 connect(mathsModule->MathIndentCB, SIGNAL(toggled(bool)),
1586 this, SLOT(change_adaptor()));
1587 connect(mathsModule->MathIndentCO, SIGNAL(activated(int)),
1588 this, SLOT(enableMathIndent(int)));
1589 connect(mathsModule->MathIndentCO, SIGNAL(activated(int)),
1590 this, SLOT(change_adaptor()));
1591 connect(mathsModule->MathIndentLE, SIGNAL(textChanged(const QString &)),
1592 this, SLOT(change_adaptor()));
1593 connect(mathsModule->MathIndentLengthCO, SIGNAL(activated(int)),
1594 this, SLOT(change_adaptor()));
1597 mathsModule->MathIndentCO->addItem(qt_("Default"), toqstr("default"));
1598 mathsModule->MathIndentCO->addItem(qt_("Custom"), toqstr("custom"));
1599 mathsModule->MathIndentLE->setValidator(new LengthValidator(
1600 mathsModule->MathIndentLE, false));
1601 // initialize the length validator
1602 bc().addCheckedLineEdit(mathsModule->MathIndentLE, mathsModule->MathIndentCB);
1603 bc().addCheckedLineEditPanel(mathsModule->MathIndentLE, docPS, N_("Math Options"));
1604 mathsModule->MathNumberingPosCO->addItem(qt_("Left"));
1605 mathsModule->MathNumberingPosCO->addItem(qt_("Default"));
1606 mathsModule->MathNumberingPosCO->addItem(qt_("Right"));
1607 mathsModule->MathNumberingPosCO->setCurrentIndex(1);
1611 latexModule = new UiWidget<Ui::LaTeXUi>(this);
1612 connect(latexModule->optionsLE, SIGNAL(textChanged(QString)),
1613 this, SLOT(change_adaptor()));
1614 connect(latexModule->defaultOptionsCB, SIGNAL(clicked()),
1615 this, SLOT(change_adaptor()));
1616 connect(latexModule->psdriverCO, SIGNAL(activated(int)),
1617 this, SLOT(change_adaptor()));
1618 connect(latexModule->classCO, SIGNAL(activated(int)),
1619 this, SLOT(classChanged_adaptor()));
1620 connect(latexModule->classCO, SIGNAL(activated(int)),
1621 this, SLOT(change_adaptor()));
1622 connect(latexModule->layoutPB, SIGNAL(clicked()),
1623 this, SLOT(browseLayout()));
1624 connect(latexModule->layoutPB, SIGNAL(clicked()),
1625 this, SLOT(change_adaptor()));
1626 connect(latexModule->childDocGB, SIGNAL(clicked()),
1627 this, SLOT(change_adaptor()));
1628 connect(latexModule->childDocLE, SIGNAL(textChanged(QString)),
1629 this, SLOT(change_adaptor()));
1630 connect(latexModule->childDocPB, SIGNAL(clicked()),
1631 this, SLOT(browseMaster()));
1632 connect(latexModule->suppressDateCB, SIGNAL(clicked()),
1633 this, SLOT(change_adaptor()));
1634 connect(latexModule->refstyleCB, SIGNAL(clicked()),
1635 this, SLOT(change_adaptor()));
1636 connect(latexModule->refFormattedCB, SIGNAL(clicked()),
1637 this, SLOT(change_adaptor()));
1639 latexModule->optionsLE->setValidator(new NoNewLineValidator(
1640 latexModule->optionsLE));
1641 latexModule->childDocLE->setValidator(new NoNewLineValidator(
1642 latexModule->childDocLE));
1644 // postscript drivers
1645 for (int n = 0; tex_graphics[n][0]; ++n) {
1646 QString enc = qt_(tex_graphics_gui[n]);
1647 latexModule->psdriverCO->addItem(enc);
1650 LayoutFileList const & bcl = LayoutFileList::get();
1651 vector<LayoutFileIndex> classList = bcl.classList();
1652 sort(classList.begin(), classList.end(), less_textclass_avail_desc());
1654 for (auto const & cvar : classList) {
1655 LayoutFile const & tc = bcl[cvar];
1656 bool const available = tc.isTeXClassAvailable();
1657 docstring const guiname = translateIfPossible(from_utf8(tc.description()));
1658 // tooltip sensu "KOMA-Script Article [Class 'scrartcl']"
1659 QString tooltip = toqstr(bformat(_("%1$s [Class '%2$s']"), guiname, from_utf8(tc.latexname())));
1661 docstring const output_type = _("LaTeX");
1662 tooltip += '\n' + toqstr(bformat(_("Class not found by LyX. "
1663 "Please check if you have the matching %1$s class "
1664 "and all required packages (%2$s) installed."),
1665 output_type, from_utf8(tc.prerequisites(", "))));
1667 latexModule->classCO->addItemSort(toqstr(tc.name()),
1669 toqstr(translateIfPossible(from_utf8(tc.category()))),
1671 true, true, true, available);
1676 branchesModule = new GuiBranches(this);
1677 connect(branchesModule, SIGNAL(changed()),
1678 this, SLOT(change_adaptor()));
1679 connect(branchesModule, SIGNAL(renameBranches(docstring const &, docstring const &)),
1680 this, SLOT(branchesRename(docstring const &, docstring const &)));
1681 connect(branchesModule, SIGNAL(okPressed()), this, SLOT(slotOK()));
1682 updateUnknownBranches();
1686 preambleModule = new PreambleModule(this);
1687 connect(preambleModule, SIGNAL(changed()),
1688 this, SLOT(change_adaptor()));
1690 localLayout = new LocalLayout(this);
1691 connect(localLayout, SIGNAL(changed()),
1692 this, SLOT(change_adaptor()));
1696 bulletsModule = new BulletsModule(this);
1697 connect(bulletsModule, SIGNAL(changed()),
1698 this, SLOT(change_adaptor()));
1702 modulesModule = new UiWidget<Ui::ModulesUi>(this);
1703 modulesModule->availableLV->header()->setVisible(false);
1704 modulesModule->availableLV->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
1705 modulesModule->availableLV->header()->setStretchLastSection(false);
1706 modulesModule->selectedLV->header()->setVisible(false);
1707 modulesModule->selectedLV->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
1708 modulesModule->selectedLV->header()->setStretchLastSection(false);
1710 new ModuleSelectionManager(this, modulesModule->availableLV,
1711 modulesModule->selectedLV,
1712 modulesModule->addPB,
1713 modulesModule->deletePB,
1714 modulesModule->upPB,
1715 modulesModule->downPB,
1716 availableModel(), selectedModel(), this);
1717 connect(selectionManager, SIGNAL(updateHook()),
1718 this, SLOT(updateModuleInfo()));
1719 connect(selectionManager, SIGNAL(selectionChanged()),
1720 this, SLOT(modulesChanged()));
1722 filter_ = new FancyLineEdit(this);
1723 filter_->setClearButton(true);
1724 filter_->setPlaceholderText(qt_("All avail. modules"));
1725 modulesModule->moduleFilterBarL->addWidget(filter_, 0);
1726 modulesModule->findModulesLA->setBuddy(filter_);
1728 connect(filter_, SIGNAL(rightButtonClicked()),
1729 this, SLOT(resetModuleFilter()));
1730 connect(filter_, SIGNAL(textEdited(QString)),
1731 this, SLOT(moduleFilterChanged(QString)));
1732 connect(filter_, SIGNAL(returnPressed()),
1733 this, SLOT(moduleFilterPressed()));
1734 connect(filter_, &FancyLineEdit::downPressed,
1735 modulesModule->availableLV, [this](){ focusAndHighlight(modulesModule->availableLV); });
1739 pdfSupportModule = new UiWidget<Ui::PDFSupportUi>(this);
1740 connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
1741 this, SLOT(change_adaptor()));
1742 connect(pdfSupportModule->titleLE, SIGNAL(textChanged(QString)),
1743 this, SLOT(change_adaptor()));
1744 connect(pdfSupportModule->authorLE, SIGNAL(textChanged(QString)),
1745 this, SLOT(change_adaptor()));
1746 connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(QString)),
1747 this, SLOT(change_adaptor()));
1748 connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(QString)),
1749 this, SLOT(change_adaptor()));
1750 connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
1751 this, SLOT(change_adaptor()));
1752 connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
1753 this, SLOT(change_adaptor()));
1754 connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
1755 this, SLOT(change_adaptor()));
1756 connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
1757 this, SLOT(bookmarksopenChanged(bool)));
1758 connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
1759 this, SLOT(change_adaptor()));
1760 connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
1761 this, SLOT(change_adaptor()));
1762 connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
1763 this, SLOT(change_adaptor()));
1764 connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
1765 this, SLOT(change_adaptor()));
1766 connect(pdfSupportModule->backrefCO, SIGNAL(activated(int)),
1767 this, SLOT(change_adaptor()));
1768 connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
1769 this, SLOT(change_adaptor()));
1770 connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
1771 this, SLOT(change_adaptor()));
1772 connect(pdfSupportModule->optionsTE, SIGNAL(textChanged()),
1773 this, SLOT(change_adaptor()));
1774 connect(pdfSupportModule->metadataTE, SIGNAL(textChanged()),
1775 this, SLOT(change_adaptor()));
1777 pdfSupportModule->titleLE->setValidator(new NoNewLineValidator(
1778 pdfSupportModule->titleLE));
1779 pdfSupportModule->authorLE->setValidator(new NoNewLineValidator(
1780 pdfSupportModule->authorLE));
1781 pdfSupportModule->subjectLE->setValidator(new NoNewLineValidator(
1782 pdfSupportModule->subjectLE));
1783 pdfSupportModule->keywordsLE->setValidator(new NoNewLineValidator(
1784 pdfSupportModule->keywordsLE));
1786 pdf_options_highlighter_ = new LaTeXHighlighter(
1787 pdfSupportModule->optionsTE->document(), true, true);
1788 pdf_metadata_highlighter_ = new LaTeXHighlighter(
1789 pdfSupportModule->metadataTE->document(), true, true);
1791 for (int i = 0; backref_opts[i][0]; ++i)
1792 pdfSupportModule->backrefCO->addItem(qt_(backref_opts_gui[i]));
1796 floatModule = new FloatPlacement;
1797 connect(floatModule, SIGNAL(changed()),
1798 this, SLOT(change_adaptor()));
1802 listingsModule = new UiWidget<Ui::ListingsSettingsUi>(this);
1803 connect(listingsModule->listingsED, SIGNAL(textChanged()),
1804 this, SLOT(change_adaptor()));
1805 connect(listingsModule->bypassCB, SIGNAL(clicked()),
1806 this, SLOT(change_adaptor()));
1807 connect(listingsModule->bypassCB, SIGNAL(clicked()),
1808 this, SLOT(setListingsMessage()));
1809 connect(listingsModule->packageCO, SIGNAL(activated(int)),
1810 this, SLOT(change_adaptor()));
1811 connect(listingsModule->packageCO, SIGNAL(activated(int)),
1812 this, SLOT(listingsPackageChanged(int)));
1813 connect(listingsModule->listingsED, SIGNAL(textChanged()),
1814 this, SLOT(setListingsMessage()));
1815 listingsModule->listingsTB->setPlainText(
1816 qt_("Input listings parameters below. Enter ? for a list of parameters."));
1818 for (int i = 0; lst_packages[i][0]; ++i)
1819 listingsModule->packageCO->addItem(lst_packages[i]);
1823 docPS->addPanel(latexModule, N_("Document Class"));
1824 docPS->addPanel(masterChildModule, N_("Child Documents"));
1825 docPS->addPanel(modulesModule, N_("Modules"));
1826 docPS->addPanel(localLayout, N_("Local Layout"));
1827 docPS->addPanel(fontModule, N_("Fonts"));
1828 docPS->addPanel(textLayoutModule, N_("Text Layout"));
1829 docPS->addPanel(pageLayoutModule, N_("Page Layout"));
1830 docPS->addPanel(marginsModule, N_("Page Margins"));
1831 docPS->addPanel(langModule, N_("Language"));
1832 docPS->addPanel(colorModule, N_("Colors"));
1833 docPS->addPanel(changesModule, N_("Change Tracking"));
1834 docPS->addPanel(numberingModule, N_("Numbering & TOC"));
1835 docPS->addPanel(biblioModule, N_("Bibliography"));
1836 docPS->addPanel(indicesModule, N_("Indexes"));
1837 docPS->addPanel(pdfSupportModule, N_("PDF Properties"));
1838 docPS->addPanel(mathsModule, N_("Math Options"));
1839 docPS->addPanel(floatModule, N_("Float Settings"));
1840 docPS->addPanel(listingsModule, N_("Listings[[inset]]"));
1841 docPS->addPanel(bulletsModule, N_("Bullets"));
1842 docPS->addPanel(branchesModule, N_("Branches"));
1843 docPS->addPanel(outputModule, N_("Output"));
1844 docPS->addPanel(preambleModule, N_("LaTeX Preamble"));
1845 docPS->setCurrentPanel("Document Class");
1847 // Filter out (dark/light) mode changes
1848 installEventFilter(this);
1852 void GuiDocument::onBufferViewChanged()
1855 // We are just switching back. Nothing to do.
1856 switchback_ = false;
1859 BufferView const * view = bufferview();
1860 string const new_filename = view ? view->buffer().absFileName() : string();
1861 // If we switched buffer really and the previous file name is different to
1862 // the current one, we ask on unapplied changes (#9369)
1863 // FIXME: This is more complicated than it should be. Why do we need these to cycles?
1864 // And ideally, we should propose to apply without having to switch back
1865 // (e.g., via a LFUN_BUFFER_PARAMS_APPLY_OTHER)
1866 if (!prev_buffer_filename_.empty() && prev_buffer_filename_ != new_filename
1867 && buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
1868 // Only ask if we haven't yet in this cycle
1869 int const ret = prompted_ ? 3 : Alert::prompt(_("Unapplied changes"),
1870 _("Some changes in the previous document were not yet applied.\n"
1871 "Do you want to switch back and apply them?"),
1872 1, 1, _("Yes, &Switch Back"), _("No, &Dismiss Changes"));
1874 // Switch to previous buffer view and apply
1876 // Record that we have asked.
1878 lyx::dispatch(FuncRequest(LFUN_BUFFER_SWITCH, prev_buffer_filename_));
1880 } else if (ret == 3) {
1881 // We are in the second cycle. Set back.
1887 if (isVisibleView())
1888 initialiseParams("");
1892 void GuiDocument::saveDefaultClicked()
1898 void GuiDocument::useDefaultsClicked()
1904 void GuiDocument::change_adaptor()
1906 nonModuleChanged_ = true;
1911 void GuiDocument::shellescapeChanged()
1913 shellescapeChanged_ = true;
1917 void GuiDocument::bookmarksopenChanged(bool state)
1919 pdfSupportModule->bookmarksopenlevelSB->setEnabled(state);
1920 pdfSupportModule->bookmarksopenlevelLA->setEnabled(state);
1924 void GuiDocument::changeTrackingChanged(bool state)
1926 // This is triggered if the CT state is toggled outside
1927 // the document dialog (e.g., menu).
1928 changesModule->trackChangesCB->setChecked(state);
1932 void GuiDocument::slotApply()
1934 bool only_shellescape_changed = !nonModuleChanged_ && !modulesChanged_;
1935 bool wasclean = buffer().isClean();
1936 GuiDialog::slotApply();
1937 if (wasclean && only_shellescape_changed)
1938 buffer().markClean();
1939 modulesChanged_ = false;
1944 void GuiDocument::slotOK()
1946 bool only_shellescape_changed = !nonModuleChanged_ && !modulesChanged_;
1947 bool wasclean = buffer().isClean();
1948 GuiDialog::slotOK();
1949 if (wasclean && only_shellescape_changed)
1950 buffer().markClean();
1951 modulesChanged_ = false;
1955 void GuiDocument::slotButtonBox(QAbstractButton * button)
1957 switch (buttonBox->standardButton(button)) {
1958 case QDialogButtonBox::Ok:
1961 case QDialogButtonBox::Apply:
1964 case QDialogButtonBox::Cancel:
1967 case QDialogButtonBox::Reset:
1968 case QDialogButtonBox::RestoreDefaults:
1977 void GuiDocument::filterModules(QString const & str)
1979 updateAvailableModules();
1983 modules_av_model_.clear();
1984 list<modInfoStruct> modInfoList = getModuleInfo();
1985 // Sort names according to the locale
1986 modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
1987 return 0 < b.name.localeAwareCompare(a.name);
1990 QIcon user_icon(guiApp ? guiApp->getScaledPixmap("images/", "lyxfiles-user")
1991 : getPixmap("images/", "lyxfiles-user", "svgz,png"));
1992 QIcon system_icon(guiApp ? guiApp->getScaledPixmap("images/", "lyxfiles-system")
1993 : getPixmap("images/", "lyxfiles-system", "svgz,png"));
1996 for (modInfoStruct const & m : modInfoList) {
1997 if (m.name.contains(str, Qt::CaseInsensitive) || contains(m.id, fromqstr(str))) {
1998 QStandardItem * item = new QStandardItem();
1999 item->setData(m.name, Qt::DisplayRole);
2000 item->setData(toqstr(m.id), Qt::UserRole);
2001 item->setData(m.description, Qt::ToolTipRole);
2002 item->setEditable(false);
2004 item->setIcon(user_icon);
2006 item->setIcon(system_icon);
2007 modules_av_model_.insertRow(i, item);
2014 void GuiDocument::moduleFilterChanged(const QString & text)
2016 if (!text.isEmpty()) {
2017 filterModules(filter_->text());
2020 filterModules(filter_->text());
2021 filter_->setFocus();
2025 void GuiDocument::moduleFilterPressed()
2027 filterModules(filter_->text());
2031 void GuiDocument::resetModuleFilter()
2033 filter_->setText(QString());
2034 filterModules(filter_->text());
2038 void GuiDocument::includeonlyClicked(QTreeWidgetItem * item, int)
2040 if (item == nullptr)
2043 string child = fromqstr(item->text(0));
2048 if (isChildIncluded(child))
2049 includeonlys_.remove(child);
2051 includeonlys_.push_back(child);
2053 updateIncludeonlys(false);
2058 QString GuiDocument::validateListingsParameters()
2060 if (listingsModule->bypassCB->isChecked())
2062 string const package =
2063 lst_packages[listingsModule->packageCO->currentIndex()];
2064 string params = fromqstr(listingsModule->listingsED->toPlainText());
2065 InsetListingsParams lstparams(params);
2066 lstparams.setMinted(package == "Minted");
2067 return toqstr(lstparams.validate());
2071 void GuiDocument::setListingsMessage()
2074 static bool isOK = true;
2075 QString msg = validateListingsParameters();
2076 if (msg.isEmpty()) {
2077 listingsModule->listingsTB->setTextColor(QColor());
2081 listingsModule->listingsTB->setPlainText(
2082 qt_("Input listings parameters below. "
2083 "Enter ? for a list of parameters."));
2086 listingsModule->listingsTB->setTextColor(QColor(255, 0, 0));
2087 listingsModule->listingsTB->setPlainText(msg);
2092 void GuiDocument::listingsPackageChanged(int index)
2094 string const package = lst_packages[index];
2095 if (package == "Minted" && lyxrc.pygmentize_command.empty()) {
2096 Alert::warning(_("Pygments driver command not found!"),
2097 _("The driver command necessary to use the minted package\n"
2098 "(pygmentize) has not been found. Make sure you have\n"
2099 "the python-pygments module installed or, if the driver\n"
2100 "is named differently, to add the following line to the\n"
2101 "document preamble:\n\n"
2102 "\\AtBeginDocument{\\renewcommand{\\MintedPygmentize}{driver}}\n\n"
2103 "where 'driver' is name of the driver command."));
2108 void GuiDocument::setLSpacing(int item)
2110 textLayoutModule->lspacingLE->setEnabled(item == 3);
2114 void GuiDocument::setIndent(int item)
2116 bool const enable = (textLayoutModule->indentCO->itemData(item) == "custom");
2117 textLayoutModule->indentLE->setEnabled(enable);
2118 textLayoutModule->indentLengthCO->setEnabled(enable);
2119 textLayoutModule->skipLE->setEnabled(false);
2120 textLayoutModule->skipLengthCO->setEnabled(false);
2121 // needed to catch empty custom case
2127 void GuiDocument::enableIndent(bool indent)
2129 textLayoutModule->skipLE->setEnabled(!indent);
2130 textLayoutModule->skipLengthCO->setEnabled(!indent);
2132 setIndent(textLayoutModule->indentCO->currentIndex());
2136 void GuiDocument::setSkip(int item)
2138 VSpace::VSpaceKind kind =
2139 VSpace::VSpaceKind(textLayoutModule->skipCO->itemData(item).toInt());
2140 bool const enable = (kind == VSpace::LENGTH);
2141 textLayoutModule->skipLE->setEnabled(enable);
2142 textLayoutModule->skipLengthCO->setEnabled(enable);
2143 // needed to catch empty custom case
2149 void GuiDocument::enableSkip(bool skip)
2151 textLayoutModule->indentLE->setEnabled(!skip);
2152 textLayoutModule->indentLengthCO->setEnabled(!skip);
2154 setSkip(textLayoutModule->skipCO->currentIndex());
2157 void GuiDocument::allowMathIndent() {
2158 // only disable when not checked, checked does not always allow enabling
2159 if (!mathsModule->MathIndentCB->isChecked()) {
2160 mathsModule->MathIndentLE->setEnabled(false);
2161 mathsModule->MathIndentLengthCO->setEnabled(false);
2163 if (mathsModule->MathIndentCB->isChecked()
2164 && mathsModule->MathIndentCO->itemData(mathsModule->MathIndentCO->currentIndex()) == "custom") {
2165 mathsModule->MathIndentLE->setEnabled(true);
2166 mathsModule->MathIndentLengthCO->setEnabled(true);
2171 void GuiDocument::enableMathIndent(int item)
2173 bool const enable = (item == 1);
2174 mathsModule->MathIndentLE->setEnabled(enable);
2175 mathsModule->MathIndentLengthCO->setEnabled(enable);
2176 // needed to catch empty custom case
2182 void GuiDocument::setMargins()
2184 bool const extern_geometry =
2185 documentClass().provides("geometry");
2186 marginsModule->marginCB->setEnabled(!extern_geometry);
2187 if (extern_geometry) {
2188 marginsModule->marginCB->setChecked(false);
2189 setCustomMargins(true);
2191 marginsModule->marginCB->setChecked(!bp_.use_geometry);
2192 setCustomMargins(!bp_.use_geometry);
2197 void GuiDocument::papersizeChanged(int paper_size)
2199 setCustomPapersize(paper_size == 1);
2203 void GuiDocument::setCustomPapersize(bool custom)
2205 pageLayoutModule->paperwidthL->setEnabled(custom);
2206 pageLayoutModule->paperwidthLE->setEnabled(custom);
2207 pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
2208 pageLayoutModule->paperheightL->setEnabled(custom);
2209 pageLayoutModule->paperheightLE->setEnabled(custom);
2210 pageLayoutModule->paperheightLE->setFocus();
2211 pageLayoutModule->paperheightUnitCO->setEnabled(custom);
2215 void GuiDocument::setColSep()
2217 setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
2221 void GuiDocument::setCustomMargins(bool custom)
2223 marginsModule->topL->setEnabled(!custom);
2224 marginsModule->topLE->setEnabled(!custom);
2225 marginsModule->topUnit->setEnabled(!custom);
2227 marginsModule->bottomL->setEnabled(!custom);
2228 marginsModule->bottomLE->setEnabled(!custom);
2229 marginsModule->bottomUnit->setEnabled(!custom);
2231 marginsModule->innerL->setEnabled(!custom);
2232 marginsModule->innerLE->setEnabled(!custom);
2233 marginsModule->innerUnit->setEnabled(!custom);
2235 marginsModule->outerL->setEnabled(!custom);
2236 marginsModule->outerLE->setEnabled(!custom);
2237 marginsModule->outerUnit->setEnabled(!custom);
2239 marginsModule->headheightL->setEnabled(!custom);
2240 marginsModule->headheightLE->setEnabled(!custom);
2241 marginsModule->headheightUnit->setEnabled(!custom);
2243 marginsModule->headsepL->setEnabled(!custom);
2244 marginsModule->headsepLE->setEnabled(!custom);
2245 marginsModule->headsepUnit->setEnabled(!custom);
2247 marginsModule->footskipL->setEnabled(!custom);
2248 marginsModule->footskipLE->setEnabled(!custom);
2249 marginsModule->footskipUnit->setEnabled(!custom);
2251 bool const enableColSep = !custom &&
2252 textLayoutModule->twoColumnCB->checkState() == Qt::Checked;
2253 marginsModule->columnsepL->setEnabled(enableColSep);
2254 marginsModule->columnsepLE->setEnabled(enableColSep);
2255 marginsModule->columnsepUnit->setEnabled(enableColSep);
2257 // set some placeholder text that hint on defaults
2258 QString const placeholder = marginsModule->marginCB->isChecked() ?
2259 qt_("Default margins") : qt_("Package defaults");
2260 // set tooltip depending on gemoetry state
2261 QString const tooltip = marginsModule->marginCB->isChecked() ?
2262 qt_("If no value is given, the defaults as set by the class, a package or the preamble are used.")
2263 : qt_("If no value is given, the defaults as set by the geometry package or a package/class overriding geometry's defaults are used.");
2264 marginsModule->topLE->setPlaceholderText(placeholder);
2265 marginsModule->bottomLE->setPlaceholderText(placeholder);
2266 marginsModule->innerLE->setPlaceholderText(placeholder);
2267 marginsModule->outerLE->setPlaceholderText(placeholder);
2268 marginsModule->headheightLE->setPlaceholderText(placeholder);
2269 marginsModule->headsepLE->setPlaceholderText(placeholder);
2270 marginsModule->footskipLE->setPlaceholderText(placeholder);
2271 marginsModule->columnsepLE->setPlaceholderText(placeholder);
2272 marginsModule->topLE->setToolTip(tooltip);
2273 marginsModule->bottomLE->setToolTip(tooltip);
2274 marginsModule->innerLE->setToolTip(tooltip);
2275 marginsModule->outerLE->setToolTip(tooltip);
2276 marginsModule->headheightLE->setToolTip(tooltip);
2277 marginsModule->headsepLE->setToolTip(tooltip);
2278 marginsModule->footskipLE->setToolTip(tooltip);
2279 marginsModule->columnsepLE->setToolTip(tooltip);
2283 void GuiDocument::changeBackgroundColor()
2285 QColor const & newColor = getColor(rgb2qcolor(set_backgroundcolor));
2286 if (!newColor.isValid())
2289 colorModule->pageBackgroundCF->setVisible(true);
2290 colorModule->pageBackgroundCF->setStyleSheet(
2291 colorFrameStyleSheet(newColor));
2293 set_backgroundcolor = rgbFromHexName(fromqstr(newColor.name()));
2294 is_backgroundcolor = true;
2299 void GuiDocument::deleteBackgroundColor()
2301 // set the color back to default by setting an empty StyleSheet
2302 colorModule->pageBackgroundCF->setStyleSheet(QLatin1String(""));
2303 colorModule->pageBackgroundCF->setVisible(false);
2304 // save default color (white)
2305 set_backgroundcolor = rgbFromHexName("#ffffff");
2306 is_backgroundcolor = false;
2311 void GuiDocument::changeFontColor()
2313 QColor const & newColor = getColor(rgb2qcolor(set_fontcolor));
2314 if (!newColor.isValid())
2317 colorModule->mainTextCF->setVisible(true);
2318 colorModule->mainTextCF->setStyleSheet(
2319 colorFrameStyleSheet(newColor));
2321 set_fontcolor = rgbFromHexName(fromqstr(newColor.name()));
2322 is_fontcolor = true;
2327 void GuiDocument::deleteFontColor()
2329 // set the button color back to default by setting an empty StyleSheet
2330 colorModule->mainTextCF->setStyleSheet(QLatin1String(""));
2331 colorModule->mainTextCF->setVisible(false);
2332 // save default color (black)
2333 set_fontcolor = rgbFromHexName("#000000");
2334 is_fontcolor = false;
2339 void GuiDocument::changeNoteFontColor()
2341 QColor const & newColor = getColor(rgb2qcolor(set_notefontcolor));
2342 if (!newColor.isValid())
2345 colorModule->noteFontCF->setStyleSheet(
2346 colorFrameStyleSheet(newColor));
2348 set_notefontcolor = rgbFromHexName(fromqstr(newColor.name()));
2349 is_notefontcolor = true;
2354 void GuiDocument::deleteNoteFontColor()
2356 // set the color back to pref
2357 theApp()->getRgbColor(Color_greyedouttext, set_notefontcolor);
2358 colorModule->noteFontCF->setStyleSheet(
2359 colorFrameStyleSheet(rgb2qcolor(set_notefontcolor)));
2360 is_notefontcolor = false;
2365 void GuiDocument::changeBoxBackgroundColor()
2367 QColor const & newColor = getColor(rgb2qcolor(set_boxbgcolor));
2368 if (!newColor.isValid())
2371 colorModule->boxBackgroundCF->setStyleSheet(
2372 colorFrameStyleSheet(newColor));
2374 set_boxbgcolor = rgbFromHexName(fromqstr(newColor.name()));
2375 is_boxbgcolor = true;
2380 void GuiDocument::deleteBoxBackgroundColor()
2382 // set the color back to pref
2383 theApp()->getRgbColor(Color_shadedbg, set_boxbgcolor);
2384 colorModule->boxBackgroundCF->setStyleSheet(
2385 colorFrameStyleSheet(rgb2qcolor(set_boxbgcolor)));
2386 is_boxbgcolor = false;
2391 void GuiDocument::updateQuoteStyles(bool const set)
2393 Language const * lang = lyx::languages.getLanguage(
2394 fromqstr(langModule->languageCO->itemData(
2395 langModule->languageCO->currentIndex()).toString()));
2397 QuoteStyle def = bp_.getQuoteStyle(lang->quoteStyle());
2399 langModule->quoteStyleCO->clear();
2401 bool has_default = false;
2402 for (int i = 0; i < quoteparams.stylescount(); ++i) {
2403 QuoteStyle qs = QuoteStyle(i);
2404 if (qs == QuoteStyle::Dynamic)
2406 bool const langdef = (qs == def);
2408 // add the default style on top
2409 langModule->quoteStyleCO->insertItem(0,
2410 toqstr(quoteparams.getGuiLabel(qs, langdef)), static_cast<int>(qs));
2414 langModule->quoteStyleCO->addItem(
2415 toqstr(quoteparams.getGuiLabel(qs, langdef)), static_cast<int>(qs));
2417 // Use document serif font to assure quotation marks are distinguishable
2418 QFont comboFont(toqstr(lyxrc.roman_font_name),
2419 langModule->quoteStyleCO->fontInfo().pointSize() * 1.4, -1, false);
2420 QFontMetrics fm(comboFont);
2421 // calculate width of the widest item in the set font
2423 for (int i = 0; i < langModule->quoteStyleCO->count(); ++i) {
2424 langModule->quoteStyleCO->setItemData(i, QVariant(comboFont), Qt::FontRole);
2425 QString str = langModule->quoteStyleCO->itemText(i);
2426 #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
2427 qswidth = max(qswidth, fm.horizontalAdvance(str));
2429 qswidth = max(qswidth, fm.width(str));
2432 // add scrollbar width and margin to width
2433 qswidth += langModule->quoteStyleCO->style()->pixelMetric(QStyle::PM_ScrollBarExtent);
2434 qswidth += langModule->quoteStyleCO->view()->autoScrollMargin();
2435 langModule->quoteStyleCO->view()->setMinimumWidth(qswidth);
2436 if (set && has_default)
2437 // (re)set to the default style
2438 langModule->quoteStyleCO->setCurrentIndex(0);
2442 void GuiDocument::languageChanged(int i)
2444 // some languages only work with Polyglossia
2445 Language const * lang = lyx::languages.getLanguage(
2446 fromqstr(langModule->languageCO->itemData(i).toString()));
2447 if (lang->babel().empty() && !lang->polyglossia().empty()
2448 && lang->required() != "CJK" && lang->required() != "japanese") {
2449 // If we force to switch fontspec on, store
2450 // current state (#8717)
2451 if (fontModule->osFontsCB->isEnabled())
2452 forced_fontspec_activation =
2453 !fontModule->osFontsCB->isChecked();
2454 fontModule->osFontsCB->setChecked(true);
2455 fontModule->osFontsCB->setEnabled(false);
2458 fontModule->osFontsCB->setEnabled(true);
2459 // If we have forced to switch fontspec on,
2460 // restore previous state (#8717)
2461 if (forced_fontspec_activation)
2462 fontModule->osFontsCB->setChecked(false);
2463 forced_fontspec_activation = false;
2466 // set appropriate quotation mark style
2467 updateQuoteStyles(true);
2471 void GuiDocument::osFontsChanged(bool nontexfonts)
2473 bool const tex_fonts = !nontexfonts;
2474 // store current fonts
2475 QString const font_roman = fontModule->fontsRomanCO->getData(
2476 fontModule->fontsRomanCO->currentIndex());
2477 QString const font_sans = fontModule->fontsSansCO->getData(
2478 fontModule->fontsSansCO->currentIndex());
2479 QString const font_typewriter = fontModule->fontsTypewriterCO->getData(
2480 fontModule->fontsTypewriterCO->currentIndex());
2481 QString const font_math = fontModule->fontsMathCO->itemData(
2482 fontModule->fontsMathCO->currentIndex()).toString();
2483 int const font_sf_scale = fontModule->scaleSansSB->value();
2484 int const font_tt_scale = fontModule->scaleTypewriterSB->value();
2487 // store default format
2488 QString const dformat = outputModule->defaultFormatCO->itemData(
2489 outputModule->defaultFormatCO->currentIndex()).toString();
2490 updateDefaultFormat();
2491 // try to restore default format
2492 int index = outputModule->defaultFormatCO->findData(dformat);
2493 // set to default if format is not found
2496 outputModule->defaultFormatCO->setCurrentIndex(index);
2498 // try to restore fonts which were selected two toggles ago
2499 if (!fontModule->font_roman.isEmpty())
2500 fontModule->fontsRomanCO->set(fontModule->font_roman);
2501 if (!fontModule->font_sans.isEmpty())
2502 fontModule->fontsSansCO->set(fontModule->font_sans);
2503 if (!fontModule->font_typewriter.isEmpty())
2504 fontModule->fontsTypewriterCO->set(fontModule->font_typewriter);
2505 index = fontModule->fontsMathCO->findData(fontModule->font_math);
2507 fontModule->fontsMathCO->setCurrentIndex(index);
2508 // save fonts for next next toggle
2509 fontModule->font_roman = font_roman;
2510 fontModule->font_sans = font_sans;
2511 fontModule->font_typewriter = font_typewriter;
2512 fontModule->font_math = font_math;
2513 fontModule->font_sf_scale = font_sf_scale;
2514 fontModule->font_tt_scale = font_tt_scale;
2516 // non-tex fonts override the "\inputencoding" option with "utf8-plain"
2517 langModule->encodingCO->setEnabled(tex_fonts);
2518 inputencodingToDialog();
2520 fontModule->cjkFontLE->setEnabled(tex_fonts);
2521 fontModule->cjkFontLA->setEnabled(tex_fonts);
2523 updateFontOptions();
2525 fontModule->fontencLA->setEnabled(tex_fonts);
2526 fontModule->fontencCO->setEnabled(tex_fonts);
2528 fontModule->fontencLE->setEnabled(false);
2530 fontencChanged(fontModule->fontencCO->currentIndex());
2534 void GuiDocument::encodingSwitched(int i)
2536 bool const tex_fonts = !fontModule->osFontsCB->isChecked();
2537 langModule->unicodeEncodingCO->setEnabled(tex_fonts);
2538 langModule->customEncodingCO->setEnabled(tex_fonts);
2539 langModule->autoEncodingCO->setEnabled(tex_fonts);
2540 langModule->unicodeEncodingCO->setVisible(i == EncodingSets::unicode);
2541 langModule->autoEncodingCO->setVisible(i == EncodingSets::legacy);
2542 langModule->customEncodingCO->setVisible(i == EncodingSets::custom);
2544 case EncodingSets::unicode:
2545 langModule->encodingVariantLA->setBuddy(langModule->unicodeEncodingCO);
2547 case EncodingSets::legacy:
2548 langModule->encodingVariantLA->setBuddy(langModule->autoEncodingCO);
2550 case EncodingSets::custom:
2551 langModule->encodingVariantLA->setBuddy(langModule->customEncodingCO);
2556 langModule->unicodeEncodingCO->setItemText(1, qt_("Direct (No inputenc)"));
2558 langModule->unicodeEncodingCO->setItemText(1, qt_("Direct (XeTeX/LuaTeX)"));
2561 void GuiDocument::inputencodingToDialog()
2563 QString inputenc = toqstr(bp_.inputenc);
2565 if (fontModule->osFontsCB->isChecked()) { // non-tex fonts require utf8-plain
2566 langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
2567 langModule->unicodeEncodingCO->setCurrentIndex(
2568 langModule->unicodeEncodingCO->findData("utf8-plain"));
2569 } else if (inputenc.startsWith("utf8")) {
2570 langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
2571 p = langModule->unicodeEncodingCO->findData(inputenc);
2574 langModule->unicodeEncodingCO->setCurrentIndex(p);
2575 langModule->autoEncodingCO->setCurrentIndex(0);
2576 langModule->customEncodingCO->setCurrentIndex(0);
2577 } else if (inputenc.startsWith("auto")) {
2578 langModule->encodingCO->setCurrentIndex(EncodingSets::legacy);
2579 p = langModule->autoEncodingCO->findData(inputenc);
2582 langModule->unicodeEncodingCO->setCurrentIndex(0);
2583 langModule->autoEncodingCO->setCurrentIndex(p);
2584 langModule->customEncodingCO->setCurrentIndex(0);
2586 langModule->encodingCO->setCurrentIndex(EncodingSets::custom);
2587 p = langModule->customEncodingCO->findData(inputenc);
2590 langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
2592 langModule->unicodeEncodingCO->setCurrentIndex(0);
2593 langModule->autoEncodingCO->setCurrentIndex(0);
2594 langModule->customEncodingCO->setCurrentIndex(p);
2596 encodingSwitched(langModule->encodingCO->currentIndex());
2600 void GuiDocument::mathFontChanged(int)
2602 updateFontOptions();
2605 void GuiDocument::fontOsfToggled(bool state)
2607 if (fontModule->osFontsCB->isChecked())
2609 QString font = fontModule->fontsRomanCO->getData(
2610 fontModule->fontsRomanCO->currentIndex());
2611 if (hasMonolithicExpertSet(font))
2612 fontModule->fontScCB->setChecked(state);
2616 void GuiDocument::fontScToggled(bool state)
2618 if (fontModule->osFontsCB->isChecked())
2620 QString font = fontModule->fontsRomanCO->getData(
2621 fontModule->fontsRomanCO->currentIndex());
2622 if (hasMonolithicExpertSet(font))
2623 fontModule->fontOsfCB->setChecked(state);
2627 void GuiDocument::updateExtraOpts()
2629 QString font = fontModule->fontsRomanCO->getData(
2630 fontModule->fontsRomanCO->currentIndex());
2631 bool const rm_opts = providesExtraOpts(font);
2632 font = fontModule->fontsSansCO->getData(
2633 fontModule->fontsSansCO->currentIndex());
2634 bool const sf_opts = providesExtraOpts(font);
2635 font = fontModule->fontsTypewriterCO->getData(
2636 fontModule->fontsTypewriterCO->currentIndex());
2637 bool const tt_opts = providesExtraOpts(font);
2638 fontModule->fontspecRomanLA->setEnabled(rm_opts);
2639 fontModule->fontspecRomanLE->setEnabled(rm_opts);
2640 fontModule->fontspecSansLA->setEnabled(sf_opts);
2641 fontModule->fontspecSansLE->setEnabled(sf_opts);
2642 fontModule->fontspecTypewriterLA->setEnabled(tt_opts);
2643 fontModule->fontspecTypewriterLE->setEnabled(tt_opts);
2647 void GuiDocument::updateFontOptions()
2649 QString font = fontModule->fontsSansCO->getData(
2650 fontModule->fontsSansCO->currentIndex());
2651 bool scalable = providesScale(font);
2652 fontModule->scaleSansSB->setEnabled(scalable);
2653 fontModule->scaleSansLA->setEnabled(scalable);
2654 fontModule->fontSansOsfCB->setEnabled(providesOSF(font));
2655 font = fontModule->fontsTypewriterCO->getData(
2656 fontModule->fontsTypewriterCO->currentIndex());
2657 scalable = providesScale(font);
2658 fontModule->scaleTypewriterSB->setEnabled(scalable);
2659 fontModule->scaleTypewriterLA->setEnabled(scalable);
2660 fontModule->fontTypewriterOsfCB->setEnabled(providesOSF(font));
2661 font = fontModule->fontsRomanCO->getData(
2662 fontModule->fontsRomanCO->currentIndex());
2663 fontModule->fontScCB->setEnabled(providesSC(font));
2664 fontModule->fontOsfCB->setEnabled(providesOSF(font));
2666 updateMathFonts(font);
2670 void GuiDocument::updateFontsize(string const & items, string const & sel)
2672 fontModule->fontsizeCO->clear();
2673 fontModule->fontsizeCO->addItem(qt_("Default"));
2675 for (int n = 0; !token(items,'|',n).empty(); ++n)
2676 fontModule->fontsizeCO->
2677 addItem(toqstr(token(items,'|',n)));
2679 for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
2680 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
2681 fontModule->fontsizeCO->setCurrentIndex(n);
2688 bool GuiDocument::ot1() const
2690 QString const fontenc =
2691 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
2692 int const i = langModule->languageCO->currentIndex();
2695 QString const langname = langModule->languageCO->itemData(i).toString();
2696 Language const * newlang = lyx::languages.getLanguage(fromqstr(langname));
2697 return (fontenc == "default"
2698 || (fontenc == "auto" && newlang->fontenc(buffer().params()) == "OT1")
2699 || (fontenc == "custom" && fontModule->fontencLE->text() == "OT1"));
2703 bool GuiDocument::completeFontset() const
2705 return (fontModule->fontsSansCO->getData(
2706 fontModule->fontsSansCO->currentIndex()) == "default"
2707 && fontModule->fontsSansCO->getData(
2708 fontModule->fontsTypewriterCO->currentIndex()) == "default");
2712 bool GuiDocument::noMathFont() const
2714 return (fontModule->fontsMathCO->itemData(
2715 fontModule->fontsMathCO->currentIndex()).toString() == "default");
2719 void GuiDocument::updateTexFonts()
2721 LaTeXFonts::TexFontMap texfontmap = theLaTeXFonts().getLaTeXFonts();
2723 LaTeXFonts::TexFontMap::const_iterator it = texfontmap.begin();
2724 LaTeXFonts::TexFontMap::const_iterator end = texfontmap.end();
2725 for (; it != end; ++it) {
2726 LaTeXFont lf = it->second;
2727 if (lf.name().empty()) {
2728 LYXERR0("Error: Unnamed font: " << it->first);
2731 docstring const family = lf.family();
2732 docstring guiname = translateIfPossible(lf.guiname());
2733 if (!lf.available(ot1(), noMathFont()))
2734 guiname += _(" (not installed)");
2736 rmfonts_.insert(toqstr(guiname), toqstr(it->first));
2737 else if (family == "sf")
2738 sffonts_.insert(toqstr(guiname), toqstr(it->first));
2739 else if (family == "tt")
2740 ttfonts_.insert(toqstr(guiname), toqstr(it->first));
2741 else if (family == "math")
2742 mathfonts_.insert(toqstr(guiname), toqstr(it->first));
2747 void GuiDocument::updateFontlist()
2749 // reset the filters of the CategorizedCombos
2750 fontModule->fontsRomanCO->resetFilter();
2751 fontModule->fontsSansCO->resetFilter();
2752 fontModule->fontsTypewriterCO->resetFilter();
2753 fontModule->fontsRomanCO->clear();
2754 fontModule->fontsSansCO->clear();
2755 fontModule->fontsTypewriterCO->clear();
2756 fontModule->fontsMathCO->clear();
2758 // With fontspec (XeTeX, LuaTeX), we have access to all system fonts, but not the LaTeX fonts
2759 if (fontModule->osFontsCB->isChecked()) {
2760 fontModule->fontsRomanCO->addItemSort(QString("default"), qt_("Default"),
2761 QString(), qt_("Default font (as set by class)"),
2762 false, false, false, true, true);
2763 fontModule->fontsSansCO->addItemSort(QString("default"), qt_("Default"),
2764 QString(), qt_("Default font (as set by class)"),
2765 false, false, false, true, true);
2766 fontModule->fontsTypewriterCO->addItemSort(QString("default"), qt_("Default"),
2767 QString(), qt_("Default font (as set by class)"),
2768 false, false, false, true, true);
2769 QString unimath = qt_("Non-TeX Fonts Default");
2770 if (!LaTeXFeatures::isAvailable("unicode-math"))
2771 unimath += qt_(" (not available)");
2772 fontModule->fontsMathCO->addItem(qt_("Class Default (TeX Fonts)"), QString("auto"));
2773 fontModule->fontsMathCO->addItem(unimath, QString("default"));
2775 #if QT_VERSION >= 0x060000
2776 const QStringList families(QFontDatabase::families());
2778 QFontDatabase fontdb;
2779 const QStringList families(fontdb.families());
2781 for (auto const & family : families) {
2782 fontModule->fontsRomanCO->addItemSort(family, family,
2783 QString(), QString(),
2784 false, false, false, true, true);
2785 fontModule->fontsSansCO->addItemSort(family, family,
2786 QString(), QString(),
2787 false, false, false, true, true);
2788 fontModule->fontsTypewriterCO->addItemSort(family, family,
2789 QString(), QString(),
2790 false, false, false, true, true);
2795 if (rmfonts_.empty())
2798 fontModule->fontsRomanCO->addItemSort(QString("default"), qt_("Default"),
2799 QString(), qt_("Default font (as set by class)"),
2800 false, false, false, true, true);
2801 QMap<QString, QString>::const_iterator rmi = rmfonts_.constBegin();
2802 while (rmi != rmfonts_.constEnd()) {
2803 fontModule->fontsRomanCO->addItemSort(rmi.value(), rmi.key(),
2804 QString(), QString(),
2805 false, false, false, true, true);
2809 fontModule->fontsSansCO->addItemSort(QString("default"), qt_("Default"),
2810 QString(), qt_("Default font (as set by class)"),
2811 false, false, false, true, true);
2812 QMap<QString, QString>::const_iterator sfi = sffonts_.constBegin();
2813 while (sfi != sffonts_.constEnd()) {
2814 fontModule->fontsSansCO->addItemSort(sfi.value(), sfi.key(),
2815 QString(), QString(),
2816 false, false, false, true, true);
2820 fontModule->fontsTypewriterCO->addItemSort(QString("default"), qt_("Default"),
2821 QString(), qt_("Default font (as set by class)"),
2822 false, false, false, true, true);
2823 QMap<QString, QString>::const_iterator tti = ttfonts_.constBegin();
2824 while (tti != ttfonts_.constEnd()) {
2825 fontModule->fontsTypewriterCO->addItemSort(tti.value(), tti.key(),
2826 QString(), QString(),
2827 false, false, false, true, true);
2831 fontModule->fontsMathCO->addItem(qt_("Automatic"), QString("auto"));
2832 fontModule->fontsMathCO->addItem(qt_("Class Default"), QString("default"));
2833 QMap<QString, QString>::const_iterator mmi = mathfonts_.constBegin();
2834 while (mmi != mathfonts_.constEnd()) {
2835 fontModule->fontsMathCO->addItem(mmi.key(), mmi.value());
2841 void GuiDocument::fontencChanged(int item)
2843 fontModule->fontencLE->setEnabled(
2844 fontModule->fontencCO->itemData(item).toString() == "custom");
2845 // The availability of TeX fonts depends on the font encoding
2847 updateFontOptions();
2851 void GuiDocument::updateMathFonts(QString const & rm)
2853 if (fontModule->osFontsCB->isChecked())
2855 QString const math =
2856 fontModule->fontsMathCO->itemData(fontModule->fontsMathCO->currentIndex()).toString();
2857 int const i = fontModule->fontsMathCO->findData("default");
2858 if (providesNoMath(rm) && i == -1)
2859 fontModule->fontsMathCO->insertItem(1, qt_("Class Default"), QString("default"));
2860 else if (!providesNoMath(rm) && i != -1) {
2861 int const c = fontModule->fontsMathCO->currentIndex();
2862 fontModule->fontsMathCO->removeItem(i);
2864 fontModule->fontsMathCO->setCurrentIndex(0);
2869 void GuiDocument::romanChanged(int item)
2871 QString const font = fontModule->fontsRomanCO->getData(item);
2872 fontModule->fontOsfCB->setEnabled(providesOSF(font));
2874 if (fontModule->osFontsCB->isChecked())
2876 fontModule->fontScCB->setEnabled(providesSC(font));
2877 updateMathFonts(font);
2881 void GuiDocument::sansChanged(int item)
2883 QString const font = fontModule->fontsSansCO->getData(item);
2884 bool const scalable = providesScale(font);
2885 fontModule->scaleSansSB->setEnabled(scalable);
2886 fontModule->scaleSansLA->setEnabled(scalable);
2887 fontModule->fontSansOsfCB->setEnabled(providesOSF(font));
2892 void GuiDocument::ttChanged(int item)
2894 QString const font = fontModule->fontsTypewriterCO->getData(item);
2895 bool scalable = providesScale(font);
2896 fontModule->scaleTypewriterSB->setEnabled(scalable);
2897 fontModule->scaleTypewriterLA->setEnabled(scalable);
2898 fontModule->fontTypewriterOsfCB->setEnabled(providesOSF(font));
2903 void GuiDocument::updatePagestyle(string const & items, string const & sel)
2906 pageLayoutModule->pagestyleCO->clear();
2907 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
2909 for (int n = 0; !token(items, '|', n).empty(); ++n) {
2910 string style = token(items, '|', n);
2911 QString style_gui = qt_(style);
2912 pagestyles.push_back(pair<string, QString>(style, style_gui));
2913 pageLayoutModule->pagestyleCO->addItem(style_gui);
2916 if (sel == "default") {
2917 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
2923 for (auto const & pagestyle : pagestyles)
2924 if (pagestyle.first == sel)
2925 nn = pageLayoutModule->pagestyleCO->findText(pagestyle.second);
2928 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
2932 void GuiDocument::browseLayout()
2934 QString const label1 = qt_("Lay&outs");
2935 QString const dir1 = toqstr(lyxrc.document_path);
2936 QStringList const filter(qt_("LyX Layout (*.layout)"));
2937 QString file = browseRelToParent(QString(), bufferFilePath(),
2938 qt_("Local layout file"), filter, false,
2941 if (!file.endsWith(".layout"))
2944 FileName layoutFile = support::makeAbsPath(fromqstr(file),
2945 fromqstr(bufferFilePath()));
2947 int const ret = Alert::prompt(_("Local layout file"),
2948 _("The layout file you have selected is a local layout\n"
2949 "file, not one in the system or user directory.\n"
2950 "Your document will not work with this layout if you\n"
2951 "move the layout file to a different directory."),
2952 1, 1, _("&Set Layout"), _("&Cancel"));
2956 // load the layout file
2957 LayoutFileList & bcl = LayoutFileList::get();
2958 string classname = layoutFile.onlyFileName();
2959 // this will update an existing layout if that layout has been loaded before.
2960 LayoutFileIndex name = support::onlyFileName(bcl.addLocalLayout(
2961 classname.substr(0, classname.size() - 7),
2962 layoutFile.onlyPath().absFileName()));
2965 Alert::error(_("Error"),
2966 _("Unable to read local layout file."));
2970 const_cast<Buffer &>(buffer()).setLayoutPos(layoutFile.onlyPath().absFileName());
2972 // do not trigger classChanged if there is no change.
2973 if (latexModule->classCO->currentText() == toqstr(name))
2977 bool const avail = latexModule->classCO->set(toqstr(name));
2979 LayoutFile const & tc = bcl[name];
2980 docstring const guiname = translateIfPossible(from_utf8(tc.description()));
2981 // tooltip sensu "KOMA-Script Article [Class 'scrartcl']"
2982 QString tooltip = toqstr(bformat(_("%1$s [Class '%2$s']"), guiname, from_utf8(tc.latexname())));
2983 tooltip += '\n' + qt_("This is a local layout file.");
2984 latexModule->classCO->addItemSort(toqstr(tc.name()), toqstr(guiname),
2985 toqstr(translateIfPossible(from_utf8(tc.category()))),
2987 true, true, true, true);
2988 latexModule->classCO->set(toqstr(name));
2995 void GuiDocument::browseMaster()
2997 QString const title = qt_("Select master document");
2998 QString const dir1 = toqstr(lyxrc.document_path);
2999 QString const old = latexModule->childDocLE->text();
3000 QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
3001 QStringList const filter(qt_("LyX Files (*.lyx)"));
3002 QString file = browseRelToSub(old, docpath, title, filter, false,
3003 qt_("D&ocuments"), toqstr(lyxrc.document_path));
3005 if (!file.isEmpty())
3006 latexModule->childDocLE->setText(file);
3010 void GuiDocument::classChanged_adaptor()
3012 const_cast<Buffer &>(buffer()).setLayoutPos(string());
3017 void GuiDocument::classChanged()
3019 int idx = latexModule->classCO->currentIndex();
3022 string const classname = fromqstr(latexModule->classCO->getData(idx));
3024 if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
3025 int const ret = Alert::prompt(_("Unapplied changes"),
3026 _("Some changes in the dialog were not yet applied.\n"
3027 "If you do not apply now, they will be lost after this action."),
3028 1, 1, _("&Apply"), _("&Dismiss"));
3033 // We load the TextClass as soon as it is selected. This is
3034 // necessary so that other options in the dialog can be updated
3035 // according to the new class. Note, however, that, if you use
3036 // the scroll wheel when sitting on the combo box, we'll load a
3037 // lot of TextClass objects very quickly....
3038 if (!bp_.setBaseClass(classname, buffer().layoutPos())) {
3039 Alert::error(_("Error"), _("Unable to set document class."));
3042 if (lyxrc.auto_reset_options)
3043 bp_.useClassDefaults();
3045 // With the introduction of modules came a distinction between the base
3046 // class and the document class. The former corresponds to the main layout
3047 // file; the latter is that plus the modules (or the document-specific layout,
3048 // or whatever else there could be). Our parameters come from the document
3049 // class. So when we set the base class, we also need to recreate the document
3050 // class. Otherwise, we still have the old one.
3051 bp_.makeDocumentClass();
3056 void GuiDocument::languagePackageChanged(int i)
3058 langModule->languagePackageLE->setEnabled(
3059 langModule->languagePackageCO->itemData(i).toString() == "custom");
3063 void GuiDocument::biblioChanged()
3065 biblioChanged_ = true;
3070 void GuiDocument::checkPossibleCiteEngines()
3072 // Check if the class provides a specific engine,
3073 // and if so, enforce this.
3074 string force_engine;
3075 if (documentClass().provides("natbib")
3076 || documentClass().provides("natbib-internal"))
3077 force_engine = "natbib";
3078 else if (documentClass().provides("jurabib"))
3079 force_engine = "jurabib";
3080 else if (documentClass().provides("biblatex"))
3081 force_engine = "biblatex";
3082 else if (documentClass().provides("biblatex-natbib"))
3083 force_engine = "biblatex-natbib";
3085 if (!force_engine.empty())
3086 biblioModule->citeEngineCO->setCurrentIndex(
3087 biblioModule->citeEngineCO->findData(toqstr(force_engine)));
3088 biblioModule->citeEngineCO->setEnabled(force_engine.empty());
3092 void GuiDocument::rescanBibFiles()
3095 rescanTexStyles("bbx cbx");
3097 rescanTexStyles("bst");
3101 void GuiDocument::resetDefaultBibfile(string const & which)
3103 QString const engine =
3104 biblioModule->citeEngineCO->itemData(
3105 biblioModule->citeEngineCO->currentIndex()).toString();
3107 CiteEngineType const cet =
3108 CiteEngineType(biblioModule->citeStyleCO->itemData(
3109 biblioModule->citeStyleCO->currentIndex()).toInt());
3111 updateDefaultBiblio(theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet), which);
3115 void GuiDocument::resetDefaultBbxBibfile()
3117 resetDefaultBibfile("bbx");
3121 void GuiDocument::resetDefaultCbxBibfile()
3123 resetDefaultBibfile("cbx");
3127 void GuiDocument::citeEngineChanged(int n)
3129 QString const engine =
3130 biblioModule->citeEngineCO->itemData(n).toString();
3132 vector<string> const engs =
3133 theCiteEnginesList[fromqstr(engine)]->getEngineType();
3135 updateCiteStyles(engs);
3136 updateEngineDependends();
3137 resetDefaultBibfile();
3142 void GuiDocument::updateEngineDependends()
3144 bool const biblatex = isBiblatex();
3146 // These are only useful with BibTeX
3147 biblioModule->defaultBiblioCO->setEnabled(!biblatex);
3148 biblioModule->bibtexStyleLA->setEnabled(!biblatex);
3149 biblioModule->resetDefaultBiblioPB->setEnabled(!biblatex);
3150 biblioModule->bibtopicCB->setEnabled(!biblatex);
3152 // These are only useful with Biblatex
3153 biblioModule->biblatexBbxCO->setEnabled(biblatex);
3154 biblioModule->biblatexBbxLA->setEnabled(biblatex);
3155 biblioModule->biblatexCbxCO->setEnabled(biblatex);
3156 biblioModule->biblatexCbxLA->setEnabled(biblatex);
3157 biblioModule->resetBbxPB->setEnabled(biblatex);
3158 biblioModule->resetCbxPB->setEnabled(biblatex);
3159 biblioModule->matchBbxPB->setEnabled(biblatex);
3161 // These are useful with biblatex, jurabib and natbib
3162 QString const engine =
3163 biblioModule->citeEngineCO->itemData(
3164 biblioModule->citeEngineCO->currentIndex()).toString();
3165 LyXCiteEngine const * ce = theCiteEnginesList[fromqstr(engine)];
3167 bool const citepack = ce->required("biblatex.sty") || ce->required("jurabib.sty")
3168 || ce->required("natbib.sty");
3169 biblioModule->citePackageOptionsLE->setEnabled(citepack);
3170 biblioModule->citePackageOptionsL->setEnabled(citepack);
3174 void GuiDocument::citeStyleChanged()
3176 QString const engine =
3177 biblioModule->citeEngineCO->itemData(
3178 biblioModule->citeEngineCO->currentIndex()).toString();
3179 QString const currentDef = isBiblatex() ?
3180 biblioModule->biblatexBbxCO->currentText()
3181 : biblioModule->defaultBiblioCO->currentText();
3182 if (theCiteEnginesList[fromqstr(engine)]->isDefaultBiblio(fromqstr(currentDef)))
3183 resetDefaultBibfile();
3189 void GuiDocument::bibtexChanged(int n)
3191 biblioModule->bibtexOptionsLE->setEnabled(
3192 biblioModule->bibtexCO->itemData(n).toString() != "default");
3197 void GuiDocument::updateCiteStyles(vector<string> const & engs, CiteEngineType const & sel)
3199 biblioModule->citeStyleCO->clear();
3201 vector<string>::const_iterator it = engs.begin();
3202 vector<string>::const_iterator end = engs.end();
3203 for (; it != end; ++it) {
3204 if (*it == "default")
3205 biblioModule->citeStyleCO->addItem(qt_("Basic numerical"),
3206 ENGINE_TYPE_DEFAULT);
3207 else if (*it == "authoryear")
3208 biblioModule->citeStyleCO->addItem(qt_("Author-year"),
3209 ENGINE_TYPE_AUTHORYEAR);
3210 else if (*it == "numerical")
3211 biblioModule->citeStyleCO->addItem(qt_("Author-number"),
3212 ENGINE_TYPE_NUMERICAL);
3214 int i = biblioModule->citeStyleCO->findData(sel);
3215 if (biblioModule->citeStyleCO->findData(sel) == -1)
3217 biblioModule->citeStyleCO->setCurrentIndex(i);
3219 biblioModule->citationStyleL->setEnabled(engs.size() > 1);
3220 biblioModule->citeStyleCO->setEnabled(engs.size() > 1);
3224 void GuiDocument::updateEngineType(string const & items, CiteEngineType const & sel)
3226 engine_types_.clear();
3228 for (int n = 0; !token(items, '|', n).empty(); ++n) {
3229 string style = token(items, '|', n);
3230 engine_types_.push_back(style);
3233 updateCiteStyles(engine_types_, sel);
3239 // both of these should take a vector<docstring>
3241 // This is an insanely complicated attempt to make this sort of thing
3242 // work with RTL languages.
3243 docstring formatStrVec(vector<string> const & v, docstring const & s)
3245 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
3249 return translateIfPossible(from_utf8(v[0]));
3250 if (v.size() == 2) {
3251 docstring retval = _("%1$s and %2$s");
3252 retval = subst(retval, _("and"), s);
3253 return bformat(retval, translateIfPossible(from_utf8(v[0])),
3254 translateIfPossible(from_utf8(v[1])));
3256 // The idea here is to format all but the last two items...
3257 int const vSize = v.size();
3258 docstring t2 = _("%1$s, %2$s");
3259 docstring retval = translateIfPossible(from_utf8(v[0]));
3260 for (int i = 1; i < vSize - 2; ++i)
3261 retval = bformat(t2, retval, translateIfPossible(from_utf8(v[i])));
3262 //...and then to plug them, and the last two, into this schema
3263 docstring t = _("%1$s, %2$s, and %3$s");
3264 t = subst(t, _("and"), s);
3265 return bformat(t, retval, translateIfPossible(from_utf8(v[vSize - 2])),
3266 translateIfPossible(from_utf8(v[vSize - 1])));
3269 vector<string> idsToNames(vector<string> const & idList)
3271 vector<string> retval;
3272 vector<string>::const_iterator it = idList.begin();
3273 vector<string>::const_iterator end = idList.end();
3274 for (; it != end; ++it) {
3275 LyXModule const * const mod = theModuleList[*it];
3277 retval.push_back(to_utf8(bformat(_("%1$s (unavailable)"),
3278 translateIfPossible(from_utf8(*it)))));
3280 retval.push_back(mod->getName());
3284 } // end anonymous namespace
3287 void GuiDocument::modulesToParams(BufferParams & bp)
3289 // update list of loaded modules
3290 bp.clearLayoutModules();
3291 int const srows = modules_sel_model_.rowCount();
3292 for (int i = 0; i < srows; ++i)
3293 bp.addLayoutModule(modules_sel_model_.getIDString(i));
3294 updateSelectedModules();
3296 // update the list of removed modules
3297 bp.clearRemovedModules();
3298 LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
3299 list<string>::const_iterator rit = reqmods.begin();
3300 list<string>::const_iterator ren = reqmods.end();
3302 // check each of the default modules
3303 for (; rit != ren; ++rit) {
3304 list<string>::const_iterator mit = bp.getModules().begin();
3305 list<string>::const_iterator men = bp.getModules().end();
3307 for (; mit != men; ++mit) {
3314 // the module isn't present so must have been removed by the user
3315 bp.addRemovedModule(*rit);
3320 void GuiDocument::modulesChanged()
3322 modulesToParams(bp_);
3324 if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()
3325 && (nonModuleChanged_ || shellescapeChanged_)) {
3326 int const ret = Alert::prompt(_("Unapplied changes"),
3327 _("Some changes in the dialog were not yet applied.\n"
3328 "If you do not apply now, they will be lost after this action."),
3329 1, 1, _("&Apply"), _("&Dismiss"));
3334 modulesChanged_ = true;
3335 bp_.makeDocumentClass();
3341 void GuiDocument::updateModuleInfo()
3343 selectionManager->update();
3345 //Module description
3346 bool const focus_on_selected = selectionManager->selectedFocused();
3347 QAbstractItemView * lv;
3348 bool category = false;
3349 if (focus_on_selected) {
3350 lv = modulesModule->selectedLV;
3353 lv = modulesModule->availableLV;
3354 if (lv->selectionModel()->selectedIndexes().isEmpty()) {
3355 modulesModule->infoML->document()->clear();
3358 QModelIndex const & idx = lv->selectionModel()->currentIndex();
3363 if (!focus_on_selected
3364 && modules_av_model_.itemFromIndex(idx)->hasChildren()) {
3365 // This is a category header
3366 modulesModule->infoML->document()->clear();
3370 string const modName = focus_on_selected ?
3371 modules_sel_model_.getIDString(idx.row())
3372 : fromqstr(modules_av_model_.data(idx, Qt::UserRole).toString());
3373 docstring desc = getModuleDescription(modName);
3375 LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
3376 if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
3379 desc += _("Module provided by document class.");
3383 docstring cat = getModuleCategory(modName);
3387 desc += bformat(_("<p><b>Category:</b> %1$s.</p>"),
3388 translateIfPossible(cat));
3392 vector<string> pkglist = getPackageList(modName);
3393 docstring pkgdesc = formatStrVec(pkglist, _("and"));
3394 if (!pkgdesc.empty()) {
3397 desc += bformat(_("<p><b>Package(s) required:</b> %1$s.</p>"), pkgdesc);
3400 pkglist = getRequiredList(modName);
3401 if (!pkglist.empty()) {
3402 vector<string> const reqdescs = idsToNames(pkglist);
3403 pkgdesc = formatStrVec(reqdescs, _("or"));
3406 desc += bformat(_("<p><b>Modules required:</b> %1$s.</p>"), pkgdesc);
3409 pkglist = getExcludedList(modName);
3410 if (!pkglist.empty()) {
3411 vector<string> const reqdescs = idsToNames(pkglist);
3412 pkgdesc = formatStrVec(reqdescs, _( "and"));
3415 desc += bformat(_("<p><b>Modules excluded:</b> %1$s.</p>"), pkgdesc);
3420 desc += bformat(_("<p><b>Filename:</b> <tt>%1$s.module</tt>.</p>"), from_utf8(modName));
3422 if (!isModuleAvailable(modName)) {
3425 desc += _("<p><font color=red><b>WARNING: Some required packages are unavailable!</b></font></p>");
3428 modulesModule->infoML->document()->setHtml(toqstr(desc));
3432 void GuiDocument::updateNumbering()
3434 DocumentClass const & tclass = documentClass();
3436 numberingModule->tocTW->setUpdatesEnabled(false);
3437 numberingModule->tocTW->clear();
3439 int const depth = numberingModule->depthSL->value();
3440 int const toc = numberingModule->tocSL->value();
3441 QString const no = qt_("No");
3442 QString const yes = qt_("Yes");
3443 QTreeWidgetItem * item = nullptr;
3445 DocumentClass::const_iterator lit = tclass.begin();
3446 DocumentClass::const_iterator len = tclass.end();
3447 for (; lit != len; ++lit) {
3448 int const toclevel = lit->toclevel;
3449 if (toclevel != Layout::NOT_IN_TOC && !lit->counter.empty()) {
3450 item = new QTreeWidgetItem(numberingModule->tocTW);
3451 item->setText(0, toqstr(translateIfPossible(lit->name())));
3452 item->setText(1, (toclevel <= depth) ? yes : no);
3453 item->setText(2, (toclevel <= toc) ? yes : no);
3457 numberingModule->tocTW->setUpdatesEnabled(true);
3458 numberingModule->tocTW->update();
3462 void GuiDocument::getTableStyles()
3464 // We look for lyx files in the subdirectory dir of
3466 // 2) build_lyxdir (if not empty)
3468 // in this order. Files with a given sub-hierarchy will
3469 // only be listed once.
3470 // We also consider i18n subdirectories and store them separately.
3473 // The three locations to look at.
3474 string const user = addPath(package().user_support().absFileName(), "tabletemplates");
3475 string const build = addPath(package().build_support().absFileName(), "tabletemplates");
3476 string const system = addPath(package().system_support().absFileName(), "tabletemplates");
3478 dirs << toqstr(user)
3482 for (int i = 0; i < dirs.size(); ++i) {
3483 QString const & dir = dirs.at(i);
3484 QDirIterator it(dir, QDir::Files, QDirIterator::Subdirectories);
3485 while (it.hasNext()) {
3486 QString fn = QFileInfo(it.next()).fileName();
3487 if (!fn.endsWith(".lyx") || fn.contains("_1x"))
3489 QString data = fn.left(fn.lastIndexOf(".lyx"));
3490 QString guiname = data;
3491 guiname = toqstr(translateIfPossible(qstring_to_ucs4(guiname.replace('_', ' '))));
3492 QString relpath = toqstr(makeRelPath(qstring_to_ucs4(fn),
3493 qstring_to_ucs4(dir)));
3494 if (textLayoutModule->tableStyleCO->findData(data) == -1)
3495 textLayoutModule->tableStyleCO->addItem(guiname, data);
3501 void GuiDocument::updateDefaultFormat()
3505 // make a copy in order to consider unapplied changes
3506 BufferParams param_copy = buffer().params();
3507 param_copy.useNonTeXFonts = fontModule->osFontsCB->isChecked();
3508 int const idx = latexModule->classCO->currentIndex();
3510 string const classname = fromqstr(latexModule->classCO->getData(idx));
3511 param_copy.setBaseClass(classname, buffer().layoutPos());
3512 param_copy.makeDocumentClass(true);
3514 outputModule->defaultFormatCO->blockSignals(true);
3515 outputModule->defaultFormatCO->clear();
3516 outputModule->defaultFormatCO->addItem(qt_("Default"),
3517 QVariant(QString("default")));
3518 FormatList const & formats =
3519 param_copy.exportableFormats(true);
3520 for (Format const * f : formats)
3521 outputModule->defaultFormatCO->addItem
3522 (toqstr(translateIfPossible(f->prettyname())),
3523 QVariant(toqstr(f->name())));
3524 outputModule->defaultFormatCO->blockSignals(false);
3528 bool GuiDocument::isChildIncluded(string const & child)
3530 if (includeonlys_.empty())
3532 return (std::find(includeonlys_.begin(),
3533 includeonlys_.end(), child) != includeonlys_.end());
3537 void GuiDocument::applyView()
3539 // auto-validate local layout
3540 if (!localLayout->isValid()) {
3541 localLayout->validate();
3542 if (!localLayout->isValid()) {
3543 setApplyStopped(true);
3544 docPS->setCurrentPanel(N_("Local Layout"));
3550 preambleModule->apply(bp_);
3551 localLayout->apply(bp_);
3554 bp_.suppress_date = latexModule->suppressDateCB->isChecked();
3555 bp_.use_refstyle = latexModule->refstyleCB->isChecked();
3556 bp_.use_formatted_ref = latexModule->refFormattedCB->isChecked();
3559 string const engine =
3560 fromqstr(biblioModule->citeEngineCO->itemData(
3561 biblioModule->citeEngineCO->currentIndex()).toString());
3562 bp_.setCiteEngine(engine);
3564 CiteEngineType const style = CiteEngineType(biblioModule->citeStyleCO->itemData(
3565 biblioModule->citeStyleCO->currentIndex()).toInt());
3566 if (theCiteEnginesList[engine]->hasEngineType(style))
3567 bp_.setCiteEngineType(style);
3569 bp_.setCiteEngineType(ENGINE_TYPE_DEFAULT);
3571 bp_.splitbib(biblioModule->bibtopicCB->isChecked());
3573 bp_.multibib = fromqstr(biblioModule->bibunitsCO->itemData(
3574 biblioModule->bibunitsCO->currentIndex()).toString());
3576 bp_.setDefaultBiblioStyle(fromqstr(biblioModule->defaultBiblioCO->currentText()));
3578 bp_.biblatex_bibstyle = fromqstr(biblioModule->biblatexBbxCO->currentText());
3579 bp_.biblatex_citestyle = fromqstr(biblioModule->biblatexCbxCO->currentText());
3580 bp_.biblio_opts = fromqstr(biblioModule->citePackageOptionsLE->text());
3582 string const bibtex_command =
3583 fromqstr(biblioModule->bibtexCO->itemData(
3584 biblioModule->bibtexCO->currentIndex()).toString());
3585 string const bibtex_options =
3586 fromqstr(biblioModule->bibtexOptionsLE->text());
3587 if (bibtex_command == "default" || bibtex_options.empty())
3588 bp_.bibtex_command = bibtex_command;
3590 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
3592 if (biblioChanged_) {
3593 buffer().invalidateBibinfoCache();
3594 buffer().removeBiblioTempFiles();
3598 indicesModule->apply(bp_);
3600 // language & quotes
3601 switch (langModule->encodingCO->currentIndex()) {
3602 case EncodingSets::unicode: {
3603 if (!fontModule->osFontsCB->isChecked())
3604 bp_.inputenc = fromqstr(langModule->unicodeEncodingCO->itemData(
3605 langModule->unicodeEncodingCO->currentIndex()).toString());
3608 case EncodingSets::legacy: {
3609 bp_.inputenc = "auto-legacy";
3610 bp_.inputenc = fromqstr(langModule->autoEncodingCO->itemData(
3611 langModule->autoEncodingCO->currentIndex()).toString());
3614 case EncodingSets::custom: {
3615 bp_.inputenc = fromqstr(langModule->customEncodingCO->itemData(
3616 langModule->customEncodingCO->currentIndex()).toString());
3620 // this should never happen
3621 bp_.inputenc = "utf8";
3623 bp_.quotes_style = QuoteStyle(langModule->quoteStyleCO->itemData(
3624 langModule->quoteStyleCO->currentIndex()).toInt());
3625 bp_.dynamic_quotes = langModule->dynamicQuotesCB->isChecked();
3627 QString const langname = langModule->languageCO->itemData(
3628 langModule->languageCO->currentIndex()).toString();
3629 Language const * newlang = lyx::languages.getLanguage(fromqstr(langname));
3630 Cursor & cur = const_cast<BufferView *>(bufferview())->cursor();
3631 // If current cursor language was the document language, then update it too.
3632 if (cur.current_font.language() == bp_.language) {
3633 cur.current_font.setLanguage(newlang);
3634 cur.real_current_font.setLanguage(newlang);
3636 bp_.language = newlang;
3638 QString const pack = langModule->languagePackageCO->itemData(
3639 langModule->languagePackageCO->currentIndex()).toString();
3640 if (pack == "custom")
3642 fromqstr(langModule->languagePackageLE->text());
3644 bp_.lang_package = fromqstr(pack);
3647 bp_.backgroundcolor = set_backgroundcolor;
3648 bp_.isbackgroundcolor = is_backgroundcolor;
3649 bp_.fontcolor = set_fontcolor;
3650 bp_.isfontcolor = is_fontcolor;
3651 bp_.notefontcolor = set_notefontcolor;
3652 bp_.isnotefontcolor = is_notefontcolor;
3653 if (is_notefontcolor) {
3654 // Set information used in statusbar (#12130)
3655 lcolor.setColor("notefontcolor", lyx::X11hexname(set_notefontcolor));
3656 lcolor.setGUIName("notefontcolor", N_("greyedout inset text"));
3658 bp_.boxbgcolor = set_boxbgcolor;
3659 bp_.isboxbgcolor = is_boxbgcolor;
3662 if (bp_.documentClass().hasTocLevels()) {
3663 bp_.tocdepth = numberingModule->tocSL->value();
3664 bp_.secnumdepth = numberingModule->depthSL->value();
3666 bp_.use_lineno = numberingModule->linenoCB->isChecked();
3667 bp_.lineno_opts = fromqstr(numberingModule->linenoLE->text());
3670 bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
3671 bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
3672 bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
3673 bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
3676 bp_.graphics_driver =
3677 tex_graphics[latexModule->psdriverCO->currentIndex()];
3680 int idx = latexModule->classCO->currentIndex();
3682 string const classname = fromqstr(latexModule->classCO->getData(idx));
3683 bp_.setBaseClass(classname, buffer().layoutPos());
3687 modulesToParams(bp_);
3690 map<string, string> const & packages = BufferParams::auto_packages();
3691 for (map<string, string>::const_iterator it = packages.begin();
3692 it != packages.end(); ++it) {
3693 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
3696 int row = mathsModule->packagesTW->row(item);
3699 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1)->layout()->itemAt(0)->widget();
3700 if (rb->isChecked()) {
3701 bp_.use_package(it->first, BufferParams::package_auto);
3704 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2)->layout()->itemAt(0)->widget();
3705 if (rb->isChecked()) {
3706 bp_.use_package(it->first, BufferParams::package_on);
3709 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3)->layout()->itemAt(0)->widget();
3710 if (rb->isChecked())
3711 bp_.use_package(it->first, BufferParams::package_off);
3713 // if math is indented
3714 bp_.is_math_indent = mathsModule->MathIndentCB->isChecked();
3715 if (bp_.is_math_indent) {
3716 // if formulas are indented
3717 if (mathsModule->MathIndentCO->itemData(mathsModule->MathIndentCO->currentIndex()) == "custom") {
3718 Length mathindent(widgetsToLength(mathsModule->MathIndentLE,
3719 mathsModule->MathIndentLengthCO));
3720 bp_.setMathIndent(mathindent);
3723 bp_.setMathIndent(Length());
3725 switch (mathsModule->MathNumberingPosCO->currentIndex()) {
3727 bp_.math_numbering_side = BufferParams::LEFT;
3730 bp_.math_numbering_side = BufferParams::DEFAULT;
3733 bp_.math_numbering_side = BufferParams::RIGHT;
3736 // this should never happen
3737 bp_.math_numbering_side = BufferParams::DEFAULT;
3742 if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
3743 bp_.pagestyle = "default";
3745 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
3746 for (size_t i = 0; i != pagestyles.size(); ++i)
3747 if (pagestyles[i].second == style_gui)
3748 bp_.pagestyle = pagestyles[i].first;
3752 switch (textLayoutModule->lspacingCO->currentIndex()) {
3754 bp_.spacing().set(Spacing::Single);
3757 bp_.spacing().set(Spacing::Onehalf);
3760 bp_.spacing().set(Spacing::Double);
3763 string s = widgetToDoubleStr(textLayoutModule->lspacingLE);
3765 bp_.spacing().set(Spacing::Single);
3767 bp_.spacing().set(Spacing::Other, s);
3772 if (textLayoutModule->twoColumnCB->isChecked())
3777 bp_.justification = textLayoutModule->justCB->isChecked();
3779 if (textLayoutModule->indentRB->isChecked()) {
3780 // if paragraphs are separated by an indentation
3781 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
3782 if (textLayoutModule->indentCO->itemData(textLayoutModule->indentCO->currentIndex()) == "custom") {
3783 Length parindent(widgetsToLength(textLayoutModule->indentLE,
3784 textLayoutModule->indentLengthCO));
3785 bp_.setParIndent(parindent);
3788 bp_.setParIndent(Length());
3790 // if paragraphs are separated by a skip
3791 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
3792 VSpace::VSpaceKind spacekind =
3793 VSpace::VSpaceKind(textLayoutModule->skipCO->itemData(textLayoutModule->skipCO->currentIndex()).toInt());
3794 switch (spacekind) {
3795 case VSpace::SMALLSKIP:
3796 case VSpace::MEDSKIP:
3797 case VSpace::BIGSKIP:
3798 case VSpace::HALFLINE:
3799 case VSpace::FULLLINE:
3800 bp_.setDefSkip(VSpace(spacekind));
3802 case VSpace::LENGTH: {
3804 widgetsToLength(textLayoutModule->skipLE,
3805 textLayoutModule->skipLengthCO)
3811 // this should never happen
3812 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
3816 bp_.tablestyle = fromqstr(textLayoutModule->tableStyleCO->itemData(
3817 textLayoutModule->tableStyleCO->currentIndex()).toString());
3820 fromqstr(latexModule->optionsLE->text());
3822 bp_.use_default_options =
3823 latexModule->defaultOptionsCB->isChecked();
3825 if (latexModule->childDocGB->isChecked())
3827 fromqstr(latexModule->childDocLE->text());
3829 bp_.master = string();
3832 bp_.clearIncludedChildren();
3833 updateIncludeonlys();
3834 if (masterChildModule->includeonlyRB->isChecked()) {
3835 list<string>::const_iterator it = includeonlys_.begin();
3836 for (; it != includeonlys_.end() ; ++it) {
3837 bp_.addIncludedChildren(*it);
3840 if (masterChildModule->maintainCRNoneRB->isChecked())
3841 bp_.maintain_unincluded_children =
3842 BufferParams::CM_None;
3843 else if (masterChildModule->maintainCRMostlyRB->isChecked())
3844 bp_.maintain_unincluded_children =
3845 BufferParams::CM_Mostly;
3847 bp_.maintain_unincluded_children =
3848 BufferParams::CM_Strict;
3849 updateIncludeonlyDisplay();
3852 bp_.float_placement = floatModule->getPlacement();
3853 bp_.float_alignment = floatModule->getAlignment();
3856 // text should have passed validation
3857 idx = listingsModule->packageCO->currentIndex();
3858 bp_.use_minted = string(lst_packages[idx]) == "Minted";
3859 bp_.listings_params =
3860 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
3863 bp_.default_output_format = fromqstr(outputModule->defaultFormatCO->itemData(
3864 outputModule->defaultFormatCO->currentIndex()).toString());
3866 bool const nontexfonts = fontModule->osFontsCB->isChecked();
3867 bp_.useNonTeXFonts = nontexfonts;
3869 bp_.shell_escape = outputModule->shellescapeCB->isChecked();
3870 if (!bp_.shell_escape)
3871 theSession().shellescapeFiles().remove(buffer().absFileName());
3872 else if (!theSession().shellescapeFiles().find(buffer().absFileName()))
3873 theSession().shellescapeFiles().insert(buffer().absFileName());
3874 Buffer & buf = const_cast<Buffer &>(buffer());
3875 buf.params().shell_escape = bp_.shell_escape;
3877 bp_.output_sync = outputModule->outputsyncCB->isChecked();
3879 bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
3881 int mathfmt = outputModule->mathoutCB->currentIndex();
3884 BufferParams::MathOutput const mo =
3885 static_cast<BufferParams::MathOutput>(mathfmt);
3886 bp_.html_math_output = mo;
3887 bp_.html_be_strict = outputModule->strictCB->isChecked();
3888 bp_.html_css_as_file = outputModule->cssCB->isChecked();
3889 bp_.html_math_img_scale = outputModule->mathimgSB->value();
3890 bp_.display_pixel_ratio = theGuiApp()->pixelRatio();
3892 int tablefmt = outputModule->tableoutCB->currentIndex();
3895 auto const to = static_cast<BufferParams::TableOutput>(tablefmt);
3896 bp_.docbook_table_output = to;
3898 int mathmlprefix = outputModule->mathmlprefixCB->currentIndex();
3899 if (mathmlprefix == -1)
3901 auto const mp = static_cast<BufferParams::MathMLNameSpacePrefix>(mathmlprefix);
3902 bp_.docbook_mathml_prefix = mp;
3904 bp_.save_transient_properties =
3905 outputModule->saveTransientPropertiesCB->isChecked();
3906 bp_.postpone_fragile_content =
3907 outputModule->postponeFragileCB->isChecked();
3910 bp_.fonts_roman[nontexfonts] =
3911 fromqstr(fontModule->fontsRomanCO->
3912 getData(fontModule->fontsRomanCO->currentIndex()));
3913 bp_.fonts_roman[!nontexfonts] = fromqstr(fontModule->font_roman);
3914 bp_.font_roman_opts = fromqstr(fontModule->fontspecRomanLE->text());
3916 bp_.fonts_sans[nontexfonts] =
3917 fromqstr(fontModule->fontsSansCO->
3918 getData(fontModule->fontsSansCO->currentIndex()));
3919 bp_.fonts_sans[!nontexfonts] = fromqstr(fontModule->font_sans);
3920 bp_.font_sans_opts = fromqstr(fontModule->fontspecSansLE->text());
3922 bp_.fonts_typewriter[nontexfonts] =
3923 fromqstr(fontModule->fontsTypewriterCO->
3924 getData(fontModule->fontsTypewriterCO->currentIndex()));
3925 bp_.fonts_typewriter[!nontexfonts] = fromqstr(fontModule->font_typewriter);
3926 bp_.font_typewriter_opts = fromqstr(fontModule->fontspecTypewriterLE->text());
3928 bp_.fonts_math[nontexfonts] =
3929 fromqstr(fontModule->fontsMathCO->
3930 itemData(fontModule->fontsMathCO->currentIndex()).toString());
3931 bp_.fonts_math[!nontexfonts] = fromqstr(fontModule->font_math);
3933 QString const fontenc =
3934 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
3935 if (fontenc == "custom")
3936 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
3938 bp_.fontenc = fromqstr(fontenc);
3941 fromqstr(fontModule->cjkFontLE->text());
3943 bp_.use_microtype = fontModule->microtypeCB->isChecked();
3944 bp_.use_dash_ligatures = !fontModule->dashesCB->isChecked();
3946 bp_.fonts_sans_scale[nontexfonts] = fontModule->scaleSansSB->value();
3947 bp_.fonts_sans_scale[!nontexfonts] = fontModule->font_sf_scale;
3949 bp_.fonts_typewriter_scale[nontexfonts] = fontModule->scaleTypewriterSB->value();
3950 bp_.fonts_typewriter_scale[!nontexfonts] = fontModule->font_tt_scale;
3952 bp_.fonts_expert_sc = fontModule->fontScCB->isChecked();
3954 bp_.fonts_roman_osf = fontModule->fontOsfCB->isChecked();
3955 bp_.fonts_sans_osf = fontModule->fontSansOsfCB->isChecked();
3956 bp_.fonts_typewriter_osf = fontModule->fontTypewriterOsfCB->isChecked();
3958 bp_.fonts_default_family = GuiDocument::fontfamilies[
3959 fontModule->fontsDefaultCO->currentIndex()];
3961 if (fontModule->fontsizeCO->currentIndex() == 0)
3962 bp_.fontsize = "default";
3965 fromqstr(fontModule->fontsizeCO->currentText());
3968 bp_.papersize = PAPER_SIZE(
3969 pageLayoutModule->papersizeCO->currentIndex());
3971 bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
3972 pageLayoutModule->paperwidthUnitCO);
3974 bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
3975 pageLayoutModule->paperheightUnitCO);
3977 if (pageLayoutModule->facingPagesCB->isChecked())
3978 bp_.sides = TwoSides;
3980 bp_.sides = OneSide;
3982 if (pageLayoutModule->landscapeRB->isChecked())
3983 bp_.orientation = ORIENTATION_LANDSCAPE;
3985 bp_.orientation = ORIENTATION_PORTRAIT;
3988 bp_.use_geometry = !marginsModule->marginCB->isChecked();
3990 Ui::MarginsUi const * m = marginsModule;
3992 bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
3993 bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
3994 bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
3995 bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
3996 bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
3997 bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
3998 bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
3999 bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
4002 branchesModule->apply(bp_);
4005 PDFOptions & pdf = bp_.pdfoptions();
4006 pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
4007 pdf.title = fromqstr(pdfSupportModule->titleLE->text());
4008 pdf.author = fromqstr(pdfSupportModule->authorLE->text());
4009 pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
4010 pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
4012 pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
4013 pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
4014 pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
4015 pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
4017 pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
4018 pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
4019 pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
4020 pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
4022 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
4023 if (pdfSupportModule->fullscreenCB->isChecked())
4024 pdf.pagemode = pdf.pagemode_fullscreen;
4026 pdf.pagemode.clear();
4027 pdf.quoted_options = pdf.quoted_options_check(
4028 fromqstr(pdfSupportModule->optionsTE->toPlainText()));
4029 bp_.document_metadata = qstring_to_ucs4(pdfSupportModule->metadataTE->toPlainText()
4030 .trimmed().replace(QRegularExpression("\n+"), "\n"));
4033 bp_.track_changes = changesModule->trackChangesCB->isChecked();
4034 bp_.output_changes = changesModule->outputChangesCB->isChecked();
4035 bool const cb_switched_off = (bp_.change_bars
4036 && !changesModule->changeBarsCB->isChecked());
4037 bp_.change_bars = changesModule->changeBarsCB->isChecked();
4038 if (cb_switched_off)
4039 // if change bars have been switched off,
4040 // we need to ditch the aux file
4041 buffer().requireFreshStart(true);
4044 nonModuleChanged_ = false;
4045 shellescapeChanged_ = false;
4049 void GuiDocument::paramsToDialog()
4051 // set the default unit
4052 Length::UNIT const default_unit = Length::defaultUnit();
4055 preambleModule->update(bp_, id());
4056 localLayout->update(bp_, id());
4059 latexModule->suppressDateCB->setChecked(bp_.suppress_date);
4060 latexModule->refstyleCB->setChecked(bp_.use_refstyle);
4061 latexModule->refFormattedCB->setChecked(bp_.use_formatted_ref);
4064 string const cite_engine = bp_.citeEngine();
4066 biblioModule->citeEngineCO->setCurrentIndex(
4067 biblioModule->citeEngineCO->findData(toqstr(cite_engine)));
4069 updateEngineType(documentClass().opt_enginetype(),
4070 bp_.citeEngineType());
4072 checkPossibleCiteEngines();
4074 biblioModule->citeStyleCO->setCurrentIndex(
4075 biblioModule->citeStyleCO->findData(bp_.citeEngineType()));
4077 biblioModule->bibtopicCB->setChecked(bp_.splitbib());
4079 biblioModule->bibunitsCO->clear();
4080 biblioModule->bibunitsCO->addItem(qt_("No"), QString());
4081 if (documentClass().hasLaTeXLayout("part"))
4082 biblioModule->bibunitsCO->addItem(qt_("per part"), toqstr("part"));
4083 if (documentClass().hasLaTeXLayout("chapter"))
4084 biblioModule->bibunitsCO->addItem(qt_("per chapter"), toqstr("chapter"));
4085 if (documentClass().hasLaTeXLayout("section"))
4086 biblioModule->bibunitsCO->addItem(qt_("per section"), toqstr("section"));
4087 if (documentClass().hasLaTeXLayout("subsection"))
4088 biblioModule->bibunitsCO->addItem(qt_("per subsection"), toqstr("subsection"));
4089 biblioModule->bibunitsCO->addItem(qt_("per child document"), toqstr("child"));
4091 int const mbpos = biblioModule->bibunitsCO->findData(toqstr(bp_.multibib));
4093 biblioModule->bibunitsCO->setCurrentIndex(mbpos);
4095 biblioModule->bibunitsCO->setCurrentIndex(0);
4097 updateEngineDependends();
4100 updateDefaultBiblio(bp_.biblatex_bibstyle, "bbx");
4101 updateDefaultBiblio(bp_.biblatex_citestyle, "cbx");
4103 updateDefaultBiblio(bp_.defaultBiblioStyle());
4105 biblioModule->citePackageOptionsLE->setText(toqstr(bp_.biblio_opts));
4109 split(bp_.bibtex_command, command, ' ');
4111 int bpos = biblioModule->bibtexCO->findData(toqstr(command));
4113 // We add and set the unknown compiler, indicating that it is unavailable
4114 // to assure document compilation and for security reasons, a fallback
4115 // will be used on document processing stage
4116 biblioModule->bibtexCO->addItem(toqstr(bformat(_("%1$s (not available)"),
4117 from_utf8(command))), toqstr(command));
4118 bpos = biblioModule->bibtexCO->findData(toqstr(command));
4120 biblioModule->bibtexCO->setCurrentIndex(bpos);
4121 biblioModule->bibtexOptionsLE->setText(toqstr(options).trimmed());
4122 biblioModule->bibtexOptionsLE->setEnabled(
4123 biblioModule->bibtexCO->currentIndex() != 0);
4125 biblioChanged_ = false;
4128 // We may be called when there is no Buffer, e.g., when
4129 // the last view has just been closed.
4130 bool const isReadOnly = isBufferAvailable() ? buffer().isReadonly() : false;
4131 indicesModule->update(bp_, isReadOnly);
4133 // language & quotes
4134 int const pos = langModule->languageCO->findData(toqstr(
4135 bp_.language->lang()));
4136 langModule->languageCO->setCurrentIndex(pos);
4138 updateQuoteStyles();
4140 langModule->quoteStyleCO->setCurrentIndex(
4141 langModule->quoteStyleCO->findData(static_cast<int>(bp_.quotes_style)));
4142 langModule->dynamicQuotesCB->setChecked(bp_.dynamic_quotes);
4144 // LaTeX input encoding: set after the fonts (see below)
4146 int p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
4148 langModule->languagePackageCO->setCurrentIndex(
4149 langModule->languagePackageCO->findData("custom"));
4150 langModule->languagePackageLE->setText(toqstr(bp_.lang_package));
4152 langModule->languagePackageCO->setCurrentIndex(p);
4153 langModule->languagePackageLE->clear();
4157 if (bp_.isfontcolor) {
4158 colorModule->mainTextCF->setStyleSheet(
4159 colorFrameStyleSheet(rgb2qcolor(bp_.fontcolor)));
4160 colorModule->mainTextCF->setVisible(true);
4162 colorModule->mainTextCF->setVisible(false);
4163 set_fontcolor = bp_.fontcolor;
4164 is_fontcolor = bp_.isfontcolor;
4166 colorModule->noteFontCF->setStyleSheet(
4167 colorFrameStyleSheet(rgb2qcolor(bp_.notefontcolor)));
4168 set_notefontcolor = bp_.notefontcolor;
4169 is_notefontcolor = bp_.isnotefontcolor;
4171 if (bp_.isbackgroundcolor) {
4172 colorModule->pageBackgroundCF->setStyleSheet(
4173 colorFrameStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
4174 colorModule->pageBackgroundCF->setVisible(true);
4176 colorModule->pageBackgroundCF->setVisible(false);
4177 set_backgroundcolor = bp_.backgroundcolor;
4178 is_backgroundcolor = bp_.isbackgroundcolor;
4180 colorModule->boxBackgroundCF->setStyleSheet(
4181 colorFrameStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
4182 set_boxbgcolor = bp_.boxbgcolor;
4183 is_boxbgcolor = bp_.isboxbgcolor;
4186 int const min_toclevel = documentClass().min_toclevel();
4187 int const max_toclevel = documentClass().max_toclevel();
4188 if (documentClass().hasTocLevels()) {
4189 numberingModule->setEnabled(true);
4190 numberingModule->depthSL->setMinimum(min_toclevel - 1);
4191 numberingModule->depthSL->setMaximum(max_toclevel);
4192 numberingModule->depthSL->setValue(bp_.secnumdepth);
4193 numberingModule->tocSL->setMaximum(min_toclevel - 1);
4194 numberingModule->tocSL->setMaximum(max_toclevel);
4195 numberingModule->tocSL->setValue(bp_.tocdepth);
4198 numberingModule->setEnabled(false);
4199 numberingModule->tocTW->clear();
4202 numberingModule->linenoCB->setChecked(bp_.use_lineno);
4203 numberingModule->linenoLE->setEnabled(bp_.use_lineno);
4204 numberingModule->linenoLA->setEnabled(bp_.use_lineno);
4205 numberingModule->linenoLE->setText(toqstr(bp_.lineno_opts));
4208 bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
4209 bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
4210 bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
4211 bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
4212 bulletsModule->init();
4215 int nitem = findToken(tex_graphics, bp_.graphics_driver);
4217 latexModule->psdriverCO->setCurrentIndex(nitem);
4221 mathsModule->MathIndentCB->setChecked(bp_.is_math_indent);
4222 if (bp_.is_math_indent) {
4223 Length const mathindent = bp_.getMathIndent();
4225 if (!mathindent.empty()) {
4226 lengthToWidgets(mathsModule->MathIndentLE,
4227 mathsModule->MathIndentLengthCO,
4228 mathindent, default_unit);
4231 mathsModule->MathIndentCO->setCurrentIndex(indent);
4232 enableMathIndent(indent);
4234 switch(bp_.math_numbering_side) {
4235 case BufferParams::LEFT:
4236 mathsModule->MathNumberingPosCO->setCurrentIndex(0);
4238 case BufferParams::DEFAULT:
4239 mathsModule->MathNumberingPosCO->setCurrentIndex(1);
4241 case BufferParams::RIGHT:
4242 mathsModule->MathNumberingPosCO->setCurrentIndex(2);
4245 map<string, string> const & packages = BufferParams::auto_packages();
4246 for (map<string, string>::const_iterator it = packages.begin();
4247 it != packages.end(); ++it) {
4248 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
4251 int row = mathsModule->packagesTW->row(item);
4252 switch (bp_.use_package(it->first)) {
4253 case BufferParams::package_off: {
4255 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3)->layout()->itemAt(0)->widget();
4256 rb->setChecked(true);
4259 case BufferParams::package_on: {
4261 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2)->layout()->itemAt(0)->widget();
4262 rb->setChecked(true);
4265 case BufferParams::package_auto: {
4267 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1)->layout()->itemAt(0)->widget();
4268 rb->setChecked(true);
4274 switch (bp_.spacing().getSpace()) {
4275 case Spacing::Other: nitem = 3; break;
4276 case Spacing::Double: nitem = 2; break;
4277 case Spacing::Onehalf: nitem = 1; break;
4278 case Spacing::Default: case Spacing::Single: nitem = 0; break;
4282 string const & layoutID = bp_.baseClassID();
4283 setLayoutComboByIDString(layoutID);
4285 updatePagestyle(documentClass().opt_pagestyle(),
4288 textLayoutModule->lspacingCO->setCurrentIndex(nitem);
4289 if (bp_.spacing().getSpace() == Spacing::Other) {
4290 doubleToWidget(textLayoutModule->lspacingLE,
4291 bp_.spacing().getValueAsString());
4294 int ts = textLayoutModule->tableStyleCO->findData(toqstr(bp_.tablestyle));
4296 textLayoutModule->tableStyleCO->setCurrentIndex(ts);
4298 if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
4299 textLayoutModule->indentRB->setChecked(true);
4300 string parindent = bp_.getParIndent().asString();
4301 QString indent = toqstr("default");
4302 if (!parindent.empty()) {
4303 lengthToWidgets(textLayoutModule->indentLE,
4304 textLayoutModule->indentLengthCO,
4305 parindent, default_unit);
4306 indent = toqstr("custom");
4308 textLayoutModule->indentCO->setCurrentIndex(textLayoutModule->indentCO->findData(indent));
4309 setIndent(textLayoutModule->indentCO->currentIndex());
4311 textLayoutModule->skipRB->setChecked(true);
4312 VSpace::VSpaceKind skip = bp_.getDefSkip().kind();
4313 textLayoutModule->skipCO->setCurrentIndex(textLayoutModule->skipCO->findData(skip));
4314 if (skip == VSpace::LENGTH) {
4315 string const length = bp_.getDefSkip().asLyXCommand();
4316 lengthToWidgets(textLayoutModule->skipLE,
4317 textLayoutModule->skipLengthCO,
4318 length, default_unit);
4320 setSkip(textLayoutModule->skipCO->currentIndex());
4323 textLayoutModule->twoColumnCB->setChecked(
4325 textLayoutModule->justCB->setChecked(bp_.justification);
4327 if (!bp_.options.empty()) {
4328 latexModule->optionsLE->setText(
4329 toqstr(bp_.options));
4331 latexModule->optionsLE->setText(QString());
4335 latexModule->defaultOptionsCB->setChecked(
4336 bp_.use_default_options);
4337 updateSelectedModules();
4338 selectionManager->updateProvidedModules(
4339 bp_.baseClass()->providedModules());
4340 selectionManager->updateExcludedModules(
4341 bp_.baseClass()->excludedModules());
4343 if (!documentClass().options().empty()) {
4344 latexModule->defaultOptionsLE->setText(
4345 toqstr(documentClass().options()));
4347 latexModule->defaultOptionsLE->setText(
4348 toqstr(_("[No options predefined]")));
4351 latexModule->defaultOptionsLE->setEnabled(
4352 bp_.use_default_options
4353 && !documentClass().options().empty());
4355 latexModule->defaultOptionsCB->setEnabled(
4356 !documentClass().options().empty());
4358 if (!bp_.master.empty()) {
4359 latexModule->childDocGB->setChecked(true);
4360 latexModule->childDocLE->setText(
4361 toqstr(bp_.master));
4363 latexModule->childDocLE->setText(QString());
4364 latexModule->childDocGB->setChecked(false);
4368 if (!bufferview() || !buffer().hasChildren()) {
4369 masterChildModule->childrenTW->clear();
4370 includeonlys_.clear();
4371 docPS->showPanel("Child Documents", false);
4372 if (docPS->isCurrentPanel("Child Documents"))
4373 docPS->setCurrentPanel("Document Class");
4375 docPS->showPanel("Child Documents", true);
4376 masterChildModule->setEnabled(true);
4377 includeonlys_ = bp_.getIncludedChildren();
4378 updateIncludeonlys();
4379 updateIncludeonlyDisplay();
4381 switch (bp_.maintain_unincluded_children) {
4382 case BufferParams::CM_None:
4383 masterChildModule->maintainCRNoneRB->setChecked(true);
4385 case BufferParams::CM_Mostly:
4386 masterChildModule->maintainCRMostlyRB->setChecked(true);
4388 case BufferParams::CM_Strict:
4390 masterChildModule->maintainCRStrictRB->setChecked(true);
4395 floatModule->setPlacement(bp_.float_placement);
4396 floatModule->setAlignment(bp_.float_alignment);
4399 // break listings_params to multiple lines
4401 InsetListingsParams(bp_.listings_params).separatedParams();
4402 listingsModule->listingsED->setPlainText(toqstr(lstparams));
4403 int nn = findToken(lst_packages, bp_.use_minted ? "Minted" : "Listings");
4405 listingsModule->packageCO->setCurrentIndex(nn);
4408 // some languages only work with Polyglossia (which requires non-TeX fonts)
4409 Language const * lang = lyx::languages.getLanguage(
4410 fromqstr(langModule->languageCO->itemData(
4411 langModule->languageCO->currentIndex()).toString()));
4412 bool const need_fontspec =
4413 lang->babel().empty() && !lang->polyglossia().empty()
4414 && lang->required() != "CJK" && lang->required() != "japanese";
4415 bool const os_fonts_available =
4416 bp_.baseClass()->outputType() == lyx::LATEX
4417 && LaTeXFeatures::isAvailable("fontspec");
4418 fontModule->osFontsCB->setEnabled(os_fonts_available && !need_fontspec);
4419 fontModule->osFontsCB->setChecked(
4420 (os_fonts_available && bp_.useNonTeXFonts) || need_fontspec);
4421 updateFontsize(documentClass().opt_fontsize(),
4424 QString font = toqstr(bp_.fontsRoman());
4425 bool foundfont = fontModule->fontsRomanCO->set(font, false);
4427 fontModule->fontsRomanCO->addItemSort(font, font + qt_(" (not installed)"),
4428 qt_("Uninstalled used fonts"),
4429 qt_("This font is not installed and won't be used in output"),
4430 false, false, false, true);
4431 fontModule->fontsRomanCO->set(font);
4433 fontModule->font_roman = toqstr(bp_.fonts_roman[!bp_.useNonTeXFonts]);
4435 font = toqstr(bp_.fontsSans());
4436 foundfont = fontModule->fontsSansCO->set(font, false);
4438 fontModule->fontsSansCO->addItemSort(font, font + qt_(" (not installed)"),
4439 qt_("Uninstalled used fonts"),
4440 qt_("This font is not installed and won't be used in output"),
4441 false, false, false, true);
4442 fontModule->fontsSansCO->set(font);
4444 fontModule->font_sans = toqstr(bp_.fonts_sans[!bp_.useNonTeXFonts]);
4446 font = toqstr(bp_.fontsTypewriter());
4447 foundfont = fontModule->fontsTypewriterCO->set(font, false);
4449 fontModule->fontsTypewriterCO->addItemSort(font, font + qt_(" (not installed)"),
4450 qt_("Uninstalled used fonts"),
4451 qt_("This font is not installed and won't be used in output"),
4452 false, false, false, true);
4453 fontModule->fontsTypewriterCO->set(font);
4455 fontModule->font_typewriter = toqstr(bp_.fonts_typewriter[!bp_.useNonTeXFonts]);
4457 font = toqstr(bp_.fontsMath());
4458 int mpos = fontModule->fontsMathCO->findData(font);
4460 mpos = fontModule->fontsMathCO->count();
4461 fontModule->fontsMathCO->addItem(font + qt_(" (not installed)"), font);
4463 fontModule->fontsMathCO->setCurrentIndex(mpos);
4464 fontModule->font_math = toqstr(bp_.fonts_math[!bp_.useNonTeXFonts]);
4466 if (bp_.useNonTeXFonts && os_fonts_available) {
4467 fontModule->fontencLA->setEnabled(false);
4468 fontModule->fontencCO->setEnabled(false);
4469 fontModule->fontencLE->setEnabled(false);
4471 fontModule->fontencLA->setEnabled(true);
4472 fontModule->fontencCO->setEnabled(true);
4473 fontModule->fontencLE->setEnabled(true);
4474 romanChanged(fontModule->fontsRomanCO->currentIndex());
4475 sansChanged(fontModule->fontsSansCO->currentIndex());
4476 ttChanged(fontModule->fontsTypewriterCO->currentIndex());
4478 // Handle options enabling
4479 updateFontOptions();
4481 if (!bp_.fonts_cjk.empty())
4482 fontModule->cjkFontLE->setText(
4483 toqstr(bp_.fonts_cjk));
4485 fontModule->cjkFontLE->setText(QString());
4487 fontModule->microtypeCB->setChecked(bp_.use_microtype);
4488 fontModule->dashesCB->setChecked(!bp_.use_dash_ligatures);
4490 fontModule->fontScCB->setChecked(bp_.fonts_expert_sc);
4491 fontModule->fontOsfCB->setChecked(bp_.fonts_roman_osf);
4492 fontModule->fontSansOsfCB->setChecked(bp_.fonts_sans_osf);
4493 fontModule->fontTypewriterOsfCB->setChecked(bp_.fonts_typewriter_osf);
4494 fontModule->scaleSansSB->setValue(bp_.fontsSansScale());
4495 fontModule->font_sf_scale = bp_.fonts_sans_scale[!bp_.useNonTeXFonts];
4496 fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale());
4497 fontModule->font_tt_scale = bp_.fonts_typewriter_scale[!bp_.useNonTeXFonts];
4498 if (!bp_.font_roman_opts.empty())
4499 fontModule->fontspecRomanLE->setText(
4500 toqstr(bp_.font_roman_opts));
4502 fontModule->fontspecRomanLE->setText(QString());
4503 if (!bp_.font_sans_opts.empty())
4504 fontModule->fontspecSansLE->setText(
4505 toqstr(bp_.font_sans_opts));
4507 fontModule->fontspecSansLE->setText(QString());
4508 if (!bp_.font_typewriter_opts.empty())
4509 fontModule->fontspecTypewriterLE->setText(
4510 toqstr(bp_.font_typewriter_opts));
4512 fontModule->fontspecTypewriterLE->setText(QString());
4514 nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
4516 fontModule->fontsDefaultCO->setCurrentIndex(nn);
4518 if (bp_.fontenc == "auto" || bp_.fontenc == "default") {
4519 fontModule->fontencCO->setCurrentIndex(
4520 fontModule->fontencCO->findData(toqstr(bp_.fontenc)));
4521 fontModule->fontencLE->setEnabled(false);
4523 fontModule->fontencCO->setCurrentIndex(
4524 fontModule->fontencCO->findData("custom"));
4525 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
4528 // LaTeX input encoding
4529 // Set after fonts because non-tex fonts override "\inputencoding".
4530 inputencodingToDialog();
4533 // This must be set _after_ fonts since updateDefaultFormat()
4534 // checks osFontsCB settings.
4535 // update combobox with formats
4536 updateDefaultFormat();
4537 int index = outputModule->defaultFormatCO->findData(toqstr(
4538 bp_.default_output_format));
4539 // set to default if format is not found
4542 outputModule->defaultFormatCO->setCurrentIndex(index);
4544 outputModule->shellescapeCB->setChecked(bp_.shell_escape);
4545 outputModule->outputsyncCB->setChecked(bp_.output_sync);
4546 outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
4547 outputModule->synccustomCB->setEnabled(bp_.output_sync);
4548 outputModule->synccustomLA->setEnabled(bp_.output_sync);
4550 outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
4551 outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
4552 outputModule->strictCB->setChecked(bp_.html_be_strict);
4553 outputModule->cssCB->setChecked(bp_.html_css_as_file);
4555 outputModule->tableoutCB->setCurrentIndex(bp_.docbook_table_output);
4556 outputModule->mathmlprefixCB->setCurrentIndex(bp_.docbook_mathml_prefix);
4558 outputModule->saveTransientPropertiesCB
4559 ->setChecked(bp_.save_transient_properties);
4560 outputModule->postponeFragileCB
4561 ->setChecked(bp_.postpone_fragile_content);
4564 bool const extern_geometry =
4565 documentClass().provides("geometry");
4566 int const psize = bp_.papersize;
4567 pageLayoutModule->papersizeCO->setCurrentIndex(psize);
4568 setCustomPapersize(!extern_geometry && psize == 1);
4569 pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
4571 bool const landscape =
4572 bp_.orientation == ORIENTATION_LANDSCAPE;
4573 pageLayoutModule->landscapeRB->setChecked(landscape);
4574 pageLayoutModule->portraitRB->setChecked(!landscape);
4575 pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
4576 pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
4578 pageLayoutModule->facingPagesCB->setChecked(
4579 bp_.sides == TwoSides);
4581 lengthToWidgets(pageLayoutModule->paperwidthLE,
4582 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, default_unit);
4583 lengthToWidgets(pageLayoutModule->paperheightLE,
4584 pageLayoutModule->paperheightUnitCO, bp_.paperheight, default_unit);
4587 Ui::MarginsUi * m = marginsModule;
4591 lengthToWidgets(m->topLE, m->topUnit,
4592 bp_.topmargin, default_unit);
4594 lengthToWidgets(m->bottomLE, m->bottomUnit,
4595 bp_.bottommargin, default_unit);
4597 lengthToWidgets(m->innerLE, m->innerUnit,
4598 bp_.leftmargin, default_unit);
4600 lengthToWidgets(m->outerLE, m->outerUnit,
4601 bp_.rightmargin, default_unit);
4603 lengthToWidgets(m->headheightLE, m->headheightUnit,
4604 bp_.headheight, default_unit);
4606 lengthToWidgets(m->headsepLE, m->headsepUnit,
4607 bp_.headsep, default_unit);
4609 lengthToWidgets(m->footskipLE, m->footskipUnit,
4610 bp_.footskip, default_unit);
4612 lengthToWidgets(m->columnsepLE, m->columnsepUnit,
4613 bp_.columnsep, default_unit);
4616 updateUnknownBranches();
4617 branchesModule->update(bp_);
4620 PDFOptions const & pdf = bp_.pdfoptions();
4621 pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
4622 if (bp_.documentClass().provides("hyperref"))
4623 pdfSupportModule->use_hyperrefGB->setTitle(qt_("C&ustomize Hyperref Options"));
4625 pdfSupportModule->use_hyperrefGB->setTitle(qt_("&Use Hyperref Support"));
4626 pdfSupportModule->titleLE->setText(toqstr(pdf.title));
4627 pdfSupportModule->authorLE->setText(toqstr(pdf.author));
4628 pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
4629 pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
4631 pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
4632 pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
4633 pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
4635 pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
4636 pdfSupportModule->bookmarksopenlevelSB->setEnabled(pdf.bookmarksopen);
4637 pdfSupportModule->bookmarksopenlevelLA->setEnabled(pdf.bookmarksopen);
4639 pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
4640 pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
4641 pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
4642 pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
4644 nn = findToken(backref_opts, pdf.backref);
4646 pdfSupportModule->backrefCO->setCurrentIndex(nn);
4648 pdfSupportModule->fullscreenCB->setChecked
4649 (pdf.pagemode == pdf.pagemode_fullscreen);
4651 pdfSupportModule->optionsTE->setPlainText(
4652 toqstr(pdf.quoted_options));
4654 pdfSupportModule->metadataTE->setPlainText(
4655 toqstr(rtrim(bp_.document_metadata, "\n")));
4658 changesModule->trackChangesCB->setChecked(bp_.track_changes);
4659 changesModule->outputChangesCB->setChecked(bp_.output_changes);
4660 changesModule->changeBarsCB->setChecked(bp_.change_bars);
4661 changesModule->changeBarsCB->setEnabled(bp_.output_changes);
4663 // Make sure that the bc is in the INITIAL state
4664 if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
4667 // clear changed branches cache
4668 changedBranches_.clear();
4670 // re-initiate module filter
4671 if (!filter_->text().isEmpty())
4672 moduleFilterPressed();
4675 nonModuleChanged_ = false;
4676 shellescapeChanged_ = false;
4680 void GuiDocument::saveDocDefault()
4682 // we have to apply the params first
4688 void GuiDocument::updateAvailableModules()
4690 modules_av_model_.clear();
4691 list<modInfoStruct> modInfoList = getModuleInfo();
4692 // Sort names according to the locale
4693 modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
4694 return 0 < b.name.localeAwareCompare(a.name);
4696 QIcon user_icon(guiApp ? guiApp->getScaledPixmap("images/", "lyxfiles-user")
4697 : getPixmap("images/", "lyxfiles-user", "svgz,png"));
4698 QIcon system_icon(guiApp ? guiApp->getScaledPixmap("images/", "lyxfiles-system")
4699 : getPixmap("images/", "lyxfiles-system", "svgz,png"));
4702 catfont.setBold(true);
4704 unavbrush.setColor(Qt::gray);
4705 for (modInfoStruct const & m : modInfoList) {
4706 QStandardItem * item = new QStandardItem();
4707 QStandardItem * catItem;
4708 QString const catname = m.category;
4709 QList<QStandardItem *> fcats = modules_av_model_.findItems(catname, Qt::MatchExactly);
4711 catItem = fcats.first();
4713 catItem = new QStandardItem();
4714 catItem->setText(catname);
4715 catItem->setFont(catfont);
4716 modules_av_model_.insertRow(i, catItem);
4719 item->setEditable(false);
4720 catItem->setEditable(false);
4721 item->setData(m.name, Qt::DisplayRole);
4723 item->setForeground(unavbrush);
4724 item->setData(toqstr(m.id), Qt::UserRole);
4725 item->setData(m.description, Qt::ToolTipRole);
4727 item->setIcon(user_icon);
4729 item->setIcon(system_icon);
4730 catItem->appendRow(item);
4732 modules_av_model_.sort(0);
4736 void GuiDocument::updateSelectedModules()
4738 modules_sel_model_.clear();
4739 list<modInfoStruct> const selModList = getSelectedModules();
4741 for (modInfoStruct const & m : selModList) {
4742 modules_sel_model_.insertRow(i, m.name, m.id, m.description);
4748 void GuiDocument::updateIncludeonlyDisplay()
4750 if (includeonlys_.empty()) {
4751 masterChildModule->includeallRB->setChecked(true);
4752 masterChildModule->childrenTW->setEnabled(false);
4753 masterChildModule->maintainGB->setEnabled(false);
4755 masterChildModule->includeonlyRB->setChecked(true);
4756 masterChildModule->childrenTW->setEnabled(true);
4757 masterChildModule->maintainGB->setEnabled(true);
4762 void GuiDocument::updateIncludeonlys(bool const cleanup)
4764 masterChildModule->childrenTW->clear();
4765 QString const no = qt_("No");
4766 QString const yes = qt_("Yes");
4768 ListOfBuffers children = buffer().getChildren();
4769 ListOfBuffers::const_iterator it = children.begin();
4770 ListOfBuffers::const_iterator end = children.end();
4771 bool has_unincluded = false;
4772 bool all_unincluded = true;
4773 for (; it != end; ++it) {
4774 QTreeWidgetItem * item = new QTreeWidgetItem(masterChildModule->childrenTW);
4777 to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
4778 from_utf8(buffer().filePath())));
4779 item->setText(0, toqstr(name));
4780 item->setText(1, isChildIncluded(name) ? yes : no);
4781 if (!isChildIncluded(name))
4782 has_unincluded = true;
4784 all_unincluded = false;
4786 // Both if all children are included and if none is included
4787 // is equal to "include all" (i.e., omit \includeonly).
4788 if (cleanup && (!has_unincluded || all_unincluded))
4789 includeonlys_.clear();
4793 bool GuiDocument::isBiblatex() const
4795 QString const engine =
4796 biblioModule->citeEngineCO->itemData(
4797 biblioModule->citeEngineCO->currentIndex()).toString();
4799 // this can happen if the cite engine is unknown, which can happen
4800 // if one is using a file that came from someone else, etc. in that
4801 // case, we crash if we proceed.
4802 if (engine.isEmpty())
4805 return theCiteEnginesList[fromqstr(engine)]->getCiteFramework() == "biblatex";
4809 void GuiDocument::updateDefaultBiblio(string const & style,
4810 string const & which)
4812 QString const bibstyle = toqstr(style);
4813 biblioModule->defaultBiblioCO->clear();
4818 if (which != "cbx") {
4819 // First the bbx styles
4820 biblioModule->biblatexBbxCO->clear();
4821 QStringList str = texFileList("bbxFiles.lst");
4822 // test whether we have a valid list, otherwise run rescan
4823 if (str.isEmpty()) {
4824 rescanTexStyles("bbx");
4825 str = texFileList("bbxFiles.lst");
4827 for (int i = 0; i != str.size(); ++i)
4828 str[i] = onlyFileName(str[i]);
4829 // sort on filename only (no path)
4832 for (int i = 0; i != str.count(); ++i) {
4833 QString item = changeExtension(str[i], "");
4834 if (item == bibstyle)
4836 biblioModule->biblatexBbxCO->addItem(item);
4839 if (item_nr == -1 && !bibstyle.isEmpty()) {
4840 biblioModule->biblatexBbxCO->addItem(bibstyle);
4841 item_nr = biblioModule->biblatexBbxCO->count() - 1;
4845 biblioModule->biblatexBbxCO->setCurrentIndex(item_nr);
4847 biblioModule->biblatexBbxCO->clearEditText();
4850 if (which != "bbx") {
4851 // now the cbx styles
4852 biblioModule->biblatexCbxCO->clear();
4853 QStringList str = texFileList("cbxFiles.lst");
4854 // test whether we have a valid list, otherwise run rescan
4855 if (str.isEmpty()) {
4856 rescanTexStyles("cbx");
4857 str = texFileList("cbxFiles.lst");
4859 for (int i = 0; i != str.size(); ++i)
4860 str[i] = onlyFileName(str[i]);
4861 // sort on filename only (no path)
4864 for (int i = 0; i != str.count(); ++i) {
4865 QString item = changeExtension(str[i], "");
4866 if (item == bibstyle)
4868 biblioModule->biblatexCbxCO->addItem(item);
4871 if (item_nr == -1 && !bibstyle.isEmpty()) {
4872 biblioModule->biblatexCbxCO->addItem(bibstyle);
4873 item_nr = biblioModule->biblatexCbxCO->count() - 1;
4877 biblioModule->biblatexCbxCO->setCurrentIndex(item_nr);
4879 biblioModule->biblatexCbxCO->clearEditText();
4882 biblioModule->biblatexBbxCO->clear();
4883 biblioModule->biblatexCbxCO->clear();
4884 QStringList str = texFileList("bstFiles.lst");
4885 // test whether we have a valid list, otherwise run rescan
4886 if (str.isEmpty()) {
4887 rescanTexStyles("bst");
4888 str = texFileList("bstFiles.lst");
4890 for (int i = 0; i != str.size(); ++i)
4891 str[i] = onlyFileName(str[i]);
4892 // sort on filename only (no path)
4895 for (int i = 0; i != str.count(); ++i) {
4896 QString item = changeExtension(str[i], "");
4897 if (item == bibstyle)
4899 biblioModule->defaultBiblioCO->addItem(item);
4902 if (item_nr == -1 && !bibstyle.isEmpty()) {
4903 biblioModule->defaultBiblioCO->addItem(bibstyle);
4904 item_nr = biblioModule->defaultBiblioCO->count() - 1;
4908 biblioModule->defaultBiblioCO->setCurrentIndex(item_nr);
4910 biblioModule->defaultBiblioCO->clearEditText();
4913 updateResetDefaultBiblio();
4917 void GuiDocument::updateResetDefaultBiblio()
4919 QString const engine =
4920 biblioModule->citeEngineCO->itemData(
4921 biblioModule->citeEngineCO->currentIndex()).toString();
4922 CiteEngineType const cet =
4923 CiteEngineType(biblioModule->citeStyleCO->itemData(
4924 biblioModule->citeStyleCO->currentIndex()).toInt());
4926 string const defbib = theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet);
4928 QString const bbx = biblioModule->biblatexBbxCO->currentText();
4929 QString const cbx = biblioModule->biblatexCbxCO->currentText();
4930 biblioModule->resetCbxPB->setEnabled(defbib != fromqstr(cbx));
4931 biblioModule->resetBbxPB->setEnabled(defbib != fromqstr(bbx));
4932 biblioModule->matchBbxPB->setEnabled(bbx != cbx && !cbx.isEmpty()
4933 && biblioModule->biblatexBbxCO->findText(cbx) != -1);
4935 biblioModule->resetDefaultBiblioPB->setEnabled(
4936 defbib != fromqstr(biblioModule->defaultBiblioCO->currentText()));
4940 void GuiDocument::matchBiblatexStyles()
4942 updateDefaultBiblio(fromqstr(biblioModule->biblatexCbxCO->currentText()), "bbx");
4947 void GuiDocument::updateContents()
4949 // Nothing to do here as the document settings is not cursor dependent.
4954 void GuiDocument::useClassDefaults()
4956 if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
4957 int const ret = Alert::prompt(_("Unapplied changes"),
4958 _("Some changes in the dialog were not yet applied.\n"
4959 "If you do not apply now, they will be lost after this action."),
4960 1, 1, _("&Apply"), _("&Dismiss"));
4965 int idx = latexModule->classCO->currentIndex();
4966 string const classname = fromqstr(latexModule->classCO->getData(idx));
4967 if (!bp_.setBaseClass(classname, buffer().layoutPos())) {
4968 Alert::error(_("Error"), _("Unable to set document class."));
4971 bp_.useClassDefaults();
4977 void GuiDocument::setLayoutComboByIDString(string const & idString)
4979 if (!latexModule->classCO->set(toqstr(idString)))
4980 Alert::warning(_("Can't set layout!"),
4981 bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
4985 bool GuiDocument::isValid()
4987 bool const listings_valid = validateListingsParameters().isEmpty();
4988 bool const local_layout_valid = !localLayout->editing();
4989 bool const preamble_valid = !preambleModule->editing();
4991 docPS->markPanelValid(N_("Listings[[inset]]"), listings_valid);
4992 docPS->markPanelValid(N_("Local Layout"), local_layout_valid && localLayout->isValid());
4993 docPS->markPanelValid(N_("LaTeX Preamble"), preamble_valid);
4995 return listings_valid && local_layout_valid && preamble_valid;
4999 char const * const GuiDocument::fontfamilies[5] = {
5000 "default", "rmdefault", "sfdefault", "ttdefault", ""
5004 char const * GuiDocument::fontfamilies_gui[5] = {
5005 N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
5009 bool GuiDocument::initialiseParams(string const &)
5011 BufferView const * view = bufferview();
5013 bp_ = BufferParams();
5017 prev_buffer_filename_ = view->buffer().absFileName();
5018 bp_ = view->buffer().params();
5020 updateAvailableModules();
5021 //FIXME It'd be nice to make sure here that the selected
5022 //modules are consistent: That required modules are actually
5023 //selected, and that we don't have conflicts. If so, we could
5024 //at least pop up a warning.
5030 void GuiDocument::clearParams()
5032 bp_ = BufferParams();
5036 BufferId GuiDocument::id() const
5038 BufferView const * const view = bufferview();
5039 return view? &view->buffer() : nullptr;
5043 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
5045 return moduleNames_;
5049 list<GuiDocument::modInfoStruct> const
5050 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
5052 list<modInfoStruct> mInfo;
5053 for (string const & name : mods) {
5055 LyXModule const * const mod = theModuleList[name];
5060 m.name = toqstr(name + " (") + qt_("Not Found") + toqstr(")");
5062 m.missingreqs = true;
5070 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
5072 return makeModuleInfo(params().getModules());
5076 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
5078 return makeModuleInfo(params().baseClass()->providedModules());
5082 DocumentClass const & GuiDocument::documentClass() const
5084 return bp_.documentClass();
5088 static void dispatch_bufferparams(Dialog const & dialog,
5089 BufferParams const & bp, FuncCode lfun, Buffer const * buf)
5092 ss << "\\begin_header\n";
5093 bp.writeFile(ss, buf);
5094 ss << "\\end_header\n";
5095 dialog.dispatch(FuncRequest(lfun, ss.str()));
5099 void GuiDocument::dispatchParams()
5101 // We need a non-const buffer object.
5102 Buffer & buf = const_cast<BufferView *>(bufferview())->buffer();
5103 // There may be several undo records; group them (bug #8998)
5104 // This handles undo groups automagically
5105 UndoGroupHelper ugh(&buf);
5107 // This must come first so that a language change is correctly noticed
5110 // We need to load the master before we formally update the params,
5111 // since otherwise we run updateBuffer, etc, before the child's master
5113 if (!params().master.empty()) {
5114 FileName const master_file = support::makeAbsPath(params().master,
5115 support::onlyPath(buffer().absFileName()));
5116 if (isLyXFileName(master_file.absFileName())) {
5117 Buffer * master = checkAndLoadLyXFile(master_file, true);
5119 if (master->isChild(const_cast<Buffer *>(&buffer())))
5120 const_cast<Buffer &>(buffer()).setParent(master);
5122 Alert::warning(_("Assigned master does not include this file"),
5123 bformat(_("You must include this file in the document\n"
5124 "'%1$s' in order to use the master document\n"
5125 "feature."), from_utf8(params().master)));
5127 Alert::warning(_("Could not load master"),
5128 bformat(_("The master document '%1$s'\n"
5129 "could not be loaded."),
5130 from_utf8(params().master)));
5134 // Apply the BufferParams. Note that this will set the base class
5135 // and then update the buffer's layout.
5136 dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY, &buffer());
5138 // Generate the colours requested by each new branch.
5139 BranchList & branchlist = params().branchlist();
5140 if (!branchlist.empty()) {
5141 BranchList::const_iterator it = branchlist.begin();
5142 BranchList::const_iterator const end = branchlist.end();
5143 for (; it != end; ++it) {
5144 docstring const & current_branch = it->branch();
5145 Branch const * branch = branchlist.find(current_branch);
5146 string const bcolor = branch->color();
5148 if (bcolor.size() == 7 && bcolor[0] == '#')
5149 rgbcol = lyx::rgbFromHexName(bcolor);
5151 guiApp->getRgbColor(lcolor.getFromLyXName(bcolor), rgbcol);
5152 string const x11hexname = X11hexname(rgbcol);
5153 // display the new color
5154 docstring const str = current_branch + ' ' + from_ascii(x11hexname);
5155 dispatch(FuncRequest(LFUN_SET_COLOR, str));
5158 // rename branches in the document
5159 executeBranchRenaming();
5160 // and clear changed branches cache
5161 changedBranches_.clear();
5163 // Generate the colours requested by indices.
5164 IndicesList & indiceslist = params().indiceslist();
5165 if (!indiceslist.empty()) {
5166 IndicesList::const_iterator it = indiceslist.begin();
5167 IndicesList::const_iterator const end = indiceslist.end();
5168 for (; it != end; ++it) {
5169 docstring const & current_index = it->shortcut();
5170 Index const * index = indiceslist.findShortcut(current_index);
5171 string const x11hexname = X11hexname(index->color());
5172 // display the new color
5173 docstring const str = current_index + ' ' + from_ascii(x11hexname);
5174 dispatch(FuncRequest(LFUN_SET_COLOR, str));
5178 // If we used an LFUN, we would not need these two lines:
5179 BufferView * bv = const_cast<BufferView *>(bufferview());
5180 bv->processUpdateFlags(Update::Force | Update::FitCursor);
5184 void GuiDocument::setLanguage() const
5186 Language const * const newL = bp_.language;
5187 if (buffer().params().language == newL)
5190 string const & lang_name = newL->lang();
5191 dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
5195 void GuiDocument::saveAsDefault() const
5197 dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT, &buffer());
5201 bool GuiDocument::providesOSF(QString const & font) const
5203 if (fontModule->osFontsCB->isChecked())
5204 // FIXME: we should check if the fonts really
5205 // have OSF support. But how?
5206 return font != "default";
5207 return theLaTeXFonts().getLaTeXFont(
5208 qstring_to_ucs4(font)).providesOSF(ot1(),
5214 bool GuiDocument::providesSC(QString const & font) const
5216 if (fontModule->osFontsCB->isChecked())
5218 return theLaTeXFonts().getLaTeXFont(
5219 qstring_to_ucs4(font)).providesSC(ot1(),
5225 bool GuiDocument::providesScale(QString const & font) const
5227 if (fontModule->osFontsCB->isChecked())
5228 return font != "default";
5229 return theLaTeXFonts().getLaTeXFont(
5230 qstring_to_ucs4(font)).providesScale(ot1(),
5236 bool GuiDocument::providesExtraOpts(QString const & font) const
5238 if (fontModule->osFontsCB->isChecked())
5239 return font != "default";
5240 return theLaTeXFonts().getLaTeXFont(
5241 qstring_to_ucs4(font)).providesMoreOptions(ot1(),
5247 bool GuiDocument::providesNoMath(QString const & font) const
5249 if (fontModule->osFontsCB->isChecked())
5251 return theLaTeXFonts().getLaTeXFont(
5252 qstring_to_ucs4(font)).providesNoMath(ot1(),
5257 bool GuiDocument::hasMonolithicExpertSet(QString const & font) const
5259 if (fontModule->osFontsCB->isChecked())
5261 return theLaTeXFonts().getLaTeXFont(
5262 qstring_to_ucs4(font)).hasMonolithicExpertSet(ot1(),
5269 GuiDocument::modInfoStruct GuiDocument::modInfo(LyXModule const & mod)
5271 // FIXME Unicode: docstrings would be better for these parameters but this
5272 // change requires a lot of others
5275 QString const guiname = toqstr(translateIfPossible(from_utf8(mod.getName())));
5276 m.missingreqs = !isModuleAvailable(mod.getID());
5277 if (m.missingreqs) {
5278 m.name = qt_("%1 (missing req.)").arg(guiname);
5281 m.category = mod.category().empty() ? qt_("Miscellaneous")
5282 : toqstr(translateIfPossible(from_utf8(mod.category())));
5283 QString desc = toqstr(translateIfPossible(from_utf8(mod.getDescription())));
5284 // Find the first sentence of the description
5285 QTextBoundaryFinder bf(QTextBoundaryFinder::Sentence, desc);
5286 int pos = bf.toNextBoundary();
5289 m.local = mod.isLocal();
5290 QString const mtype = m.local ? qt_("personal module") : qt_("distributed module");
5291 QString modulename = qt_("<b>Module name:</b> <i>%1</i> (%2)").arg(toqstr(m.id)).arg(mtype);
5292 // Tooltip is the desc followed by the module name and the type
5293 m.description = QString("%1%2")
5294 .arg(desc.isEmpty() ? QString() : QString("<p>%1</p>").arg(desc),
5297 m.description += QString("<p>%1</p>").arg(qt_("<b>Note:</b> Some requirements for this module are missing!"));
5302 void GuiDocument::loadModuleInfo()
5304 moduleNames_.clear();
5305 for (LyXModule const & mod : theModuleList)
5306 moduleNames_.push_back(modInfo(mod));
5310 void GuiDocument::updateUnknownBranches()
5314 list<docstring> used_branches;
5315 buffer().getUsedBranches(used_branches);
5316 list<docstring>::const_iterator it = used_branches.begin();
5317 QStringList unknown_branches;
5318 for (; it != used_branches.end() ; ++it) {
5319 if (!buffer().params().branchlist().find(*it))
5320 unknown_branches.append(toqstr(*it));
5322 branchesModule->setUnknownBranches(unknown_branches);
5326 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
5328 map<docstring, docstring>::iterator it = changedBranches_.begin();
5329 for (; it != changedBranches_.end() ; ++it) {
5330 if (it->second == oldname) {
5331 // branch has already been renamed
5332 it->second = newname;
5337 changedBranches_[oldname] = newname;
5341 void GuiDocument::executeBranchRenaming() const
5343 map<docstring, docstring>::const_iterator it = changedBranches_.begin();
5344 for (; it != changedBranches_.end() ; ++it) {
5345 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
5346 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
5351 void GuiDocument::allPackagesAuto()
5357 void GuiDocument::allPackagesAlways()
5363 void GuiDocument::allPackagesNot()
5369 void GuiDocument::allPackages(int col)
5371 for (int row = 0; row < mathsModule->packagesTW->rowCount(); ++row) {
5373 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, col)->layout()->itemAt(0)->widget();
5374 rb->setChecked(true);
5379 void GuiDocument::linenoToggled(bool on)
5381 numberingModule->linenoLE->setEnabled(on);
5382 numberingModule->linenoLA->setEnabled(on);
5386 void GuiDocument::outputChangesToggled(bool on)
5388 changesModule->changeBarsCB->setEnabled(on);
5392 void GuiDocument::setOutputSync(bool on)
5394 outputModule->synccustomCB->setEnabled(on);
5395 outputModule->synccustomLA->setEnabled(on);
5400 bool GuiDocument::eventFilter(QObject * sender, QEvent * event)
5402 if (event->type() == QEvent::ApplicationPaletteChange) {
5403 // mode switch: colors need to be updated
5404 // and the highlighting redone
5405 if (pdf_options_highlighter_) {
5406 pdf_options_highlighter_->setupColors();
5407 pdf_options_highlighter_->rehighlight();
5409 if (pdf_metadata_highlighter_) {
5410 pdf_metadata_highlighter_->setupColors();
5411 pdf_metadata_highlighter_->rehighlight();
5414 return QWidget::eventFilter(sender, event);
5418 } // namespace frontend
5421 #include "moc_GuiDocument.cpp"