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(clicked(bool)),
1276 this, SLOT(setCustomMargins(bool)));
1277 connect(marginsModule->marginCB, SIGNAL(clicked()),
1278 this, SLOT(change_adaptor()));
1279 connect(marginsModule->topLE, SIGNAL(textChanged(QString)),
1280 this, SLOT(change_adaptor()));
1281 connect(marginsModule->topUnit, SIGNAL(activated(int)),
1282 this, SLOT(change_adaptor()));
1283 connect(marginsModule->bottomLE, SIGNAL(textChanged(QString)),
1284 this, SLOT(change_adaptor()));
1285 connect(marginsModule->bottomUnit, SIGNAL(activated(int)),
1286 this, SLOT(change_adaptor()));
1287 connect(marginsModule->innerLE, SIGNAL(textChanged(QString)),
1288 this, SLOT(change_adaptor()));
1289 connect(marginsModule->innerUnit, SIGNAL(activated(int)),
1290 this, SLOT(change_adaptor()));
1291 connect(marginsModule->outerLE, SIGNAL(textChanged(QString)),
1292 this, SLOT(change_adaptor()));
1293 connect(marginsModule->outerUnit, SIGNAL(activated(int)),
1294 this, SLOT(change_adaptor()));
1295 connect(marginsModule->headheightLE, SIGNAL(textChanged(QString)),
1296 this, SLOT(change_adaptor()));
1297 connect(marginsModule->headheightUnit, SIGNAL(activated(int)),
1298 this, SLOT(change_adaptor()));
1299 connect(marginsModule->headsepLE, SIGNAL(textChanged(QString)),
1300 this, SLOT(change_adaptor()));
1301 connect(marginsModule->headsepUnit, SIGNAL(activated(int)),
1302 this, SLOT(change_adaptor()));
1303 connect(marginsModule->footskipLE, SIGNAL(textChanged(QString)),
1304 this, SLOT(change_adaptor()));
1305 connect(marginsModule->footskipUnit, SIGNAL(activated(int)),
1306 this, SLOT(change_adaptor()));
1307 connect(marginsModule->columnsepLE, SIGNAL(textChanged(QString)),
1308 this, SLOT(change_adaptor()));
1309 connect(marginsModule->columnsepUnit, SIGNAL(activated(int)),
1310 this, SLOT(change_adaptor()));
1311 marginsModule->topLE->setValidator(new LengthValidator(
1312 marginsModule->topLE));
1313 marginsModule->bottomLE->setValidator(new LengthValidator(
1314 marginsModule->bottomLE));
1315 marginsModule->innerLE->setValidator(new LengthValidator(
1316 marginsModule->innerLE));
1317 marginsModule->outerLE->setValidator(new LengthValidator(
1318 marginsModule->outerLE));
1319 marginsModule->headsepLE->setValidator(new LengthValidator(
1320 marginsModule->headsepLE));
1321 marginsModule->headheightLE->setValidator(new LengthValidator(
1322 marginsModule->headheightLE));
1323 marginsModule->footskipLE->setValidator(new LengthValidator(
1324 marginsModule->footskipLE));
1325 marginsModule->columnsepLE->setValidator(new LengthValidator(
1326 marginsModule->columnsepLE));
1328 bc().addCheckedLineEdit(marginsModule->topLE,
1329 marginsModule->topL);
1330 bc().addCheckedLineEditPanel(marginsModule->topLE,
1331 docPS, N_("Page Margins"));
1332 bc().addCheckedLineEdit(marginsModule->bottomLE,
1333 marginsModule->bottomL);
1334 bc().addCheckedLineEditPanel(marginsModule->bottomLE,
1335 docPS, N_("Page Margins"));
1336 bc().addCheckedLineEdit(marginsModule->innerLE,
1337 marginsModule->innerL);
1338 bc().addCheckedLineEditPanel(marginsModule->innerLE,
1339 docPS, N_("Page Margins"));
1340 bc().addCheckedLineEdit(marginsModule->outerLE,
1341 marginsModule->outerL);
1342 bc().addCheckedLineEditPanel(marginsModule->outerLE,
1343 docPS, N_("Page Margins"));
1344 bc().addCheckedLineEdit(marginsModule->headsepLE,
1345 marginsModule->headsepL);
1346 bc().addCheckedLineEditPanel(marginsModule->headsepLE,
1347 docPS, N_("Page Margins"));
1348 bc().addCheckedLineEdit(marginsModule->headheightLE,
1349 marginsModule->headheightL);
1350 bc().addCheckedLineEditPanel(marginsModule->headheightLE,
1351 docPS, N_("Page Margins"));
1352 bc().addCheckedLineEdit(marginsModule->footskipLE,
1353 marginsModule->footskipL);
1354 bc().addCheckedLineEditPanel(marginsModule->footskipLE,
1355 docPS, N_("Page Margins"));
1356 bc().addCheckedLineEdit(marginsModule->columnsepLE,
1357 marginsModule->columnsepL);
1358 bc().addCheckedLineEditPanel(marginsModule->columnsepLE,
1359 docPS, N_("Page Margins"));
1363 colorModule = new UiWidget<Ui::ColorUi>(this);
1364 connect(colorModule->fontColorPB, SIGNAL(clicked()),
1365 this, SLOT(changeFontColor()));
1366 connect(colorModule->delFontColorTB, SIGNAL(clicked()),
1367 this, SLOT(deleteFontColor()));
1368 connect(colorModule->noteFontColorPB, SIGNAL(clicked()),
1369 this, SLOT(changeNoteFontColor()));
1370 connect(colorModule->delNoteFontColorTB, SIGNAL(clicked()),
1371 this, SLOT(deleteNoteFontColor()));
1372 connect(colorModule->backgroundPB, SIGNAL(clicked()),
1373 this, SLOT(changeBackgroundColor()));
1374 connect(colorModule->delBackgroundTB, SIGNAL(clicked()),
1375 this, SLOT(deleteBackgroundColor()));
1376 connect(colorModule->boxBackgroundPB, SIGNAL(clicked()),
1377 this, SLOT(changeBoxBackgroundColor()));
1378 connect(colorModule->delBoxBackgroundTB, SIGNAL(clicked()),
1379 this, SLOT(deleteBoxBackgroundColor()));
1383 changesModule = new UiWidget<Ui::ChangeTrackingUi>(this);
1384 connect(changesModule->trackChangesCB, SIGNAL(clicked()),
1385 this, SLOT(change_adaptor()));
1386 connect(changesModule->outputChangesCB, SIGNAL(toggled(bool)),
1387 this, SLOT(outputChangesToggled(bool)));
1388 connect(changesModule->changeBarsCB, SIGNAL(clicked()),
1389 this, SLOT(change_adaptor()));
1390 connect(&lv, SIGNAL(changeTrackingToggled(bool)),
1391 this, SLOT(changeTrackingChanged(bool)));
1395 numberingModule = new UiWidget<Ui::NumberingUi>(this);
1396 connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
1397 this, SLOT(change_adaptor()));
1398 connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
1399 this, SLOT(change_adaptor()));
1400 connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
1401 this, SLOT(updateNumbering()));
1402 connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
1403 this, SLOT(updateNumbering()));
1404 numberingModule->tocTW->setColumnCount(3);
1405 numberingModule->tocTW->headerItem()->setText(0, qt_("Example"));
1406 numberingModule->tocTW->headerItem()->setText(1, qt_("Numbered"));
1407 numberingModule->tocTW->headerItem()->setText(2, qt_("Appears in TOC"));
1408 numberingModule->tocTW->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
1409 connect(numberingModule->linenoCB, SIGNAL(toggled(bool)),
1410 this, SLOT(linenoToggled(bool)));
1411 connect(numberingModule->linenoCB, SIGNAL(clicked()),
1412 this, SLOT(change_adaptor()));
1413 connect(numberingModule->linenoLE, SIGNAL(textChanged(QString)),
1414 this, SLOT(change_adaptor()));
1418 biblioModule = new UiWidget<Ui::BiblioUi>(this);
1419 connect(biblioModule->citeEngineCO, SIGNAL(activated(int)),
1420 this, SLOT(citeEngineChanged(int)));
1421 connect(biblioModule->citeStyleCO, SIGNAL(activated(int)),
1422 this, SLOT(citeStyleChanged()));
1423 connect(biblioModule->bibtopicCB, SIGNAL(clicked()),
1424 this, SLOT(biblioChanged()));
1425 connect(biblioModule->bibunitsCO, SIGNAL(activated(int)),
1426 this, SLOT(biblioChanged()));
1427 connect(biblioModule->bibtexCO, SIGNAL(activated(int)),
1428 this, SLOT(bibtexChanged(int)));
1429 connect(biblioModule->bibtexOptionsLE, SIGNAL(textChanged(QString)),
1430 this, SLOT(biblioChanged()));
1431 connect(biblioModule->citePackageOptionsLE, SIGNAL(textChanged(QString)),
1432 this, SLOT(biblioChanged()));
1433 connect(biblioModule->defaultBiblioCO, SIGNAL(activated(int)),
1434 this, SLOT(biblioChanged()));
1435 connect(biblioModule->defaultBiblioCO, SIGNAL(editTextChanged(QString)),
1436 this, SLOT(biblioChanged()));
1437 connect(biblioModule->defaultBiblioCO, SIGNAL(editTextChanged(QString)),
1438 this, SLOT(updateResetDefaultBiblio()));
1439 connect(biblioModule->biblatexBbxCO, SIGNAL(activated(int)),
1440 this, SLOT(biblioChanged()));
1441 connect(biblioModule->biblatexBbxCO, SIGNAL(editTextChanged(QString)),
1442 this, SLOT(biblioChanged()));
1443 connect(biblioModule->biblatexBbxCO, SIGNAL(editTextChanged(QString)),
1444 this, SLOT(updateResetDefaultBiblio()));
1445 connect(biblioModule->biblatexCbxCO, SIGNAL(activated(int)),
1446 this, SLOT(biblioChanged()));
1447 connect(biblioModule->biblatexCbxCO, SIGNAL(editTextChanged(QString)),
1448 this, SLOT(biblioChanged()));
1449 connect(biblioModule->biblatexCbxCO, SIGNAL(editTextChanged(QString)),
1450 this, SLOT(updateResetDefaultBiblio()));
1451 connect(biblioModule->rescanBibliosPB, SIGNAL(clicked()),
1452 this, SLOT(rescanBibFiles()));
1453 connect(biblioModule->resetDefaultBiblioPB, SIGNAL(clicked()),
1454 this, SLOT(resetDefaultBibfile()));
1455 connect(biblioModule->resetCbxPB, SIGNAL(clicked()),
1456 this, SLOT(resetDefaultCbxBibfile()));
1457 connect(biblioModule->resetBbxPB, SIGNAL(clicked()),
1458 this, SLOT(resetDefaultBbxBibfile()));
1459 connect(biblioModule->matchBbxPB, SIGNAL(clicked()),
1460 this, SLOT(matchBiblatexStyles()));
1462 biblioModule->citeEngineCO->clear();
1463 for (LyXCiteEngine const & cet : theCiteEnginesList) {
1464 biblioModule->citeEngineCO->addItem(qt_(cet.getName()), toqstr(cet.getID()));
1465 int const i = biblioModule->citeEngineCO->findData(toqstr(cet.getID()));
1466 biblioModule->citeEngineCO->setItemData(i, qt_(cet.getDescription()),
1470 biblioModule->bibtexOptionsLE->setValidator(new NoNewLineValidator(
1471 biblioModule->bibtexOptionsLE));
1472 biblioModule->defaultBiblioCO->lineEdit()->setValidator(new NoNewLineValidator(
1473 biblioModule->defaultBiblioCO->lineEdit()));
1474 biblioModule->citePackageOptionsLE->setValidator(new NoNewLineValidator(
1475 biblioModule->citePackageOptionsLE));
1477 // NOTE: we do not provide "custom" here for security reasons!
1478 biblioModule->bibtexCO->clear();
1479 biblioModule->bibtexCO->addItem(qt_("Default"), QString("default"));
1480 for (auto const & alts : lyxrc.bibtex_alternatives) {
1481 QString const command = toqstr(alts).left(toqstr(alts).indexOf(" "));
1482 biblioModule->bibtexCO->addItem(command, command);
1487 indicesModule = new GuiIndices;
1488 connect(indicesModule, SIGNAL(changed()),
1489 this, SLOT(change_adaptor()));
1493 mathsModule = new UiWidget<Ui::MathsUi>(this);
1494 QStringList headers;
1495 headers << qt_("Package") << qt_("Load automatically")
1496 << qt_("Load always") << qt_("Do not load");
1497 mathsModule->packagesTW->setHorizontalHeaderLabels(headers);
1498 mathsModule->packagesTW->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
1499 map<string, string> const & packages = BufferParams::auto_packages();
1500 mathsModule->packagesTW->setRowCount(packages.size());
1502 for (auto const & pkgvar : packages) {
1503 docstring const package = from_ascii(pkgvar.first);
1504 QString autoTooltip = qt_(pkgvar.second);
1505 QString alwaysTooltip;
1506 if (package == "amsmath")
1508 qt_("The AMS LaTeX packages are always used");
1510 alwaysTooltip = toqstr(bformat(
1511 _("The LaTeX package %1$s is always used"),
1513 QString neverTooltip;
1514 if (package == "amsmath")
1516 qt_("The AMS LaTeX packages are never used");
1518 neverTooltip = toqstr(bformat(
1519 _("The LaTeX package %1$s is never used"),
1521 QRadioButton * autoRB = new QRadioButton(mathsModule);
1522 QRadioButton * alwaysRB = new QRadioButton(mathsModule);
1523 QRadioButton * neverRB = new QRadioButton(mathsModule);
1524 QButtonGroup * packageGroup = new QButtonGroup(mathsModule);
1525 packageGroup->addButton(autoRB);
1526 packageGroup->addButton(alwaysRB);
1527 packageGroup->addButton(neverRB);
1528 autoRB->setToolTip(autoTooltip);
1529 alwaysRB->setToolTip(alwaysTooltip);
1530 neverRB->setToolTip(neverTooltip);
1532 // Pack the buttons in a layout in order to get proper alignment
1533 QWidget * autoRBWidget = new QWidget();
1534 QHBoxLayout * autoRBLayout = new QHBoxLayout(autoRBWidget);
1535 autoRBLayout->addWidget(autoRB);
1536 autoRBLayout->setAlignment(Qt::AlignCenter);
1537 autoRBLayout->setContentsMargins(0, 0, 0, 0);
1538 autoRBWidget->setLayout(autoRBLayout);
1540 QWidget * alwaysRBWidget = new QWidget();
1541 QHBoxLayout * alwaysRBLayout = new QHBoxLayout(alwaysRBWidget);
1542 alwaysRBLayout->addWidget(alwaysRB);
1543 alwaysRBLayout->setAlignment(Qt::AlignCenter);
1544 alwaysRBLayout->setContentsMargins(0, 0, 0, 0);
1545 alwaysRBWidget->setLayout(alwaysRBLayout);
1547 QWidget * neverRBWidget = new QWidget();
1548 QHBoxLayout * neverRBLayout = new QHBoxLayout(neverRBWidget);
1549 neverRBLayout->addWidget(neverRB);
1550 neverRBLayout->setAlignment(Qt::AlignCenter);
1551 neverRBLayout->setContentsMargins(0, 0, 0, 0);
1552 neverRBWidget->setLayout(neverRBLayout);
1554 QTableWidgetItem * pack = new QTableWidgetItem(toqstr(package));
1555 mathsModule->packagesTW->setItem(packnum, 0, pack);
1556 mathsModule->packagesTW->setCellWidget(packnum, 1, autoRBWidget);
1557 mathsModule->packagesTW->setCellWidget(packnum, 2, alwaysRBWidget);
1558 mathsModule->packagesTW->setCellWidget(packnum, 3, neverRBWidget);
1560 connect(autoRB, SIGNAL(clicked()),
1561 this, SLOT(change_adaptor()));
1562 connect(alwaysRB, SIGNAL(clicked()),
1563 this, SLOT(change_adaptor()));
1564 connect(neverRB, SIGNAL(clicked()),
1565 this, SLOT(change_adaptor()));
1568 connect(mathsModule->allPackagesAutoPB, SIGNAL(clicked()),
1569 this, SLOT(allPackagesAuto()));
1570 connect(mathsModule->allPackagesAlwaysPB, SIGNAL(clicked()),
1571 this, SLOT(allPackagesAlways()));
1572 connect(mathsModule->allPackagesNotPB, SIGNAL(clicked()),
1573 this, SLOT(allPackagesNot()));
1574 connect(mathsModule->allPackagesAutoPB, SIGNAL(clicked()),
1575 this, SLOT(change_adaptor()));
1576 connect(mathsModule->allPackagesAlwaysPB, SIGNAL(clicked()),
1577 this, SLOT(change_adaptor()));
1578 connect(mathsModule->allPackagesNotPB, SIGNAL(clicked()),
1579 this, SLOT(change_adaptor()));
1580 connect(mathsModule->MathNumberingPosCO, SIGNAL(activated(int)),
1581 this, SLOT(change_adaptor()));
1583 connect(mathsModule->MathIndentCB, SIGNAL(toggled(bool)),
1584 this, SLOT(allowMathIndent()));
1585 connect(mathsModule->MathIndentCB, SIGNAL(toggled(bool)),
1586 this, SLOT(change_adaptor()));
1587 connect(mathsModule->MathIndentCO, SIGNAL(activated(int)),
1588 this, SLOT(enableMathIndent(int)));
1589 connect(mathsModule->MathIndentCO, SIGNAL(activated(int)),
1590 this, SLOT(change_adaptor()));
1591 connect(mathsModule->MathIndentLE, SIGNAL(textChanged(const QString &)),
1592 this, SLOT(change_adaptor()));
1593 connect(mathsModule->MathIndentLengthCO, SIGNAL(activated(int)),
1594 this, SLOT(change_adaptor()));
1597 mathsModule->MathIndentCO->addItem(qt_("Default"), toqstr("default"));
1598 mathsModule->MathIndentCO->addItem(qt_("Custom"), toqstr("custom"));
1599 mathsModule->MathIndentLE->setValidator(new LengthValidator(
1600 mathsModule->MathIndentLE, false));
1601 // initialize the length validator
1602 bc().addCheckedLineEdit(mathsModule->MathIndentLE, mathsModule->MathIndentCB);
1603 bc().addCheckedLineEditPanel(mathsModule->MathIndentLE, docPS, N_("Math Options"));
1604 mathsModule->MathNumberingPosCO->addItem(qt_("Left"));
1605 mathsModule->MathNumberingPosCO->addItem(qt_("Default"));
1606 mathsModule->MathNumberingPosCO->addItem(qt_("Right"));
1607 mathsModule->MathNumberingPosCO->setCurrentIndex(1);
1611 latexModule = new UiWidget<Ui::LaTeXUi>(this);
1612 connect(latexModule->optionsLE, SIGNAL(textChanged(QString)),
1613 this, SLOT(change_adaptor()));
1614 connect(latexModule->defaultOptionsCB, SIGNAL(clicked()),
1615 this, SLOT(change_adaptor()));
1616 connect(latexModule->psdriverCO, SIGNAL(activated(int)),
1617 this, SLOT(change_adaptor()));
1618 connect(latexModule->classCO, SIGNAL(activated(int)),
1619 this, SLOT(classChanged_adaptor()));
1620 connect(latexModule->classCO, SIGNAL(activated(int)),
1621 this, SLOT(change_adaptor()));
1622 connect(latexModule->layoutPB, SIGNAL(clicked()),
1623 this, SLOT(browseLayout()));
1624 connect(latexModule->layoutPB, SIGNAL(clicked()),
1625 this, SLOT(change_adaptor()));
1626 connect(latexModule->childDocGB, SIGNAL(clicked()),
1627 this, SLOT(change_adaptor()));
1628 connect(latexModule->childDocLE, SIGNAL(textChanged(QString)),
1629 this, SLOT(change_adaptor()));
1630 connect(latexModule->childDocPB, SIGNAL(clicked()),
1631 this, SLOT(browseMaster()));
1632 connect(latexModule->suppressDateCB, SIGNAL(clicked()),
1633 this, SLOT(change_adaptor()));
1634 connect(latexModule->refstyleCB, SIGNAL(clicked()),
1635 this, SLOT(change_adaptor()));
1636 connect(latexModule->refFormattedCB, SIGNAL(clicked()),
1637 this, SLOT(change_adaptor()));
1639 latexModule->optionsLE->setValidator(new NoNewLineValidator(
1640 latexModule->optionsLE));
1641 latexModule->childDocLE->setValidator(new NoNewLineValidator(
1642 latexModule->childDocLE));
1644 // postscript drivers
1645 for (int n = 0; tex_graphics[n][0]; ++n) {
1646 QString enc = qt_(tex_graphics_gui[n]);
1647 latexModule->psdriverCO->addItem(enc);
1650 LayoutFileList const & bcl = LayoutFileList::get();
1651 vector<LayoutFileIndex> classList = bcl.classList();
1652 sort(classList.begin(), classList.end(), less_textclass_avail_desc());
1654 for (auto const & cvar : classList) {
1655 LayoutFile const & tc = bcl[cvar];
1656 bool const available = tc.isTeXClassAvailable();
1657 docstring const guiname = translateIfPossible(from_utf8(tc.description()));
1658 // tooltip sensu "KOMA-Script Article [Class 'scrartcl']"
1659 QString tooltip = toqstr(bformat(_("%1$s [Class '%2$s']"), guiname, from_utf8(tc.latexname())));
1661 docstring const output_type = _("LaTeX");
1662 tooltip += '\n' + toqstr(bformat(_("Class not found by LyX. "
1663 "Please check if you have the matching %1$s class "
1664 "and all required packages (%2$s) installed."),
1665 output_type, from_utf8(tc.prerequisites(", "))));
1667 latexModule->classCO->addItemSort(toqstr(tc.name()),
1669 toqstr(translateIfPossible(from_utf8(tc.category()))),
1671 true, true, true, available);
1676 branchesModule = new GuiBranches(this);
1677 connect(branchesModule, SIGNAL(changed()),
1678 this, SLOT(change_adaptor()));
1679 connect(branchesModule, SIGNAL(renameBranches(docstring const &, docstring const &)),
1680 this, SLOT(branchesRename(docstring const &, docstring const &)));
1681 connect(branchesModule, SIGNAL(okPressed()), this, SLOT(slotOK()));
1682 updateUnknownBranches();
1686 preambleModule = new PreambleModule(this);
1687 connect(preambleModule, SIGNAL(changed()),
1688 this, SLOT(change_adaptor()));
1690 localLayout = new LocalLayout(this);
1691 connect(localLayout, SIGNAL(changed()),
1692 this, SLOT(change_adaptor()));
1696 bulletsModule = new BulletsModule(this);
1697 connect(bulletsModule, SIGNAL(changed()),
1698 this, SLOT(change_adaptor()));
1702 modulesModule = new UiWidget<Ui::ModulesUi>(this);
1703 modulesModule->availableLV->header()->setVisible(false);
1704 modulesModule->availableLV->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
1705 modulesModule->availableLV->header()->setStretchLastSection(false);
1706 modulesModule->selectedLV->header()->setVisible(false);
1707 modulesModule->selectedLV->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
1708 modulesModule->selectedLV->header()->setStretchLastSection(false);
1710 new ModuleSelectionManager(this, modulesModule->availableLV,
1711 modulesModule->selectedLV,
1712 modulesModule->addPB,
1713 modulesModule->deletePB,
1714 modulesModule->upPB,
1715 modulesModule->downPB,
1716 availableModel(), selectedModel(), this);
1717 connect(selectionManager, SIGNAL(updateHook()),
1718 this, SLOT(updateModuleInfo()));
1719 connect(selectionManager, SIGNAL(selectionChanged()),
1720 this, SLOT(modulesChanged()));
1722 filter_ = new FancyLineEdit(this);
1723 filter_->setClearButton(true);
1724 filter_->setPlaceholderText(qt_("All avail. modules"));
1725 modulesModule->moduleFilterBarL->addWidget(filter_, 0);
1726 modulesModule->findModulesLA->setBuddy(filter_);
1728 connect(filter_, SIGNAL(rightButtonClicked()),
1729 this, SLOT(resetModuleFilter()));
1730 connect(filter_, SIGNAL(textEdited(QString)),
1731 this, SLOT(moduleFilterChanged(QString)));
1732 connect(filter_, SIGNAL(returnPressed()),
1733 this, SLOT(moduleFilterPressed()));
1734 connect(filter_, &FancyLineEdit::downPressed,
1735 modulesModule->availableLV, [this](){ focusAndHighlight(modulesModule->availableLV); });
1739 pdfSupportModule = new UiWidget<Ui::PDFSupportUi>(this);
1740 connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
1741 this, SLOT(change_adaptor()));
1742 connect(pdfSupportModule->titleLE, SIGNAL(textChanged(QString)),
1743 this, SLOT(change_adaptor()));
1744 connect(pdfSupportModule->authorLE, SIGNAL(textChanged(QString)),
1745 this, SLOT(change_adaptor()));
1746 connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(QString)),
1747 this, SLOT(change_adaptor()));
1748 connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(QString)),
1749 this, SLOT(change_adaptor()));
1750 connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
1751 this, SLOT(change_adaptor()));
1752 connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
1753 this, SLOT(change_adaptor()));
1754 connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
1755 this, SLOT(change_adaptor()));
1756 connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
1757 this, SLOT(bookmarksopenChanged(bool)));
1758 connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
1759 this, SLOT(change_adaptor()));
1760 connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
1761 this, SLOT(change_adaptor()));
1762 connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
1763 this, SLOT(change_adaptor()));
1764 connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
1765 this, SLOT(change_adaptor()));
1766 connect(pdfSupportModule->backrefCO, SIGNAL(activated(int)),
1767 this, SLOT(change_adaptor()));
1768 connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
1769 this, SLOT(change_adaptor()));
1770 connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
1771 this, SLOT(change_adaptor()));
1772 connect(pdfSupportModule->optionsTE, SIGNAL(textChanged()),
1773 this, SLOT(change_adaptor()));
1774 connect(pdfSupportModule->metadataTE, SIGNAL(textChanged()),
1775 this, SLOT(change_adaptor()));
1777 pdfSupportModule->titleLE->setValidator(new NoNewLineValidator(
1778 pdfSupportModule->titleLE));
1779 pdfSupportModule->authorLE->setValidator(new NoNewLineValidator(
1780 pdfSupportModule->authorLE));
1781 pdfSupportModule->subjectLE->setValidator(new NoNewLineValidator(
1782 pdfSupportModule->subjectLE));
1783 pdfSupportModule->keywordsLE->setValidator(new NoNewLineValidator(
1784 pdfSupportModule->keywordsLE));
1786 pdf_options_highlighter_ = new LaTeXHighlighter(
1787 pdfSupportModule->optionsTE->document(), true, true);
1788 pdf_metadata_highlighter_ = new LaTeXHighlighter(
1789 pdfSupportModule->metadataTE->document(), true, true);
1791 for (int i = 0; backref_opts[i][0]; ++i)
1792 pdfSupportModule->backrefCO->addItem(qt_(backref_opts_gui[i]));
1796 floatModule = new FloatPlacement;
1797 connect(floatModule, SIGNAL(changed()),
1798 this, SLOT(change_adaptor()));
1802 listingsModule = new UiWidget<Ui::ListingsSettingsUi>(this);
1803 connect(listingsModule->listingsED, SIGNAL(textChanged()),
1804 this, SLOT(change_adaptor()));
1805 connect(listingsModule->bypassCB, SIGNAL(clicked()),
1806 this, SLOT(change_adaptor()));
1807 connect(listingsModule->bypassCB, SIGNAL(clicked()),
1808 this, SLOT(setListingsMessage()));
1809 connect(listingsModule->packageCO, SIGNAL(activated(int)),
1810 this, SLOT(change_adaptor()));
1811 connect(listingsModule->packageCO, SIGNAL(activated(int)),
1812 this, SLOT(listingsPackageChanged(int)));
1813 connect(listingsModule->listingsED, SIGNAL(textChanged()),
1814 this, SLOT(setListingsMessage()));
1815 listingsModule->listingsTB->setPlainText(
1816 qt_("Input listings parameters below. Enter ? for a list of parameters."));
1818 for (int i = 0; lst_packages[i][0]; ++i)
1819 listingsModule->packageCO->addItem(lst_packages[i]);
1823 docPS->addPanel(latexModule, N_("Document Class"));
1824 docPS->addPanel(masterChildModule, N_("Child Documents"));
1825 docPS->addPanel(modulesModule, N_("Modules"));
1826 docPS->addPanel(localLayout, N_("Local Layout"));
1827 docPS->addPanel(fontModule, N_("Fonts"));
1828 docPS->addPanel(textLayoutModule, N_("Text Layout"));
1829 docPS->addPanel(pageLayoutModule, N_("Page Layout"));
1830 docPS->addPanel(marginsModule, N_("Page Margins"));
1831 docPS->addPanel(langModule, N_("Language"));
1832 docPS->addPanel(colorModule, N_("Colors"));
1833 docPS->addPanel(changesModule, N_("Change Tracking"));
1834 docPS->addPanel(numberingModule, N_("Numbering & TOC"));
1835 docPS->addPanel(biblioModule, N_("Bibliography"));
1836 docPS->addPanel(indicesModule, N_("Indexes"));
1837 docPS->addPanel(pdfSupportModule, N_("PDF Properties"));
1838 docPS->addPanel(mathsModule, N_("Math Options"));
1839 docPS->addPanel(floatModule, N_("Float Settings"));
1840 docPS->addPanel(listingsModule, N_("Listings[[inset]]"));
1841 docPS->addPanel(bulletsModule, N_("Bullets"));
1842 docPS->addPanel(branchesModule, N_("Branches"));
1843 docPS->addPanel(outputModule, N_("Output"));
1844 docPS->addPanel(preambleModule, N_("LaTeX Preamble"));
1845 docPS->setCurrentPanel("Document Class");
1847 // Filter out (dark/light) mode changes
1848 installEventFilter(this);
1852 void GuiDocument::onBufferViewChanged()
1855 // We are just switching back. Nothing to do.
1856 switchback_ = false;
1859 BufferView const * view = bufferview();
1860 string const new_filename = view ? view->buffer().absFileName() : string();
1861 // If we switched buffer really and the previous file name is different to
1862 // the current one, we ask on unapplied changes (#9369)
1863 // FIXME: This is more complicated than it should be. Why do we need these to cycles?
1864 // And ideally, we should propose to apply without having to switch back
1865 // (e.g., via a LFUN_BUFFER_PARAMS_APPLY_OTHER)
1866 if (!prev_buffer_filename_.empty() && prev_buffer_filename_ != new_filename
1867 && buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
1868 // Only ask if we haven't yet in this cycle
1869 int const ret = prompted_ ? 3 : Alert::prompt(_("Unapplied changes"),
1870 _("Some changes in the previous document were not yet applied.\n"
1871 "Do you want to switch back and apply them?"),
1872 1, 1, _("Yes, &Switch Back"), _("No, &Dismiss Changes"));
1874 // Switch to previous buffer view and apply
1876 // Record that we have asked.
1878 lyx::dispatch(FuncRequest(LFUN_BUFFER_SWITCH, prev_buffer_filename_));
1880 } else if (ret == 3) {
1881 // We are in the second cycle. Set back.
1887 if (isVisibleView())
1888 initialiseParams("");
1892 void GuiDocument::saveDefaultClicked()
1898 void GuiDocument::useDefaultsClicked()
1904 void GuiDocument::change_adaptor()
1906 nonModuleChanged_ = true;
1911 void GuiDocument::shellescapeChanged()
1913 shellescapeChanged_ = true;
1917 void GuiDocument::bookmarksopenChanged(bool state)
1919 pdfSupportModule->bookmarksopenlevelSB->setEnabled(state);
1920 pdfSupportModule->bookmarksopenlevelLA->setEnabled(state);
1924 void GuiDocument::changeTrackingChanged(bool state)
1926 // This is triggered if the CT state is toggled outside
1927 // the document dialog (e.g., menu).
1928 changesModule->trackChangesCB->setChecked(state);
1932 void GuiDocument::slotApply()
1934 bool only_shellescape_changed = !nonModuleChanged_ && !modulesChanged_;
1935 bool wasclean = buffer().isClean();
1936 GuiDialog::slotApply();
1937 if (wasclean && only_shellescape_changed)
1938 buffer().markClean();
1939 modulesChanged_ = false;
1944 void GuiDocument::slotOK()
1946 bool only_shellescape_changed = !nonModuleChanged_ && !modulesChanged_;
1947 bool wasclean = buffer().isClean();
1948 GuiDialog::slotOK();
1949 if (wasclean && only_shellescape_changed)
1950 buffer().markClean();
1951 modulesChanged_ = false;
1955 void GuiDocument::slotButtonBox(QAbstractButton * button)
1957 switch (buttonBox->standardButton(button)) {
1958 case QDialogButtonBox::Ok:
1961 case QDialogButtonBox::Apply:
1964 case QDialogButtonBox::Cancel:
1967 case QDialogButtonBox::Reset:
1968 case QDialogButtonBox::RestoreDefaults:
1977 void GuiDocument::filterModules(QString const & str)
1979 updateAvailableModules();
1983 modules_av_model_.clear();
1984 list<modInfoStruct> modInfoList = getModuleInfo();
1985 // Sort names according to the locale
1986 modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
1987 return 0 < b.name.localeAwareCompare(a.name);
1990 QIcon user_icon(guiApp ? guiApp->getScaledPixmap("images/", "lyxfiles-user")
1991 : getPixmap("images/", "lyxfiles-user", "svgz,png"));
1992 QIcon system_icon(guiApp ? guiApp->getScaledPixmap("images/", "lyxfiles-system")
1993 : getPixmap("images/", "lyxfiles-system", "svgz,png"));
1996 for (modInfoStruct const & m : modInfoList) {
1997 if (m.name.contains(str, Qt::CaseInsensitive) || contains(m.id, fromqstr(str))) {
1998 QStandardItem * item = new QStandardItem();
1999 item->setData(m.name, Qt::DisplayRole);
2000 item->setData(toqstr(m.id), Qt::UserRole);
2001 item->setData(m.description, Qt::ToolTipRole);
2002 item->setEditable(false);
2004 item->setIcon(user_icon);
2006 item->setIcon(system_icon);
2007 modules_av_model_.insertRow(i, item);
2014 void GuiDocument::moduleFilterChanged(const QString & text)
2016 if (!text.isEmpty()) {
2017 filterModules(filter_->text());
2020 filterModules(filter_->text());
2021 filter_->setFocus();
2025 void GuiDocument::moduleFilterPressed()
2027 filterModules(filter_->text());
2031 void GuiDocument::resetModuleFilter()
2033 filter_->setText(QString());
2034 filterModules(filter_->text());
2038 void GuiDocument::includeonlyClicked(QTreeWidgetItem * item, int)
2040 if (item == nullptr)
2043 string child = fromqstr(item->text(0));
2048 if (isChildIncluded(child))
2049 includeonlys_.remove(child);
2051 includeonlys_.push_back(child);
2053 updateIncludeonlys(false);
2058 QString GuiDocument::validateListingsParameters()
2060 if (listingsModule->bypassCB->isChecked())
2062 string const package =
2063 lst_packages[listingsModule->packageCO->currentIndex()];
2064 string params = fromqstr(listingsModule->listingsED->toPlainText());
2065 InsetListingsParams lstparams(params);
2066 lstparams.setMinted(package == "Minted");
2067 return toqstr(lstparams.validate());
2071 void GuiDocument::setListingsMessage()
2074 static bool isOK = true;
2075 QString msg = validateListingsParameters();
2076 if (msg.isEmpty()) {
2077 listingsModule->listingsTB->setTextColor(QColor());
2081 listingsModule->listingsTB->setPlainText(
2082 qt_("Input listings parameters below. "
2083 "Enter ? for a list of parameters."));
2086 listingsModule->listingsTB->setTextColor(QColor(255, 0, 0));
2087 listingsModule->listingsTB->setPlainText(msg);
2092 void GuiDocument::listingsPackageChanged(int index)
2094 string const package = lst_packages[index];
2095 if (package == "Minted" && lyxrc.pygmentize_command.empty()) {
2096 Alert::warning(_("Pygments driver command not found!"),
2097 _("The driver command necessary to use the minted package\n"
2098 "(pygmentize) has not been found. Make sure you have\n"
2099 "the python-pygments module installed or, if the driver\n"
2100 "is named differently, to add the following line to the\n"
2101 "document preamble:\n\n"
2102 "\\AtBeginDocument{\\renewcommand{\\MintedPygmentize}{driver}}\n\n"
2103 "where 'driver' is name of the driver command."));
2108 void GuiDocument::setLSpacing(int item)
2110 textLayoutModule->lspacingLE->setEnabled(item == 3);
2114 void GuiDocument::setIndent(int item)
2116 bool const enable = (textLayoutModule->indentCO->itemData(item) == "custom");
2117 textLayoutModule->indentLE->setEnabled(enable);
2118 textLayoutModule->indentLengthCO->setEnabled(enable);
2119 textLayoutModule->skipLE->setEnabled(false);
2120 textLayoutModule->skipLengthCO->setEnabled(false);
2121 // needed to catch empty custom case
2127 void GuiDocument::enableIndent(bool indent)
2129 textLayoutModule->skipLE->setEnabled(!indent);
2130 textLayoutModule->skipLengthCO->setEnabled(!indent);
2132 setIndent(textLayoutModule->indentCO->currentIndex());
2136 void GuiDocument::setSkip(int item)
2138 VSpace::VSpaceKind kind =
2139 VSpace::VSpaceKind(textLayoutModule->skipCO->itemData(item).toInt());
2140 bool const enable = (kind == VSpace::LENGTH);
2141 textLayoutModule->skipLE->setEnabled(enable);
2142 textLayoutModule->skipLengthCO->setEnabled(enable);
2143 // needed to catch empty custom case
2149 void GuiDocument::enableSkip(bool skip)
2151 textLayoutModule->indentLE->setEnabled(!skip);
2152 textLayoutModule->indentLengthCO->setEnabled(!skip);
2154 setSkip(textLayoutModule->skipCO->currentIndex());
2157 void GuiDocument::allowMathIndent() {
2158 // only disable when not checked, checked does not always allow enabling
2159 if (!mathsModule->MathIndentCB->isChecked()) {
2160 mathsModule->MathIndentLE->setEnabled(false);
2161 mathsModule->MathIndentLengthCO->setEnabled(false);
2163 if (mathsModule->MathIndentCB->isChecked()
2164 && mathsModule->MathIndentCO->itemData(mathsModule->MathIndentCO->currentIndex()) == "custom") {
2165 mathsModule->MathIndentLE->setEnabled(true);
2166 mathsModule->MathIndentLengthCO->setEnabled(true);
2171 void GuiDocument::enableMathIndent(int item)
2173 bool const enable = (item == 1);
2174 mathsModule->MathIndentLE->setEnabled(enable);
2175 mathsModule->MathIndentLengthCO->setEnabled(enable);
2176 // needed to catch empty custom case
2182 void GuiDocument::setMargins()
2184 bool const extern_geometry =
2185 documentClass().provides("geometry");
2186 marginsModule->marginCB->setEnabled(!extern_geometry);
2187 if (extern_geometry) {
2188 marginsModule->marginCB->setChecked(false);
2189 setCustomMargins(true);
2191 marginsModule->marginCB->setChecked(!bp_.use_geometry);
2192 setCustomMargins(!bp_.use_geometry);
2197 void GuiDocument::papersizeChanged(int paper_size)
2199 setCustomPapersize(paper_size == 1);
2203 void GuiDocument::setCustomPapersize(bool custom)
2205 pageLayoutModule->paperwidthL->setEnabled(custom);
2206 pageLayoutModule->paperwidthLE->setEnabled(custom);
2207 pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
2208 pageLayoutModule->paperheightL->setEnabled(custom);
2209 pageLayoutModule->paperheightLE->setEnabled(custom);
2210 pageLayoutModule->paperheightLE->setFocus();
2211 pageLayoutModule->paperheightUnitCO->setEnabled(custom);
2215 void GuiDocument::setColSep()
2217 setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
2221 void GuiDocument::setCustomMargins(bool cb_checked)
2223 bool const custom_margins = !cb_checked;
2224 if (custom_margins) {
2225 Length::UNIT const default_unit = Length::defaultUnit();
2226 // fill with chached values
2227 lengthToWidgets(marginsModule->topLE,
2228 marginsModule->topUnit,
2229 tmp_topmargin_, default_unit);
2230 lengthToWidgets(marginsModule->bottomLE,
2231 marginsModule->bottomUnit,
2232 tmp_bottommargin_, default_unit);
2233 lengthToWidgets(marginsModule->innerLE,
2234 marginsModule->innerUnit,
2235 tmp_leftmargin_, default_unit);
2236 lengthToWidgets(marginsModule->outerLE,
2237 marginsModule->outerUnit,
2238 tmp_rightmargin_, default_unit);
2239 lengthToWidgets(marginsModule->headheightLE,
2240 marginsModule->headheightUnit,
2241 tmp_headheight_, default_unit);
2242 lengthToWidgets(marginsModule->headsepLE,
2243 marginsModule->headsepUnit,
2244 tmp_headsep_, default_unit);
2245 lengthToWidgets(marginsModule->footskipLE,
2246 marginsModule->footskipUnit,
2247 tmp_footskip_, default_unit);
2248 lengthToWidgets(marginsModule->columnsepLE,
2249 marginsModule->columnsepUnit,
2250 tmp_columnsep_, default_unit);
2251 } else { // default margins
2252 // Cache current values
2253 tmp_leftmargin_ = widgetsToLength(marginsModule->innerLE,
2254 marginsModule->innerUnit);
2255 tmp_topmargin_ = widgetsToLength(marginsModule->topLE,
2256 marginsModule->topUnit);
2257 tmp_rightmargin_ = widgetsToLength(marginsModule->outerLE,
2258 marginsModule->outerUnit);
2259 tmp_bottommargin_ = widgetsToLength(marginsModule->bottomLE,
2260 marginsModule->bottomUnit);
2261 tmp_headheight_ = widgetsToLength(marginsModule->headheightLE,
2262 marginsModule->headheightUnit);
2263 tmp_headsep_ = widgetsToLength(marginsModule->headsepLE,
2264 marginsModule->headsepUnit);
2265 tmp_footskip_ = widgetsToLength(marginsModule->footskipLE,
2266 marginsModule->footskipUnit);
2267 tmp_columnsep_ = widgetsToLength(marginsModule->columnsepLE,
2268 marginsModule->columnsepUnit);
2270 marginsModule->topLE->clear();
2271 marginsModule->bottomLE->clear();
2272 marginsModule->innerLE->clear();
2273 marginsModule->outerLE->clear();
2274 marginsModule->headheightLE->clear();
2275 marginsModule->headsepLE->clear();
2276 marginsModule->footskipLE->clear();
2277 marginsModule->columnsepLE->clear();
2280 marginsModule->topL->setEnabled(custom_margins);
2281 marginsModule->topLE->setEnabled(custom_margins);
2282 marginsModule->topUnit->setEnabled(custom_margins);
2284 marginsModule->bottomL->setEnabled(custom_margins);
2285 marginsModule->bottomLE->setEnabled(custom_margins);
2286 marginsModule->bottomUnit->setEnabled(custom_margins);
2288 marginsModule->innerL->setEnabled(custom_margins);
2289 marginsModule->innerLE->setEnabled(custom_margins);
2290 marginsModule->innerUnit->setEnabled(custom_margins);
2292 marginsModule->outerL->setEnabled(custom_margins);
2293 marginsModule->outerLE->setEnabled(custom_margins);
2294 marginsModule->outerUnit->setEnabled(custom_margins);
2296 marginsModule->headheightL->setEnabled(custom_margins);
2297 marginsModule->headheightLE->setEnabled(custom_margins);
2298 marginsModule->headheightUnit->setEnabled(custom_margins);
2300 marginsModule->headsepL->setEnabled(custom_margins);
2301 marginsModule->headsepLE->setEnabled(custom_margins);
2302 marginsModule->headsepUnit->setEnabled(custom_margins);
2304 marginsModule->footskipL->setEnabled(custom_margins);
2305 marginsModule->footskipLE->setEnabled(custom_margins);
2306 marginsModule->footskipUnit->setEnabled(custom_margins);
2308 bool const enableColSep = custom_margins &&
2309 textLayoutModule->twoColumnCB->isChecked();
2310 marginsModule->columnsepL->setEnabled(enableColSep);
2311 marginsModule->columnsepLE->setEnabled(enableColSep);
2312 marginsModule->columnsepUnit->setEnabled(enableColSep);
2314 // set some placeholder text that hint on defaults
2315 QString const placeholder = marginsModule->marginCB->isChecked() ?
2316 qt_("Default margins") : qt_("Package defaults");
2317 // set tooltip depending on gemoetry state
2318 QString const tooltip = marginsModule->marginCB->isChecked() ?
2319 qt_("If no value is given, the defaults as set by the class, a package or the preamble are used.")
2320 : qt_("If no value is given, the defaults as set by the geometry package or a package/class overriding geometry's defaults are used.");
2321 marginsModule->topLE->setPlaceholderText(placeholder);
2322 marginsModule->bottomLE->setPlaceholderText(placeholder);
2323 marginsModule->innerLE->setPlaceholderText(placeholder);
2324 marginsModule->outerLE->setPlaceholderText(placeholder);
2325 marginsModule->headheightLE->setPlaceholderText(placeholder);
2326 marginsModule->headsepLE->setPlaceholderText(placeholder);
2327 marginsModule->footskipLE->setPlaceholderText(placeholder);
2328 marginsModule->columnsepLE->setPlaceholderText(placeholder);
2329 marginsModule->topLE->setToolTip(tooltip);
2330 marginsModule->bottomLE->setToolTip(tooltip);
2331 marginsModule->innerLE->setToolTip(tooltip);
2332 marginsModule->outerLE->setToolTip(tooltip);
2333 marginsModule->headheightLE->setToolTip(tooltip);
2334 marginsModule->headsepLE->setToolTip(tooltip);
2335 marginsModule->footskipLE->setToolTip(tooltip);
2336 marginsModule->columnsepLE->setToolTip(tooltip);
2340 void GuiDocument::changeBackgroundColor()
2342 QColor const & newColor = getColor(rgb2qcolor(set_backgroundcolor));
2343 if (!newColor.isValid())
2346 colorModule->pageBackgroundCF->setVisible(true);
2347 colorModule->pageBackgroundCF->setStyleSheet(
2348 colorFrameStyleSheet(newColor));
2350 set_backgroundcolor = rgbFromHexName(fromqstr(newColor.name()));
2351 is_backgroundcolor = true;
2356 void GuiDocument::deleteBackgroundColor()
2358 // set the color back to default by setting an empty StyleSheet
2359 colorModule->pageBackgroundCF->setStyleSheet(QLatin1String(""));
2360 colorModule->pageBackgroundCF->setVisible(false);
2361 // save default color (white)
2362 set_backgroundcolor = rgbFromHexName("#ffffff");
2363 is_backgroundcolor = false;
2368 void GuiDocument::changeFontColor()
2370 QColor const & newColor = getColor(rgb2qcolor(set_fontcolor));
2371 if (!newColor.isValid())
2374 colorModule->mainTextCF->setVisible(true);
2375 colorModule->mainTextCF->setStyleSheet(
2376 colorFrameStyleSheet(newColor));
2378 set_fontcolor = rgbFromHexName(fromqstr(newColor.name()));
2379 is_fontcolor = true;
2384 void GuiDocument::deleteFontColor()
2386 // set the button color back to default by setting an empty StyleSheet
2387 colorModule->mainTextCF->setStyleSheet(QLatin1String(""));
2388 colorModule->mainTextCF->setVisible(false);
2389 // save default color (black)
2390 set_fontcolor = rgbFromHexName("#000000");
2391 is_fontcolor = false;
2396 void GuiDocument::changeNoteFontColor()
2398 QColor const & newColor = getColor(rgb2qcolor(set_notefontcolor));
2399 if (!newColor.isValid())
2402 colorModule->noteFontCF->setStyleSheet(
2403 colorFrameStyleSheet(newColor));
2405 set_notefontcolor = rgbFromHexName(fromqstr(newColor.name()));
2406 is_notefontcolor = true;
2411 void GuiDocument::deleteNoteFontColor()
2413 // set the color back to pref
2414 theApp()->getRgbColor(Color_greyedouttext, set_notefontcolor);
2415 colorModule->noteFontCF->setStyleSheet(
2416 colorFrameStyleSheet(rgb2qcolor(set_notefontcolor)));
2417 is_notefontcolor = false;
2422 void GuiDocument::changeBoxBackgroundColor()
2424 QColor const & newColor = getColor(rgb2qcolor(set_boxbgcolor));
2425 if (!newColor.isValid())
2428 colorModule->boxBackgroundCF->setStyleSheet(
2429 colorFrameStyleSheet(newColor));
2431 set_boxbgcolor = rgbFromHexName(fromqstr(newColor.name()));
2432 is_boxbgcolor = true;
2437 void GuiDocument::deleteBoxBackgroundColor()
2439 // set the color back to pref
2440 theApp()->getRgbColor(Color_shadedbg, set_boxbgcolor);
2441 colorModule->boxBackgroundCF->setStyleSheet(
2442 colorFrameStyleSheet(rgb2qcolor(set_boxbgcolor)));
2443 is_boxbgcolor = false;
2448 void GuiDocument::updateQuoteStyles(bool const set)
2450 Language const * lang = lyx::languages.getLanguage(
2451 fromqstr(langModule->languageCO->itemData(
2452 langModule->languageCO->currentIndex()).toString()));
2454 QuoteStyle def = bp_.getQuoteStyle(lang->quoteStyle());
2456 langModule->quoteStyleCO->clear();
2458 bool has_default = false;
2459 for (int i = 0; i < quoteparams.stylescount(); ++i) {
2460 QuoteStyle qs = QuoteStyle(i);
2461 if (qs == QuoteStyle::Dynamic)
2463 bool const langdef = (qs == def);
2465 // add the default style on top
2466 langModule->quoteStyleCO->insertItem(0,
2467 toqstr(quoteparams.getGuiLabel(qs, langdef)), static_cast<int>(qs));
2471 langModule->quoteStyleCO->addItem(
2472 toqstr(quoteparams.getGuiLabel(qs, langdef)), static_cast<int>(qs));
2474 // Use document serif font to assure quotation marks are distinguishable
2475 QFont comboFont(toqstr(lyxrc.roman_font_name),
2476 langModule->quoteStyleCO->fontInfo().pointSize() * 1.4, -1, false);
2477 QFontMetrics fm(comboFont);
2478 // calculate width of the widest item in the set font
2480 for (int i = 0; i < langModule->quoteStyleCO->count(); ++i) {
2481 langModule->quoteStyleCO->setItemData(i, QVariant(comboFont), Qt::FontRole);
2482 QString str = langModule->quoteStyleCO->itemText(i);
2483 #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
2484 qswidth = max(qswidth, fm.horizontalAdvance(str));
2486 qswidth = max(qswidth, fm.width(str));
2489 // add scrollbar width and margin to width
2490 qswidth += langModule->quoteStyleCO->style()->pixelMetric(QStyle::PM_ScrollBarExtent);
2491 qswidth += langModule->quoteStyleCO->view()->autoScrollMargin();
2492 langModule->quoteStyleCO->view()->setMinimumWidth(qswidth);
2493 if (set && has_default)
2494 // (re)set to the default style
2495 langModule->quoteStyleCO->setCurrentIndex(0);
2499 void GuiDocument::languageChanged(int i)
2501 // some languages only work with Polyglossia
2502 Language const * lang = lyx::languages.getLanguage(
2503 fromqstr(langModule->languageCO->itemData(i).toString()));
2504 if (lang->babel().empty() && !lang->polyglossia().empty()
2505 && lang->required() != "CJK" && lang->required() != "japanese") {
2506 // If we force to switch fontspec on, store
2507 // current state (#8717)
2508 if (fontModule->osFontsCB->isEnabled())
2509 forced_fontspec_activation =
2510 !fontModule->osFontsCB->isChecked();
2511 fontModule->osFontsCB->setChecked(true);
2512 fontModule->osFontsCB->setEnabled(false);
2515 fontModule->osFontsCB->setEnabled(true);
2516 // If we have forced to switch fontspec on,
2517 // restore previous state (#8717)
2518 if (forced_fontspec_activation)
2519 fontModule->osFontsCB->setChecked(false);
2520 forced_fontspec_activation = false;
2523 // set appropriate quotation mark style
2524 updateQuoteStyles(true);
2528 void GuiDocument::osFontsChanged(bool nontexfonts)
2530 bool const tex_fonts = !nontexfonts;
2531 // store current fonts
2532 QString const font_roman = fontModule->fontsRomanCO->getData(
2533 fontModule->fontsRomanCO->currentIndex());
2534 QString const font_sans = fontModule->fontsSansCO->getData(
2535 fontModule->fontsSansCO->currentIndex());
2536 QString const font_typewriter = fontModule->fontsTypewriterCO->getData(
2537 fontModule->fontsTypewriterCO->currentIndex());
2538 QString const font_math = fontModule->fontsMathCO->itemData(
2539 fontModule->fontsMathCO->currentIndex()).toString();
2540 int const font_sf_scale = fontModule->scaleSansSB->value();
2541 int const font_tt_scale = fontModule->scaleTypewriterSB->value();
2544 // store default format
2545 QString const dformat = outputModule->defaultFormatCO->itemData(
2546 outputModule->defaultFormatCO->currentIndex()).toString();
2547 updateDefaultFormat();
2548 // try to restore default format
2549 int index = outputModule->defaultFormatCO->findData(dformat);
2550 // set to default if format is not found
2553 outputModule->defaultFormatCO->setCurrentIndex(index);
2555 // try to restore fonts which were selected two toggles ago
2556 if (!fontModule->font_roman.isEmpty())
2557 fontModule->fontsRomanCO->set(fontModule->font_roman);
2558 if (!fontModule->font_sans.isEmpty())
2559 fontModule->fontsSansCO->set(fontModule->font_sans);
2560 if (!fontModule->font_typewriter.isEmpty())
2561 fontModule->fontsTypewriterCO->set(fontModule->font_typewriter);
2562 index = fontModule->fontsMathCO->findData(fontModule->font_math);
2564 fontModule->fontsMathCO->setCurrentIndex(index);
2565 // save fonts for next next toggle
2566 fontModule->font_roman = font_roman;
2567 fontModule->font_sans = font_sans;
2568 fontModule->font_typewriter = font_typewriter;
2569 fontModule->font_math = font_math;
2570 fontModule->font_sf_scale = font_sf_scale;
2571 fontModule->font_tt_scale = font_tt_scale;
2573 // non-tex fonts override the "\inputencoding" option with "utf8-plain"
2574 langModule->encodingCO->setEnabled(tex_fonts);
2575 inputencodingToDialog();
2577 fontModule->cjkFontLE->setEnabled(tex_fonts);
2578 fontModule->cjkFontLA->setEnabled(tex_fonts);
2580 updateFontOptions();
2582 fontModule->fontencLA->setEnabled(tex_fonts);
2583 fontModule->fontencCO->setEnabled(tex_fonts);
2585 fontModule->fontencLE->setEnabled(false);
2587 fontencChanged(fontModule->fontencCO->currentIndex());
2591 void GuiDocument::encodingSwitched(int i)
2593 bool const tex_fonts = !fontModule->osFontsCB->isChecked();
2594 langModule->unicodeEncodingCO->setEnabled(tex_fonts);
2595 langModule->customEncodingCO->setEnabled(tex_fonts);
2596 langModule->autoEncodingCO->setEnabled(tex_fonts);
2597 langModule->unicodeEncodingCO->setVisible(i == EncodingSets::unicode);
2598 langModule->autoEncodingCO->setVisible(i == EncodingSets::legacy);
2599 langModule->customEncodingCO->setVisible(i == EncodingSets::custom);
2601 case EncodingSets::unicode:
2602 langModule->encodingVariantLA->setBuddy(langModule->unicodeEncodingCO);
2604 case EncodingSets::legacy:
2605 langModule->encodingVariantLA->setBuddy(langModule->autoEncodingCO);
2607 case EncodingSets::custom:
2608 langModule->encodingVariantLA->setBuddy(langModule->customEncodingCO);
2613 langModule->unicodeEncodingCO->setItemText(1, qt_("Direct (No inputenc)"));
2615 langModule->unicodeEncodingCO->setItemText(1, qt_("Direct (XeTeX/LuaTeX)"));
2618 void GuiDocument::inputencodingToDialog()
2620 QString inputenc = toqstr(bp_.inputenc);
2622 if (fontModule->osFontsCB->isChecked()) { // non-tex fonts require utf8-plain
2623 langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
2624 langModule->unicodeEncodingCO->setCurrentIndex(
2625 langModule->unicodeEncodingCO->findData("utf8-plain"));
2626 } else if (inputenc.startsWith("utf8")) {
2627 langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
2628 p = langModule->unicodeEncodingCO->findData(inputenc);
2631 langModule->unicodeEncodingCO->setCurrentIndex(p);
2632 langModule->autoEncodingCO->setCurrentIndex(0);
2633 langModule->customEncodingCO->setCurrentIndex(0);
2634 } else if (inputenc.startsWith("auto")) {
2635 langModule->encodingCO->setCurrentIndex(EncodingSets::legacy);
2636 p = langModule->autoEncodingCO->findData(inputenc);
2639 langModule->unicodeEncodingCO->setCurrentIndex(0);
2640 langModule->autoEncodingCO->setCurrentIndex(p);
2641 langModule->customEncodingCO->setCurrentIndex(0);
2643 langModule->encodingCO->setCurrentIndex(EncodingSets::custom);
2644 p = langModule->customEncodingCO->findData(inputenc);
2647 langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
2649 langModule->unicodeEncodingCO->setCurrentIndex(0);
2650 langModule->autoEncodingCO->setCurrentIndex(0);
2651 langModule->customEncodingCO->setCurrentIndex(p);
2653 encodingSwitched(langModule->encodingCO->currentIndex());
2657 void GuiDocument::mathFontChanged(int)
2659 updateFontOptions();
2662 void GuiDocument::fontOsfToggled(bool state)
2664 if (fontModule->osFontsCB->isChecked())
2666 QString font = fontModule->fontsRomanCO->getData(
2667 fontModule->fontsRomanCO->currentIndex());
2668 if (hasMonolithicExpertSet(font))
2669 fontModule->fontScCB->setChecked(state);
2673 void GuiDocument::fontScToggled(bool state)
2675 if (fontModule->osFontsCB->isChecked())
2677 QString font = fontModule->fontsRomanCO->getData(
2678 fontModule->fontsRomanCO->currentIndex());
2679 if (hasMonolithicExpertSet(font))
2680 fontModule->fontOsfCB->setChecked(state);
2684 void GuiDocument::updateExtraOpts()
2686 QString font = fontModule->fontsRomanCO->getData(
2687 fontModule->fontsRomanCO->currentIndex());
2688 bool const rm_opts = providesExtraOpts(font);
2689 font = fontModule->fontsSansCO->getData(
2690 fontModule->fontsSansCO->currentIndex());
2691 bool const sf_opts = providesExtraOpts(font);
2692 font = fontModule->fontsTypewriterCO->getData(
2693 fontModule->fontsTypewriterCO->currentIndex());
2694 bool const tt_opts = providesExtraOpts(font);
2695 fontModule->fontspecRomanLA->setEnabled(rm_opts);
2696 fontModule->fontspecRomanLE->setEnabled(rm_opts);
2697 fontModule->fontspecSansLA->setEnabled(sf_opts);
2698 fontModule->fontspecSansLE->setEnabled(sf_opts);
2699 fontModule->fontspecTypewriterLA->setEnabled(tt_opts);
2700 fontModule->fontspecTypewriterLE->setEnabled(tt_opts);
2704 void GuiDocument::updateFontOptions()
2706 QString font = fontModule->fontsSansCO->getData(
2707 fontModule->fontsSansCO->currentIndex());
2708 bool scalable = providesScale(font);
2709 fontModule->scaleSansSB->setEnabled(scalable);
2710 fontModule->scaleSansLA->setEnabled(scalable);
2711 fontModule->fontSansOsfCB->setEnabled(providesOSF(font));
2712 font = fontModule->fontsTypewriterCO->getData(
2713 fontModule->fontsTypewriterCO->currentIndex());
2714 scalable = providesScale(font);
2715 fontModule->scaleTypewriterSB->setEnabled(scalable);
2716 fontModule->scaleTypewriterLA->setEnabled(scalable);
2717 fontModule->fontTypewriterOsfCB->setEnabled(providesOSF(font));
2718 font = fontModule->fontsRomanCO->getData(
2719 fontModule->fontsRomanCO->currentIndex());
2720 fontModule->fontScCB->setEnabled(providesSC(font));
2721 fontModule->fontOsfCB->setEnabled(providesOSF(font));
2723 updateMathFonts(font);
2727 void GuiDocument::updateFontsize(string const & items, string const & sel)
2729 fontModule->fontsizeCO->clear();
2730 fontModule->fontsizeCO->addItem(qt_("Default"));
2732 for (int n = 0; !token(items,'|',n).empty(); ++n)
2733 fontModule->fontsizeCO->
2734 addItem(toqstr(token(items,'|',n)));
2736 for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
2737 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
2738 fontModule->fontsizeCO->setCurrentIndex(n);
2745 bool GuiDocument::ot1() const
2747 QString const fontenc =
2748 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
2749 int const i = langModule->languageCO->currentIndex();
2752 QString const langname = langModule->languageCO->itemData(i).toString();
2753 Language const * newlang = lyx::languages.getLanguage(fromqstr(langname));
2754 return (fontenc == "default"
2755 || (fontenc == "auto" && newlang->fontenc(buffer().params()) == "OT1")
2756 || (fontenc == "custom" && fontModule->fontencLE->text() == "OT1"));
2760 bool GuiDocument::completeFontset() const
2762 return (fontModule->fontsSansCO->getData(
2763 fontModule->fontsSansCO->currentIndex()) == "default"
2764 && fontModule->fontsSansCO->getData(
2765 fontModule->fontsTypewriterCO->currentIndex()) == "default");
2769 bool GuiDocument::noMathFont() const
2771 return (fontModule->fontsMathCO->itemData(
2772 fontModule->fontsMathCO->currentIndex()).toString() == "default");
2776 void GuiDocument::updateTexFonts()
2778 LaTeXFonts::TexFontMap texfontmap = theLaTeXFonts().getLaTeXFonts();
2780 LaTeXFonts::TexFontMap::const_iterator it = texfontmap.begin();
2781 LaTeXFonts::TexFontMap::const_iterator end = texfontmap.end();
2782 for (; it != end; ++it) {
2783 LaTeXFont lf = it->second;
2784 if (lf.name().empty()) {
2785 LYXERR0("Error: Unnamed font: " << it->first);
2788 docstring const family = lf.family();
2789 docstring guiname = translateIfPossible(lf.guiname());
2790 if (!lf.available(ot1(), noMathFont()))
2791 guiname += _(" (not installed)");
2793 rmfonts_.insert(toqstr(guiname), toqstr(it->first));
2794 else if (family == "sf")
2795 sffonts_.insert(toqstr(guiname), toqstr(it->first));
2796 else if (family == "tt")
2797 ttfonts_.insert(toqstr(guiname), toqstr(it->first));
2798 else if (family == "math")
2799 mathfonts_.insert(toqstr(guiname), toqstr(it->first));
2804 void GuiDocument::updateFontlist()
2806 // reset the filters of the CategorizedCombos
2807 fontModule->fontsRomanCO->resetFilter();
2808 fontModule->fontsSansCO->resetFilter();
2809 fontModule->fontsTypewriterCO->resetFilter();
2810 fontModule->fontsRomanCO->clear();
2811 fontModule->fontsSansCO->clear();
2812 fontModule->fontsTypewriterCO->clear();
2813 fontModule->fontsMathCO->clear();
2815 // With fontspec (XeTeX, LuaTeX), we have access to all system fonts, but not the LaTeX fonts
2816 if (fontModule->osFontsCB->isChecked()) {
2817 fontModule->fontsRomanCO->addItemSort(QString("default"), qt_("Default"),
2818 QString(), qt_("Default font (as set by class)"),
2819 false, false, false, true, true);
2820 fontModule->fontsSansCO->addItemSort(QString("default"), qt_("Default"),
2821 QString(), qt_("Default font (as set by class)"),
2822 false, false, false, true, true);
2823 fontModule->fontsTypewriterCO->addItemSort(QString("default"), qt_("Default"),
2824 QString(), qt_("Default font (as set by class)"),
2825 false, false, false, true, true);
2826 QString unimath = qt_("Non-TeX Fonts Default");
2827 if (!LaTeXFeatures::isAvailable("unicode-math"))
2828 unimath += qt_(" (not available)");
2829 fontModule->fontsMathCO->addItem(qt_("Class Default (TeX Fonts)"), QString("auto"));
2830 fontModule->fontsMathCO->addItem(unimath, QString("default"));
2832 #if QT_VERSION >= 0x060000
2833 const QStringList families(QFontDatabase::families());
2835 QFontDatabase fontdb;
2836 const QStringList families(fontdb.families());
2838 for (auto const & family : families) {
2839 fontModule->fontsRomanCO->addItemSort(family, family,
2840 QString(), QString(),
2841 false, false, false, true, true);
2842 fontModule->fontsSansCO->addItemSort(family, family,
2843 QString(), QString(),
2844 false, false, false, true, true);
2845 fontModule->fontsTypewriterCO->addItemSort(family, family,
2846 QString(), QString(),
2847 false, false, false, true, true);
2852 if (rmfonts_.empty())
2855 fontModule->fontsRomanCO->addItemSort(QString("default"), qt_("Default"),
2856 QString(), qt_("Default font (as set by class)"),
2857 false, false, false, true, true);
2858 QMap<QString, QString>::const_iterator rmi = rmfonts_.constBegin();
2859 while (rmi != rmfonts_.constEnd()) {
2860 fontModule->fontsRomanCO->addItemSort(rmi.value(), rmi.key(),
2861 QString(), QString(),
2862 false, false, false, true, true);
2866 fontModule->fontsSansCO->addItemSort(QString("default"), qt_("Default"),
2867 QString(), qt_("Default font (as set by class)"),
2868 false, false, false, true, true);
2869 QMap<QString, QString>::const_iterator sfi = sffonts_.constBegin();
2870 while (sfi != sffonts_.constEnd()) {
2871 fontModule->fontsSansCO->addItemSort(sfi.value(), sfi.key(),
2872 QString(), QString(),
2873 false, false, false, true, true);
2877 fontModule->fontsTypewriterCO->addItemSort(QString("default"), qt_("Default"),
2878 QString(), qt_("Default font (as set by class)"),
2879 false, false, false, true, true);
2880 QMap<QString, QString>::const_iterator tti = ttfonts_.constBegin();
2881 while (tti != ttfonts_.constEnd()) {
2882 fontModule->fontsTypewriterCO->addItemSort(tti.value(), tti.key(),
2883 QString(), QString(),
2884 false, false, false, true, true);
2888 fontModule->fontsMathCO->addItem(qt_("Automatic"), QString("auto"));
2889 fontModule->fontsMathCO->addItem(qt_("Class Default"), QString("default"));
2890 QMap<QString, QString>::const_iterator mmi = mathfonts_.constBegin();
2891 while (mmi != mathfonts_.constEnd()) {
2892 fontModule->fontsMathCO->addItem(mmi.key(), mmi.value());
2898 void GuiDocument::fontencChanged(int item)
2900 fontModule->fontencLE->setEnabled(
2901 fontModule->fontencCO->itemData(item).toString() == "custom");
2902 // The availability of TeX fonts depends on the font encoding
2904 updateFontOptions();
2908 void GuiDocument::updateMathFonts(QString const & rm)
2910 if (fontModule->osFontsCB->isChecked())
2912 QString const math =
2913 fontModule->fontsMathCO->itemData(fontModule->fontsMathCO->currentIndex()).toString();
2914 int const i = fontModule->fontsMathCO->findData("default");
2915 if (providesNoMath(rm) && i == -1)
2916 fontModule->fontsMathCO->insertItem(1, qt_("Class Default"), QString("default"));
2917 else if (!providesNoMath(rm) && i != -1) {
2918 int const c = fontModule->fontsMathCO->currentIndex();
2919 fontModule->fontsMathCO->removeItem(i);
2921 fontModule->fontsMathCO->setCurrentIndex(0);
2926 void GuiDocument::romanChanged(int item)
2928 QString const font = fontModule->fontsRomanCO->getData(item);
2929 fontModule->fontOsfCB->setEnabled(providesOSF(font));
2931 if (fontModule->osFontsCB->isChecked())
2933 fontModule->fontScCB->setEnabled(providesSC(font));
2934 updateMathFonts(font);
2938 void GuiDocument::sansChanged(int item)
2940 QString const font = fontModule->fontsSansCO->getData(item);
2941 bool const scalable = providesScale(font);
2942 fontModule->scaleSansSB->setEnabled(scalable);
2943 fontModule->scaleSansLA->setEnabled(scalable);
2944 fontModule->fontSansOsfCB->setEnabled(providesOSF(font));
2949 void GuiDocument::ttChanged(int item)
2951 QString const font = fontModule->fontsTypewriterCO->getData(item);
2952 bool scalable = providesScale(font);
2953 fontModule->scaleTypewriterSB->setEnabled(scalable);
2954 fontModule->scaleTypewriterLA->setEnabled(scalable);
2955 fontModule->fontTypewriterOsfCB->setEnabled(providesOSF(font));
2960 void GuiDocument::updatePagestyle(string const & items, string const & sel)
2963 pageLayoutModule->pagestyleCO->clear();
2964 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
2966 for (int n = 0; !token(items, '|', n).empty(); ++n) {
2967 string style = token(items, '|', n);
2968 QString style_gui = qt_(style);
2969 pagestyles.push_back(pair<string, QString>(style, style_gui));
2970 pageLayoutModule->pagestyleCO->addItem(style_gui);
2973 if (sel == "default") {
2974 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
2980 for (auto const & pagestyle : pagestyles)
2981 if (pagestyle.first == sel)
2982 nn = pageLayoutModule->pagestyleCO->findText(pagestyle.second);
2985 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
2989 void GuiDocument::browseLayout()
2991 QString const label1 = qt_("Lay&outs");
2992 QString const dir1 = toqstr(lyxrc.document_path);
2993 QStringList const filter(qt_("LyX Layout (*.layout)"));
2994 QString file = browseRelToParent(QString(), bufferFilePath(),
2995 qt_("Local layout file"), filter, false,
2998 if (!file.endsWith(".layout"))
3001 FileName layoutFile = support::makeAbsPath(fromqstr(file),
3002 fromqstr(bufferFilePath()));
3004 int const ret = Alert::prompt(_("Local layout file"),
3005 _("The layout file you have selected is a local layout\n"
3006 "file, not one in the system or user directory.\n"
3007 "Your document will not work with this layout if you\n"
3008 "move the layout file to a different directory."),
3009 1, 1, _("&Set Layout"), _("&Cancel"));
3013 // load the layout file
3014 LayoutFileList & bcl = LayoutFileList::get();
3015 string classname = layoutFile.onlyFileName();
3016 // this will update an existing layout if that layout has been loaded before.
3017 LayoutFileIndex name = support::onlyFileName(bcl.addLocalLayout(
3018 classname.substr(0, classname.size() - 7),
3019 layoutFile.onlyPath().absFileName()));
3022 Alert::error(_("Error"),
3023 _("Unable to read local layout file."));
3027 const_cast<Buffer &>(buffer()).setLayoutPos(layoutFile.onlyPath().absFileName());
3029 // do not trigger classChanged if there is no change.
3030 if (latexModule->classCO->currentText() == toqstr(name))
3034 bool const avail = latexModule->classCO->set(toqstr(name));
3036 LayoutFile const & tc = bcl[name];
3037 docstring const guiname = translateIfPossible(from_utf8(tc.description()));
3038 // tooltip sensu "KOMA-Script Article [Class 'scrartcl']"
3039 QString tooltip = toqstr(bformat(_("%1$s [Class '%2$s']"), guiname, from_utf8(tc.latexname())));
3040 tooltip += '\n' + qt_("This is a local layout file.");
3041 latexModule->classCO->addItemSort(toqstr(tc.name()), toqstr(guiname),
3042 toqstr(translateIfPossible(from_utf8(tc.category()))),
3044 true, true, true, true);
3045 latexModule->classCO->set(toqstr(name));
3052 void GuiDocument::browseMaster()
3054 QString const title = qt_("Select master document");
3055 QString const dir1 = toqstr(lyxrc.document_path);
3056 QString const old = latexModule->childDocLE->text();
3057 QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
3058 QStringList const filter(qt_("LyX Files (*.lyx)"));
3059 QString file = browseRelToSub(old, docpath, title, filter, false,
3060 qt_("D&ocuments"), toqstr(lyxrc.document_path));
3062 if (!file.isEmpty())
3063 latexModule->childDocLE->setText(file);
3067 void GuiDocument::classChanged_adaptor()
3069 const_cast<Buffer &>(buffer()).setLayoutPos(string());
3074 void GuiDocument::classChanged()
3076 int idx = latexModule->classCO->currentIndex();
3079 string const classname = fromqstr(latexModule->classCO->getData(idx));
3081 if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
3082 int const ret = Alert::prompt(_("Unapplied changes"),
3083 _("Some changes in the dialog were not yet applied.\n"
3084 "If you do not apply now, they will be lost after this action."),
3085 1, 1, _("&Apply"), _("&Dismiss"));
3090 // We load the TextClass as soon as it is selected. This is
3091 // necessary so that other options in the dialog can be updated
3092 // according to the new class. Note, however, that, if you use
3093 // the scroll wheel when sitting on the combo box, we'll load a
3094 // lot of TextClass objects very quickly....
3095 if (!bp_.setBaseClass(classname, buffer().layoutPos())) {
3096 Alert::error(_("Error"), _("Unable to set document class."));
3099 if (lyxrc.auto_reset_options)
3100 bp_.useClassDefaults();
3102 // With the introduction of modules came a distinction between the base
3103 // class and the document class. The former corresponds to the main layout
3104 // file; the latter is that plus the modules (or the document-specific layout,
3105 // or whatever else there could be). Our parameters come from the document
3106 // class. So when we set the base class, we also need to recreate the document
3107 // class. Otherwise, we still have the old one.
3108 bp_.makeDocumentClass();
3113 void GuiDocument::languagePackageChanged(int i)
3115 langModule->languagePackageLE->setEnabled(
3116 langModule->languagePackageCO->itemData(i).toString() == "custom");
3120 void GuiDocument::biblioChanged()
3122 biblioChanged_ = true;
3127 void GuiDocument::checkPossibleCiteEngines()
3129 // Check if the class provides a specific engine,
3130 // and if so, enforce this.
3131 string force_engine;
3132 if (documentClass().provides("natbib")
3133 || documentClass().provides("natbib-internal"))
3134 force_engine = "natbib";
3135 else if (documentClass().provides("jurabib"))
3136 force_engine = "jurabib";
3137 else if (documentClass().provides("biblatex"))
3138 force_engine = "biblatex";
3139 else if (documentClass().provides("biblatex-natbib"))
3140 force_engine = "biblatex-natbib";
3142 if (!force_engine.empty())
3143 biblioModule->citeEngineCO->setCurrentIndex(
3144 biblioModule->citeEngineCO->findData(toqstr(force_engine)));
3145 biblioModule->citeEngineCO->setEnabled(force_engine.empty());
3149 void GuiDocument::rescanBibFiles()
3152 rescanTexStyles("bbx cbx");
3154 rescanTexStyles("bst");
3158 void GuiDocument::resetDefaultBibfile(string const & which)
3160 QString const engine =
3161 biblioModule->citeEngineCO->itemData(
3162 biblioModule->citeEngineCO->currentIndex()).toString();
3164 CiteEngineType const cet =
3165 CiteEngineType(biblioModule->citeStyleCO->itemData(
3166 biblioModule->citeStyleCO->currentIndex()).toInt());
3168 updateDefaultBiblio(theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet), which);
3172 void GuiDocument::resetDefaultBbxBibfile()
3174 resetDefaultBibfile("bbx");
3178 void GuiDocument::resetDefaultCbxBibfile()
3180 resetDefaultBibfile("cbx");
3184 void GuiDocument::citeEngineChanged(int n)
3186 QString const engine =
3187 biblioModule->citeEngineCO->itemData(n).toString();
3189 vector<string> const engs =
3190 theCiteEnginesList[fromqstr(engine)]->getEngineType();
3192 updateCiteStyles(engs);
3193 updateEngineDependends();
3194 resetDefaultBibfile();
3199 void GuiDocument::updateEngineDependends()
3201 bool const biblatex = isBiblatex();
3203 // These are only useful with BibTeX
3204 biblioModule->defaultBiblioCO->setEnabled(!biblatex);
3205 biblioModule->bibtexStyleLA->setEnabled(!biblatex);
3206 biblioModule->resetDefaultBiblioPB->setEnabled(!biblatex);
3207 biblioModule->bibtopicCB->setEnabled(!biblatex);
3209 // These are only useful with Biblatex
3210 biblioModule->biblatexBbxCO->setEnabled(biblatex);
3211 biblioModule->biblatexBbxLA->setEnabled(biblatex);
3212 biblioModule->biblatexCbxCO->setEnabled(biblatex);
3213 biblioModule->biblatexCbxLA->setEnabled(biblatex);
3214 biblioModule->resetBbxPB->setEnabled(biblatex);
3215 biblioModule->resetCbxPB->setEnabled(biblatex);
3216 biblioModule->matchBbxPB->setEnabled(biblatex);
3218 // These are useful with biblatex, jurabib and natbib
3219 QString const engine =
3220 biblioModule->citeEngineCO->itemData(
3221 biblioModule->citeEngineCO->currentIndex()).toString();
3222 LyXCiteEngine const * ce = theCiteEnginesList[fromqstr(engine)];
3224 bool const citepack = ce->required("biblatex.sty") || ce->required("jurabib.sty")
3225 || ce->required("natbib.sty");
3226 biblioModule->citePackageOptionsLE->setEnabled(citepack);
3227 biblioModule->citePackageOptionsL->setEnabled(citepack);
3231 void GuiDocument::citeStyleChanged()
3233 QString const engine =
3234 biblioModule->citeEngineCO->itemData(
3235 biblioModule->citeEngineCO->currentIndex()).toString();
3236 QString const currentDef = isBiblatex() ?
3237 biblioModule->biblatexBbxCO->currentText()
3238 : biblioModule->defaultBiblioCO->currentText();
3239 if (theCiteEnginesList[fromqstr(engine)]->isDefaultBiblio(fromqstr(currentDef)))
3240 resetDefaultBibfile();
3246 void GuiDocument::bibtexChanged(int n)
3248 biblioModule->bibtexOptionsLE->setEnabled(
3249 biblioModule->bibtexCO->itemData(n).toString() != "default");
3254 void GuiDocument::updateCiteStyles(vector<string> const & engs, CiteEngineType const & sel)
3256 biblioModule->citeStyleCO->clear();
3258 vector<string>::const_iterator it = engs.begin();
3259 vector<string>::const_iterator end = engs.end();
3260 for (; it != end; ++it) {
3261 if (*it == "default")
3262 biblioModule->citeStyleCO->addItem(qt_("Basic numerical"),
3263 ENGINE_TYPE_DEFAULT);
3264 else if (*it == "authoryear")
3265 biblioModule->citeStyleCO->addItem(qt_("Author-year"),
3266 ENGINE_TYPE_AUTHORYEAR);
3267 else if (*it == "numerical")
3268 biblioModule->citeStyleCO->addItem(qt_("Author-number"),
3269 ENGINE_TYPE_NUMERICAL);
3271 int i = biblioModule->citeStyleCO->findData(sel);
3272 if (biblioModule->citeStyleCO->findData(sel) == -1)
3274 biblioModule->citeStyleCO->setCurrentIndex(i);
3276 biblioModule->citationStyleL->setEnabled(engs.size() > 1);
3277 biblioModule->citeStyleCO->setEnabled(engs.size() > 1);
3281 void GuiDocument::updateEngineType(string const & items, CiteEngineType const & sel)
3283 engine_types_.clear();
3285 for (int n = 0; !token(items, '|', n).empty(); ++n) {
3286 string style = token(items, '|', n);
3287 engine_types_.push_back(style);
3290 updateCiteStyles(engine_types_, sel);
3296 // both of these should take a vector<docstring>
3298 // This is an insanely complicated attempt to make this sort of thing
3299 // work with RTL languages.
3300 docstring formatStrVec(vector<string> const & v, docstring const & s)
3302 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
3306 return translateIfPossible(from_utf8(v[0]));
3307 if (v.size() == 2) {
3308 docstring retval = _("%1$s and %2$s");
3309 retval = subst(retval, _("and"), s);
3310 return bformat(retval, translateIfPossible(from_utf8(v[0])),
3311 translateIfPossible(from_utf8(v[1])));
3313 // The idea here is to format all but the last two items...
3314 int const vSize = v.size();
3315 docstring t2 = _("%1$s, %2$s");
3316 docstring retval = translateIfPossible(from_utf8(v[0]));
3317 for (int i = 1; i < vSize - 2; ++i)
3318 retval = bformat(t2, retval, translateIfPossible(from_utf8(v[i])));
3319 //...and then to plug them, and the last two, into this schema
3320 docstring t = _("%1$s, %2$s, and %3$s");
3321 t = subst(t, _("and"), s);
3322 return bformat(t, retval, translateIfPossible(from_utf8(v[vSize - 2])),
3323 translateIfPossible(from_utf8(v[vSize - 1])));
3326 vector<string> idsToNames(vector<string> const & idList)
3328 vector<string> retval;
3329 vector<string>::const_iterator it = idList.begin();
3330 vector<string>::const_iterator end = idList.end();
3331 for (; it != end; ++it) {
3332 LyXModule const * const mod = theModuleList[*it];
3334 retval.push_back(to_utf8(bformat(_("%1$s (unavailable)"),
3335 translateIfPossible(from_utf8(*it)))));
3337 retval.push_back(mod->getName());
3341 } // end anonymous namespace
3344 void GuiDocument::modulesToParams(BufferParams & bp)
3346 // update list of loaded modules
3347 bp.clearLayoutModules();
3348 int const srows = modules_sel_model_.rowCount();
3349 for (int i = 0; i < srows; ++i)
3350 bp.addLayoutModule(modules_sel_model_.getIDString(i));
3351 updateSelectedModules();
3353 // update the list of removed modules
3354 bp.clearRemovedModules();
3355 LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
3356 list<string>::const_iterator rit = reqmods.begin();
3357 list<string>::const_iterator ren = reqmods.end();
3359 // check each of the default modules
3360 for (; rit != ren; ++rit) {
3361 list<string>::const_iterator mit = bp.getModules().begin();
3362 list<string>::const_iterator men = bp.getModules().end();
3364 for (; mit != men; ++mit) {
3371 // the module isn't present so must have been removed by the user
3372 bp.addRemovedModule(*rit);
3377 void GuiDocument::modulesChanged()
3379 modulesToParams(bp_);
3381 if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()
3382 && (nonModuleChanged_ || shellescapeChanged_)) {
3383 int const ret = Alert::prompt(_("Unapplied changes"),
3384 _("Some changes in the dialog were not yet applied.\n"
3385 "If you do not apply now, they will be lost after this action."),
3386 1, 1, _("&Apply"), _("&Dismiss"));
3391 modulesChanged_ = true;
3392 bp_.makeDocumentClass();
3398 void GuiDocument::updateModuleInfo()
3400 selectionManager->update();
3402 //Module description
3403 bool const focus_on_selected = selectionManager->selectedFocused();
3404 QAbstractItemView * lv;
3405 bool category = false;
3406 if (focus_on_selected) {
3407 lv = modulesModule->selectedLV;
3410 lv = modulesModule->availableLV;
3411 if (lv->selectionModel()->selectedIndexes().isEmpty()) {
3412 modulesModule->infoML->document()->clear();
3415 QModelIndex const & idx = lv->selectionModel()->currentIndex();
3420 if (!focus_on_selected
3421 && modules_av_model_.itemFromIndex(idx)->hasChildren()) {
3422 // This is a category header
3423 modulesModule->infoML->document()->clear();
3427 string const modName = focus_on_selected ?
3428 modules_sel_model_.getIDString(idx.row())
3429 : fromqstr(modules_av_model_.data(idx, Qt::UserRole).toString());
3430 docstring desc = getModuleDescription(modName);
3432 LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
3433 if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
3436 desc += _("Module provided by document class.");
3440 docstring cat = getModuleCategory(modName);
3444 desc += bformat(_("<p><b>Category:</b> %1$s.</p>"),
3445 translateIfPossible(cat));
3449 vector<string> pkglist = getPackageList(modName);
3450 docstring pkgdesc = formatStrVec(pkglist, _("and"));
3451 if (!pkgdesc.empty()) {
3454 desc += bformat(_("<p><b>Package(s) required:</b> %1$s.</p>"), pkgdesc);
3457 pkglist = getRequiredList(modName);
3458 if (!pkglist.empty()) {
3459 vector<string> const reqdescs = idsToNames(pkglist);
3460 pkgdesc = formatStrVec(reqdescs, _("or"));
3463 desc += bformat(_("<p><b>Modules required:</b> %1$s.</p>"), pkgdesc);
3466 pkglist = getExcludedList(modName);
3467 if (!pkglist.empty()) {
3468 vector<string> const reqdescs = idsToNames(pkglist);
3469 pkgdesc = formatStrVec(reqdescs, _( "and"));
3472 desc += bformat(_("<p><b>Modules excluded:</b> %1$s.</p>"), pkgdesc);
3477 desc += bformat(_("<p><b>Filename:</b> <tt>%1$s.module</tt>.</p>"), from_utf8(modName));
3479 if (!isModuleAvailable(modName)) {
3482 desc += _("<p><font color=red><b>WARNING: Some required packages are unavailable!</b></font></p>");
3485 modulesModule->infoML->document()->setHtml(toqstr(desc));
3489 void GuiDocument::updateNumbering()
3491 DocumentClass const & tclass = documentClass();
3493 numberingModule->tocTW->setUpdatesEnabled(false);
3494 numberingModule->tocTW->clear();
3496 int const depth = numberingModule->depthSL->value();
3497 int const toc = numberingModule->tocSL->value();
3498 QString const no = qt_("No");
3499 QString const yes = qt_("Yes");
3500 QTreeWidgetItem * item = nullptr;
3502 DocumentClass::const_iterator lit = tclass.begin();
3503 DocumentClass::const_iterator len = tclass.end();
3504 for (; lit != len; ++lit) {
3505 int const toclevel = lit->toclevel;
3506 if (toclevel != Layout::NOT_IN_TOC && !lit->counter.empty()) {
3507 item = new QTreeWidgetItem(numberingModule->tocTW);
3508 item->setText(0, toqstr(translateIfPossible(lit->name())));
3509 item->setText(1, (toclevel <= depth) ? yes : no);
3510 item->setText(2, (toclevel <= toc) ? yes : no);
3514 numberingModule->tocTW->setUpdatesEnabled(true);
3515 numberingModule->tocTW->update();
3519 void GuiDocument::getTableStyles()
3521 // We look for lyx files in the subdirectory dir of
3523 // 2) build_lyxdir (if not empty)
3525 // in this order. Files with a given sub-hierarchy will
3526 // only be listed once.
3527 // We also consider i18n subdirectories and store them separately.
3530 // The three locations to look at.
3531 string const user = addPath(package().user_support().absFileName(), "tabletemplates");
3532 string const build = addPath(package().build_support().absFileName(), "tabletemplates");
3533 string const system = addPath(package().system_support().absFileName(), "tabletemplates");
3535 dirs << toqstr(user)
3539 for (int i = 0; i < dirs.size(); ++i) {
3540 QString const & dir = dirs.at(i);
3541 QDirIterator it(dir, QDir::Files, QDirIterator::Subdirectories);
3542 while (it.hasNext()) {
3543 QString fn = QFileInfo(it.next()).fileName();
3544 if (!fn.endsWith(".lyx") || fn.contains("_1x"))
3546 QString data = fn.left(fn.lastIndexOf(".lyx"));
3547 QString guiname = data;
3548 guiname = toqstr(translateIfPossible(qstring_to_ucs4(guiname.replace('_', ' '))));
3549 QString relpath = toqstr(makeRelPath(qstring_to_ucs4(fn),
3550 qstring_to_ucs4(dir)));
3551 if (textLayoutModule->tableStyleCO->findData(data) == -1)
3552 textLayoutModule->tableStyleCO->addItem(guiname, data);
3558 void GuiDocument::updateDefaultFormat()
3562 // make a copy in order to consider unapplied changes
3563 BufferParams param_copy = buffer().params();
3564 param_copy.useNonTeXFonts = fontModule->osFontsCB->isChecked();
3565 int const idx = latexModule->classCO->currentIndex();
3567 string const classname = fromqstr(latexModule->classCO->getData(idx));
3568 param_copy.setBaseClass(classname, buffer().layoutPos());
3569 param_copy.makeDocumentClass(true);
3571 outputModule->defaultFormatCO->blockSignals(true);
3572 outputModule->defaultFormatCO->clear();
3573 outputModule->defaultFormatCO->addItem(qt_("Default"),
3574 QVariant(QString("default")));
3575 FormatList const & formats =
3576 param_copy.exportableFormats(true);
3577 for (Format const * f : formats)
3578 outputModule->defaultFormatCO->addItem
3579 (toqstr(translateIfPossible(f->prettyname())),
3580 QVariant(toqstr(f->name())));
3581 outputModule->defaultFormatCO->blockSignals(false);
3585 bool GuiDocument::isChildIncluded(string const & child)
3587 if (includeonlys_.empty())
3589 return (std::find(includeonlys_.begin(),
3590 includeonlys_.end(), child) != includeonlys_.end());
3594 void GuiDocument::applyView()
3596 // auto-validate local layout
3597 if (!localLayout->isValid()) {
3598 localLayout->validate();
3599 if (!localLayout->isValid()) {
3600 setApplyStopped(true);
3601 docPS->setCurrentPanel(N_("Local Layout"));
3607 preambleModule->apply(bp_);
3608 localLayout->apply(bp_);
3611 bp_.suppress_date = latexModule->suppressDateCB->isChecked();
3612 bp_.use_refstyle = latexModule->refstyleCB->isChecked();
3613 bp_.use_formatted_ref = latexModule->refFormattedCB->isChecked();
3616 string const engine =
3617 fromqstr(biblioModule->citeEngineCO->itemData(
3618 biblioModule->citeEngineCO->currentIndex()).toString());
3619 bp_.setCiteEngine(engine);
3621 CiteEngineType const style = CiteEngineType(biblioModule->citeStyleCO->itemData(
3622 biblioModule->citeStyleCO->currentIndex()).toInt());
3623 if (theCiteEnginesList[engine]->hasEngineType(style))
3624 bp_.setCiteEngineType(style);
3626 bp_.setCiteEngineType(ENGINE_TYPE_DEFAULT);
3628 bp_.splitbib(biblioModule->bibtopicCB->isChecked());
3630 bp_.multibib = fromqstr(biblioModule->bibunitsCO->itemData(
3631 biblioModule->bibunitsCO->currentIndex()).toString());
3633 bp_.setDefaultBiblioStyle(fromqstr(biblioModule->defaultBiblioCO->currentText()));
3635 bp_.biblatex_bibstyle = fromqstr(biblioModule->biblatexBbxCO->currentText());
3636 bp_.biblatex_citestyle = fromqstr(biblioModule->biblatexCbxCO->currentText());
3637 bp_.biblio_opts = fromqstr(biblioModule->citePackageOptionsLE->text());
3639 string const bibtex_command =
3640 fromqstr(biblioModule->bibtexCO->itemData(
3641 biblioModule->bibtexCO->currentIndex()).toString());
3642 string const bibtex_options =
3643 fromqstr(biblioModule->bibtexOptionsLE->text());
3644 if (bibtex_command == "default" || bibtex_options.empty())
3645 bp_.bibtex_command = bibtex_command;
3647 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
3649 if (biblioChanged_) {
3650 buffer().invalidateBibinfoCache();
3651 buffer().removeBiblioTempFiles();
3655 indicesModule->apply(bp_);
3657 // language & quotes
3658 switch (langModule->encodingCO->currentIndex()) {
3659 case EncodingSets::unicode: {
3660 if (!fontModule->osFontsCB->isChecked())
3661 bp_.inputenc = fromqstr(langModule->unicodeEncodingCO->itemData(
3662 langModule->unicodeEncodingCO->currentIndex()).toString());
3665 case EncodingSets::legacy: {
3666 bp_.inputenc = "auto-legacy";
3667 bp_.inputenc = fromqstr(langModule->autoEncodingCO->itemData(
3668 langModule->autoEncodingCO->currentIndex()).toString());
3671 case EncodingSets::custom: {
3672 bp_.inputenc = fromqstr(langModule->customEncodingCO->itemData(
3673 langModule->customEncodingCO->currentIndex()).toString());
3677 // this should never happen
3678 bp_.inputenc = "utf8";
3680 bp_.quotes_style = QuoteStyle(langModule->quoteStyleCO->itemData(
3681 langModule->quoteStyleCO->currentIndex()).toInt());
3682 bp_.dynamic_quotes = langModule->dynamicQuotesCB->isChecked();
3684 QString const langname = langModule->languageCO->itemData(
3685 langModule->languageCO->currentIndex()).toString();
3686 Language const * newlang = lyx::languages.getLanguage(fromqstr(langname));
3687 Cursor & cur = const_cast<BufferView *>(bufferview())->cursor();
3688 // If current cursor language was the document language, then update it too.
3689 if (cur.current_font.language() == bp_.language) {
3690 cur.current_font.setLanguage(newlang);
3691 cur.real_current_font.setLanguage(newlang);
3693 bp_.language = newlang;
3695 QString const pack = langModule->languagePackageCO->itemData(
3696 langModule->languagePackageCO->currentIndex()).toString();
3697 if (pack == "custom")
3699 fromqstr(langModule->languagePackageLE->text());
3701 bp_.lang_package = fromqstr(pack);
3704 bp_.backgroundcolor = set_backgroundcolor;
3705 bp_.isbackgroundcolor = is_backgroundcolor;
3706 bp_.fontcolor = set_fontcolor;
3707 bp_.isfontcolor = is_fontcolor;
3708 bp_.notefontcolor = set_notefontcolor;
3709 bp_.isnotefontcolor = is_notefontcolor;
3710 if (is_notefontcolor) {
3711 // Set information used in statusbar (#12130)
3712 lcolor.setColor("notefontcolor", lyx::X11hexname(set_notefontcolor));
3713 lcolor.setGUIName("notefontcolor", N_("greyedout inset text"));
3715 bp_.boxbgcolor = set_boxbgcolor;
3716 bp_.isboxbgcolor = is_boxbgcolor;
3719 if (bp_.documentClass().hasTocLevels()) {
3720 bp_.tocdepth = numberingModule->tocSL->value();
3721 bp_.secnumdepth = numberingModule->depthSL->value();
3723 bp_.use_lineno = numberingModule->linenoCB->isChecked();
3724 bp_.lineno_opts = fromqstr(numberingModule->linenoLE->text());
3727 bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
3728 bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
3729 bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
3730 bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
3733 bp_.graphics_driver =
3734 tex_graphics[latexModule->psdriverCO->currentIndex()];
3737 int idx = latexModule->classCO->currentIndex();
3739 string const classname = fromqstr(latexModule->classCO->getData(idx));
3740 bp_.setBaseClass(classname, buffer().layoutPos());
3744 modulesToParams(bp_);
3747 map<string, string> const & packages = BufferParams::auto_packages();
3748 for (map<string, string>::const_iterator it = packages.begin();
3749 it != packages.end(); ++it) {
3750 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
3753 int row = mathsModule->packagesTW->row(item);
3756 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1)->layout()->itemAt(0)->widget();
3757 if (rb->isChecked()) {
3758 bp_.use_package(it->first, BufferParams::package_auto);
3761 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2)->layout()->itemAt(0)->widget();
3762 if (rb->isChecked()) {
3763 bp_.use_package(it->first, BufferParams::package_on);
3766 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3)->layout()->itemAt(0)->widget();
3767 if (rb->isChecked())
3768 bp_.use_package(it->first, BufferParams::package_off);
3770 // if math is indented
3771 bp_.is_math_indent = mathsModule->MathIndentCB->isChecked();
3772 if (bp_.is_math_indent) {
3773 // if formulas are indented
3774 if (mathsModule->MathIndentCO->itemData(mathsModule->MathIndentCO->currentIndex()) == "custom") {
3775 Length mathindent(widgetsToLength(mathsModule->MathIndentLE,
3776 mathsModule->MathIndentLengthCO));
3777 bp_.setMathIndent(mathindent);
3780 bp_.setMathIndent(Length());
3782 switch (mathsModule->MathNumberingPosCO->currentIndex()) {
3784 bp_.math_numbering_side = BufferParams::LEFT;
3787 bp_.math_numbering_side = BufferParams::DEFAULT;
3790 bp_.math_numbering_side = BufferParams::RIGHT;
3793 // this should never happen
3794 bp_.math_numbering_side = BufferParams::DEFAULT;
3799 if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
3800 bp_.pagestyle = "default";
3802 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
3803 for (size_t i = 0; i != pagestyles.size(); ++i)
3804 if (pagestyles[i].second == style_gui)
3805 bp_.pagestyle = pagestyles[i].first;
3809 switch (textLayoutModule->lspacingCO->currentIndex()) {
3811 bp_.spacing().set(Spacing::Single);
3814 bp_.spacing().set(Spacing::Onehalf);
3817 bp_.spacing().set(Spacing::Double);
3820 string s = widgetToDoubleStr(textLayoutModule->lspacingLE);
3822 bp_.spacing().set(Spacing::Single);
3824 bp_.spacing().set(Spacing::Other, s);
3829 if (textLayoutModule->twoColumnCB->isChecked())
3834 bp_.justification = textLayoutModule->justCB->isChecked();
3836 if (textLayoutModule->indentRB->isChecked()) {
3837 // if paragraphs are separated by an indentation
3838 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
3839 if (textLayoutModule->indentCO->itemData(textLayoutModule->indentCO->currentIndex()) == "custom") {
3840 Length parindent(widgetsToLength(textLayoutModule->indentLE,
3841 textLayoutModule->indentLengthCO));
3842 bp_.setParIndent(parindent);
3845 bp_.setParIndent(Length());
3847 // if paragraphs are separated by a skip
3848 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
3849 VSpace::VSpaceKind spacekind =
3850 VSpace::VSpaceKind(textLayoutModule->skipCO->itemData(textLayoutModule->skipCO->currentIndex()).toInt());
3851 switch (spacekind) {
3852 case VSpace::SMALLSKIP:
3853 case VSpace::MEDSKIP:
3854 case VSpace::BIGSKIP:
3855 case VSpace::HALFLINE:
3856 case VSpace::FULLLINE:
3857 bp_.setDefSkip(VSpace(spacekind));
3859 case VSpace::LENGTH: {
3861 widgetsToLength(textLayoutModule->skipLE,
3862 textLayoutModule->skipLengthCO)
3868 // this should never happen
3869 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
3873 bp_.tablestyle = fromqstr(textLayoutModule->tableStyleCO->itemData(
3874 textLayoutModule->tableStyleCO->currentIndex()).toString());
3877 fromqstr(latexModule->optionsLE->text());
3879 bp_.use_default_options =
3880 latexModule->defaultOptionsCB->isChecked();
3882 if (latexModule->childDocGB->isChecked())
3884 fromqstr(latexModule->childDocLE->text());
3886 bp_.master = string();
3889 bp_.clearIncludedChildren();
3890 updateIncludeonlys();
3891 if (masterChildModule->includeonlyRB->isChecked()) {
3892 list<string>::const_iterator it = includeonlys_.begin();
3893 for (; it != includeonlys_.end() ; ++it) {
3894 bp_.addIncludedChildren(*it);
3897 if (masterChildModule->maintainCRNoneRB->isChecked())
3898 bp_.maintain_unincluded_children =
3899 BufferParams::CM_None;
3900 else if (masterChildModule->maintainCRMostlyRB->isChecked())
3901 bp_.maintain_unincluded_children =
3902 BufferParams::CM_Mostly;
3904 bp_.maintain_unincluded_children =
3905 BufferParams::CM_Strict;
3906 updateIncludeonlyDisplay();
3909 bp_.float_placement = floatModule->getPlacement();
3910 bp_.float_alignment = floatModule->getAlignment();
3913 // text should have passed validation
3914 idx = listingsModule->packageCO->currentIndex();
3915 bp_.use_minted = string(lst_packages[idx]) == "Minted";
3916 bp_.listings_params =
3917 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
3920 bp_.default_output_format = fromqstr(outputModule->defaultFormatCO->itemData(
3921 outputModule->defaultFormatCO->currentIndex()).toString());
3923 bool const nontexfonts = fontModule->osFontsCB->isChecked();
3924 bp_.useNonTeXFonts = nontexfonts;
3926 bp_.shell_escape = outputModule->shellescapeCB->isChecked();
3927 if (!bp_.shell_escape)
3928 theSession().shellescapeFiles().remove(buffer().absFileName());
3929 else if (!theSession().shellescapeFiles().find(buffer().absFileName()))
3930 theSession().shellescapeFiles().insert(buffer().absFileName());
3931 Buffer & buf = const_cast<Buffer &>(buffer());
3932 buf.params().shell_escape = bp_.shell_escape;
3934 bp_.output_sync = outputModule->outputsyncCB->isChecked();
3936 bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
3938 int mathfmt = outputModule->mathoutCB->currentIndex();
3941 BufferParams::MathOutput const mo =
3942 static_cast<BufferParams::MathOutput>(mathfmt);
3943 bp_.html_math_output = mo;
3944 bp_.html_be_strict = outputModule->strictCB->isChecked();
3945 bp_.html_css_as_file = outputModule->cssCB->isChecked();
3946 bp_.html_math_img_scale = outputModule->mathimgSB->value();
3947 bp_.display_pixel_ratio = theGuiApp()->pixelRatio();
3949 int tablefmt = outputModule->tableoutCB->currentIndex();
3952 auto const to = static_cast<BufferParams::TableOutput>(tablefmt);
3953 bp_.docbook_table_output = to;
3955 int mathmlprefix = outputModule->mathmlprefixCB->currentIndex();
3956 if (mathmlprefix == -1)
3958 auto const mp = static_cast<BufferParams::MathMLNameSpacePrefix>(mathmlprefix);
3959 bp_.docbook_mathml_prefix = mp;
3961 bp_.save_transient_properties =
3962 outputModule->saveTransientPropertiesCB->isChecked();
3963 bp_.postpone_fragile_content =
3964 outputModule->postponeFragileCB->isChecked();
3967 bp_.fonts_roman[nontexfonts] =
3968 fromqstr(fontModule->fontsRomanCO->
3969 getData(fontModule->fontsRomanCO->currentIndex()));
3970 bp_.fonts_roman[!nontexfonts] = fromqstr(fontModule->font_roman);
3971 bp_.font_roman_opts = fromqstr(fontModule->fontspecRomanLE->text());
3973 bp_.fonts_sans[nontexfonts] =
3974 fromqstr(fontModule->fontsSansCO->
3975 getData(fontModule->fontsSansCO->currentIndex()));
3976 bp_.fonts_sans[!nontexfonts] = fromqstr(fontModule->font_sans);
3977 bp_.font_sans_opts = fromqstr(fontModule->fontspecSansLE->text());
3979 bp_.fonts_typewriter[nontexfonts] =
3980 fromqstr(fontModule->fontsTypewriterCO->
3981 getData(fontModule->fontsTypewriterCO->currentIndex()));
3982 bp_.fonts_typewriter[!nontexfonts] = fromqstr(fontModule->font_typewriter);
3983 bp_.font_typewriter_opts = fromqstr(fontModule->fontspecTypewriterLE->text());
3985 bp_.fonts_math[nontexfonts] =
3986 fromqstr(fontModule->fontsMathCO->
3987 itemData(fontModule->fontsMathCO->currentIndex()).toString());
3988 bp_.fonts_math[!nontexfonts] = fromqstr(fontModule->font_math);
3990 QString const fontenc =
3991 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
3992 if (fontenc == "custom")
3993 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
3995 bp_.fontenc = fromqstr(fontenc);
3998 fromqstr(fontModule->cjkFontLE->text());
4000 bp_.use_microtype = fontModule->microtypeCB->isChecked();
4001 bp_.use_dash_ligatures = !fontModule->dashesCB->isChecked();
4003 bp_.fonts_sans_scale[nontexfonts] = fontModule->scaleSansSB->value();
4004 bp_.fonts_sans_scale[!nontexfonts] = fontModule->font_sf_scale;
4006 bp_.fonts_typewriter_scale[nontexfonts] = fontModule->scaleTypewriterSB->value();
4007 bp_.fonts_typewriter_scale[!nontexfonts] = fontModule->font_tt_scale;
4009 bp_.fonts_expert_sc = fontModule->fontScCB->isChecked();
4011 bp_.fonts_roman_osf = fontModule->fontOsfCB->isChecked();
4012 bp_.fonts_sans_osf = fontModule->fontSansOsfCB->isChecked();
4013 bp_.fonts_typewriter_osf = fontModule->fontTypewriterOsfCB->isChecked();
4015 bp_.fonts_default_family = GuiDocument::fontfamilies[
4016 fontModule->fontsDefaultCO->currentIndex()];
4018 if (fontModule->fontsizeCO->currentIndex() == 0)
4019 bp_.fontsize = "default";
4022 fromqstr(fontModule->fontsizeCO->currentText());
4025 bp_.papersize = PAPER_SIZE(
4026 pageLayoutModule->papersizeCO->currentIndex());
4028 bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
4029 pageLayoutModule->paperwidthUnitCO);
4031 bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
4032 pageLayoutModule->paperheightUnitCO);
4034 if (pageLayoutModule->facingPagesCB->isChecked())
4035 bp_.sides = TwoSides;
4037 bp_.sides = OneSide;
4039 if (pageLayoutModule->landscapeRB->isChecked())
4040 bp_.orientation = ORIENTATION_LANDSCAPE;
4042 bp_.orientation = ORIENTATION_PORTRAIT;
4045 bp_.use_geometry = !marginsModule->marginCB->isChecked();
4047 Ui::MarginsUi const * m = marginsModule;
4049 if (bp_.use_geometry) {
4050 bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
4051 bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
4052 bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
4053 bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
4054 bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
4055 bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
4056 bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
4057 bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
4061 branchesModule->apply(bp_);
4064 PDFOptions & pdf = bp_.pdfoptions();
4065 pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
4066 pdf.title = fromqstr(pdfSupportModule->titleLE->text());
4067 pdf.author = fromqstr(pdfSupportModule->authorLE->text());
4068 pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
4069 pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
4071 pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
4072 pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
4073 pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
4074 pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
4076 pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
4077 pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
4078 pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
4079 pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
4081 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
4082 if (pdfSupportModule->fullscreenCB->isChecked())
4083 pdf.pagemode = pdf.pagemode_fullscreen;
4085 pdf.pagemode.clear();
4086 pdf.quoted_options = pdf.quoted_options_check(
4087 fromqstr(pdfSupportModule->optionsTE->toPlainText()));
4088 bp_.document_metadata = qstring_to_ucs4(pdfSupportModule->metadataTE->toPlainText()
4089 .trimmed().replace(QRegularExpression("\n+"), "\n"));
4092 bp_.track_changes = changesModule->trackChangesCB->isChecked();
4093 bp_.output_changes = changesModule->outputChangesCB->isChecked();
4094 bool const cb_switched_off = (bp_.change_bars
4095 && !changesModule->changeBarsCB->isChecked());
4096 bp_.change_bars = changesModule->changeBarsCB->isChecked();
4097 if (cb_switched_off)
4098 // if change bars have been switched off,
4099 // we need to ditch the aux file
4100 buffer().requireFreshStart(true);
4103 nonModuleChanged_ = false;
4104 shellescapeChanged_ = false;
4108 void GuiDocument::paramsToDialog()
4110 // set the default unit
4111 Length::UNIT const default_unit = Length::defaultUnit();
4114 preambleModule->update(bp_, id());
4115 localLayout->update(bp_, id());
4118 latexModule->suppressDateCB->setChecked(bp_.suppress_date);
4119 latexModule->refstyleCB->setChecked(bp_.use_refstyle);
4120 latexModule->refFormattedCB->setChecked(bp_.use_formatted_ref);
4123 string const cite_engine = bp_.citeEngine();
4125 biblioModule->citeEngineCO->setCurrentIndex(
4126 biblioModule->citeEngineCO->findData(toqstr(cite_engine)));
4128 updateEngineType(documentClass().opt_enginetype(),
4129 bp_.citeEngineType());
4131 checkPossibleCiteEngines();
4133 biblioModule->citeStyleCO->setCurrentIndex(
4134 biblioModule->citeStyleCO->findData(bp_.citeEngineType()));
4136 biblioModule->bibtopicCB->setChecked(bp_.splitbib());
4138 biblioModule->bibunitsCO->clear();
4139 biblioModule->bibunitsCO->addItem(qt_("No"), QString());
4140 if (documentClass().hasLaTeXLayout("part"))
4141 biblioModule->bibunitsCO->addItem(qt_("per part"), toqstr("part"));
4142 if (documentClass().hasLaTeXLayout("chapter"))
4143 biblioModule->bibunitsCO->addItem(qt_("per chapter"), toqstr("chapter"));
4144 if (documentClass().hasLaTeXLayout("section"))
4145 biblioModule->bibunitsCO->addItem(qt_("per section"), toqstr("section"));
4146 if (documentClass().hasLaTeXLayout("subsection"))
4147 biblioModule->bibunitsCO->addItem(qt_("per subsection"), toqstr("subsection"));
4148 biblioModule->bibunitsCO->addItem(qt_("per child document"), toqstr("child"));
4150 int const mbpos = biblioModule->bibunitsCO->findData(toqstr(bp_.multibib));
4152 biblioModule->bibunitsCO->setCurrentIndex(mbpos);
4154 biblioModule->bibunitsCO->setCurrentIndex(0);
4156 updateEngineDependends();
4159 updateDefaultBiblio(bp_.biblatex_bibstyle, "bbx");
4160 updateDefaultBiblio(bp_.biblatex_citestyle, "cbx");
4162 updateDefaultBiblio(bp_.defaultBiblioStyle());
4164 biblioModule->citePackageOptionsLE->setText(toqstr(bp_.biblio_opts));
4168 split(bp_.bibtex_command, command, ' ');
4170 int bpos = biblioModule->bibtexCO->findData(toqstr(command));
4172 // We add and set the unknown compiler, indicating that it is unavailable
4173 // to assure document compilation and for security reasons, a fallback
4174 // will be used on document processing stage
4175 biblioModule->bibtexCO->addItem(toqstr(bformat(_("%1$s (not available)"),
4176 from_utf8(command))), toqstr(command));
4177 bpos = biblioModule->bibtexCO->findData(toqstr(command));
4179 biblioModule->bibtexCO->setCurrentIndex(bpos);
4180 biblioModule->bibtexOptionsLE->setText(toqstr(options).trimmed());
4181 biblioModule->bibtexOptionsLE->setEnabled(
4182 biblioModule->bibtexCO->currentIndex() != 0);
4184 biblioChanged_ = false;
4187 // We may be called when there is no Buffer, e.g., when
4188 // the last view has just been closed.
4189 bool const isReadOnly = isBufferAvailable() ? buffer().isReadonly() : false;
4190 indicesModule->update(bp_, isReadOnly);
4192 // language & quotes
4193 int const pos = langModule->languageCO->findData(toqstr(
4194 bp_.language->lang()));
4195 langModule->languageCO->setCurrentIndex(pos);
4197 updateQuoteStyles();
4199 langModule->quoteStyleCO->setCurrentIndex(
4200 langModule->quoteStyleCO->findData(static_cast<int>(bp_.quotes_style)));
4201 langModule->dynamicQuotesCB->setChecked(bp_.dynamic_quotes);
4203 // LaTeX input encoding: set after the fonts (see below)
4205 int p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
4207 langModule->languagePackageCO->setCurrentIndex(
4208 langModule->languagePackageCO->findData("custom"));
4209 langModule->languagePackageLE->setText(toqstr(bp_.lang_package));
4211 langModule->languagePackageCO->setCurrentIndex(p);
4212 langModule->languagePackageLE->clear();
4216 if (bp_.isfontcolor) {
4217 colorModule->mainTextCF->setStyleSheet(
4218 colorFrameStyleSheet(rgb2qcolor(bp_.fontcolor)));
4219 colorModule->mainTextCF->setVisible(true);
4221 colorModule->mainTextCF->setVisible(false);
4222 set_fontcolor = bp_.fontcolor;
4223 is_fontcolor = bp_.isfontcolor;
4225 colorModule->noteFontCF->setStyleSheet(
4226 colorFrameStyleSheet(rgb2qcolor(bp_.notefontcolor)));
4227 set_notefontcolor = bp_.notefontcolor;
4228 is_notefontcolor = bp_.isnotefontcolor;
4230 if (bp_.isbackgroundcolor) {
4231 colorModule->pageBackgroundCF->setStyleSheet(
4232 colorFrameStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
4233 colorModule->pageBackgroundCF->setVisible(true);
4235 colorModule->pageBackgroundCF->setVisible(false);
4236 set_backgroundcolor = bp_.backgroundcolor;
4237 is_backgroundcolor = bp_.isbackgroundcolor;
4239 colorModule->boxBackgroundCF->setStyleSheet(
4240 colorFrameStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
4241 set_boxbgcolor = bp_.boxbgcolor;
4242 is_boxbgcolor = bp_.isboxbgcolor;
4245 int const min_toclevel = documentClass().min_toclevel();
4246 int const max_toclevel = documentClass().max_toclevel();
4247 if (documentClass().hasTocLevels()) {
4248 numberingModule->setEnabled(true);
4249 numberingModule->depthSL->setMinimum(min_toclevel - 1);
4250 numberingModule->depthSL->setMaximum(max_toclevel);
4251 numberingModule->depthSL->setValue(bp_.secnumdepth);
4252 numberingModule->tocSL->setMaximum(min_toclevel - 1);
4253 numberingModule->tocSL->setMaximum(max_toclevel);
4254 numberingModule->tocSL->setValue(bp_.tocdepth);
4257 numberingModule->setEnabled(false);
4258 numberingModule->tocTW->clear();
4261 numberingModule->linenoCB->setChecked(bp_.use_lineno);
4262 numberingModule->linenoLE->setEnabled(bp_.use_lineno);
4263 numberingModule->linenoLA->setEnabled(bp_.use_lineno);
4264 numberingModule->linenoLE->setText(toqstr(bp_.lineno_opts));
4267 bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
4268 bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
4269 bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
4270 bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
4271 bulletsModule->init();
4274 int nitem = findToken(tex_graphics, bp_.graphics_driver);
4276 latexModule->psdriverCO->setCurrentIndex(nitem);
4280 mathsModule->MathIndentCB->setChecked(bp_.is_math_indent);
4281 if (bp_.is_math_indent) {
4282 Length const mathindent = bp_.getMathIndent();
4284 if (!mathindent.empty()) {
4285 lengthToWidgets(mathsModule->MathIndentLE,
4286 mathsModule->MathIndentLengthCO,
4287 mathindent, default_unit);
4290 mathsModule->MathIndentCO->setCurrentIndex(indent);
4291 enableMathIndent(indent);
4293 switch(bp_.math_numbering_side) {
4294 case BufferParams::LEFT:
4295 mathsModule->MathNumberingPosCO->setCurrentIndex(0);
4297 case BufferParams::DEFAULT:
4298 mathsModule->MathNumberingPosCO->setCurrentIndex(1);
4300 case BufferParams::RIGHT:
4301 mathsModule->MathNumberingPosCO->setCurrentIndex(2);
4304 map<string, string> const & packages = BufferParams::auto_packages();
4305 for (map<string, string>::const_iterator it = packages.begin();
4306 it != packages.end(); ++it) {
4307 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
4310 int row = mathsModule->packagesTW->row(item);
4311 switch (bp_.use_package(it->first)) {
4312 case BufferParams::package_off: {
4314 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3)->layout()->itemAt(0)->widget();
4315 rb->setChecked(true);
4318 case BufferParams::package_on: {
4320 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2)->layout()->itemAt(0)->widget();
4321 rb->setChecked(true);
4324 case BufferParams::package_auto: {
4326 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1)->layout()->itemAt(0)->widget();
4327 rb->setChecked(true);
4333 switch (bp_.spacing().getSpace()) {
4334 case Spacing::Other: nitem = 3; break;
4335 case Spacing::Double: nitem = 2; break;
4336 case Spacing::Onehalf: nitem = 1; break;
4337 case Spacing::Default: case Spacing::Single: nitem = 0; break;
4341 string const & layoutID = bp_.baseClassID();
4342 setLayoutComboByIDString(layoutID);
4344 updatePagestyle(documentClass().opt_pagestyle(),
4347 textLayoutModule->lspacingCO->setCurrentIndex(nitem);
4348 if (bp_.spacing().getSpace() == Spacing::Other) {
4349 doubleToWidget(textLayoutModule->lspacingLE,
4350 bp_.spacing().getValueAsString());
4353 int ts = textLayoutModule->tableStyleCO->findData(toqstr(bp_.tablestyle));
4355 textLayoutModule->tableStyleCO->setCurrentIndex(ts);
4357 if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
4358 textLayoutModule->indentRB->setChecked(true);
4359 string parindent = bp_.getParIndent().asString();
4360 QString indent = toqstr("default");
4361 if (!parindent.empty()) {
4362 lengthToWidgets(textLayoutModule->indentLE,
4363 textLayoutModule->indentLengthCO,
4364 parindent, default_unit);
4365 indent = toqstr("custom");
4367 textLayoutModule->indentCO->setCurrentIndex(textLayoutModule->indentCO->findData(indent));
4368 setIndent(textLayoutModule->indentCO->currentIndex());
4370 textLayoutModule->skipRB->setChecked(true);
4371 VSpace::VSpaceKind skip = bp_.getDefSkip().kind();
4372 textLayoutModule->skipCO->setCurrentIndex(textLayoutModule->skipCO->findData(skip));
4373 if (skip == VSpace::LENGTH) {
4374 string const length = bp_.getDefSkip().asLyXCommand();
4375 lengthToWidgets(textLayoutModule->skipLE,
4376 textLayoutModule->skipLengthCO,
4377 length, default_unit);
4379 setSkip(textLayoutModule->skipCO->currentIndex());
4382 textLayoutModule->twoColumnCB->setChecked(
4384 textLayoutModule->justCB->setChecked(bp_.justification);
4386 if (!bp_.options.empty()) {
4387 latexModule->optionsLE->setText(
4388 toqstr(bp_.options));
4390 latexModule->optionsLE->setText(QString());
4394 latexModule->defaultOptionsCB->setChecked(
4395 bp_.use_default_options);
4396 updateSelectedModules();
4397 selectionManager->updateProvidedModules(
4398 bp_.baseClass()->providedModules());
4399 selectionManager->updateExcludedModules(
4400 bp_.baseClass()->excludedModules());
4402 if (!documentClass().options().empty()) {
4403 latexModule->defaultOptionsLE->setText(
4404 toqstr(documentClass().options()));
4406 latexModule->defaultOptionsLE->setText(
4407 toqstr(_("[No options predefined]")));
4410 latexModule->defaultOptionsLE->setEnabled(
4411 bp_.use_default_options
4412 && !documentClass().options().empty());
4414 latexModule->defaultOptionsCB->setEnabled(
4415 !documentClass().options().empty());
4417 if (!bp_.master.empty()) {
4418 latexModule->childDocGB->setChecked(true);
4419 latexModule->childDocLE->setText(
4420 toqstr(bp_.master));
4422 latexModule->childDocLE->setText(QString());
4423 latexModule->childDocGB->setChecked(false);
4427 if (!bufferview() || !buffer().hasChildren()) {
4428 masterChildModule->childrenTW->clear();
4429 includeonlys_.clear();
4430 docPS->showPanel("Child Documents", false);
4431 if (docPS->isCurrentPanel("Child Documents"))
4432 docPS->setCurrentPanel("Document Class");
4434 docPS->showPanel("Child Documents", true);
4435 masterChildModule->setEnabled(true);
4436 includeonlys_ = bp_.getIncludedChildren();
4437 updateIncludeonlys();
4438 updateIncludeonlyDisplay();
4440 switch (bp_.maintain_unincluded_children) {
4441 case BufferParams::CM_None:
4442 masterChildModule->maintainCRNoneRB->setChecked(true);
4444 case BufferParams::CM_Mostly:
4445 masterChildModule->maintainCRMostlyRB->setChecked(true);
4447 case BufferParams::CM_Strict:
4449 masterChildModule->maintainCRStrictRB->setChecked(true);
4454 floatModule->setPlacement(bp_.float_placement);
4455 floatModule->setAlignment(bp_.float_alignment);
4458 // break listings_params to multiple lines
4460 InsetListingsParams(bp_.listings_params).separatedParams();
4461 listingsModule->listingsED->setPlainText(toqstr(lstparams));
4462 int nn = findToken(lst_packages, bp_.use_minted ? "Minted" : "Listings");
4464 listingsModule->packageCO->setCurrentIndex(nn);
4467 // some languages only work with Polyglossia (which requires non-TeX fonts)
4468 Language const * lang = lyx::languages.getLanguage(
4469 fromqstr(langModule->languageCO->itemData(
4470 langModule->languageCO->currentIndex()).toString()));
4471 bool const need_fontspec =
4472 lang->babel().empty() && !lang->polyglossia().empty()
4473 && lang->required() != "CJK" && lang->required() != "japanese";
4474 bool const os_fonts_available =
4475 bp_.baseClass()->outputType() == lyx::LATEX
4476 && LaTeXFeatures::isAvailable("fontspec");
4477 fontModule->osFontsCB->setEnabled(os_fonts_available && !need_fontspec);
4478 fontModule->osFontsCB->setChecked(
4479 (os_fonts_available && bp_.useNonTeXFonts) || need_fontspec);
4480 updateFontsize(documentClass().opt_fontsize(),
4483 QString font = toqstr(bp_.fontsRoman());
4484 bool foundfont = fontModule->fontsRomanCO->set(font, false);
4486 fontModule->fontsRomanCO->addItemSort(font, font + qt_(" (not installed)"),
4487 qt_("Uninstalled used fonts"),
4488 qt_("This font is not installed and won't be used in output"),
4489 false, false, false, true);
4490 fontModule->fontsRomanCO->set(font);
4492 fontModule->font_roman = toqstr(bp_.fonts_roman[!bp_.useNonTeXFonts]);
4494 font = toqstr(bp_.fontsSans());
4495 foundfont = fontModule->fontsSansCO->set(font, false);
4497 fontModule->fontsSansCO->addItemSort(font, font + qt_(" (not installed)"),
4498 qt_("Uninstalled used fonts"),
4499 qt_("This font is not installed and won't be used in output"),
4500 false, false, false, true);
4501 fontModule->fontsSansCO->set(font);
4503 fontModule->font_sans = toqstr(bp_.fonts_sans[!bp_.useNonTeXFonts]);
4505 font = toqstr(bp_.fontsTypewriter());
4506 foundfont = fontModule->fontsTypewriterCO->set(font, false);
4508 fontModule->fontsTypewriterCO->addItemSort(font, font + qt_(" (not installed)"),
4509 qt_("Uninstalled used fonts"),
4510 qt_("This font is not installed and won't be used in output"),
4511 false, false, false, true);
4512 fontModule->fontsTypewriterCO->set(font);
4514 fontModule->font_typewriter = toqstr(bp_.fonts_typewriter[!bp_.useNonTeXFonts]);
4516 font = toqstr(bp_.fontsMath());
4517 int mpos = fontModule->fontsMathCO->findData(font);
4519 mpos = fontModule->fontsMathCO->count();
4520 fontModule->fontsMathCO->addItem(font + qt_(" (not installed)"), font);
4522 fontModule->fontsMathCO->setCurrentIndex(mpos);
4523 fontModule->font_math = toqstr(bp_.fonts_math[!bp_.useNonTeXFonts]);
4525 if (bp_.useNonTeXFonts && os_fonts_available) {
4526 fontModule->fontencLA->setEnabled(false);
4527 fontModule->fontencCO->setEnabled(false);
4528 fontModule->fontencLE->setEnabled(false);
4530 fontModule->fontencLA->setEnabled(true);
4531 fontModule->fontencCO->setEnabled(true);
4532 fontModule->fontencLE->setEnabled(true);
4533 romanChanged(fontModule->fontsRomanCO->currentIndex());
4534 sansChanged(fontModule->fontsSansCO->currentIndex());
4535 ttChanged(fontModule->fontsTypewriterCO->currentIndex());
4537 // Handle options enabling
4538 updateFontOptions();
4540 if (!bp_.fonts_cjk.empty())
4541 fontModule->cjkFontLE->setText(
4542 toqstr(bp_.fonts_cjk));
4544 fontModule->cjkFontLE->setText(QString());
4546 fontModule->microtypeCB->setChecked(bp_.use_microtype);
4547 fontModule->dashesCB->setChecked(!bp_.use_dash_ligatures);
4549 fontModule->fontScCB->setChecked(bp_.fonts_expert_sc);
4550 fontModule->fontOsfCB->setChecked(bp_.fonts_roman_osf);
4551 fontModule->fontSansOsfCB->setChecked(bp_.fonts_sans_osf);
4552 fontModule->fontTypewriterOsfCB->setChecked(bp_.fonts_typewriter_osf);
4553 fontModule->scaleSansSB->setValue(bp_.fontsSansScale());
4554 fontModule->font_sf_scale = bp_.fonts_sans_scale[!bp_.useNonTeXFonts];
4555 fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale());
4556 fontModule->font_tt_scale = bp_.fonts_typewriter_scale[!bp_.useNonTeXFonts];
4557 if (!bp_.font_roman_opts.empty())
4558 fontModule->fontspecRomanLE->setText(
4559 toqstr(bp_.font_roman_opts));
4561 fontModule->fontspecRomanLE->setText(QString());
4562 if (!bp_.font_sans_opts.empty())
4563 fontModule->fontspecSansLE->setText(
4564 toqstr(bp_.font_sans_opts));
4566 fontModule->fontspecSansLE->setText(QString());
4567 if (!bp_.font_typewriter_opts.empty())
4568 fontModule->fontspecTypewriterLE->setText(
4569 toqstr(bp_.font_typewriter_opts));
4571 fontModule->fontspecTypewriterLE->setText(QString());
4573 nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
4575 fontModule->fontsDefaultCO->setCurrentIndex(nn);
4577 if (bp_.fontenc == "auto" || bp_.fontenc == "default") {
4578 fontModule->fontencCO->setCurrentIndex(
4579 fontModule->fontencCO->findData(toqstr(bp_.fontenc)));
4580 fontModule->fontencLE->setEnabled(false);
4582 fontModule->fontencCO->setCurrentIndex(
4583 fontModule->fontencCO->findData("custom"));
4584 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
4587 // LaTeX input encoding
4588 // Set after fonts because non-tex fonts override "\inputencoding".
4589 inputencodingToDialog();
4592 // This must be set _after_ fonts since updateDefaultFormat()
4593 // checks osFontsCB settings.
4594 // update combobox with formats
4595 updateDefaultFormat();
4596 int index = outputModule->defaultFormatCO->findData(toqstr(
4597 bp_.default_output_format));
4598 // set to default if format is not found
4601 outputModule->defaultFormatCO->setCurrentIndex(index);
4603 outputModule->shellescapeCB->setChecked(bp_.shell_escape);
4604 outputModule->outputsyncCB->setChecked(bp_.output_sync);
4605 outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
4606 outputModule->synccustomCB->setEnabled(bp_.output_sync);
4607 outputModule->synccustomLA->setEnabled(bp_.output_sync);
4609 outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
4610 outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
4611 outputModule->strictCB->setChecked(bp_.html_be_strict);
4612 outputModule->cssCB->setChecked(bp_.html_css_as_file);
4614 outputModule->tableoutCB->setCurrentIndex(bp_.docbook_table_output);
4615 outputModule->mathmlprefixCB->setCurrentIndex(bp_.docbook_mathml_prefix);
4617 outputModule->saveTransientPropertiesCB
4618 ->setChecked(bp_.save_transient_properties);
4619 outputModule->postponeFragileCB
4620 ->setChecked(bp_.postpone_fragile_content);
4623 bool const extern_geometry =
4624 documentClass().provides("geometry");
4625 int const psize = bp_.papersize;
4626 pageLayoutModule->papersizeCO->setCurrentIndex(psize);
4627 setCustomPapersize(!extern_geometry && psize == 1);
4628 pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
4630 bool const landscape =
4631 bp_.orientation == ORIENTATION_LANDSCAPE;
4632 pageLayoutModule->landscapeRB->setChecked(landscape);
4633 pageLayoutModule->portraitRB->setChecked(!landscape);
4634 pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
4635 pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
4637 pageLayoutModule->facingPagesCB->setChecked(
4638 bp_.sides == TwoSides);
4640 lengthToWidgets(pageLayoutModule->paperwidthLE,
4641 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, default_unit);
4642 lengthToWidgets(pageLayoutModule->paperheightLE,
4643 pageLayoutModule->paperheightUnitCO, bp_.paperheight, default_unit);
4646 Ui::MarginsUi * m = marginsModule;
4648 tmp_leftmargin_ = bp_.leftmargin;
4649 tmp_topmargin_ = bp_.topmargin;
4650 tmp_rightmargin_ = bp_.rightmargin;
4651 tmp_bottommargin_ = bp_.bottommargin;
4652 tmp_headheight_ = bp_.headheight;
4653 tmp_headsep_ = bp_.headsep;
4654 tmp_footskip_ = bp_.footskip;
4655 tmp_columnsep_ = bp_.columnsep;
4657 lengthToWidgets(m->topLE, m->topUnit,
4658 bp_.topmargin, default_unit);
4659 lengthToWidgets(m->bottomLE, m->bottomUnit,
4660 bp_.bottommargin, default_unit);
4661 lengthToWidgets(m->innerLE, m->innerUnit,
4662 bp_.leftmargin, default_unit);
4663 lengthToWidgets(m->outerLE, m->outerUnit,
4664 bp_.rightmargin, default_unit);
4665 lengthToWidgets(m->headheightLE, m->headheightUnit,
4666 bp_.headheight, default_unit);
4667 lengthToWidgets(m->headsepLE, m->headsepUnit,
4668 bp_.headsep, default_unit);
4669 lengthToWidgets(m->footskipLE, m->footskipUnit,
4670 bp_.footskip, default_unit);
4671 lengthToWidgets(m->columnsepLE, m->columnsepUnit,
4672 bp_.columnsep, default_unit);
4677 updateUnknownBranches();
4678 branchesModule->update(bp_);
4681 PDFOptions const & pdf = bp_.pdfoptions();
4682 pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
4683 if (bp_.documentClass().provides("hyperref"))
4684 pdfSupportModule->use_hyperrefGB->setTitle(qt_("C&ustomize Hyperref Options"));
4686 pdfSupportModule->use_hyperrefGB->setTitle(qt_("&Use Hyperref Support"));
4687 pdfSupportModule->titleLE->setText(toqstr(pdf.title));
4688 pdfSupportModule->authorLE->setText(toqstr(pdf.author));
4689 pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
4690 pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
4692 pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
4693 pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
4694 pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
4696 pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
4697 pdfSupportModule->bookmarksopenlevelSB->setEnabled(pdf.bookmarksopen);
4698 pdfSupportModule->bookmarksopenlevelLA->setEnabled(pdf.bookmarksopen);
4700 pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
4701 pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
4702 pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
4703 pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
4705 nn = findToken(backref_opts, pdf.backref);
4707 pdfSupportModule->backrefCO->setCurrentIndex(nn);
4709 pdfSupportModule->fullscreenCB->setChecked
4710 (pdf.pagemode == pdf.pagemode_fullscreen);
4712 pdfSupportModule->optionsTE->setPlainText(
4713 toqstr(pdf.quoted_options));
4715 pdfSupportModule->metadataTE->setPlainText(
4716 toqstr(rtrim(bp_.document_metadata, "\n")));
4719 changesModule->trackChangesCB->setChecked(bp_.track_changes);
4720 changesModule->outputChangesCB->setChecked(bp_.output_changes);
4721 changesModule->changeBarsCB->setChecked(bp_.change_bars);
4722 changesModule->changeBarsCB->setEnabled(bp_.output_changes);
4724 // Make sure that the bc is in the INITIAL state
4725 if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
4728 // clear changed branches cache
4729 changedBranches_.clear();
4731 // re-initiate module filter
4732 if (!filter_->text().isEmpty())
4733 moduleFilterPressed();
4736 nonModuleChanged_ = false;
4737 shellescapeChanged_ = false;
4741 void GuiDocument::saveDocDefault()
4743 // we have to apply the params first
4749 void GuiDocument::updateAvailableModules()
4751 modules_av_model_.clear();
4752 list<modInfoStruct> modInfoList = getModuleInfo();
4753 // Sort names according to the locale
4754 modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
4755 return 0 < b.name.localeAwareCompare(a.name);
4757 QIcon user_icon(guiApp ? guiApp->getScaledPixmap("images/", "lyxfiles-user")
4758 : getPixmap("images/", "lyxfiles-user", "svgz,png"));
4759 QIcon system_icon(guiApp ? guiApp->getScaledPixmap("images/", "lyxfiles-system")
4760 : getPixmap("images/", "lyxfiles-system", "svgz,png"));
4763 catfont.setBold(true);
4765 unavbrush.setColor(Qt::gray);
4766 for (modInfoStruct const & m : modInfoList) {
4767 QStandardItem * item = new QStandardItem();
4768 QStandardItem * catItem;
4769 QString const catname = m.category;
4770 QList<QStandardItem *> fcats = modules_av_model_.findItems(catname, Qt::MatchExactly);
4772 catItem = fcats.first();
4774 catItem = new QStandardItem();
4775 catItem->setText(catname);
4776 catItem->setFont(catfont);
4777 modules_av_model_.insertRow(i, catItem);
4780 item->setEditable(false);
4781 catItem->setEditable(false);
4782 item->setData(m.name, Qt::DisplayRole);
4784 item->setForeground(unavbrush);
4785 item->setData(toqstr(m.id), Qt::UserRole);
4786 item->setData(m.description, Qt::ToolTipRole);
4788 item->setIcon(user_icon);
4790 item->setIcon(system_icon);
4791 catItem->appendRow(item);
4793 modules_av_model_.sort(0);
4797 void GuiDocument::updateSelectedModules()
4799 modules_sel_model_.clear();
4800 list<modInfoStruct> const selModList = getSelectedModules();
4802 for (modInfoStruct const & m : selModList) {
4803 modules_sel_model_.insertRow(i, m.name, m.id, m.description);
4809 void GuiDocument::updateIncludeonlyDisplay()
4811 if (includeonlys_.empty()) {
4812 masterChildModule->includeallRB->setChecked(true);
4813 masterChildModule->childrenTW->setEnabled(false);
4814 masterChildModule->maintainGB->setEnabled(false);
4816 masterChildModule->includeonlyRB->setChecked(true);
4817 masterChildModule->childrenTW->setEnabled(true);
4818 masterChildModule->maintainGB->setEnabled(true);
4823 void GuiDocument::updateIncludeonlys(bool const cleanup)
4825 masterChildModule->childrenTW->clear();
4826 QString const no = qt_("No");
4827 QString const yes = qt_("Yes");
4829 ListOfBuffers children = buffer().getChildren();
4830 ListOfBuffers::const_iterator it = children.begin();
4831 ListOfBuffers::const_iterator end = children.end();
4832 bool has_unincluded = false;
4833 bool all_unincluded = true;
4834 for (; it != end; ++it) {
4835 QTreeWidgetItem * item = new QTreeWidgetItem(masterChildModule->childrenTW);
4838 to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
4839 from_utf8(buffer().filePath())));
4840 item->setText(0, toqstr(name));
4841 item->setText(1, isChildIncluded(name) ? yes : no);
4842 if (!isChildIncluded(name))
4843 has_unincluded = true;
4845 all_unincluded = false;
4847 // Both if all children are included and if none is included
4848 // is equal to "include all" (i.e., omit \includeonly).
4849 if (cleanup && (!has_unincluded || all_unincluded))
4850 includeonlys_.clear();
4854 bool GuiDocument::isBiblatex() const
4856 QString const engine =
4857 biblioModule->citeEngineCO->itemData(
4858 biblioModule->citeEngineCO->currentIndex()).toString();
4860 // this can happen if the cite engine is unknown, which can happen
4861 // if one is using a file that came from someone else, etc. in that
4862 // case, we crash if we proceed.
4863 if (engine.isEmpty())
4866 return theCiteEnginesList[fromqstr(engine)]->getCiteFramework() == "biblatex";
4870 void GuiDocument::updateDefaultBiblio(string const & style,
4871 string const & which)
4873 QString const bibstyle = toqstr(style);
4874 biblioModule->defaultBiblioCO->clear();
4879 if (which != "cbx") {
4880 // First the bbx styles
4881 biblioModule->biblatexBbxCO->clear();
4882 QStringList str = texFileList("bbxFiles.lst");
4883 // test whether we have a valid list, otherwise run rescan
4884 if (str.isEmpty()) {
4885 rescanTexStyles("bbx");
4886 str = texFileList("bbxFiles.lst");
4888 for (int i = 0; i != str.size(); ++i)
4889 str[i] = onlyFileName(str[i]);
4890 // sort on filename only (no path)
4893 for (int i = 0; i != str.count(); ++i) {
4894 QString item = changeExtension(str[i], "");
4895 if (item == bibstyle)
4897 biblioModule->biblatexBbxCO->addItem(item);
4900 if (item_nr == -1 && !bibstyle.isEmpty()) {
4901 biblioModule->biblatexBbxCO->addItem(bibstyle);
4902 item_nr = biblioModule->biblatexBbxCO->count() - 1;
4906 biblioModule->biblatexBbxCO->setCurrentIndex(item_nr);
4908 biblioModule->biblatexBbxCO->clearEditText();
4911 if (which != "bbx") {
4912 // now the cbx styles
4913 biblioModule->biblatexCbxCO->clear();
4914 QStringList str = texFileList("cbxFiles.lst");
4915 // test whether we have a valid list, otherwise run rescan
4916 if (str.isEmpty()) {
4917 rescanTexStyles("cbx");
4918 str = texFileList("cbxFiles.lst");
4920 for (int i = 0; i != str.size(); ++i)
4921 str[i] = onlyFileName(str[i]);
4922 // sort on filename only (no path)
4925 for (int i = 0; i != str.count(); ++i) {
4926 QString item = changeExtension(str[i], "");
4927 if (item == bibstyle)
4929 biblioModule->biblatexCbxCO->addItem(item);
4932 if (item_nr == -1 && !bibstyle.isEmpty()) {
4933 biblioModule->biblatexCbxCO->addItem(bibstyle);
4934 item_nr = biblioModule->biblatexCbxCO->count() - 1;
4938 biblioModule->biblatexCbxCO->setCurrentIndex(item_nr);
4940 biblioModule->biblatexCbxCO->clearEditText();
4943 biblioModule->biblatexBbxCO->clear();
4944 biblioModule->biblatexCbxCO->clear();
4945 QStringList str = texFileList("bstFiles.lst");
4946 // test whether we have a valid list, otherwise run rescan
4947 if (str.isEmpty()) {
4948 rescanTexStyles("bst");
4949 str = texFileList("bstFiles.lst");
4951 for (int i = 0; i != str.size(); ++i)
4952 str[i] = onlyFileName(str[i]);
4953 // sort on filename only (no path)
4956 for (int i = 0; i != str.count(); ++i) {
4957 QString item = changeExtension(str[i], "");
4958 if (item == bibstyle)
4960 biblioModule->defaultBiblioCO->addItem(item);
4963 if (item_nr == -1 && !bibstyle.isEmpty()) {
4964 biblioModule->defaultBiblioCO->addItem(bibstyle);
4965 item_nr = biblioModule->defaultBiblioCO->count() - 1;
4969 biblioModule->defaultBiblioCO->setCurrentIndex(item_nr);
4971 biblioModule->defaultBiblioCO->clearEditText();
4974 updateResetDefaultBiblio();
4978 void GuiDocument::updateResetDefaultBiblio()
4980 QString const engine =
4981 biblioModule->citeEngineCO->itemData(
4982 biblioModule->citeEngineCO->currentIndex()).toString();
4983 CiteEngineType const cet =
4984 CiteEngineType(biblioModule->citeStyleCO->itemData(
4985 biblioModule->citeStyleCO->currentIndex()).toInt());
4987 string const defbib = theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet);
4989 QString const bbx = biblioModule->biblatexBbxCO->currentText();
4990 QString const cbx = biblioModule->biblatexCbxCO->currentText();
4991 biblioModule->resetCbxPB->setEnabled(defbib != fromqstr(cbx));
4992 biblioModule->resetBbxPB->setEnabled(defbib != fromqstr(bbx));
4993 biblioModule->matchBbxPB->setEnabled(bbx != cbx && !cbx.isEmpty()
4994 && biblioModule->biblatexBbxCO->findText(cbx) != -1);
4996 biblioModule->resetDefaultBiblioPB->setEnabled(
4997 defbib != fromqstr(biblioModule->defaultBiblioCO->currentText()));
5001 void GuiDocument::matchBiblatexStyles()
5003 updateDefaultBiblio(fromqstr(biblioModule->biblatexCbxCO->currentText()), "bbx");
5008 void GuiDocument::updateContents()
5010 // Nothing to do here as the document settings is not cursor dependent.
5015 void GuiDocument::useClassDefaults()
5017 if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
5018 int const ret = Alert::prompt(_("Unapplied changes"),
5019 _("Some changes in the dialog were not yet applied.\n"
5020 "If you do not apply now, they will be lost after this action."),
5021 1, 1, _("&Apply"), _("&Dismiss"));
5026 int idx = latexModule->classCO->currentIndex();
5027 string const classname = fromqstr(latexModule->classCO->getData(idx));
5028 if (!bp_.setBaseClass(classname, buffer().layoutPos())) {
5029 Alert::error(_("Error"), _("Unable to set document class."));
5032 bp_.useClassDefaults();
5038 void GuiDocument::setLayoutComboByIDString(string const & idString)
5040 if (!latexModule->classCO->set(toqstr(idString)))
5041 Alert::warning(_("Can't set layout!"),
5042 bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
5046 bool GuiDocument::isValid()
5048 bool const listings_valid = validateListingsParameters().isEmpty();
5049 bool const local_layout_valid = !localLayout->editing();
5050 bool const preamble_valid = !preambleModule->editing();
5052 docPS->markPanelValid(N_("Listings[[inset]]"), listings_valid);
5053 docPS->markPanelValid(N_("Local Layout"), local_layout_valid && localLayout->isValid());
5054 docPS->markPanelValid(N_("LaTeX Preamble"), preamble_valid);
5056 return listings_valid && local_layout_valid && preamble_valid;
5060 char const * const GuiDocument::fontfamilies[5] = {
5061 "default", "rmdefault", "sfdefault", "ttdefault", ""
5065 char const * GuiDocument::fontfamilies_gui[5] = {
5066 N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
5070 bool GuiDocument::initialiseParams(string const &)
5072 BufferView const * view = bufferview();
5074 bp_ = BufferParams();
5078 prev_buffer_filename_ = view->buffer().absFileName();
5079 bp_ = view->buffer().params();
5081 updateAvailableModules();
5082 //FIXME It'd be nice to make sure here that the selected
5083 //modules are consistent: That required modules are actually
5084 //selected, and that we don't have conflicts. If so, we could
5085 //at least pop up a warning.
5091 void GuiDocument::clearParams()
5093 bp_ = BufferParams();
5097 BufferId GuiDocument::id() const
5099 BufferView const * const view = bufferview();
5100 return view? &view->buffer() : nullptr;
5104 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
5106 return moduleNames_;
5110 list<GuiDocument::modInfoStruct> const
5111 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
5113 list<modInfoStruct> mInfo;
5114 for (string const & name : mods) {
5116 LyXModule const * const mod = theModuleList[name];
5121 m.name = toqstr(name + " (") + qt_("Not Found") + toqstr(")");
5123 m.missingreqs = true;
5131 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
5133 return makeModuleInfo(params().getModules());
5137 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
5139 return makeModuleInfo(params().baseClass()->providedModules());
5143 DocumentClass const & GuiDocument::documentClass() const
5145 return bp_.documentClass();
5149 static void dispatch_bufferparams(Dialog const & dialog,
5150 BufferParams const & bp, FuncCode lfun, Buffer const * buf)
5153 ss << "\\begin_header\n";
5154 bp.writeFile(ss, buf);
5155 ss << "\\end_header\n";
5156 dialog.dispatch(FuncRequest(lfun, ss.str()));
5160 void GuiDocument::dispatchParams()
5162 // We need a non-const buffer object.
5163 Buffer & buf = const_cast<BufferView *>(bufferview())->buffer();
5164 // There may be several undo records; group them (bug #8998)
5165 // This handles undo groups automagically
5166 UndoGroupHelper ugh(&buf);
5168 // This must come first so that a language change is correctly noticed
5171 // We need to load the master before we formally update the params,
5172 // since otherwise we run updateBuffer, etc, before the child's master
5174 if (!params().master.empty()) {
5175 FileName const master_file = support::makeAbsPath(params().master,
5176 support::onlyPath(buffer().absFileName()));
5177 if (isLyXFileName(master_file.absFileName())) {
5178 Buffer * master = checkAndLoadLyXFile(master_file, true);
5180 if (master->isChild(const_cast<Buffer *>(&buffer())))
5181 const_cast<Buffer &>(buffer()).setParent(master);
5183 Alert::warning(_("Assigned master does not include this file"),
5184 bformat(_("You must include this file in the document\n"
5185 "'%1$s' in order to use the master document\n"
5186 "feature."), from_utf8(params().master)));
5188 Alert::warning(_("Could not load master"),
5189 bformat(_("The master document '%1$s'\n"
5190 "could not be loaded."),
5191 from_utf8(params().master)));
5195 // Apply the BufferParams. Note that this will set the base class
5196 // and then update the buffer's layout.
5197 dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY, &buffer());
5199 // Generate the colours requested by each new branch.
5200 BranchList & branchlist = params().branchlist();
5201 if (!branchlist.empty()) {
5202 BranchList::const_iterator it = branchlist.begin();
5203 BranchList::const_iterator const end = branchlist.end();
5204 for (; it != end; ++it) {
5205 docstring const & current_branch = it->branch();
5206 Branch const * branch = branchlist.find(current_branch);
5207 string const bcolor = branch->color();
5209 if (bcolor.size() == 7 && bcolor[0] == '#')
5210 rgbcol = lyx::rgbFromHexName(bcolor);
5212 guiApp->getRgbColor(lcolor.getFromLyXName(bcolor), rgbcol);
5213 string const x11hexname = X11hexname(rgbcol);
5214 // display the new color
5215 docstring const str = current_branch + ' ' + from_ascii(x11hexname);
5216 dispatch(FuncRequest(LFUN_SET_COLOR, str));
5219 // rename branches in the document
5220 executeBranchRenaming();
5221 // and clear changed branches cache
5222 changedBranches_.clear();
5224 // Generate the colours requested by indices.
5225 IndicesList & indiceslist = params().indiceslist();
5226 if (!indiceslist.empty()) {
5227 IndicesList::const_iterator it = indiceslist.begin();
5228 IndicesList::const_iterator const end = indiceslist.end();
5229 for (; it != end; ++it) {
5230 docstring const & current_index = it->shortcut();
5231 Index const * index = indiceslist.findShortcut(current_index);
5232 string const x11hexname = X11hexname(index->color());
5233 // display the new color
5234 docstring const str = current_index + ' ' + from_ascii(x11hexname);
5235 dispatch(FuncRequest(LFUN_SET_COLOR, str));
5239 // If we used an LFUN, we would not need these two lines:
5240 BufferView * bv = const_cast<BufferView *>(bufferview());
5241 bv->processUpdateFlags(Update::Force | Update::FitCursor);
5245 void GuiDocument::setLanguage() const
5247 Language const * const newL = bp_.language;
5248 if (buffer().params().language == newL)
5251 string const & lang_name = newL->lang();
5252 dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
5256 void GuiDocument::saveAsDefault() const
5258 dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT, &buffer());
5262 bool GuiDocument::providesOSF(QString const & font) const
5264 if (fontModule->osFontsCB->isChecked())
5265 // FIXME: we should check if the fonts really
5266 // have OSF support. But how?
5267 return font != "default";
5268 return theLaTeXFonts().getLaTeXFont(
5269 qstring_to_ucs4(font)).providesOSF(ot1(),
5275 bool GuiDocument::providesSC(QString const & font) const
5277 if (fontModule->osFontsCB->isChecked())
5279 return theLaTeXFonts().getLaTeXFont(
5280 qstring_to_ucs4(font)).providesSC(ot1(),
5286 bool GuiDocument::providesScale(QString const & font) const
5288 if (fontModule->osFontsCB->isChecked())
5289 return font != "default";
5290 return theLaTeXFonts().getLaTeXFont(
5291 qstring_to_ucs4(font)).providesScale(ot1(),
5297 bool GuiDocument::providesExtraOpts(QString const & font) const
5299 if (fontModule->osFontsCB->isChecked())
5300 return font != "default";
5301 return theLaTeXFonts().getLaTeXFont(
5302 qstring_to_ucs4(font)).providesMoreOptions(ot1(),
5308 bool GuiDocument::providesNoMath(QString const & font) const
5310 if (fontModule->osFontsCB->isChecked())
5312 return theLaTeXFonts().getLaTeXFont(
5313 qstring_to_ucs4(font)).providesNoMath(ot1(),
5318 bool GuiDocument::hasMonolithicExpertSet(QString const & font) const
5320 if (fontModule->osFontsCB->isChecked())
5322 return theLaTeXFonts().getLaTeXFont(
5323 qstring_to_ucs4(font)).hasMonolithicExpertSet(ot1(),
5330 GuiDocument::modInfoStruct GuiDocument::modInfo(LyXModule const & mod)
5332 // FIXME Unicode: docstrings would be better for these parameters but this
5333 // change requires a lot of others
5336 QString const guiname = toqstr(translateIfPossible(from_utf8(mod.getName())));
5337 m.missingreqs = !isModuleAvailable(mod.getID());
5338 if (m.missingreqs) {
5339 m.name = qt_("%1 (missing req.)").arg(guiname);
5342 m.category = mod.category().empty() ? qt_("Miscellaneous")
5343 : toqstr(translateIfPossible(from_utf8(mod.category())));
5344 QString desc = toqstr(translateIfPossible(from_utf8(mod.getDescription())));
5345 // Find the first sentence of the description
5346 QTextBoundaryFinder bf(QTextBoundaryFinder::Sentence, desc);
5347 int pos = bf.toNextBoundary();
5350 m.local = mod.isLocal();
5351 QString const mtype = m.local ? qt_("personal module") : qt_("distributed module");
5352 QString modulename = qt_("<b>Module name:</b> <i>%1</i> (%2)").arg(toqstr(m.id)).arg(mtype);
5353 // Tooltip is the desc followed by the module name and the type
5354 m.description = QString("%1%2")
5355 .arg(desc.isEmpty() ? QString() : QString("<p>%1</p>").arg(desc),
5358 m.description += QString("<p>%1</p>").arg(qt_("<b>Note:</b> Some requirements for this module are missing!"));
5363 void GuiDocument::loadModuleInfo()
5365 moduleNames_.clear();
5366 for (LyXModule const & mod : theModuleList)
5367 moduleNames_.push_back(modInfo(mod));
5371 void GuiDocument::updateUnknownBranches()
5375 list<docstring> used_branches;
5376 buffer().getUsedBranches(used_branches);
5377 list<docstring>::const_iterator it = used_branches.begin();
5378 QStringList unknown_branches;
5379 for (; it != used_branches.end() ; ++it) {
5380 if (!buffer().params().branchlist().find(*it))
5381 unknown_branches.append(toqstr(*it));
5383 branchesModule->setUnknownBranches(unknown_branches);
5387 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
5389 map<docstring, docstring>::iterator it = changedBranches_.begin();
5390 for (; it != changedBranches_.end() ; ++it) {
5391 if (it->second == oldname) {
5392 // branch has already been renamed
5393 it->second = newname;
5398 changedBranches_[oldname] = newname;
5402 void GuiDocument::executeBranchRenaming() const
5404 map<docstring, docstring>::const_iterator it = changedBranches_.begin();
5405 for (; it != changedBranches_.end() ; ++it) {
5406 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
5407 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
5412 void GuiDocument::allPackagesAuto()
5418 void GuiDocument::allPackagesAlways()
5424 void GuiDocument::allPackagesNot()
5430 void GuiDocument::allPackages(int col)
5432 for (int row = 0; row < mathsModule->packagesTW->rowCount(); ++row) {
5434 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, col)->layout()->itemAt(0)->widget();
5435 rb->setChecked(true);
5440 void GuiDocument::linenoToggled(bool on)
5442 numberingModule->linenoLE->setEnabled(on);
5443 numberingModule->linenoLA->setEnabled(on);
5447 void GuiDocument::outputChangesToggled(bool on)
5449 changesModule->changeBarsCB->setEnabled(on);
5453 void GuiDocument::setOutputSync(bool on)
5455 outputModule->synccustomCB->setEnabled(on);
5456 outputModule->synccustomLA->setEnabled(on);
5461 bool GuiDocument::eventFilter(QObject * sender, QEvent * event)
5463 if (event->type() == QEvent::ApplicationPaletteChange) {
5464 // mode switch: colors need to be updated
5465 // and the highlighting redone
5466 if (pdf_options_highlighter_) {
5467 pdf_options_highlighter_->setupColors();
5468 pdf_options_highlighter_->rehighlight();
5470 if (pdf_metadata_highlighter_) {
5471 pdf_metadata_highlighter_->setupColors();
5472 pdf_metadata_highlighter_->rehighlight();
5475 return QWidget::eventFilter(sender, event);
5479 } // namespace frontend
5482 #include "moc_GuiDocument.cpp"