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));
1785 (void) new LaTeXHighlighter(pdfSupportModule->optionsTE->document(), true, true);
1786 (void) new LaTeXHighlighter(pdfSupportModule->metadataTE->document(), true, true);
1788 for (int i = 0; backref_opts[i][0]; ++i)
1789 pdfSupportModule->backrefCO->addItem(qt_(backref_opts_gui[i]));
1793 floatModule = new FloatPlacement;
1794 connect(floatModule, SIGNAL(changed()),
1795 this, SLOT(change_adaptor()));
1799 listingsModule = new UiWidget<Ui::ListingsSettingsUi>(this);
1800 connect(listingsModule->listingsED, SIGNAL(textChanged()),
1801 this, SLOT(change_adaptor()));
1802 connect(listingsModule->bypassCB, SIGNAL(clicked()),
1803 this, SLOT(change_adaptor()));
1804 connect(listingsModule->bypassCB, SIGNAL(clicked()),
1805 this, SLOT(setListingsMessage()));
1806 connect(listingsModule->packageCO, SIGNAL(activated(int)),
1807 this, SLOT(change_adaptor()));
1808 connect(listingsModule->packageCO, SIGNAL(activated(int)),
1809 this, SLOT(listingsPackageChanged(int)));
1810 connect(listingsModule->listingsED, SIGNAL(textChanged()),
1811 this, SLOT(setListingsMessage()));
1812 listingsModule->listingsTB->setPlainText(
1813 qt_("Input listings parameters below. Enter ? for a list of parameters."));
1815 for (int i = 0; lst_packages[i][0]; ++i)
1816 listingsModule->packageCO->addItem(lst_packages[i]);
1820 docPS->addPanel(latexModule, N_("Document Class"));
1821 docPS->addPanel(masterChildModule, N_("Child Documents"));
1822 docPS->addPanel(modulesModule, N_("Modules"));
1823 docPS->addPanel(localLayout, N_("Local Layout"));
1824 docPS->addPanel(fontModule, N_("Fonts"));
1825 docPS->addPanel(textLayoutModule, N_("Text Layout"));
1826 docPS->addPanel(pageLayoutModule, N_("Page Layout"));
1827 docPS->addPanel(marginsModule, N_("Page Margins"));
1828 docPS->addPanel(langModule, N_("Language"));
1829 docPS->addPanel(colorModule, N_("Colors"));
1830 docPS->addPanel(changesModule, N_("Change Tracking"));
1831 docPS->addPanel(numberingModule, N_("Numbering & TOC"));
1832 docPS->addPanel(biblioModule, N_("Bibliography"));
1833 docPS->addPanel(indicesModule, N_("Indexes"));
1834 docPS->addPanel(pdfSupportModule, N_("PDF Properties"));
1835 docPS->addPanel(mathsModule, N_("Math Options"));
1836 docPS->addPanel(floatModule, N_("Float Settings"));
1837 docPS->addPanel(listingsModule, N_("Listings[[inset]]"));
1838 docPS->addPanel(bulletsModule, N_("Bullets"));
1839 docPS->addPanel(branchesModule, N_("Branches"));
1840 docPS->addPanel(outputModule, N_("Output"));
1841 docPS->addPanel(preambleModule, N_("LaTeX Preamble"));
1842 docPS->setCurrentPanel("Document Class");
1846 void GuiDocument::onBufferViewChanged()
1849 // We are just switching back. Nothing to do.
1850 switchback_ = false;
1853 BufferView const * view = bufferview();
1854 string const new_filename = view ? view->buffer().absFileName() : string();
1855 // If we switched buffer really and the previous file name is different to
1856 // the current one, we ask on unapplied changes (#9369)
1857 // FIXME: This is more complicated than it should be. Why do we need these to cycles?
1858 // And ideally, we should propose to apply without having to switch back
1859 // (e.g., via a LFUN_BUFFER_PARAMS_APPLY_OTHER)
1860 if (!prev_buffer_filename_.empty() && prev_buffer_filename_ != new_filename
1861 && buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
1862 // Only ask if we haven't yet in this cycle
1863 int const ret = prompted_ ? 3 : Alert::prompt(_("Unapplied changes"),
1864 _("Some changes in the previous document were not yet applied.\n"
1865 "Do you want to switch back and apply them?"),
1866 1, 1, _("Yes, &Switch Back"), _("No, &Dismiss Changes"));
1868 // Switch to previous buffer view and apply
1870 // Record that we have asked.
1872 lyx::dispatch(FuncRequest(LFUN_BUFFER_SWITCH, prev_buffer_filename_));
1874 } else if (ret == 3) {
1875 // We are in the second cycle. Set back.
1881 if (isVisibleView())
1882 initialiseParams("");
1886 void GuiDocument::saveDefaultClicked()
1892 void GuiDocument::useDefaultsClicked()
1898 void GuiDocument::change_adaptor()
1900 nonModuleChanged_ = true;
1905 void GuiDocument::shellescapeChanged()
1907 shellescapeChanged_ = true;
1911 void GuiDocument::bookmarksopenChanged(bool state)
1913 pdfSupportModule->bookmarksopenlevelSB->setEnabled(state);
1914 pdfSupportModule->bookmarksopenlevelLA->setEnabled(state);
1918 void GuiDocument::changeTrackingChanged(bool state)
1920 // This is triggered if the CT state is toggled outside
1921 // the document dialog (e.g., menu).
1922 changesModule->trackChangesCB->setChecked(state);
1926 void GuiDocument::slotApply()
1928 bool only_shellescape_changed = !nonModuleChanged_ && !modulesChanged_;
1929 bool wasclean = buffer().isClean();
1930 GuiDialog::slotApply();
1931 if (wasclean && only_shellescape_changed)
1932 buffer().markClean();
1933 modulesChanged_ = false;
1938 void GuiDocument::slotOK()
1940 bool only_shellescape_changed = !nonModuleChanged_ && !modulesChanged_;
1941 bool wasclean = buffer().isClean();
1942 GuiDialog::slotOK();
1943 if (wasclean && only_shellescape_changed)
1944 buffer().markClean();
1945 modulesChanged_ = false;
1949 void GuiDocument::slotButtonBox(QAbstractButton * button)
1951 switch (buttonBox->standardButton(button)) {
1952 case QDialogButtonBox::Ok:
1955 case QDialogButtonBox::Apply:
1958 case QDialogButtonBox::Cancel:
1961 case QDialogButtonBox::Reset:
1962 case QDialogButtonBox::RestoreDefaults:
1971 void GuiDocument::filterModules(QString const & str)
1973 updateAvailableModules();
1977 modules_av_model_.clear();
1978 list<modInfoStruct> modInfoList = getModuleInfo();
1979 // Sort names according to the locale
1980 modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
1981 return 0 < b.name.localeAwareCompare(a.name);
1984 QIcon user_icon(guiApp ? guiApp->getScaledPixmap("images/", "lyxfiles-user")
1985 : getPixmap("images/", "lyxfiles-user", "svgz,png"));
1986 QIcon system_icon(guiApp ? guiApp->getScaledPixmap("images/", "lyxfiles-system")
1987 : getPixmap("images/", "lyxfiles-system", "svgz,png"));
1990 for (modInfoStruct const & m : modInfoList) {
1991 if (m.name.contains(str, Qt::CaseInsensitive) || contains(m.id, fromqstr(str))) {
1992 QStandardItem * item = new QStandardItem();
1993 item->setData(m.name, Qt::DisplayRole);
1994 item->setData(toqstr(m.id), Qt::UserRole);
1995 item->setData(m.description, Qt::ToolTipRole);
1996 item->setEditable(false);
1998 item->setIcon(user_icon);
2000 item->setIcon(system_icon);
2001 modules_av_model_.insertRow(i, item);
2008 void GuiDocument::moduleFilterChanged(const QString & text)
2010 if (!text.isEmpty()) {
2011 filterModules(filter_->text());
2014 filterModules(filter_->text());
2015 filter_->setFocus();
2019 void GuiDocument::moduleFilterPressed()
2021 filterModules(filter_->text());
2025 void GuiDocument::resetModuleFilter()
2027 filter_->setText(QString());
2028 filterModules(filter_->text());
2032 void GuiDocument::includeonlyClicked(QTreeWidgetItem * item, int)
2034 if (item == nullptr)
2037 string child = fromqstr(item->text(0));
2042 if (isChildIncluded(child))
2043 includeonlys_.remove(child);
2045 includeonlys_.push_back(child);
2047 updateIncludeonlys(false);
2052 QString GuiDocument::validateListingsParameters()
2054 if (listingsModule->bypassCB->isChecked())
2056 string const package =
2057 lst_packages[listingsModule->packageCO->currentIndex()];
2058 string params = fromqstr(listingsModule->listingsED->toPlainText());
2059 InsetListingsParams lstparams(params);
2060 lstparams.setMinted(package == "Minted");
2061 return toqstr(lstparams.validate());
2065 void GuiDocument::setListingsMessage()
2068 static bool isOK = true;
2069 QString msg = validateListingsParameters();
2070 if (msg.isEmpty()) {
2071 listingsModule->listingsTB->setTextColor(QColor());
2075 listingsModule->listingsTB->setPlainText(
2076 qt_("Input listings parameters below. "
2077 "Enter ? for a list of parameters."));
2080 listingsModule->listingsTB->setTextColor(QColor(255, 0, 0));
2081 listingsModule->listingsTB->setPlainText(msg);
2086 void GuiDocument::listingsPackageChanged(int index)
2088 string const package = lst_packages[index];
2089 if (package == "Minted" && lyxrc.pygmentize_command.empty()) {
2090 Alert::warning(_("Pygments driver command not found!"),
2091 _("The driver command necessary to use the minted package\n"
2092 "(pygmentize) has not been found. Make sure you have\n"
2093 "the python-pygments module installed or, if the driver\n"
2094 "is named differently, to add the following line to the\n"
2095 "document preamble:\n\n"
2096 "\\AtBeginDocument{\\renewcommand{\\MintedPygmentize}{driver}}\n\n"
2097 "where 'driver' is name of the driver command."));
2102 void GuiDocument::setLSpacing(int item)
2104 textLayoutModule->lspacingLE->setEnabled(item == 3);
2108 void GuiDocument::setIndent(int item)
2110 bool const enable = (textLayoutModule->indentCO->itemData(item) == "custom");
2111 textLayoutModule->indentLE->setEnabled(enable);
2112 textLayoutModule->indentLengthCO->setEnabled(enable);
2113 textLayoutModule->skipLE->setEnabled(false);
2114 textLayoutModule->skipLengthCO->setEnabled(false);
2115 // needed to catch empty custom case
2121 void GuiDocument::enableIndent(bool indent)
2123 textLayoutModule->skipLE->setEnabled(!indent);
2124 textLayoutModule->skipLengthCO->setEnabled(!indent);
2126 setIndent(textLayoutModule->indentCO->currentIndex());
2130 void GuiDocument::setSkip(int item)
2132 VSpace::VSpaceKind kind =
2133 VSpace::VSpaceKind(textLayoutModule->skipCO->itemData(item).toInt());
2134 bool const enable = (kind == VSpace::LENGTH);
2135 textLayoutModule->skipLE->setEnabled(enable);
2136 textLayoutModule->skipLengthCO->setEnabled(enable);
2137 // needed to catch empty custom case
2143 void GuiDocument::enableSkip(bool skip)
2145 textLayoutModule->indentLE->setEnabled(!skip);
2146 textLayoutModule->indentLengthCO->setEnabled(!skip);
2148 setSkip(textLayoutModule->skipCO->currentIndex());
2151 void GuiDocument::allowMathIndent() {
2152 // only disable when not checked, checked does not always allow enabling
2153 if (!mathsModule->MathIndentCB->isChecked()) {
2154 mathsModule->MathIndentLE->setEnabled(false);
2155 mathsModule->MathIndentLengthCO->setEnabled(false);
2157 if (mathsModule->MathIndentCB->isChecked()
2158 && mathsModule->MathIndentCO->itemData(mathsModule->MathIndentCO->currentIndex()) == "custom") {
2159 mathsModule->MathIndentLE->setEnabled(true);
2160 mathsModule->MathIndentLengthCO->setEnabled(true);
2165 void GuiDocument::enableMathIndent(int item)
2167 bool const enable = (item == 1);
2168 mathsModule->MathIndentLE->setEnabled(enable);
2169 mathsModule->MathIndentLengthCO->setEnabled(enable);
2170 // needed to catch empty custom case
2176 void GuiDocument::setMargins()
2178 bool const extern_geometry =
2179 documentClass().provides("geometry");
2180 marginsModule->marginCB->setEnabled(!extern_geometry);
2181 if (extern_geometry) {
2182 marginsModule->marginCB->setChecked(false);
2183 setCustomMargins(true);
2185 marginsModule->marginCB->setChecked(!bp_.use_geometry);
2186 setCustomMargins(!bp_.use_geometry);
2191 void GuiDocument::papersizeChanged(int paper_size)
2193 setCustomPapersize(paper_size == 1);
2197 void GuiDocument::setCustomPapersize(bool custom)
2199 pageLayoutModule->paperwidthL->setEnabled(custom);
2200 pageLayoutModule->paperwidthLE->setEnabled(custom);
2201 pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
2202 pageLayoutModule->paperheightL->setEnabled(custom);
2203 pageLayoutModule->paperheightLE->setEnabled(custom);
2204 pageLayoutModule->paperheightLE->setFocus();
2205 pageLayoutModule->paperheightUnitCO->setEnabled(custom);
2209 void GuiDocument::setColSep()
2211 setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
2215 void GuiDocument::setCustomMargins(bool custom)
2217 marginsModule->topL->setEnabled(!custom);
2218 marginsModule->topLE->setEnabled(!custom);
2219 marginsModule->topUnit->setEnabled(!custom);
2221 marginsModule->bottomL->setEnabled(!custom);
2222 marginsModule->bottomLE->setEnabled(!custom);
2223 marginsModule->bottomUnit->setEnabled(!custom);
2225 marginsModule->innerL->setEnabled(!custom);
2226 marginsModule->innerLE->setEnabled(!custom);
2227 marginsModule->innerUnit->setEnabled(!custom);
2229 marginsModule->outerL->setEnabled(!custom);
2230 marginsModule->outerLE->setEnabled(!custom);
2231 marginsModule->outerUnit->setEnabled(!custom);
2233 marginsModule->headheightL->setEnabled(!custom);
2234 marginsModule->headheightLE->setEnabled(!custom);
2235 marginsModule->headheightUnit->setEnabled(!custom);
2237 marginsModule->headsepL->setEnabled(!custom);
2238 marginsModule->headsepLE->setEnabled(!custom);
2239 marginsModule->headsepUnit->setEnabled(!custom);
2241 marginsModule->footskipL->setEnabled(!custom);
2242 marginsModule->footskipLE->setEnabled(!custom);
2243 marginsModule->footskipUnit->setEnabled(!custom);
2245 bool const enableColSep = !custom &&
2246 textLayoutModule->twoColumnCB->checkState() == Qt::Checked;
2247 marginsModule->columnsepL->setEnabled(enableColSep);
2248 marginsModule->columnsepLE->setEnabled(enableColSep);
2249 marginsModule->columnsepUnit->setEnabled(enableColSep);
2251 // set some placeholder text that hint on defaults
2252 QString const placeholder = marginsModule->marginCB->isChecked() ?
2253 qt_("Default margins") : qt_("Package defaults");
2254 // set tooltip depending on gemoetry state
2255 QString const tooltip = marginsModule->marginCB->isChecked() ?
2256 qt_("If no value is given, the defaults as set by the class, a package or the preamble are used.")
2257 : qt_("If no value is given, the defaults as set by the geometry package or a package/class overriding geometry's defaults are used.");
2258 marginsModule->topLE->setPlaceholderText(placeholder);
2259 marginsModule->bottomLE->setPlaceholderText(placeholder);
2260 marginsModule->innerLE->setPlaceholderText(placeholder);
2261 marginsModule->outerLE->setPlaceholderText(placeholder);
2262 marginsModule->headheightLE->setPlaceholderText(placeholder);
2263 marginsModule->headsepLE->setPlaceholderText(placeholder);
2264 marginsModule->footskipLE->setPlaceholderText(placeholder);
2265 marginsModule->columnsepLE->setPlaceholderText(placeholder);
2266 marginsModule->topLE->setToolTip(tooltip);
2267 marginsModule->bottomLE->setToolTip(tooltip);
2268 marginsModule->innerLE->setToolTip(tooltip);
2269 marginsModule->outerLE->setToolTip(tooltip);
2270 marginsModule->headheightLE->setToolTip(tooltip);
2271 marginsModule->headsepLE->setToolTip(tooltip);
2272 marginsModule->footskipLE->setToolTip(tooltip);
2273 marginsModule->columnsepLE->setToolTip(tooltip);
2277 void GuiDocument::changeBackgroundColor()
2279 QColor const & newColor = getColor(rgb2qcolor(set_backgroundcolor));
2280 if (!newColor.isValid())
2283 colorModule->pageBackgroundCF->setVisible(true);
2284 colorModule->pageBackgroundCF->setStyleSheet(
2285 colorFrameStyleSheet(newColor));
2287 set_backgroundcolor = rgbFromHexName(fromqstr(newColor.name()));
2288 is_backgroundcolor = true;
2293 void GuiDocument::deleteBackgroundColor()
2295 // set the color back to default by setting an empty StyleSheet
2296 colorModule->pageBackgroundCF->setStyleSheet(QLatin1String(""));
2297 colorModule->pageBackgroundCF->setVisible(false);
2298 // save default color (white)
2299 set_backgroundcolor = rgbFromHexName("#ffffff");
2300 is_backgroundcolor = false;
2305 void GuiDocument::changeFontColor()
2307 QColor const & newColor = getColor(rgb2qcolor(set_fontcolor));
2308 if (!newColor.isValid())
2311 colorModule->mainTextCF->setVisible(true);
2312 colorModule->mainTextCF->setStyleSheet(
2313 colorFrameStyleSheet(newColor));
2315 set_fontcolor = rgbFromHexName(fromqstr(newColor.name()));
2316 is_fontcolor = true;
2321 void GuiDocument::deleteFontColor()
2323 // set the button color back to default by setting an empty StyleSheet
2324 colorModule->mainTextCF->setStyleSheet(QLatin1String(""));
2325 colorModule->mainTextCF->setVisible(false);
2326 // save default color (black)
2327 set_fontcolor = rgbFromHexName("#000000");
2328 is_fontcolor = false;
2333 void GuiDocument::changeNoteFontColor()
2335 QColor const & newColor = getColor(rgb2qcolor(set_notefontcolor));
2336 if (!newColor.isValid())
2339 colorModule->noteFontCF->setStyleSheet(
2340 colorFrameStyleSheet(newColor));
2342 set_notefontcolor = rgbFromHexName(fromqstr(newColor.name()));
2343 is_notefontcolor = true;
2348 void GuiDocument::deleteNoteFontColor()
2350 // set the color back to pref
2351 theApp()->getRgbColor(Color_greyedouttext, set_notefontcolor);
2352 colorModule->noteFontCF->setStyleSheet(
2353 colorFrameStyleSheet(rgb2qcolor(set_notefontcolor)));
2354 is_notefontcolor = false;
2359 void GuiDocument::changeBoxBackgroundColor()
2361 QColor const & newColor = getColor(rgb2qcolor(set_boxbgcolor));
2362 if (!newColor.isValid())
2365 colorModule->boxBackgroundCF->setStyleSheet(
2366 colorFrameStyleSheet(newColor));
2368 set_boxbgcolor = rgbFromHexName(fromqstr(newColor.name()));
2369 is_boxbgcolor = true;
2374 void GuiDocument::deleteBoxBackgroundColor()
2376 // set the color back to pref
2377 theApp()->getRgbColor(Color_shadedbg, set_boxbgcolor);
2378 colorModule->boxBackgroundCF->setStyleSheet(
2379 colorFrameStyleSheet(rgb2qcolor(set_boxbgcolor)));
2380 is_boxbgcolor = false;
2385 void GuiDocument::updateQuoteStyles(bool const set)
2387 Language const * lang = lyx::languages.getLanguage(
2388 fromqstr(langModule->languageCO->itemData(
2389 langModule->languageCO->currentIndex()).toString()));
2391 QuoteStyle def = bp_.getQuoteStyle(lang->quoteStyle());
2393 langModule->quoteStyleCO->clear();
2395 bool has_default = false;
2396 for (int i = 0; i < quoteparams.stylescount(); ++i) {
2397 QuoteStyle qs = QuoteStyle(i);
2398 if (qs == QuoteStyle::Dynamic)
2400 bool const langdef = (qs == def);
2402 // add the default style on top
2403 langModule->quoteStyleCO->insertItem(0,
2404 toqstr(quoteparams.getGuiLabel(qs, langdef)), static_cast<int>(qs));
2408 langModule->quoteStyleCO->addItem(
2409 toqstr(quoteparams.getGuiLabel(qs, langdef)), static_cast<int>(qs));
2411 // Use document serif font to assure quotation marks are distinguishable
2412 QFont comboFont(toqstr(lyxrc.roman_font_name),
2413 langModule->quoteStyleCO->fontInfo().pointSize() * 1.4, -1, false);
2414 QFontMetrics fm(comboFont);
2415 // calculate width of the widest item in the set font
2417 for (int i = 0; i < langModule->quoteStyleCO->count(); ++i) {
2418 langModule->quoteStyleCO->setItemData(i, QVariant(comboFont), Qt::FontRole);
2419 QString str = langModule->quoteStyleCO->itemText(i);
2420 #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
2421 qswidth = max(qswidth, fm.horizontalAdvance(str));
2423 qswidth = max(qswidth, fm.width(str));
2426 // add scrollbar width and margin to width
2427 qswidth += langModule->quoteStyleCO->style()->pixelMetric(QStyle::PM_ScrollBarExtent);
2428 qswidth += langModule->quoteStyleCO->view()->autoScrollMargin();
2429 langModule->quoteStyleCO->view()->setMinimumWidth(qswidth);
2430 if (set && has_default)
2431 // (re)set to the default style
2432 langModule->quoteStyleCO->setCurrentIndex(0);
2436 void GuiDocument::languageChanged(int i)
2438 // some languages only work with Polyglossia
2439 Language const * lang = lyx::languages.getLanguage(
2440 fromqstr(langModule->languageCO->itemData(i).toString()));
2441 if (lang->babel().empty() && !lang->polyglossia().empty()
2442 && lang->required() != "CJK" && lang->required() != "japanese") {
2443 // If we force to switch fontspec on, store
2444 // current state (#8717)
2445 if (fontModule->osFontsCB->isEnabled())
2446 forced_fontspec_activation =
2447 !fontModule->osFontsCB->isChecked();
2448 fontModule->osFontsCB->setChecked(true);
2449 fontModule->osFontsCB->setEnabled(false);
2452 fontModule->osFontsCB->setEnabled(true);
2453 // If we have forced to switch fontspec on,
2454 // restore previous state (#8717)
2455 if (forced_fontspec_activation)
2456 fontModule->osFontsCB->setChecked(false);
2457 forced_fontspec_activation = false;
2460 // set appropriate quotation mark style
2461 updateQuoteStyles(true);
2465 void GuiDocument::osFontsChanged(bool nontexfonts)
2467 bool const tex_fonts = !nontexfonts;
2468 // store current fonts
2469 QString const font_roman = fontModule->fontsRomanCO->getData(
2470 fontModule->fontsRomanCO->currentIndex());
2471 QString const font_sans = fontModule->fontsSansCO->getData(
2472 fontModule->fontsSansCO->currentIndex());
2473 QString const font_typewriter = fontModule->fontsTypewriterCO->getData(
2474 fontModule->fontsTypewriterCO->currentIndex());
2475 QString const font_math = fontModule->fontsMathCO->itemData(
2476 fontModule->fontsMathCO->currentIndex()).toString();
2477 int const font_sf_scale = fontModule->scaleSansSB->value();
2478 int const font_tt_scale = fontModule->scaleTypewriterSB->value();
2481 // store default format
2482 QString const dformat = outputModule->defaultFormatCO->itemData(
2483 outputModule->defaultFormatCO->currentIndex()).toString();
2484 updateDefaultFormat();
2485 // try to restore default format
2486 int index = outputModule->defaultFormatCO->findData(dformat);
2487 // set to default if format is not found
2490 outputModule->defaultFormatCO->setCurrentIndex(index);
2492 // try to restore fonts which were selected two toggles ago
2493 if (!fontModule->font_roman.isEmpty())
2494 fontModule->fontsRomanCO->set(fontModule->font_roman);
2495 if (!fontModule->font_sans.isEmpty())
2496 fontModule->fontsSansCO->set(fontModule->font_sans);
2497 if (!fontModule->font_typewriter.isEmpty())
2498 fontModule->fontsTypewriterCO->set(fontModule->font_typewriter);
2499 index = fontModule->fontsMathCO->findData(fontModule->font_math);
2501 fontModule->fontsMathCO->setCurrentIndex(index);
2502 // save fonts for next next toggle
2503 fontModule->font_roman = font_roman;
2504 fontModule->font_sans = font_sans;
2505 fontModule->font_typewriter = font_typewriter;
2506 fontModule->font_math = font_math;
2507 fontModule->font_sf_scale = font_sf_scale;
2508 fontModule->font_tt_scale = font_tt_scale;
2510 // non-tex fonts override the "\inputencoding" option with "utf8-plain"
2511 langModule->encodingCO->setEnabled(tex_fonts);
2512 inputencodingToDialog();
2514 fontModule->cjkFontLE->setEnabled(tex_fonts);
2515 fontModule->cjkFontLA->setEnabled(tex_fonts);
2517 updateFontOptions();
2519 fontModule->fontencLA->setEnabled(tex_fonts);
2520 fontModule->fontencCO->setEnabled(tex_fonts);
2522 fontModule->fontencLE->setEnabled(false);
2524 fontencChanged(fontModule->fontencCO->currentIndex());
2528 void GuiDocument::encodingSwitched(int i)
2530 bool const tex_fonts = !fontModule->osFontsCB->isChecked();
2531 langModule->unicodeEncodingCO->setEnabled(tex_fonts);
2532 langModule->customEncodingCO->setEnabled(tex_fonts);
2533 langModule->autoEncodingCO->setEnabled(tex_fonts);
2534 langModule->unicodeEncodingCO->setVisible(i == EncodingSets::unicode);
2535 langModule->autoEncodingCO->setVisible(i == EncodingSets::legacy);
2536 langModule->customEncodingCO->setVisible(i == EncodingSets::custom);
2538 case EncodingSets::unicode:
2539 langModule->encodingVariantLA->setBuddy(langModule->unicodeEncodingCO);
2541 case EncodingSets::legacy:
2542 langModule->encodingVariantLA->setBuddy(langModule->autoEncodingCO);
2544 case EncodingSets::custom:
2545 langModule->encodingVariantLA->setBuddy(langModule->customEncodingCO);
2550 langModule->unicodeEncodingCO->setItemText(1, qt_("Direct (No inputenc)"));
2552 langModule->unicodeEncodingCO->setItemText(1, qt_("Direct (XeTeX/LuaTeX)"));
2555 void GuiDocument::inputencodingToDialog()
2557 QString inputenc = toqstr(bp_.inputenc);
2559 if (fontModule->osFontsCB->isChecked()) { // non-tex fonts require utf8-plain
2560 langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
2561 langModule->unicodeEncodingCO->setCurrentIndex(
2562 langModule->unicodeEncodingCO->findData("utf8-plain"));
2563 } else if (inputenc.startsWith("utf8")) {
2564 langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
2565 p = langModule->unicodeEncodingCO->findData(inputenc);
2568 langModule->unicodeEncodingCO->setCurrentIndex(p);
2569 langModule->autoEncodingCO->setCurrentIndex(0);
2570 langModule->customEncodingCO->setCurrentIndex(0);
2571 } else if (inputenc.startsWith("auto")) {
2572 langModule->encodingCO->setCurrentIndex(EncodingSets::legacy);
2573 p = langModule->autoEncodingCO->findData(inputenc);
2576 langModule->unicodeEncodingCO->setCurrentIndex(0);
2577 langModule->autoEncodingCO->setCurrentIndex(p);
2578 langModule->customEncodingCO->setCurrentIndex(0);
2580 langModule->encodingCO->setCurrentIndex(EncodingSets::custom);
2581 p = langModule->customEncodingCO->findData(inputenc);
2584 langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
2586 langModule->unicodeEncodingCO->setCurrentIndex(0);
2587 langModule->autoEncodingCO->setCurrentIndex(0);
2588 langModule->customEncodingCO->setCurrentIndex(p);
2590 encodingSwitched(langModule->encodingCO->currentIndex());
2594 void GuiDocument::mathFontChanged(int)
2596 updateFontOptions();
2599 void GuiDocument::fontOsfToggled(bool state)
2601 if (fontModule->osFontsCB->isChecked())
2603 QString font = fontModule->fontsRomanCO->getData(
2604 fontModule->fontsRomanCO->currentIndex());
2605 if (hasMonolithicExpertSet(font))
2606 fontModule->fontScCB->setChecked(state);
2610 void GuiDocument::fontScToggled(bool state)
2612 if (fontModule->osFontsCB->isChecked())
2614 QString font = fontModule->fontsRomanCO->getData(
2615 fontModule->fontsRomanCO->currentIndex());
2616 if (hasMonolithicExpertSet(font))
2617 fontModule->fontOsfCB->setChecked(state);
2621 void GuiDocument::updateExtraOpts()
2623 QString font = fontModule->fontsRomanCO->getData(
2624 fontModule->fontsRomanCO->currentIndex());
2625 bool const rm_opts = providesExtraOpts(font);
2626 font = fontModule->fontsSansCO->getData(
2627 fontModule->fontsSansCO->currentIndex());
2628 bool const sf_opts = providesExtraOpts(font);
2629 font = fontModule->fontsTypewriterCO->getData(
2630 fontModule->fontsTypewriterCO->currentIndex());
2631 bool const tt_opts = providesExtraOpts(font);
2632 fontModule->fontspecRomanLA->setEnabled(rm_opts);
2633 fontModule->fontspecRomanLE->setEnabled(rm_opts);
2634 fontModule->fontspecSansLA->setEnabled(sf_opts);
2635 fontModule->fontspecSansLE->setEnabled(sf_opts);
2636 fontModule->fontspecTypewriterLA->setEnabled(tt_opts);
2637 fontModule->fontspecTypewriterLE->setEnabled(tt_opts);
2641 void GuiDocument::updateFontOptions()
2643 QString font = fontModule->fontsSansCO->getData(
2644 fontModule->fontsSansCO->currentIndex());
2645 bool scalable = providesScale(font);
2646 fontModule->scaleSansSB->setEnabled(scalable);
2647 fontModule->scaleSansLA->setEnabled(scalable);
2648 fontModule->fontSansOsfCB->setEnabled(providesOSF(font));
2649 font = fontModule->fontsTypewriterCO->getData(
2650 fontModule->fontsTypewriterCO->currentIndex());
2651 scalable = providesScale(font);
2652 fontModule->scaleTypewriterSB->setEnabled(scalable);
2653 fontModule->scaleTypewriterLA->setEnabled(scalable);
2654 fontModule->fontTypewriterOsfCB->setEnabled(providesOSF(font));
2655 font = fontModule->fontsRomanCO->getData(
2656 fontModule->fontsRomanCO->currentIndex());
2657 fontModule->fontScCB->setEnabled(providesSC(font));
2658 fontModule->fontOsfCB->setEnabled(providesOSF(font));
2660 updateMathFonts(font);
2664 void GuiDocument::updateFontsize(string const & items, string const & sel)
2666 fontModule->fontsizeCO->clear();
2667 fontModule->fontsizeCO->addItem(qt_("Default"));
2669 for (int n = 0; !token(items,'|',n).empty(); ++n)
2670 fontModule->fontsizeCO->
2671 addItem(toqstr(token(items,'|',n)));
2673 for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
2674 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
2675 fontModule->fontsizeCO->setCurrentIndex(n);
2682 bool GuiDocument::ot1() const
2684 QString const fontenc =
2685 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
2686 int const i = langModule->languageCO->currentIndex();
2689 QString const langname = langModule->languageCO->itemData(i).toString();
2690 Language const * newlang = lyx::languages.getLanguage(fromqstr(langname));
2691 return (fontenc == "default"
2692 || (fontenc == "auto" && newlang->fontenc(buffer().params()) == "OT1")
2693 || (fontenc == "custom" && fontModule->fontencLE->text() == "OT1"));
2697 bool GuiDocument::completeFontset() const
2699 return (fontModule->fontsSansCO->getData(
2700 fontModule->fontsSansCO->currentIndex()) == "default"
2701 && fontModule->fontsSansCO->getData(
2702 fontModule->fontsTypewriterCO->currentIndex()) == "default");
2706 bool GuiDocument::noMathFont() const
2708 return (fontModule->fontsMathCO->itemData(
2709 fontModule->fontsMathCO->currentIndex()).toString() == "default");
2713 void GuiDocument::updateTexFonts()
2715 LaTeXFonts::TexFontMap texfontmap = theLaTeXFonts().getLaTeXFonts();
2717 LaTeXFonts::TexFontMap::const_iterator it = texfontmap.begin();
2718 LaTeXFonts::TexFontMap::const_iterator end = texfontmap.end();
2719 for (; it != end; ++it) {
2720 LaTeXFont lf = it->second;
2721 if (lf.name().empty()) {
2722 LYXERR0("Error: Unnamed font: " << it->first);
2725 docstring const family = lf.family();
2726 docstring guiname = translateIfPossible(lf.guiname());
2727 if (!lf.available(ot1(), noMathFont()))
2728 guiname += _(" (not installed)");
2730 rmfonts_.insert(toqstr(guiname), toqstr(it->first));
2731 else if (family == "sf")
2732 sffonts_.insert(toqstr(guiname), toqstr(it->first));
2733 else if (family == "tt")
2734 ttfonts_.insert(toqstr(guiname), toqstr(it->first));
2735 else if (family == "math")
2736 mathfonts_.insert(toqstr(guiname), toqstr(it->first));
2741 void GuiDocument::updateFontlist()
2743 // reset the filters of the CategorizedCombos
2744 fontModule->fontsRomanCO->resetFilter();
2745 fontModule->fontsSansCO->resetFilter();
2746 fontModule->fontsTypewriterCO->resetFilter();
2747 fontModule->fontsRomanCO->clear();
2748 fontModule->fontsSansCO->clear();
2749 fontModule->fontsTypewriterCO->clear();
2750 fontModule->fontsMathCO->clear();
2752 // With fontspec (XeTeX, LuaTeX), we have access to all system fonts, but not the LaTeX fonts
2753 if (fontModule->osFontsCB->isChecked()) {
2754 fontModule->fontsRomanCO->addItemSort(QString("default"), qt_("Default"),
2755 QString(), qt_("Default font (as set by class)"),
2756 false, false, false, true, true);
2757 fontModule->fontsSansCO->addItemSort(QString("default"), qt_("Default"),
2758 QString(), qt_("Default font (as set by class)"),
2759 false, false, false, true, true);
2760 fontModule->fontsTypewriterCO->addItemSort(QString("default"), qt_("Default"),
2761 QString(), qt_("Default font (as set by class)"),
2762 false, false, false, true, true);
2763 QString unimath = qt_("Non-TeX Fonts Default");
2764 if (!LaTeXFeatures::isAvailable("unicode-math"))
2765 unimath += qt_(" (not available)");
2766 fontModule->fontsMathCO->addItem(qt_("Class Default (TeX Fonts)"), QString("auto"));
2767 fontModule->fontsMathCO->addItem(unimath, QString("default"));
2769 #if QT_VERSION >= 0x060000
2770 const QStringList families(QFontDatabase::families());
2772 QFontDatabase fontdb;
2773 const QStringList families(fontdb.families());
2775 for (auto const & family : families) {
2776 fontModule->fontsRomanCO->addItemSort(family, family,
2777 QString(), QString(),
2778 false, false, false, true, true);
2779 fontModule->fontsSansCO->addItemSort(family, family,
2780 QString(), QString(),
2781 false, false, false, true, true);
2782 fontModule->fontsTypewriterCO->addItemSort(family, family,
2783 QString(), QString(),
2784 false, false, false, true, true);
2789 if (rmfonts_.empty())
2792 fontModule->fontsRomanCO->addItemSort(QString("default"), qt_("Default"),
2793 QString(), qt_("Default font (as set by class)"),
2794 false, false, false, true, true);
2795 QMap<QString, QString>::const_iterator rmi = rmfonts_.constBegin();
2796 while (rmi != rmfonts_.constEnd()) {
2797 fontModule->fontsRomanCO->addItemSort(rmi.value(), rmi.key(),
2798 QString(), QString(),
2799 false, false, false, true, true);
2803 fontModule->fontsSansCO->addItemSort(QString("default"), qt_("Default"),
2804 QString(), qt_("Default font (as set by class)"),
2805 false, false, false, true, true);
2806 QMap<QString, QString>::const_iterator sfi = sffonts_.constBegin();
2807 while (sfi != sffonts_.constEnd()) {
2808 fontModule->fontsSansCO->addItemSort(sfi.value(), sfi.key(),
2809 QString(), QString(),
2810 false, false, false, true, true);
2814 fontModule->fontsTypewriterCO->addItemSort(QString("default"), qt_("Default"),
2815 QString(), qt_("Default font (as set by class)"),
2816 false, false, false, true, true);
2817 QMap<QString, QString>::const_iterator tti = ttfonts_.constBegin();
2818 while (tti != ttfonts_.constEnd()) {
2819 fontModule->fontsTypewriterCO->addItemSort(tti.value(), tti.key(),
2820 QString(), QString(),
2821 false, false, false, true, true);
2825 fontModule->fontsMathCO->addItem(qt_("Automatic"), QString("auto"));
2826 fontModule->fontsMathCO->addItem(qt_("Class Default"), QString("default"));
2827 QMap<QString, QString>::const_iterator mmi = mathfonts_.constBegin();
2828 while (mmi != mathfonts_.constEnd()) {
2829 fontModule->fontsMathCO->addItem(mmi.key(), mmi.value());
2835 void GuiDocument::fontencChanged(int item)
2837 fontModule->fontencLE->setEnabled(
2838 fontModule->fontencCO->itemData(item).toString() == "custom");
2839 // The availability of TeX fonts depends on the font encoding
2841 updateFontOptions();
2845 void GuiDocument::updateMathFonts(QString const & rm)
2847 if (fontModule->osFontsCB->isChecked())
2849 QString const math =
2850 fontModule->fontsMathCO->itemData(fontModule->fontsMathCO->currentIndex()).toString();
2851 int const i = fontModule->fontsMathCO->findData("default");
2852 if (providesNoMath(rm) && i == -1)
2853 fontModule->fontsMathCO->insertItem(1, qt_("Class Default"), QString("default"));
2854 else if (!providesNoMath(rm) && i != -1) {
2855 int const c = fontModule->fontsMathCO->currentIndex();
2856 fontModule->fontsMathCO->removeItem(i);
2858 fontModule->fontsMathCO->setCurrentIndex(0);
2863 void GuiDocument::romanChanged(int item)
2865 QString const font = fontModule->fontsRomanCO->getData(item);
2866 fontModule->fontOsfCB->setEnabled(providesOSF(font));
2868 if (fontModule->osFontsCB->isChecked())
2870 fontModule->fontScCB->setEnabled(providesSC(font));
2871 updateMathFonts(font);
2875 void GuiDocument::sansChanged(int item)
2877 QString const font = fontModule->fontsSansCO->getData(item);
2878 bool const scalable = providesScale(font);
2879 fontModule->scaleSansSB->setEnabled(scalable);
2880 fontModule->scaleSansLA->setEnabled(scalable);
2881 fontModule->fontSansOsfCB->setEnabled(providesOSF(font));
2886 void GuiDocument::ttChanged(int item)
2888 QString const font = fontModule->fontsTypewriterCO->getData(item);
2889 bool scalable = providesScale(font);
2890 fontModule->scaleTypewriterSB->setEnabled(scalable);
2891 fontModule->scaleTypewriterLA->setEnabled(scalable);
2892 fontModule->fontTypewriterOsfCB->setEnabled(providesOSF(font));
2897 void GuiDocument::updatePagestyle(string const & items, string const & sel)
2900 pageLayoutModule->pagestyleCO->clear();
2901 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
2903 for (int n = 0; !token(items, '|', n).empty(); ++n) {
2904 string style = token(items, '|', n);
2905 QString style_gui = qt_(style);
2906 pagestyles.push_back(pair<string, QString>(style, style_gui));
2907 pageLayoutModule->pagestyleCO->addItem(style_gui);
2910 if (sel == "default") {
2911 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
2917 for (auto const & pagestyle : pagestyles)
2918 if (pagestyle.first == sel)
2919 nn = pageLayoutModule->pagestyleCO->findText(pagestyle.second);
2922 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
2926 void GuiDocument::browseLayout()
2928 QString const label1 = qt_("Lay&outs");
2929 QString const dir1 = toqstr(lyxrc.document_path);
2930 QStringList const filter(qt_("LyX Layout (*.layout)"));
2931 QString file = browseRelToParent(QString(), bufferFilePath(),
2932 qt_("Local layout file"), filter, false,
2935 if (!file.endsWith(".layout"))
2938 FileName layoutFile = support::makeAbsPath(fromqstr(file),
2939 fromqstr(bufferFilePath()));
2941 int const ret = Alert::prompt(_("Local layout file"),
2942 _("The layout file you have selected is a local layout\n"
2943 "file, not one in the system or user directory.\n"
2944 "Your document will not work with this layout if you\n"
2945 "move the layout file to a different directory."),
2946 1, 1, _("&Set Layout"), _("&Cancel"));
2950 // load the layout file
2951 LayoutFileList & bcl = LayoutFileList::get();
2952 string classname = layoutFile.onlyFileName();
2953 // this will update an existing layout if that layout has been loaded before.
2954 LayoutFileIndex name = support::onlyFileName(bcl.addLocalLayout(
2955 classname.substr(0, classname.size() - 7),
2956 layoutFile.onlyPath().absFileName()));
2959 Alert::error(_("Error"),
2960 _("Unable to read local layout file."));
2964 const_cast<Buffer &>(buffer()).setLayoutPos(layoutFile.onlyPath().absFileName());
2966 // do not trigger classChanged if there is no change.
2967 if (latexModule->classCO->currentText() == toqstr(name))
2971 bool const avail = latexModule->classCO->set(toqstr(name));
2973 LayoutFile const & tc = bcl[name];
2974 docstring const guiname = translateIfPossible(from_utf8(tc.description()));
2975 // tooltip sensu "KOMA-Script Article [Class 'scrartcl']"
2976 QString tooltip = toqstr(bformat(_("%1$s [Class '%2$s']"), guiname, from_utf8(tc.latexname())));
2977 tooltip += '\n' + qt_("This is a local layout file.");
2978 latexModule->classCO->addItemSort(toqstr(tc.name()), toqstr(guiname),
2979 toqstr(translateIfPossible(from_utf8(tc.category()))),
2981 true, true, true, true);
2982 latexModule->classCO->set(toqstr(name));
2989 void GuiDocument::browseMaster()
2991 QString const title = qt_("Select master document");
2992 QString const dir1 = toqstr(lyxrc.document_path);
2993 QString const old = latexModule->childDocLE->text();
2994 QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
2995 QStringList const filter(qt_("LyX Files (*.lyx)"));
2996 QString file = browseRelToSub(old, docpath, title, filter, false,
2997 qt_("D&ocuments"), toqstr(lyxrc.document_path));
2999 if (!file.isEmpty())
3000 latexModule->childDocLE->setText(file);
3004 void GuiDocument::classChanged_adaptor()
3006 const_cast<Buffer &>(buffer()).setLayoutPos(string());
3011 void GuiDocument::classChanged()
3013 int idx = latexModule->classCO->currentIndex();
3016 string const classname = fromqstr(latexModule->classCO->getData(idx));
3018 if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
3019 int const ret = Alert::prompt(_("Unapplied changes"),
3020 _("Some changes in the dialog were not yet applied.\n"
3021 "If you do not apply now, they will be lost after this action."),
3022 1, 1, _("&Apply"), _("&Dismiss"));
3027 // We load the TextClass as soon as it is selected. This is
3028 // necessary so that other options in the dialog can be updated
3029 // according to the new class. Note, however, that, if you use
3030 // the scroll wheel when sitting on the combo box, we'll load a
3031 // lot of TextClass objects very quickly....
3032 if (!bp_.setBaseClass(classname, buffer().layoutPos())) {
3033 Alert::error(_("Error"), _("Unable to set document class."));
3036 if (lyxrc.auto_reset_options)
3037 bp_.useClassDefaults();
3039 // With the introduction of modules came a distinction between the base
3040 // class and the document class. The former corresponds to the main layout
3041 // file; the latter is that plus the modules (or the document-specific layout,
3042 // or whatever else there could be). Our parameters come from the document
3043 // class. So when we set the base class, we also need to recreate the document
3044 // class. Otherwise, we still have the old one.
3045 bp_.makeDocumentClass();
3050 void GuiDocument::languagePackageChanged(int i)
3052 langModule->languagePackageLE->setEnabled(
3053 langModule->languagePackageCO->itemData(i).toString() == "custom");
3057 void GuiDocument::biblioChanged()
3059 biblioChanged_ = true;
3064 void GuiDocument::checkPossibleCiteEngines()
3066 // Check if the class provides a specific engine,
3067 // and if so, enforce this.
3068 string force_engine;
3069 if (documentClass().provides("natbib")
3070 || documentClass().provides("natbib-internal"))
3071 force_engine = "natbib";
3072 else if (documentClass().provides("jurabib"))
3073 force_engine = "jurabib";
3074 else if (documentClass().provides("biblatex"))
3075 force_engine = "biblatex";
3076 else if (documentClass().provides("biblatex-natbib"))
3077 force_engine = "biblatex-natbib";
3079 if (!force_engine.empty())
3080 biblioModule->citeEngineCO->setCurrentIndex(
3081 biblioModule->citeEngineCO->findData(toqstr(force_engine)));
3082 biblioModule->citeEngineCO->setEnabled(force_engine.empty());
3086 void GuiDocument::rescanBibFiles()
3089 rescanTexStyles("bbx cbx");
3091 rescanTexStyles("bst");
3095 void GuiDocument::resetDefaultBibfile(string const & which)
3097 QString const engine =
3098 biblioModule->citeEngineCO->itemData(
3099 biblioModule->citeEngineCO->currentIndex()).toString();
3101 CiteEngineType const cet =
3102 CiteEngineType(biblioModule->citeStyleCO->itemData(
3103 biblioModule->citeStyleCO->currentIndex()).toInt());
3105 updateDefaultBiblio(theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet), which);
3109 void GuiDocument::resetDefaultBbxBibfile()
3111 resetDefaultBibfile("bbx");
3115 void GuiDocument::resetDefaultCbxBibfile()
3117 resetDefaultBibfile("cbx");
3121 void GuiDocument::citeEngineChanged(int n)
3123 QString const engine =
3124 biblioModule->citeEngineCO->itemData(n).toString();
3126 vector<string> const engs =
3127 theCiteEnginesList[fromqstr(engine)]->getEngineType();
3129 updateCiteStyles(engs);
3130 updateEngineDependends();
3131 resetDefaultBibfile();
3136 void GuiDocument::updateEngineDependends()
3138 bool const biblatex = isBiblatex();
3140 // These are only useful with BibTeX
3141 biblioModule->defaultBiblioCO->setEnabled(!biblatex);
3142 biblioModule->bibtexStyleLA->setEnabled(!biblatex);
3143 biblioModule->resetDefaultBiblioPB->setEnabled(!biblatex);
3144 biblioModule->bibtopicCB->setEnabled(!biblatex);
3146 // These are only useful with Biblatex
3147 biblioModule->biblatexBbxCO->setEnabled(biblatex);
3148 biblioModule->biblatexBbxLA->setEnabled(biblatex);
3149 biblioModule->biblatexCbxCO->setEnabled(biblatex);
3150 biblioModule->biblatexCbxLA->setEnabled(biblatex);
3151 biblioModule->resetBbxPB->setEnabled(biblatex);
3152 biblioModule->resetCbxPB->setEnabled(biblatex);
3153 biblioModule->matchBbxPB->setEnabled(biblatex);
3155 // These are useful with biblatex, jurabib and natbib
3156 QString const engine =
3157 biblioModule->citeEngineCO->itemData(
3158 biblioModule->citeEngineCO->currentIndex()).toString();
3159 LyXCiteEngine const * ce = theCiteEnginesList[fromqstr(engine)];
3161 bool const citepack = ce->required("biblatex.sty") || ce->required("jurabib.sty")
3162 || ce->required("natbib.sty");
3163 biblioModule->citePackageOptionsLE->setEnabled(citepack);
3164 biblioModule->citePackageOptionsL->setEnabled(citepack);
3168 void GuiDocument::citeStyleChanged()
3170 QString const engine =
3171 biblioModule->citeEngineCO->itemData(
3172 biblioModule->citeEngineCO->currentIndex()).toString();
3173 QString const currentDef = isBiblatex() ?
3174 biblioModule->biblatexBbxCO->currentText()
3175 : biblioModule->defaultBiblioCO->currentText();
3176 if (theCiteEnginesList[fromqstr(engine)]->isDefaultBiblio(fromqstr(currentDef)))
3177 resetDefaultBibfile();
3183 void GuiDocument::bibtexChanged(int n)
3185 biblioModule->bibtexOptionsLE->setEnabled(
3186 biblioModule->bibtexCO->itemData(n).toString() != "default");
3191 void GuiDocument::updateCiteStyles(vector<string> const & engs, CiteEngineType const & sel)
3193 biblioModule->citeStyleCO->clear();
3195 vector<string>::const_iterator it = engs.begin();
3196 vector<string>::const_iterator end = engs.end();
3197 for (; it != end; ++it) {
3198 if (*it == "default")
3199 biblioModule->citeStyleCO->addItem(qt_("Basic numerical"),
3200 ENGINE_TYPE_DEFAULT);
3201 else if (*it == "authoryear")
3202 biblioModule->citeStyleCO->addItem(qt_("Author-year"),
3203 ENGINE_TYPE_AUTHORYEAR);
3204 else if (*it == "numerical")
3205 biblioModule->citeStyleCO->addItem(qt_("Author-number"),
3206 ENGINE_TYPE_NUMERICAL);
3208 int i = biblioModule->citeStyleCO->findData(sel);
3209 if (biblioModule->citeStyleCO->findData(sel) == -1)
3211 biblioModule->citeStyleCO->setCurrentIndex(i);
3213 biblioModule->citationStyleL->setEnabled(engs.size() > 1);
3214 biblioModule->citeStyleCO->setEnabled(engs.size() > 1);
3218 void GuiDocument::updateEngineType(string const & items, CiteEngineType const & sel)
3220 engine_types_.clear();
3222 for (int n = 0; !token(items, '|', n).empty(); ++n) {
3223 string style = token(items, '|', n);
3224 engine_types_.push_back(style);
3227 updateCiteStyles(engine_types_, sel);
3233 // both of these should take a vector<docstring>
3235 // This is an insanely complicated attempt to make this sort of thing
3236 // work with RTL languages.
3237 docstring formatStrVec(vector<string> const & v, docstring const & s)
3239 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
3243 return translateIfPossible(from_utf8(v[0]));
3244 if (v.size() == 2) {
3245 docstring retval = _("%1$s and %2$s");
3246 retval = subst(retval, _("and"), s);
3247 return bformat(retval, translateIfPossible(from_utf8(v[0])),
3248 translateIfPossible(from_utf8(v[1])));
3250 // The idea here is to format all but the last two items...
3251 int const vSize = v.size();
3252 docstring t2 = _("%1$s, %2$s");
3253 docstring retval = translateIfPossible(from_utf8(v[0]));
3254 for (int i = 1; i < vSize - 2; ++i)
3255 retval = bformat(t2, retval, translateIfPossible(from_utf8(v[i])));
3256 //...and then to plug them, and the last two, into this schema
3257 docstring t = _("%1$s, %2$s, and %3$s");
3258 t = subst(t, _("and"), s);
3259 return bformat(t, retval, translateIfPossible(from_utf8(v[vSize - 2])),
3260 translateIfPossible(from_utf8(v[vSize - 1])));
3263 vector<string> idsToNames(vector<string> const & idList)
3265 vector<string> retval;
3266 vector<string>::const_iterator it = idList.begin();
3267 vector<string>::const_iterator end = idList.end();
3268 for (; it != end; ++it) {
3269 LyXModule const * const mod = theModuleList[*it];
3271 retval.push_back(to_utf8(bformat(_("%1$s (unavailable)"),
3272 translateIfPossible(from_utf8(*it)))));
3274 retval.push_back(mod->getName());
3278 } // end anonymous namespace
3281 void GuiDocument::modulesToParams(BufferParams & bp)
3283 // update list of loaded modules
3284 bp.clearLayoutModules();
3285 int const srows = modules_sel_model_.rowCount();
3286 for (int i = 0; i < srows; ++i)
3287 bp.addLayoutModule(modules_sel_model_.getIDString(i));
3288 updateSelectedModules();
3290 // update the list of removed modules
3291 bp.clearRemovedModules();
3292 LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
3293 list<string>::const_iterator rit = reqmods.begin();
3294 list<string>::const_iterator ren = reqmods.end();
3296 // check each of the default modules
3297 for (; rit != ren; ++rit) {
3298 list<string>::const_iterator mit = bp.getModules().begin();
3299 list<string>::const_iterator men = bp.getModules().end();
3301 for (; mit != men; ++mit) {
3308 // the module isn't present so must have been removed by the user
3309 bp.addRemovedModule(*rit);
3314 void GuiDocument::modulesChanged()
3316 modulesToParams(bp_);
3318 if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()
3319 && (nonModuleChanged_ || shellescapeChanged_)) {
3320 int const ret = Alert::prompt(_("Unapplied changes"),
3321 _("Some changes in the dialog were not yet applied.\n"
3322 "If you do not apply now, they will be lost after this action."),
3323 1, 1, _("&Apply"), _("&Dismiss"));
3328 modulesChanged_ = true;
3329 bp_.makeDocumentClass();
3335 void GuiDocument::updateModuleInfo()
3337 selectionManager->update();
3339 //Module description
3340 bool const focus_on_selected = selectionManager->selectedFocused();
3341 QAbstractItemView * lv;
3342 bool category = false;
3343 if (focus_on_selected) {
3344 lv = modulesModule->selectedLV;
3347 lv = modulesModule->availableLV;
3348 if (lv->selectionModel()->selectedIndexes().isEmpty()) {
3349 modulesModule->infoML->document()->clear();
3352 QModelIndex const & idx = lv->selectionModel()->currentIndex();
3357 if (!focus_on_selected
3358 && modules_av_model_.itemFromIndex(idx)->hasChildren()) {
3359 // This is a category header
3360 modulesModule->infoML->document()->clear();
3364 string const modName = focus_on_selected ?
3365 modules_sel_model_.getIDString(idx.row())
3366 : fromqstr(modules_av_model_.data(idx, Qt::UserRole).toString());
3367 docstring desc = getModuleDescription(modName);
3369 LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
3370 if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
3373 desc += _("Module provided by document class.");
3377 docstring cat = getModuleCategory(modName);
3381 desc += bformat(_("<p><b>Category:</b> %1$s.</p>"),
3382 translateIfPossible(cat));
3386 vector<string> pkglist = getPackageList(modName);
3387 docstring pkgdesc = formatStrVec(pkglist, _("and"));
3388 if (!pkgdesc.empty()) {
3391 desc += bformat(_("<p><b>Package(s) required:</b> %1$s.</p>"), pkgdesc);
3394 pkglist = getRequiredList(modName);
3395 if (!pkglist.empty()) {
3396 vector<string> const reqdescs = idsToNames(pkglist);
3397 pkgdesc = formatStrVec(reqdescs, _("or"));
3400 desc += bformat(_("<p><b>Modules required:</b> %1$s.</p>"), pkgdesc);
3403 pkglist = getExcludedList(modName);
3404 if (!pkglist.empty()) {
3405 vector<string> const reqdescs = idsToNames(pkglist);
3406 pkgdesc = formatStrVec(reqdescs, _( "and"));
3409 desc += bformat(_("<p><b>Modules excluded:</b> %1$s.</p>"), pkgdesc);
3414 desc += bformat(_("<p><b>Filename:</b> <tt>%1$s.module</tt>.</p>"), from_utf8(modName));
3416 if (!isModuleAvailable(modName)) {
3419 desc += _("<p><font color=red><b>WARNING: Some required packages are unavailable!</b></font></p>");
3422 modulesModule->infoML->document()->setHtml(toqstr(desc));
3426 void GuiDocument::updateNumbering()
3428 DocumentClass const & tclass = documentClass();
3430 numberingModule->tocTW->setUpdatesEnabled(false);
3431 numberingModule->tocTW->clear();
3433 int const depth = numberingModule->depthSL->value();
3434 int const toc = numberingModule->tocSL->value();
3435 QString const no = qt_("No");
3436 QString const yes = qt_("Yes");
3437 QTreeWidgetItem * item = nullptr;
3439 DocumentClass::const_iterator lit = tclass.begin();
3440 DocumentClass::const_iterator len = tclass.end();
3441 for (; lit != len; ++lit) {
3442 int const toclevel = lit->toclevel;
3443 if (toclevel != Layout::NOT_IN_TOC && !lit->counter.empty()) {
3444 item = new QTreeWidgetItem(numberingModule->tocTW);
3445 item->setText(0, toqstr(translateIfPossible(lit->name())));
3446 item->setText(1, (toclevel <= depth) ? yes : no);
3447 item->setText(2, (toclevel <= toc) ? yes : no);
3451 numberingModule->tocTW->setUpdatesEnabled(true);
3452 numberingModule->tocTW->update();
3456 void GuiDocument::getTableStyles()
3458 // We look for lyx files in the subdirectory dir of
3460 // 2) build_lyxdir (if not empty)
3462 // in this order. Files with a given sub-hierarchy will
3463 // only be listed once.
3464 // We also consider i18n subdirectories and store them separately.
3467 // The three locations to look at.
3468 string const user = addPath(package().user_support().absFileName(), "tabletemplates");
3469 string const build = addPath(package().build_support().absFileName(), "tabletemplates");
3470 string const system = addPath(package().system_support().absFileName(), "tabletemplates");
3472 dirs << toqstr(user)
3476 for (int i = 0; i < dirs.size(); ++i) {
3477 QString const & dir = dirs.at(i);
3478 QDirIterator it(dir, QDir::Files, QDirIterator::Subdirectories);
3479 while (it.hasNext()) {
3480 QString fn = QFileInfo(it.next()).fileName();
3481 if (!fn.endsWith(".lyx") || fn.contains("_1x"))
3483 QString data = fn.left(fn.lastIndexOf(".lyx"));
3484 QString guiname = data;
3485 guiname = toqstr(translateIfPossible(qstring_to_ucs4(guiname.replace('_', ' '))));
3486 QString relpath = toqstr(makeRelPath(qstring_to_ucs4(fn),
3487 qstring_to_ucs4(dir)));
3488 if (textLayoutModule->tableStyleCO->findData(data) == -1)
3489 textLayoutModule->tableStyleCO->addItem(guiname, data);
3495 void GuiDocument::updateDefaultFormat()
3499 // make a copy in order to consider unapplied changes
3500 BufferParams param_copy = buffer().params();
3501 param_copy.useNonTeXFonts = fontModule->osFontsCB->isChecked();
3502 int const idx = latexModule->classCO->currentIndex();
3504 string const classname = fromqstr(latexModule->classCO->getData(idx));
3505 param_copy.setBaseClass(classname, buffer().layoutPos());
3506 param_copy.makeDocumentClass(true);
3508 outputModule->defaultFormatCO->blockSignals(true);
3509 outputModule->defaultFormatCO->clear();
3510 outputModule->defaultFormatCO->addItem(qt_("Default"),
3511 QVariant(QString("default")));
3512 FormatList const & formats =
3513 param_copy.exportableFormats(true);
3514 for (Format const * f : formats)
3515 outputModule->defaultFormatCO->addItem
3516 (toqstr(translateIfPossible(f->prettyname())),
3517 QVariant(toqstr(f->name())));
3518 outputModule->defaultFormatCO->blockSignals(false);
3522 bool GuiDocument::isChildIncluded(string const & child)
3524 if (includeonlys_.empty())
3526 return (std::find(includeonlys_.begin(),
3527 includeonlys_.end(), child) != includeonlys_.end());
3531 void GuiDocument::applyView()
3533 // auto-validate local layout
3534 if (!localLayout->isValid()) {
3535 localLayout->validate();
3536 if (!localLayout->isValid()) {
3537 setApplyStopped(true);
3538 docPS->setCurrentPanel(N_("Local Layout"));
3544 preambleModule->apply(bp_);
3545 localLayout->apply(bp_);
3548 bp_.suppress_date = latexModule->suppressDateCB->isChecked();
3549 bp_.use_refstyle = latexModule->refstyleCB->isChecked();
3550 bp_.use_formatted_ref = latexModule->refFormattedCB->isChecked();
3553 string const engine =
3554 fromqstr(biblioModule->citeEngineCO->itemData(
3555 biblioModule->citeEngineCO->currentIndex()).toString());
3556 bp_.setCiteEngine(engine);
3558 CiteEngineType const style = CiteEngineType(biblioModule->citeStyleCO->itemData(
3559 biblioModule->citeStyleCO->currentIndex()).toInt());
3560 if (theCiteEnginesList[engine]->hasEngineType(style))
3561 bp_.setCiteEngineType(style);
3563 bp_.setCiteEngineType(ENGINE_TYPE_DEFAULT);
3565 bp_.splitbib(biblioModule->bibtopicCB->isChecked());
3567 bp_.multibib = fromqstr(biblioModule->bibunitsCO->itemData(
3568 biblioModule->bibunitsCO->currentIndex()).toString());
3570 bp_.setDefaultBiblioStyle(fromqstr(biblioModule->defaultBiblioCO->currentText()));
3572 bp_.biblatex_bibstyle = fromqstr(biblioModule->biblatexBbxCO->currentText());
3573 bp_.biblatex_citestyle = fromqstr(biblioModule->biblatexCbxCO->currentText());
3574 bp_.biblio_opts = fromqstr(biblioModule->citePackageOptionsLE->text());
3576 string const bibtex_command =
3577 fromqstr(biblioModule->bibtexCO->itemData(
3578 biblioModule->bibtexCO->currentIndex()).toString());
3579 string const bibtex_options =
3580 fromqstr(biblioModule->bibtexOptionsLE->text());
3581 if (bibtex_command == "default" || bibtex_options.empty())
3582 bp_.bibtex_command = bibtex_command;
3584 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
3586 if (biblioChanged_) {
3587 buffer().invalidateBibinfoCache();
3588 buffer().removeBiblioTempFiles();
3592 indicesModule->apply(bp_);
3594 // language & quotes
3595 switch (langModule->encodingCO->currentIndex()) {
3596 case EncodingSets::unicode: {
3597 if (!fontModule->osFontsCB->isChecked())
3598 bp_.inputenc = fromqstr(langModule->unicodeEncodingCO->itemData(
3599 langModule->unicodeEncodingCO->currentIndex()).toString());
3602 case EncodingSets::legacy: {
3603 bp_.inputenc = "auto-legacy";
3604 bp_.inputenc = fromqstr(langModule->autoEncodingCO->itemData(
3605 langModule->autoEncodingCO->currentIndex()).toString());
3608 case EncodingSets::custom: {
3609 bp_.inputenc = fromqstr(langModule->customEncodingCO->itemData(
3610 langModule->customEncodingCO->currentIndex()).toString());
3614 // this should never happen
3615 bp_.inputenc = "utf8";
3617 bp_.quotes_style = QuoteStyle(langModule->quoteStyleCO->itemData(
3618 langModule->quoteStyleCO->currentIndex()).toInt());
3619 bp_.dynamic_quotes = langModule->dynamicQuotesCB->isChecked();
3621 QString const langname = langModule->languageCO->itemData(
3622 langModule->languageCO->currentIndex()).toString();
3623 Language const * newlang = lyx::languages.getLanguage(fromqstr(langname));
3624 Cursor & cur = const_cast<BufferView *>(bufferview())->cursor();
3625 // If current cursor language was the document language, then update it too.
3626 if (cur.current_font.language() == bp_.language) {
3627 cur.current_font.setLanguage(newlang);
3628 cur.real_current_font.setLanguage(newlang);
3630 bp_.language = newlang;
3632 QString const pack = langModule->languagePackageCO->itemData(
3633 langModule->languagePackageCO->currentIndex()).toString();
3634 if (pack == "custom")
3636 fromqstr(langModule->languagePackageLE->text());
3638 bp_.lang_package = fromqstr(pack);
3641 bp_.backgroundcolor = set_backgroundcolor;
3642 bp_.isbackgroundcolor = is_backgroundcolor;
3643 bp_.fontcolor = set_fontcolor;
3644 bp_.isfontcolor = is_fontcolor;
3645 bp_.notefontcolor = set_notefontcolor;
3646 bp_.isnotefontcolor = is_notefontcolor;
3647 if (is_notefontcolor) {
3648 // Set information used in statusbar (#12130)
3649 lcolor.setColor("notefontcolor", lyx::X11hexname(set_notefontcolor));
3650 lcolor.setGUIName("notefontcolor", N_("greyedout inset text"));
3652 bp_.boxbgcolor = set_boxbgcolor;
3653 bp_.isboxbgcolor = is_boxbgcolor;
3656 if (bp_.documentClass().hasTocLevels()) {
3657 bp_.tocdepth = numberingModule->tocSL->value();
3658 bp_.secnumdepth = numberingModule->depthSL->value();
3660 bp_.use_lineno = numberingModule->linenoCB->isChecked();
3661 bp_.lineno_opts = fromqstr(numberingModule->linenoLE->text());
3664 bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
3665 bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
3666 bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
3667 bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
3670 bp_.graphics_driver =
3671 tex_graphics[latexModule->psdriverCO->currentIndex()];
3674 int idx = latexModule->classCO->currentIndex();
3676 string const classname = fromqstr(latexModule->classCO->getData(idx));
3677 bp_.setBaseClass(classname, buffer().layoutPos());
3681 modulesToParams(bp_);
3684 map<string, string> const & packages = BufferParams::auto_packages();
3685 for (map<string, string>::const_iterator it = packages.begin();
3686 it != packages.end(); ++it) {
3687 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
3690 int row = mathsModule->packagesTW->row(item);
3693 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1)->layout()->itemAt(0)->widget();
3694 if (rb->isChecked()) {
3695 bp_.use_package(it->first, BufferParams::package_auto);
3698 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2)->layout()->itemAt(0)->widget();
3699 if (rb->isChecked()) {
3700 bp_.use_package(it->first, BufferParams::package_on);
3703 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3)->layout()->itemAt(0)->widget();
3704 if (rb->isChecked())
3705 bp_.use_package(it->first, BufferParams::package_off);
3707 // if math is indented
3708 bp_.is_math_indent = mathsModule->MathIndentCB->isChecked();
3709 if (bp_.is_math_indent) {
3710 // if formulas are indented
3711 if (mathsModule->MathIndentCO->itemData(mathsModule->MathIndentCO->currentIndex()) == "custom") {
3712 Length mathindent(widgetsToLength(mathsModule->MathIndentLE,
3713 mathsModule->MathIndentLengthCO));
3714 bp_.setMathIndent(mathindent);
3717 bp_.setMathIndent(Length());
3719 switch (mathsModule->MathNumberingPosCO->currentIndex()) {
3721 bp_.math_numbering_side = BufferParams::LEFT;
3724 bp_.math_numbering_side = BufferParams::DEFAULT;
3727 bp_.math_numbering_side = BufferParams::RIGHT;
3730 // this should never happen
3731 bp_.math_numbering_side = BufferParams::DEFAULT;
3736 if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
3737 bp_.pagestyle = "default";
3739 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
3740 for (size_t i = 0; i != pagestyles.size(); ++i)
3741 if (pagestyles[i].second == style_gui)
3742 bp_.pagestyle = pagestyles[i].first;
3746 switch (textLayoutModule->lspacingCO->currentIndex()) {
3748 bp_.spacing().set(Spacing::Single);
3751 bp_.spacing().set(Spacing::Onehalf);
3754 bp_.spacing().set(Spacing::Double);
3757 string s = widgetToDoubleStr(textLayoutModule->lspacingLE);
3759 bp_.spacing().set(Spacing::Single);
3761 bp_.spacing().set(Spacing::Other, s);
3766 if (textLayoutModule->twoColumnCB->isChecked())
3771 bp_.justification = textLayoutModule->justCB->isChecked();
3773 if (textLayoutModule->indentRB->isChecked()) {
3774 // if paragraphs are separated by an indentation
3775 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
3776 if (textLayoutModule->indentCO->itemData(textLayoutModule->indentCO->currentIndex()) == "custom") {
3777 Length parindent(widgetsToLength(textLayoutModule->indentLE,
3778 textLayoutModule->indentLengthCO));
3779 bp_.setParIndent(parindent);
3782 bp_.setParIndent(Length());
3784 // if paragraphs are separated by a skip
3785 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
3786 VSpace::VSpaceKind spacekind =
3787 VSpace::VSpaceKind(textLayoutModule->skipCO->itemData(textLayoutModule->skipCO->currentIndex()).toInt());
3788 switch (spacekind) {
3789 case VSpace::SMALLSKIP:
3790 case VSpace::MEDSKIP:
3791 case VSpace::BIGSKIP:
3792 case VSpace::HALFLINE:
3793 case VSpace::FULLLINE:
3794 bp_.setDefSkip(VSpace(spacekind));
3796 case VSpace::LENGTH: {
3798 widgetsToLength(textLayoutModule->skipLE,
3799 textLayoutModule->skipLengthCO)
3805 // this should never happen
3806 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
3810 bp_.tablestyle = fromqstr(textLayoutModule->tableStyleCO->itemData(
3811 textLayoutModule->tableStyleCO->currentIndex()).toString());
3814 fromqstr(latexModule->optionsLE->text());
3816 bp_.use_default_options =
3817 latexModule->defaultOptionsCB->isChecked();
3819 if (latexModule->childDocGB->isChecked())
3821 fromqstr(latexModule->childDocLE->text());
3823 bp_.master = string();
3826 bp_.clearIncludedChildren();
3827 updateIncludeonlys();
3828 if (masterChildModule->includeonlyRB->isChecked()) {
3829 list<string>::const_iterator it = includeonlys_.begin();
3830 for (; it != includeonlys_.end() ; ++it) {
3831 bp_.addIncludedChildren(*it);
3834 if (masterChildModule->maintainCRNoneRB->isChecked())
3835 bp_.maintain_unincluded_children =
3836 BufferParams::CM_None;
3837 else if (masterChildModule->maintainCRMostlyRB->isChecked())
3838 bp_.maintain_unincluded_children =
3839 BufferParams::CM_Mostly;
3841 bp_.maintain_unincluded_children =
3842 BufferParams::CM_Strict;
3843 updateIncludeonlyDisplay();
3846 bp_.float_placement = floatModule->getPlacement();
3847 bp_.float_alignment = floatModule->getAlignment();
3850 // text should have passed validation
3851 idx = listingsModule->packageCO->currentIndex();
3852 bp_.use_minted = string(lst_packages[idx]) == "Minted";
3853 bp_.listings_params =
3854 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
3857 bp_.default_output_format = fromqstr(outputModule->defaultFormatCO->itemData(
3858 outputModule->defaultFormatCO->currentIndex()).toString());
3860 bool const nontexfonts = fontModule->osFontsCB->isChecked();
3861 bp_.useNonTeXFonts = nontexfonts;
3863 bp_.shell_escape = outputModule->shellescapeCB->isChecked();
3864 if (!bp_.shell_escape)
3865 theSession().shellescapeFiles().remove(buffer().absFileName());
3866 else if (!theSession().shellescapeFiles().find(buffer().absFileName()))
3867 theSession().shellescapeFiles().insert(buffer().absFileName());
3868 Buffer & buf = const_cast<Buffer &>(buffer());
3869 buf.params().shell_escape = bp_.shell_escape;
3871 bp_.output_sync = outputModule->outputsyncCB->isChecked();
3873 bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
3875 int mathfmt = outputModule->mathoutCB->currentIndex();
3878 BufferParams::MathOutput const mo =
3879 static_cast<BufferParams::MathOutput>(mathfmt);
3880 bp_.html_math_output = mo;
3881 bp_.html_be_strict = outputModule->strictCB->isChecked();
3882 bp_.html_css_as_file = outputModule->cssCB->isChecked();
3883 bp_.html_math_img_scale = outputModule->mathimgSB->value();
3884 bp_.display_pixel_ratio = theGuiApp()->pixelRatio();
3886 int tablefmt = outputModule->tableoutCB->currentIndex();
3889 auto const to = static_cast<BufferParams::TableOutput>(tablefmt);
3890 bp_.docbook_table_output = to;
3892 int mathmlprefix = outputModule->mathmlprefixCB->currentIndex();
3893 if (mathmlprefix == -1)
3895 auto const mp = static_cast<BufferParams::MathMLNameSpacePrefix>(mathmlprefix);
3896 bp_.docbook_mathml_prefix = mp;
3898 bp_.save_transient_properties =
3899 outputModule->saveTransientPropertiesCB->isChecked();
3900 bp_.postpone_fragile_content =
3901 outputModule->postponeFragileCB->isChecked();
3904 bp_.fonts_roman[nontexfonts] =
3905 fromqstr(fontModule->fontsRomanCO->
3906 getData(fontModule->fontsRomanCO->currentIndex()));
3907 bp_.fonts_roman[!nontexfonts] = fromqstr(fontModule->font_roman);
3908 bp_.font_roman_opts = fromqstr(fontModule->fontspecRomanLE->text());
3910 bp_.fonts_sans[nontexfonts] =
3911 fromqstr(fontModule->fontsSansCO->
3912 getData(fontModule->fontsSansCO->currentIndex()));
3913 bp_.fonts_sans[!nontexfonts] = fromqstr(fontModule->font_sans);
3914 bp_.font_sans_opts = fromqstr(fontModule->fontspecSansLE->text());
3916 bp_.fonts_typewriter[nontexfonts] =
3917 fromqstr(fontModule->fontsTypewriterCO->
3918 getData(fontModule->fontsTypewriterCO->currentIndex()));
3919 bp_.fonts_typewriter[!nontexfonts] = fromqstr(fontModule->font_typewriter);
3920 bp_.font_typewriter_opts = fromqstr(fontModule->fontspecTypewriterLE->text());
3922 bp_.fonts_math[nontexfonts] =
3923 fromqstr(fontModule->fontsMathCO->
3924 itemData(fontModule->fontsMathCO->currentIndex()).toString());
3925 bp_.fonts_math[!nontexfonts] = fromqstr(fontModule->font_math);
3927 QString const fontenc =
3928 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
3929 if (fontenc == "custom")
3930 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
3932 bp_.fontenc = fromqstr(fontenc);
3935 fromqstr(fontModule->cjkFontLE->text());
3937 bp_.use_microtype = fontModule->microtypeCB->isChecked();
3938 bp_.use_dash_ligatures = !fontModule->dashesCB->isChecked();
3940 bp_.fonts_sans_scale[nontexfonts] = fontModule->scaleSansSB->value();
3941 bp_.fonts_sans_scale[!nontexfonts] = fontModule->font_sf_scale;
3943 bp_.fonts_typewriter_scale[nontexfonts] = fontModule->scaleTypewriterSB->value();
3944 bp_.fonts_typewriter_scale[!nontexfonts] = fontModule->font_tt_scale;
3946 bp_.fonts_expert_sc = fontModule->fontScCB->isChecked();
3948 bp_.fonts_roman_osf = fontModule->fontOsfCB->isChecked();
3949 bp_.fonts_sans_osf = fontModule->fontSansOsfCB->isChecked();
3950 bp_.fonts_typewriter_osf = fontModule->fontTypewriterOsfCB->isChecked();
3952 bp_.fonts_default_family = GuiDocument::fontfamilies[
3953 fontModule->fontsDefaultCO->currentIndex()];
3955 if (fontModule->fontsizeCO->currentIndex() == 0)
3956 bp_.fontsize = "default";
3959 fromqstr(fontModule->fontsizeCO->currentText());
3962 bp_.papersize = PAPER_SIZE(
3963 pageLayoutModule->papersizeCO->currentIndex());
3965 bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
3966 pageLayoutModule->paperwidthUnitCO);
3968 bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
3969 pageLayoutModule->paperheightUnitCO);
3971 if (pageLayoutModule->facingPagesCB->isChecked())
3972 bp_.sides = TwoSides;
3974 bp_.sides = OneSide;
3976 if (pageLayoutModule->landscapeRB->isChecked())
3977 bp_.orientation = ORIENTATION_LANDSCAPE;
3979 bp_.orientation = ORIENTATION_PORTRAIT;
3982 bp_.use_geometry = !marginsModule->marginCB->isChecked();
3984 Ui::MarginsUi const * m = marginsModule;
3986 bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
3987 bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
3988 bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
3989 bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
3990 bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
3991 bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
3992 bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
3993 bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
3996 branchesModule->apply(bp_);
3999 PDFOptions & pdf = bp_.pdfoptions();
4000 pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
4001 pdf.title = fromqstr(pdfSupportModule->titleLE->text());
4002 pdf.author = fromqstr(pdfSupportModule->authorLE->text());
4003 pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
4004 pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
4006 pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
4007 pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
4008 pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
4009 pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
4011 pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
4012 pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
4013 pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
4014 pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
4016 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
4017 if (pdfSupportModule->fullscreenCB->isChecked())
4018 pdf.pagemode = pdf.pagemode_fullscreen;
4020 pdf.pagemode.clear();
4021 pdf.quoted_options = pdf.quoted_options_check(
4022 fromqstr(pdfSupportModule->optionsTE->toPlainText()));
4023 bp_.document_metadata = qstring_to_ucs4(pdfSupportModule->metadataTE->toPlainText()
4024 .trimmed().replace(QRegularExpression("\n+"), "\n"));
4027 bp_.track_changes = changesModule->trackChangesCB->isChecked();
4028 bp_.output_changes = changesModule->outputChangesCB->isChecked();
4029 bool const cb_switched_off = (bp_.change_bars
4030 && !changesModule->changeBarsCB->isChecked());
4031 bp_.change_bars = changesModule->changeBarsCB->isChecked();
4032 if (cb_switched_off)
4033 // if change bars have been switched off,
4034 // we need to ditch the aux file
4035 buffer().requireFreshStart(true);
4038 nonModuleChanged_ = false;
4039 shellescapeChanged_ = false;
4043 void GuiDocument::paramsToDialog()
4045 // set the default unit
4046 Length::UNIT const default_unit = Length::defaultUnit();
4049 preambleModule->update(bp_, id());
4050 localLayout->update(bp_, id());
4053 latexModule->suppressDateCB->setChecked(bp_.suppress_date);
4054 latexModule->refstyleCB->setChecked(bp_.use_refstyle);
4055 latexModule->refFormattedCB->setChecked(bp_.use_formatted_ref);
4058 string const cite_engine = bp_.citeEngine();
4060 biblioModule->citeEngineCO->setCurrentIndex(
4061 biblioModule->citeEngineCO->findData(toqstr(cite_engine)));
4063 updateEngineType(documentClass().opt_enginetype(),
4064 bp_.citeEngineType());
4066 checkPossibleCiteEngines();
4068 biblioModule->citeStyleCO->setCurrentIndex(
4069 biblioModule->citeStyleCO->findData(bp_.citeEngineType()));
4071 biblioModule->bibtopicCB->setChecked(bp_.splitbib());
4073 biblioModule->bibunitsCO->clear();
4074 biblioModule->bibunitsCO->addItem(qt_("No"), QString());
4075 if (documentClass().hasLaTeXLayout("part"))
4076 biblioModule->bibunitsCO->addItem(qt_("per part"), toqstr("part"));
4077 if (documentClass().hasLaTeXLayout("chapter"))
4078 biblioModule->bibunitsCO->addItem(qt_("per chapter"), toqstr("chapter"));
4079 if (documentClass().hasLaTeXLayout("section"))
4080 biblioModule->bibunitsCO->addItem(qt_("per section"), toqstr("section"));
4081 if (documentClass().hasLaTeXLayout("subsection"))
4082 biblioModule->bibunitsCO->addItem(qt_("per subsection"), toqstr("subsection"));
4083 biblioModule->bibunitsCO->addItem(qt_("per child document"), toqstr("child"));
4085 int const mbpos = biblioModule->bibunitsCO->findData(toqstr(bp_.multibib));
4087 biblioModule->bibunitsCO->setCurrentIndex(mbpos);
4089 biblioModule->bibunitsCO->setCurrentIndex(0);
4091 updateEngineDependends();
4094 updateDefaultBiblio(bp_.biblatex_bibstyle, "bbx");
4095 updateDefaultBiblio(bp_.biblatex_citestyle, "cbx");
4097 updateDefaultBiblio(bp_.defaultBiblioStyle());
4099 biblioModule->citePackageOptionsLE->setText(toqstr(bp_.biblio_opts));
4103 split(bp_.bibtex_command, command, ' ');
4105 int bpos = biblioModule->bibtexCO->findData(toqstr(command));
4107 // We add and set the unknown compiler, indicating that it is unavailable
4108 // to assure document compilation and for security reasons, a fallback
4109 // will be used on document processing stage
4110 biblioModule->bibtexCO->addItem(toqstr(bformat(_("%1$s (not available)"),
4111 from_utf8(command))), toqstr(command));
4112 bpos = biblioModule->bibtexCO->findData(toqstr(command));
4114 biblioModule->bibtexCO->setCurrentIndex(bpos);
4115 biblioModule->bibtexOptionsLE->setText(toqstr(options).trimmed());
4116 biblioModule->bibtexOptionsLE->setEnabled(
4117 biblioModule->bibtexCO->currentIndex() != 0);
4119 biblioChanged_ = false;
4122 // We may be called when there is no Buffer, e.g., when
4123 // the last view has just been closed.
4124 bool const isReadOnly = isBufferAvailable() ? buffer().isReadonly() : false;
4125 indicesModule->update(bp_, isReadOnly);
4127 // language & quotes
4128 int const pos = langModule->languageCO->findData(toqstr(
4129 bp_.language->lang()));
4130 langModule->languageCO->setCurrentIndex(pos);
4132 updateQuoteStyles();
4134 langModule->quoteStyleCO->setCurrentIndex(
4135 langModule->quoteStyleCO->findData(static_cast<int>(bp_.quotes_style)));
4136 langModule->dynamicQuotesCB->setChecked(bp_.dynamic_quotes);
4138 // LaTeX input encoding: set after the fonts (see below)
4140 int p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
4142 langModule->languagePackageCO->setCurrentIndex(
4143 langModule->languagePackageCO->findData("custom"));
4144 langModule->languagePackageLE->setText(toqstr(bp_.lang_package));
4146 langModule->languagePackageCO->setCurrentIndex(p);
4147 langModule->languagePackageLE->clear();
4151 if (bp_.isfontcolor) {
4152 colorModule->mainTextCF->setStyleSheet(
4153 colorFrameStyleSheet(rgb2qcolor(bp_.fontcolor)));
4154 colorModule->mainTextCF->setVisible(true);
4156 colorModule->mainTextCF->setVisible(false);
4157 set_fontcolor = bp_.fontcolor;
4158 is_fontcolor = bp_.isfontcolor;
4160 colorModule->noteFontCF->setStyleSheet(
4161 colorFrameStyleSheet(rgb2qcolor(bp_.notefontcolor)));
4162 set_notefontcolor = bp_.notefontcolor;
4163 is_notefontcolor = bp_.isnotefontcolor;
4165 if (bp_.isbackgroundcolor) {
4166 colorModule->pageBackgroundCF->setStyleSheet(
4167 colorFrameStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
4168 colorModule->pageBackgroundCF->setVisible(true);
4170 colorModule->pageBackgroundCF->setVisible(false);
4171 set_backgroundcolor = bp_.backgroundcolor;
4172 is_backgroundcolor = bp_.isbackgroundcolor;
4174 colorModule->boxBackgroundCF->setStyleSheet(
4175 colorFrameStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
4176 set_boxbgcolor = bp_.boxbgcolor;
4177 is_boxbgcolor = bp_.isboxbgcolor;
4180 int const min_toclevel = documentClass().min_toclevel();
4181 int const max_toclevel = documentClass().max_toclevel();
4182 if (documentClass().hasTocLevels()) {
4183 numberingModule->setEnabled(true);
4184 numberingModule->depthSL->setMinimum(min_toclevel - 1);
4185 numberingModule->depthSL->setMaximum(max_toclevel);
4186 numberingModule->depthSL->setValue(bp_.secnumdepth);
4187 numberingModule->tocSL->setMaximum(min_toclevel - 1);
4188 numberingModule->tocSL->setMaximum(max_toclevel);
4189 numberingModule->tocSL->setValue(bp_.tocdepth);
4192 numberingModule->setEnabled(false);
4193 numberingModule->tocTW->clear();
4196 numberingModule->linenoCB->setChecked(bp_.use_lineno);
4197 numberingModule->linenoLE->setEnabled(bp_.use_lineno);
4198 numberingModule->linenoLA->setEnabled(bp_.use_lineno);
4199 numberingModule->linenoLE->setText(toqstr(bp_.lineno_opts));
4202 bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
4203 bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
4204 bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
4205 bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
4206 bulletsModule->init();
4209 int nitem = findToken(tex_graphics, bp_.graphics_driver);
4211 latexModule->psdriverCO->setCurrentIndex(nitem);
4215 mathsModule->MathIndentCB->setChecked(bp_.is_math_indent);
4216 if (bp_.is_math_indent) {
4217 Length const mathindent = bp_.getMathIndent();
4219 if (!mathindent.empty()) {
4220 lengthToWidgets(mathsModule->MathIndentLE,
4221 mathsModule->MathIndentLengthCO,
4222 mathindent, default_unit);
4225 mathsModule->MathIndentCO->setCurrentIndex(indent);
4226 enableMathIndent(indent);
4228 switch(bp_.math_numbering_side) {
4229 case BufferParams::LEFT:
4230 mathsModule->MathNumberingPosCO->setCurrentIndex(0);
4232 case BufferParams::DEFAULT:
4233 mathsModule->MathNumberingPosCO->setCurrentIndex(1);
4235 case BufferParams::RIGHT:
4236 mathsModule->MathNumberingPosCO->setCurrentIndex(2);
4239 map<string, string> const & packages = BufferParams::auto_packages();
4240 for (map<string, string>::const_iterator it = packages.begin();
4241 it != packages.end(); ++it) {
4242 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
4245 int row = mathsModule->packagesTW->row(item);
4246 switch (bp_.use_package(it->first)) {
4247 case BufferParams::package_off: {
4249 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3)->layout()->itemAt(0)->widget();
4250 rb->setChecked(true);
4253 case BufferParams::package_on: {
4255 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2)->layout()->itemAt(0)->widget();
4256 rb->setChecked(true);
4259 case BufferParams::package_auto: {
4261 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1)->layout()->itemAt(0)->widget();
4262 rb->setChecked(true);
4268 switch (bp_.spacing().getSpace()) {
4269 case Spacing::Other: nitem = 3; break;
4270 case Spacing::Double: nitem = 2; break;
4271 case Spacing::Onehalf: nitem = 1; break;
4272 case Spacing::Default: case Spacing::Single: nitem = 0; break;
4276 string const & layoutID = bp_.baseClassID();
4277 setLayoutComboByIDString(layoutID);
4279 updatePagestyle(documentClass().opt_pagestyle(),
4282 textLayoutModule->lspacingCO->setCurrentIndex(nitem);
4283 if (bp_.spacing().getSpace() == Spacing::Other) {
4284 doubleToWidget(textLayoutModule->lspacingLE,
4285 bp_.spacing().getValueAsString());
4288 int ts = textLayoutModule->tableStyleCO->findData(toqstr(bp_.tablestyle));
4290 textLayoutModule->tableStyleCO->setCurrentIndex(ts);
4292 if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
4293 textLayoutModule->indentRB->setChecked(true);
4294 string parindent = bp_.getParIndent().asString();
4295 QString indent = toqstr("default");
4296 if (!parindent.empty()) {
4297 lengthToWidgets(textLayoutModule->indentLE,
4298 textLayoutModule->indentLengthCO,
4299 parindent, default_unit);
4300 indent = toqstr("custom");
4302 textLayoutModule->indentCO->setCurrentIndex(textLayoutModule->indentCO->findData(indent));
4303 setIndent(textLayoutModule->indentCO->currentIndex());
4305 textLayoutModule->skipRB->setChecked(true);
4306 VSpace::VSpaceKind skip = bp_.getDefSkip().kind();
4307 textLayoutModule->skipCO->setCurrentIndex(textLayoutModule->skipCO->findData(skip));
4308 if (skip == VSpace::LENGTH) {
4309 string const length = bp_.getDefSkip().asLyXCommand();
4310 lengthToWidgets(textLayoutModule->skipLE,
4311 textLayoutModule->skipLengthCO,
4312 length, default_unit);
4314 setSkip(textLayoutModule->skipCO->currentIndex());
4317 textLayoutModule->twoColumnCB->setChecked(
4319 textLayoutModule->justCB->setChecked(bp_.justification);
4321 if (!bp_.options.empty()) {
4322 latexModule->optionsLE->setText(
4323 toqstr(bp_.options));
4325 latexModule->optionsLE->setText(QString());
4329 latexModule->defaultOptionsCB->setChecked(
4330 bp_.use_default_options);
4331 updateSelectedModules();
4332 selectionManager->updateProvidedModules(
4333 bp_.baseClass()->providedModules());
4334 selectionManager->updateExcludedModules(
4335 bp_.baseClass()->excludedModules());
4337 if (!documentClass().options().empty()) {
4338 latexModule->defaultOptionsLE->setText(
4339 toqstr(documentClass().options()));
4341 latexModule->defaultOptionsLE->setText(
4342 toqstr(_("[No options predefined]")));
4345 latexModule->defaultOptionsLE->setEnabled(
4346 bp_.use_default_options
4347 && !documentClass().options().empty());
4349 latexModule->defaultOptionsCB->setEnabled(
4350 !documentClass().options().empty());
4352 if (!bp_.master.empty()) {
4353 latexModule->childDocGB->setChecked(true);
4354 latexModule->childDocLE->setText(
4355 toqstr(bp_.master));
4357 latexModule->childDocLE->setText(QString());
4358 latexModule->childDocGB->setChecked(false);
4362 if (!bufferview() || !buffer().hasChildren()) {
4363 masterChildModule->childrenTW->clear();
4364 includeonlys_.clear();
4365 docPS->showPanel("Child Documents", false);
4366 if (docPS->isCurrentPanel("Child Documents"))
4367 docPS->setCurrentPanel("Document Class");
4369 docPS->showPanel("Child Documents", true);
4370 masterChildModule->setEnabled(true);
4371 includeonlys_ = bp_.getIncludedChildren();
4372 updateIncludeonlys();
4373 updateIncludeonlyDisplay();
4375 switch (bp_.maintain_unincluded_children) {
4376 case BufferParams::CM_None:
4377 masterChildModule->maintainCRNoneRB->setChecked(true);
4379 case BufferParams::CM_Mostly:
4380 masterChildModule->maintainCRMostlyRB->setChecked(true);
4382 case BufferParams::CM_Strict:
4384 masterChildModule->maintainCRStrictRB->setChecked(true);
4389 floatModule->setPlacement(bp_.float_placement);
4390 floatModule->setAlignment(bp_.float_alignment);
4393 // break listings_params to multiple lines
4395 InsetListingsParams(bp_.listings_params).separatedParams();
4396 listingsModule->listingsED->setPlainText(toqstr(lstparams));
4397 int nn = findToken(lst_packages, bp_.use_minted ? "Minted" : "Listings");
4399 listingsModule->packageCO->setCurrentIndex(nn);
4402 // some languages only work with Polyglossia (which requires non-TeX fonts)
4403 Language const * lang = lyx::languages.getLanguage(
4404 fromqstr(langModule->languageCO->itemData(
4405 langModule->languageCO->currentIndex()).toString()));
4406 bool const need_fontspec =
4407 lang->babel().empty() && !lang->polyglossia().empty()
4408 && lang->required() != "CJK" && lang->required() != "japanese";
4409 bool const os_fonts_available =
4410 bp_.baseClass()->outputType() == lyx::LATEX
4411 && LaTeXFeatures::isAvailable("fontspec");
4412 fontModule->osFontsCB->setEnabled(os_fonts_available && !need_fontspec);
4413 fontModule->osFontsCB->setChecked(
4414 (os_fonts_available && bp_.useNonTeXFonts) || need_fontspec);
4415 updateFontsize(documentClass().opt_fontsize(),
4418 QString font = toqstr(bp_.fontsRoman());
4419 bool foundfont = fontModule->fontsRomanCO->set(font, false);
4421 fontModule->fontsRomanCO->addItemSort(font, font + qt_(" (not installed)"),
4422 qt_("Uninstalled used fonts"),
4423 qt_("This font is not installed and won't be used in output"),
4424 false, false, false, true);
4425 fontModule->fontsRomanCO->set(font);
4427 fontModule->font_roman = toqstr(bp_.fonts_roman[!bp_.useNonTeXFonts]);
4429 font = toqstr(bp_.fontsSans());
4430 foundfont = fontModule->fontsSansCO->set(font, false);
4432 fontModule->fontsSansCO->addItemSort(font, font + qt_(" (not installed)"),
4433 qt_("Uninstalled used fonts"),
4434 qt_("This font is not installed and won't be used in output"),
4435 false, false, false, true);
4436 fontModule->fontsSansCO->set(font);
4438 fontModule->font_sans = toqstr(bp_.fonts_sans[!bp_.useNonTeXFonts]);
4440 font = toqstr(bp_.fontsTypewriter());
4441 foundfont = fontModule->fontsTypewriterCO->set(font, false);
4443 fontModule->fontsTypewriterCO->addItemSort(font, font + qt_(" (not installed)"),
4444 qt_("Uninstalled used fonts"),
4445 qt_("This font is not installed and won't be used in output"),
4446 false, false, false, true);
4447 fontModule->fontsTypewriterCO->set(font);
4449 fontModule->font_typewriter = toqstr(bp_.fonts_typewriter[!bp_.useNonTeXFonts]);
4451 font = toqstr(bp_.fontsMath());
4452 int mpos = fontModule->fontsMathCO->findData(font);
4454 mpos = fontModule->fontsMathCO->count();
4455 fontModule->fontsMathCO->addItem(font + qt_(" (not installed)"), font);
4457 fontModule->fontsMathCO->setCurrentIndex(mpos);
4458 fontModule->font_math = toqstr(bp_.fonts_math[!bp_.useNonTeXFonts]);
4460 if (bp_.useNonTeXFonts && os_fonts_available) {
4461 fontModule->fontencLA->setEnabled(false);
4462 fontModule->fontencCO->setEnabled(false);
4463 fontModule->fontencLE->setEnabled(false);
4465 fontModule->fontencLA->setEnabled(true);
4466 fontModule->fontencCO->setEnabled(true);
4467 fontModule->fontencLE->setEnabled(true);
4468 romanChanged(fontModule->fontsRomanCO->currentIndex());
4469 sansChanged(fontModule->fontsSansCO->currentIndex());
4470 ttChanged(fontModule->fontsTypewriterCO->currentIndex());
4472 // Handle options enabling
4473 updateFontOptions();
4475 if (!bp_.fonts_cjk.empty())
4476 fontModule->cjkFontLE->setText(
4477 toqstr(bp_.fonts_cjk));
4479 fontModule->cjkFontLE->setText(QString());
4481 fontModule->microtypeCB->setChecked(bp_.use_microtype);
4482 fontModule->dashesCB->setChecked(!bp_.use_dash_ligatures);
4484 fontModule->fontScCB->setChecked(bp_.fonts_expert_sc);
4485 fontModule->fontOsfCB->setChecked(bp_.fonts_roman_osf);
4486 fontModule->fontSansOsfCB->setChecked(bp_.fonts_sans_osf);
4487 fontModule->fontTypewriterOsfCB->setChecked(bp_.fonts_typewriter_osf);
4488 fontModule->scaleSansSB->setValue(bp_.fontsSansScale());
4489 fontModule->font_sf_scale = bp_.fonts_sans_scale[!bp_.useNonTeXFonts];
4490 fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale());
4491 fontModule->font_tt_scale = bp_.fonts_typewriter_scale[!bp_.useNonTeXFonts];
4492 if (!bp_.font_roman_opts.empty())
4493 fontModule->fontspecRomanLE->setText(
4494 toqstr(bp_.font_roman_opts));
4496 fontModule->fontspecRomanLE->setText(QString());
4497 if (!bp_.font_sans_opts.empty())
4498 fontModule->fontspecSansLE->setText(
4499 toqstr(bp_.font_sans_opts));
4501 fontModule->fontspecSansLE->setText(QString());
4502 if (!bp_.font_typewriter_opts.empty())
4503 fontModule->fontspecTypewriterLE->setText(
4504 toqstr(bp_.font_typewriter_opts));
4506 fontModule->fontspecTypewriterLE->setText(QString());
4508 nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
4510 fontModule->fontsDefaultCO->setCurrentIndex(nn);
4512 if (bp_.fontenc == "auto" || bp_.fontenc == "default") {
4513 fontModule->fontencCO->setCurrentIndex(
4514 fontModule->fontencCO->findData(toqstr(bp_.fontenc)));
4515 fontModule->fontencLE->setEnabled(false);
4517 fontModule->fontencCO->setCurrentIndex(
4518 fontModule->fontencCO->findData("custom"));
4519 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
4522 // LaTeX input encoding
4523 // Set after fonts because non-tex fonts override "\inputencoding".
4524 inputencodingToDialog();
4527 // This must be set _after_ fonts since updateDefaultFormat()
4528 // checks osFontsCB settings.
4529 // update combobox with formats
4530 updateDefaultFormat();
4531 int index = outputModule->defaultFormatCO->findData(toqstr(
4532 bp_.default_output_format));
4533 // set to default if format is not found
4536 outputModule->defaultFormatCO->setCurrentIndex(index);
4538 outputModule->shellescapeCB->setChecked(bp_.shell_escape);
4539 outputModule->outputsyncCB->setChecked(bp_.output_sync);
4540 outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
4541 outputModule->synccustomCB->setEnabled(bp_.output_sync);
4542 outputModule->synccustomLA->setEnabled(bp_.output_sync);
4544 outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
4545 outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
4546 outputModule->strictCB->setChecked(bp_.html_be_strict);
4547 outputModule->cssCB->setChecked(bp_.html_css_as_file);
4549 outputModule->tableoutCB->setCurrentIndex(bp_.docbook_table_output);
4550 outputModule->mathmlprefixCB->setCurrentIndex(bp_.docbook_mathml_prefix);
4552 outputModule->saveTransientPropertiesCB
4553 ->setChecked(bp_.save_transient_properties);
4554 outputModule->postponeFragileCB
4555 ->setChecked(bp_.postpone_fragile_content);
4558 bool const extern_geometry =
4559 documentClass().provides("geometry");
4560 int const psize = bp_.papersize;
4561 pageLayoutModule->papersizeCO->setCurrentIndex(psize);
4562 setCustomPapersize(!extern_geometry && psize == 1);
4563 pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
4565 bool const landscape =
4566 bp_.orientation == ORIENTATION_LANDSCAPE;
4567 pageLayoutModule->landscapeRB->setChecked(landscape);
4568 pageLayoutModule->portraitRB->setChecked(!landscape);
4569 pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
4570 pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
4572 pageLayoutModule->facingPagesCB->setChecked(
4573 bp_.sides == TwoSides);
4575 lengthToWidgets(pageLayoutModule->paperwidthLE,
4576 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, default_unit);
4577 lengthToWidgets(pageLayoutModule->paperheightLE,
4578 pageLayoutModule->paperheightUnitCO, bp_.paperheight, default_unit);
4581 Ui::MarginsUi * m = marginsModule;
4585 lengthToWidgets(m->topLE, m->topUnit,
4586 bp_.topmargin, default_unit);
4588 lengthToWidgets(m->bottomLE, m->bottomUnit,
4589 bp_.bottommargin, default_unit);
4591 lengthToWidgets(m->innerLE, m->innerUnit,
4592 bp_.leftmargin, default_unit);
4594 lengthToWidgets(m->outerLE, m->outerUnit,
4595 bp_.rightmargin, default_unit);
4597 lengthToWidgets(m->headheightLE, m->headheightUnit,
4598 bp_.headheight, default_unit);
4600 lengthToWidgets(m->headsepLE, m->headsepUnit,
4601 bp_.headsep, default_unit);
4603 lengthToWidgets(m->footskipLE, m->footskipUnit,
4604 bp_.footskip, default_unit);
4606 lengthToWidgets(m->columnsepLE, m->columnsepUnit,
4607 bp_.columnsep, default_unit);
4610 updateUnknownBranches();
4611 branchesModule->update(bp_);
4614 PDFOptions const & pdf = bp_.pdfoptions();
4615 pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
4616 if (bp_.documentClass().provides("hyperref"))
4617 pdfSupportModule->use_hyperrefGB->setTitle(qt_("C&ustomize Hyperref Options"));
4619 pdfSupportModule->use_hyperrefGB->setTitle(qt_("&Use Hyperref Support"));
4620 pdfSupportModule->titleLE->setText(toqstr(pdf.title));
4621 pdfSupportModule->authorLE->setText(toqstr(pdf.author));
4622 pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
4623 pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
4625 pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
4626 pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
4627 pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
4629 pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
4630 pdfSupportModule->bookmarksopenlevelSB->setEnabled(pdf.bookmarksopen);
4631 pdfSupportModule->bookmarksopenlevelLA->setEnabled(pdf.bookmarksopen);
4633 pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
4634 pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
4635 pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
4636 pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
4638 nn = findToken(backref_opts, pdf.backref);
4640 pdfSupportModule->backrefCO->setCurrentIndex(nn);
4642 pdfSupportModule->fullscreenCB->setChecked
4643 (pdf.pagemode == pdf.pagemode_fullscreen);
4645 pdfSupportModule->optionsTE->setPlainText(
4646 toqstr(pdf.quoted_options));
4648 pdfSupportModule->metadataTE->setPlainText(
4649 toqstr(rtrim(bp_.document_metadata, "\n")));
4652 changesModule->trackChangesCB->setChecked(bp_.track_changes);
4653 changesModule->outputChangesCB->setChecked(bp_.output_changes);
4654 changesModule->changeBarsCB->setChecked(bp_.change_bars);
4655 changesModule->changeBarsCB->setEnabled(bp_.output_changes);
4657 // Make sure that the bc is in the INITIAL state
4658 if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
4661 // clear changed branches cache
4662 changedBranches_.clear();
4664 // re-initiate module filter
4665 if (!filter_->text().isEmpty())
4666 moduleFilterPressed();
4669 nonModuleChanged_ = false;
4670 shellescapeChanged_ = false;
4674 void GuiDocument::saveDocDefault()
4676 // we have to apply the params first
4682 void GuiDocument::updateAvailableModules()
4684 modules_av_model_.clear();
4685 list<modInfoStruct> modInfoList = getModuleInfo();
4686 // Sort names according to the locale
4687 modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
4688 return 0 < b.name.localeAwareCompare(a.name);
4690 QIcon user_icon(guiApp ? guiApp->getScaledPixmap("images/", "lyxfiles-user")
4691 : getPixmap("images/", "lyxfiles-user", "svgz,png"));
4692 QIcon system_icon(guiApp ? guiApp->getScaledPixmap("images/", "lyxfiles-system")
4693 : getPixmap("images/", "lyxfiles-system", "svgz,png"));
4696 catfont.setBold(true);
4698 unavbrush.setColor(Qt::gray);
4699 for (modInfoStruct const & m : modInfoList) {
4700 QStandardItem * item = new QStandardItem();
4701 QStandardItem * catItem;
4702 QString const catname = m.category;
4703 QList<QStandardItem *> fcats = modules_av_model_.findItems(catname, Qt::MatchExactly);
4705 catItem = fcats.first();
4707 catItem = new QStandardItem();
4708 catItem->setText(catname);
4709 catItem->setFont(catfont);
4710 modules_av_model_.insertRow(i, catItem);
4713 item->setEditable(false);
4714 catItem->setEditable(false);
4715 item->setData(m.name, Qt::DisplayRole);
4717 item->setForeground(unavbrush);
4718 item->setData(toqstr(m.id), Qt::UserRole);
4719 item->setData(m.description, Qt::ToolTipRole);
4721 item->setIcon(user_icon);
4723 item->setIcon(system_icon);
4724 catItem->appendRow(item);
4726 modules_av_model_.sort(0);
4730 void GuiDocument::updateSelectedModules()
4732 modules_sel_model_.clear();
4733 list<modInfoStruct> const selModList = getSelectedModules();
4735 for (modInfoStruct const & m : selModList) {
4736 modules_sel_model_.insertRow(i, m.name, m.id, m.description);
4742 void GuiDocument::updateIncludeonlyDisplay()
4744 if (includeonlys_.empty()) {
4745 masterChildModule->includeallRB->setChecked(true);
4746 masterChildModule->childrenTW->setEnabled(false);
4747 masterChildModule->maintainGB->setEnabled(false);
4749 masterChildModule->includeonlyRB->setChecked(true);
4750 masterChildModule->childrenTW->setEnabled(true);
4751 masterChildModule->maintainGB->setEnabled(true);
4756 void GuiDocument::updateIncludeonlys(bool const cleanup)
4758 masterChildModule->childrenTW->clear();
4759 QString const no = qt_("No");
4760 QString const yes = qt_("Yes");
4762 ListOfBuffers children = buffer().getChildren();
4763 ListOfBuffers::const_iterator it = children.begin();
4764 ListOfBuffers::const_iterator end = children.end();
4765 bool has_unincluded = false;
4766 bool all_unincluded = true;
4767 for (; it != end; ++it) {
4768 QTreeWidgetItem * item = new QTreeWidgetItem(masterChildModule->childrenTW);
4771 to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
4772 from_utf8(buffer().filePath())));
4773 item->setText(0, toqstr(name));
4774 item->setText(1, isChildIncluded(name) ? yes : no);
4775 if (!isChildIncluded(name))
4776 has_unincluded = true;
4778 all_unincluded = false;
4780 // Both if all children are included and if none is included
4781 // is equal to "include all" (i.e., omit \includeonly).
4782 if (cleanup && (!has_unincluded || all_unincluded))
4783 includeonlys_.clear();
4787 bool GuiDocument::isBiblatex() const
4789 QString const engine =
4790 biblioModule->citeEngineCO->itemData(
4791 biblioModule->citeEngineCO->currentIndex()).toString();
4793 // this can happen if the cite engine is unknown, which can happen
4794 // if one is using a file that came from someone else, etc. in that
4795 // case, we crash if we proceed.
4796 if (engine.isEmpty())
4799 return theCiteEnginesList[fromqstr(engine)]->getCiteFramework() == "biblatex";
4803 void GuiDocument::updateDefaultBiblio(string const & style,
4804 string const & which)
4806 QString const bibstyle = toqstr(style);
4807 biblioModule->defaultBiblioCO->clear();
4812 if (which != "cbx") {
4813 // First the bbx styles
4814 biblioModule->biblatexBbxCO->clear();
4815 QStringList str = texFileList("bbxFiles.lst");
4816 // test whether we have a valid list, otherwise run rescan
4817 if (str.isEmpty()) {
4818 rescanTexStyles("bbx");
4819 str = texFileList("bbxFiles.lst");
4821 for (int i = 0; i != str.size(); ++i)
4822 str[i] = onlyFileName(str[i]);
4823 // sort on filename only (no path)
4826 for (int i = 0; i != str.count(); ++i) {
4827 QString item = changeExtension(str[i], "");
4828 if (item == bibstyle)
4830 biblioModule->biblatexBbxCO->addItem(item);
4833 if (item_nr == -1 && !bibstyle.isEmpty()) {
4834 biblioModule->biblatexBbxCO->addItem(bibstyle);
4835 item_nr = biblioModule->biblatexBbxCO->count() - 1;
4839 biblioModule->biblatexBbxCO->setCurrentIndex(item_nr);
4841 biblioModule->biblatexBbxCO->clearEditText();
4844 if (which != "bbx") {
4845 // now the cbx styles
4846 biblioModule->biblatexCbxCO->clear();
4847 QStringList str = texFileList("cbxFiles.lst");
4848 // test whether we have a valid list, otherwise run rescan
4849 if (str.isEmpty()) {
4850 rescanTexStyles("cbx");
4851 str = texFileList("cbxFiles.lst");
4853 for (int i = 0; i != str.size(); ++i)
4854 str[i] = onlyFileName(str[i]);
4855 // sort on filename only (no path)
4858 for (int i = 0; i != str.count(); ++i) {
4859 QString item = changeExtension(str[i], "");
4860 if (item == bibstyle)
4862 biblioModule->biblatexCbxCO->addItem(item);
4865 if (item_nr == -1 && !bibstyle.isEmpty()) {
4866 biblioModule->biblatexCbxCO->addItem(bibstyle);
4867 item_nr = biblioModule->biblatexCbxCO->count() - 1;
4871 biblioModule->biblatexCbxCO->setCurrentIndex(item_nr);
4873 biblioModule->biblatexCbxCO->clearEditText();
4876 biblioModule->biblatexBbxCO->clear();
4877 biblioModule->biblatexCbxCO->clear();
4878 QStringList str = texFileList("bstFiles.lst");
4879 // test whether we have a valid list, otherwise run rescan
4880 if (str.isEmpty()) {
4881 rescanTexStyles("bst");
4882 str = texFileList("bstFiles.lst");
4884 for (int i = 0; i != str.size(); ++i)
4885 str[i] = onlyFileName(str[i]);
4886 // sort on filename only (no path)
4889 for (int i = 0; i != str.count(); ++i) {
4890 QString item = changeExtension(str[i], "");
4891 if (item == bibstyle)
4893 biblioModule->defaultBiblioCO->addItem(item);
4896 if (item_nr == -1 && !bibstyle.isEmpty()) {
4897 biblioModule->defaultBiblioCO->addItem(bibstyle);
4898 item_nr = biblioModule->defaultBiblioCO->count() - 1;
4902 biblioModule->defaultBiblioCO->setCurrentIndex(item_nr);
4904 biblioModule->defaultBiblioCO->clearEditText();
4907 updateResetDefaultBiblio();
4911 void GuiDocument::updateResetDefaultBiblio()
4913 QString const engine =
4914 biblioModule->citeEngineCO->itemData(
4915 biblioModule->citeEngineCO->currentIndex()).toString();
4916 CiteEngineType const cet =
4917 CiteEngineType(biblioModule->citeStyleCO->itemData(
4918 biblioModule->citeStyleCO->currentIndex()).toInt());
4920 string const defbib = theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet);
4922 QString const bbx = biblioModule->biblatexBbxCO->currentText();
4923 QString const cbx = biblioModule->biblatexCbxCO->currentText();
4924 biblioModule->resetCbxPB->setEnabled(defbib != fromqstr(cbx));
4925 biblioModule->resetBbxPB->setEnabled(defbib != fromqstr(bbx));
4926 biblioModule->matchBbxPB->setEnabled(bbx != cbx && !cbx.isEmpty()
4927 && biblioModule->biblatexBbxCO->findText(cbx) != -1);
4929 biblioModule->resetDefaultBiblioPB->setEnabled(
4930 defbib != fromqstr(biblioModule->defaultBiblioCO->currentText()));
4934 void GuiDocument::matchBiblatexStyles()
4936 updateDefaultBiblio(fromqstr(biblioModule->biblatexCbxCO->currentText()), "bbx");
4941 void GuiDocument::updateContents()
4943 // Nothing to do here as the document settings is not cursor dependent.
4948 void GuiDocument::useClassDefaults()
4950 if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
4951 int const ret = Alert::prompt(_("Unapplied changes"),
4952 _("Some changes in the dialog were not yet applied.\n"
4953 "If you do not apply now, they will be lost after this action."),
4954 1, 1, _("&Apply"), _("&Dismiss"));
4959 int idx = latexModule->classCO->currentIndex();
4960 string const classname = fromqstr(latexModule->classCO->getData(idx));
4961 if (!bp_.setBaseClass(classname, buffer().layoutPos())) {
4962 Alert::error(_("Error"), _("Unable to set document class."));
4965 bp_.useClassDefaults();
4971 void GuiDocument::setLayoutComboByIDString(string const & idString)
4973 if (!latexModule->classCO->set(toqstr(idString)))
4974 Alert::warning(_("Can't set layout!"),
4975 bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
4979 bool GuiDocument::isValid()
4981 bool const listings_valid = validateListingsParameters().isEmpty();
4982 bool const local_layout_valid = !localLayout->editing();
4983 bool const preamble_valid = !preambleModule->editing();
4985 docPS->markPanelValid(N_("Listings[[inset]]"), listings_valid);
4986 docPS->markPanelValid(N_("Local Layout"), local_layout_valid && localLayout->isValid());
4987 docPS->markPanelValid(N_("LaTeX Preamble"), preamble_valid);
4989 return listings_valid && local_layout_valid && preamble_valid;
4993 char const * const GuiDocument::fontfamilies[5] = {
4994 "default", "rmdefault", "sfdefault", "ttdefault", ""
4998 char const * GuiDocument::fontfamilies_gui[5] = {
4999 N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
5003 bool GuiDocument::initialiseParams(string const &)
5005 BufferView const * view = bufferview();
5007 bp_ = BufferParams();
5011 prev_buffer_filename_ = view->buffer().absFileName();
5012 bp_ = view->buffer().params();
5014 updateAvailableModules();
5015 //FIXME It'd be nice to make sure here that the selected
5016 //modules are consistent: That required modules are actually
5017 //selected, and that we don't have conflicts. If so, we could
5018 //at least pop up a warning.
5024 void GuiDocument::clearParams()
5026 bp_ = BufferParams();
5030 BufferId GuiDocument::id() const
5032 BufferView const * const view = bufferview();
5033 return view? &view->buffer() : nullptr;
5037 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
5039 return moduleNames_;
5043 list<GuiDocument::modInfoStruct> const
5044 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
5046 list<modInfoStruct> mInfo;
5047 for (string const & name : mods) {
5049 LyXModule const * const mod = theModuleList[name];
5054 m.name = toqstr(name + " (") + qt_("Not Found") + toqstr(")");
5056 m.missingreqs = true;
5064 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
5066 return makeModuleInfo(params().getModules());
5070 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
5072 return makeModuleInfo(params().baseClass()->providedModules());
5076 DocumentClass const & GuiDocument::documentClass() const
5078 return bp_.documentClass();
5082 static void dispatch_bufferparams(Dialog const & dialog,
5083 BufferParams const & bp, FuncCode lfun, Buffer const * buf)
5086 ss << "\\begin_header\n";
5087 bp.writeFile(ss, buf);
5088 ss << "\\end_header\n";
5089 dialog.dispatch(FuncRequest(lfun, ss.str()));
5093 void GuiDocument::dispatchParams()
5095 // We need a non-const buffer object.
5096 Buffer & buf = const_cast<BufferView *>(bufferview())->buffer();
5097 // There may be several undo records; group them (bug #8998)
5098 // This handles undo groups automagically
5099 UndoGroupHelper ugh(&buf);
5101 // This must come first so that a language change is correctly noticed
5104 // We need to load the master before we formally update the params,
5105 // since otherwise we run updateBuffer, etc, before the child's master
5107 if (!params().master.empty()) {
5108 FileName const master_file = support::makeAbsPath(params().master,
5109 support::onlyPath(buffer().absFileName()));
5110 if (isLyXFileName(master_file.absFileName())) {
5111 Buffer * master = checkAndLoadLyXFile(master_file, true);
5113 if (master->isChild(const_cast<Buffer *>(&buffer())))
5114 const_cast<Buffer &>(buffer()).setParent(master);
5116 Alert::warning(_("Assigned master does not include this file"),
5117 bformat(_("You must include this file in the document\n"
5118 "'%1$s' in order to use the master document\n"
5119 "feature."), from_utf8(params().master)));
5121 Alert::warning(_("Could not load master"),
5122 bformat(_("The master document '%1$s'\n"
5123 "could not be loaded."),
5124 from_utf8(params().master)));
5128 // Apply the BufferParams. Note that this will set the base class
5129 // and then update the buffer's layout.
5130 dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY, &buffer());
5132 // Generate the colours requested by each new branch.
5133 BranchList & branchlist = params().branchlist();
5134 if (!branchlist.empty()) {
5135 BranchList::const_iterator it = branchlist.begin();
5136 BranchList::const_iterator const end = branchlist.end();
5137 for (; it != end; ++it) {
5138 docstring const & current_branch = it->branch();
5139 Branch const * branch = branchlist.find(current_branch);
5140 string const bcolor = branch->color();
5142 if (bcolor.size() == 7 && bcolor[0] == '#')
5143 rgbcol = lyx::rgbFromHexName(bcolor);
5145 guiApp->getRgbColor(lcolor.getFromLyXName(bcolor), rgbcol);
5146 string const x11hexname = X11hexname(rgbcol);
5147 // display the new color
5148 docstring const str = current_branch + ' ' + from_ascii(x11hexname);
5149 dispatch(FuncRequest(LFUN_SET_COLOR, str));
5152 // rename branches in the document
5153 executeBranchRenaming();
5154 // and clear changed branches cache
5155 changedBranches_.clear();
5157 // Generate the colours requested by indices.
5158 IndicesList & indiceslist = params().indiceslist();
5159 if (!indiceslist.empty()) {
5160 IndicesList::const_iterator it = indiceslist.begin();
5161 IndicesList::const_iterator const end = indiceslist.end();
5162 for (; it != end; ++it) {
5163 docstring const & current_index = it->shortcut();
5164 Index const * index = indiceslist.findShortcut(current_index);
5165 string const x11hexname = X11hexname(index->color());
5166 // display the new color
5167 docstring const str = current_index + ' ' + from_ascii(x11hexname);
5168 dispatch(FuncRequest(LFUN_SET_COLOR, str));
5172 // If we used an LFUN, we would not need these two lines:
5173 BufferView * bv = const_cast<BufferView *>(bufferview());
5174 bv->processUpdateFlags(Update::Force | Update::FitCursor);
5178 void GuiDocument::setLanguage() const
5180 Language const * const newL = bp_.language;
5181 if (buffer().params().language == newL)
5184 string const & lang_name = newL->lang();
5185 dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
5189 void GuiDocument::saveAsDefault() const
5191 dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT, &buffer());
5195 bool GuiDocument::providesOSF(QString const & font) const
5197 if (fontModule->osFontsCB->isChecked())
5198 // FIXME: we should check if the fonts really
5199 // have OSF support. But how?
5200 return font != "default";
5201 return theLaTeXFonts().getLaTeXFont(
5202 qstring_to_ucs4(font)).providesOSF(ot1(),
5208 bool GuiDocument::providesSC(QString const & font) const
5210 if (fontModule->osFontsCB->isChecked())
5212 return theLaTeXFonts().getLaTeXFont(
5213 qstring_to_ucs4(font)).providesSC(ot1(),
5219 bool GuiDocument::providesScale(QString const & font) const
5221 if (fontModule->osFontsCB->isChecked())
5222 return font != "default";
5223 return theLaTeXFonts().getLaTeXFont(
5224 qstring_to_ucs4(font)).providesScale(ot1(),
5230 bool GuiDocument::providesExtraOpts(QString const & font) const
5232 if (fontModule->osFontsCB->isChecked())
5233 return font != "default";
5234 return theLaTeXFonts().getLaTeXFont(
5235 qstring_to_ucs4(font)).providesMoreOptions(ot1(),
5241 bool GuiDocument::providesNoMath(QString const & font) const
5243 if (fontModule->osFontsCB->isChecked())
5245 return theLaTeXFonts().getLaTeXFont(
5246 qstring_to_ucs4(font)).providesNoMath(ot1(),
5251 bool GuiDocument::hasMonolithicExpertSet(QString const & font) const
5253 if (fontModule->osFontsCB->isChecked())
5255 return theLaTeXFonts().getLaTeXFont(
5256 qstring_to_ucs4(font)).hasMonolithicExpertSet(ot1(),
5263 GuiDocument::modInfoStruct GuiDocument::modInfo(LyXModule const & mod)
5265 // FIXME Unicode: docstrings would be better for these parameters but this
5266 // change requires a lot of others
5269 QString const guiname = toqstr(translateIfPossible(from_utf8(mod.getName())));
5270 m.missingreqs = !isModuleAvailable(mod.getID());
5271 if (m.missingreqs) {
5272 m.name = qt_("%1 (missing req.)").arg(guiname);
5275 m.category = mod.category().empty() ? qt_("Miscellaneous")
5276 : toqstr(translateIfPossible(from_utf8(mod.category())));
5277 QString desc = toqstr(translateIfPossible(from_utf8(mod.getDescription())));
5278 // Find the first sentence of the description
5279 QTextBoundaryFinder bf(QTextBoundaryFinder::Sentence, desc);
5280 int pos = bf.toNextBoundary();
5283 m.local = mod.isLocal();
5284 QString const mtype = m.local ? qt_("personal module") : qt_("distributed module");
5285 QString modulename = qt_("<b>Module name:</b> <i>%1</i> (%2)").arg(toqstr(m.id)).arg(mtype);
5286 // Tooltip is the desc followed by the module name and the type
5287 m.description = QString("%1%2")
5288 .arg(desc.isEmpty() ? QString() : QString("<p>%1</p>").arg(desc),
5291 m.description += QString("<p>%1</p>").arg(qt_("<b>Note:</b> Some requirements for this module are missing!"));
5296 void GuiDocument::loadModuleInfo()
5298 moduleNames_.clear();
5299 for (LyXModule const & mod : theModuleList)
5300 moduleNames_.push_back(modInfo(mod));
5304 void GuiDocument::updateUnknownBranches()
5308 list<docstring> used_branches;
5309 buffer().getUsedBranches(used_branches);
5310 list<docstring>::const_iterator it = used_branches.begin();
5311 QStringList unknown_branches;
5312 for (; it != used_branches.end() ; ++it) {
5313 if (!buffer().params().branchlist().find(*it))
5314 unknown_branches.append(toqstr(*it));
5316 branchesModule->setUnknownBranches(unknown_branches);
5320 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
5322 map<docstring, docstring>::iterator it = changedBranches_.begin();
5323 for (; it != changedBranches_.end() ; ++it) {
5324 if (it->second == oldname) {
5325 // branch has already been renamed
5326 it->second = newname;
5331 changedBranches_[oldname] = newname;
5335 void GuiDocument::executeBranchRenaming() const
5337 map<docstring, docstring>::const_iterator it = changedBranches_.begin();
5338 for (; it != changedBranches_.end() ; ++it) {
5339 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
5340 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
5345 void GuiDocument::allPackagesAuto()
5351 void GuiDocument::allPackagesAlways()
5357 void GuiDocument::allPackagesNot()
5363 void GuiDocument::allPackages(int col)
5365 for (int row = 0; row < mathsModule->packagesTW->rowCount(); ++row) {
5367 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, col)->layout()->itemAt(0)->widget();
5368 rb->setChecked(true);
5373 void GuiDocument::linenoToggled(bool on)
5375 numberingModule->linenoLE->setEnabled(on);
5376 numberingModule->linenoLA->setEnabled(on);
5380 void GuiDocument::outputChangesToggled(bool on)
5382 changesModule->changeBarsCB->setEnabled(on);
5386 void GuiDocument::setOutputSync(bool on)
5388 outputModule->synccustomCB->setEnabled(on);
5389 outputModule->synccustomLA->setEnabled(on);
5394 } // namespace frontend
5397 #include "moc_GuiDocument.cpp"