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 custom)
2224 // Cache current settings
2225 tmp_leftmargin_ = widgetsToLength(marginsModule->innerLE,
2226 marginsModule->innerUnit);
2227 tmp_topmargin_ = widgetsToLength(marginsModule->topLE,
2228 marginsModule->topUnit);
2229 tmp_rightmargin_ = widgetsToLength(marginsModule->outerLE,
2230 marginsModule->outerUnit);
2231 tmp_bottommargin_ = widgetsToLength(marginsModule->bottomLE,
2232 marginsModule->bottomUnit);
2233 tmp_headheight_ = widgetsToLength(marginsModule->headheightLE,
2234 marginsModule->headheightUnit);
2235 tmp_headsep_ = widgetsToLength(marginsModule->headsepLE,
2236 marginsModule->headsepUnit);
2237 tmp_footskip_ = widgetsToLength(marginsModule->footskipLE,
2238 marginsModule->footskipUnit);
2239 tmp_columnsep_ = widgetsToLength(marginsModule->columnsepLE,
2240 marginsModule->columnsepUnit);
2242 marginsModule->topLE->clear();
2243 marginsModule->bottomLE->clear();
2244 marginsModule->innerLE->clear();
2245 marginsModule->outerLE->clear();
2246 marginsModule->headheightLE->clear();
2247 marginsModule->headsepLE->clear();
2248 marginsModule->footskipLE->clear();
2249 marginsModule->columnsepLE->clear();
2251 Length::UNIT const default_unit = Length::defaultUnit();
2252 // re-fill chached values
2253 lengthToWidgets(marginsModule->topLE,
2254 marginsModule->topUnit,
2255 tmp_topmargin_, default_unit);
2256 lengthToWidgets(marginsModule->bottomLE,
2257 marginsModule->bottomUnit,
2258 tmp_bottommargin_, default_unit);
2259 lengthToWidgets(marginsModule->innerLE,
2260 marginsModule->innerUnit,
2261 tmp_leftmargin_, default_unit);
2262 lengthToWidgets(marginsModule->outerLE,
2263 marginsModule->outerUnit,
2264 tmp_rightmargin_, default_unit);
2265 lengthToWidgets(marginsModule->headheightLE,
2266 marginsModule->headheightUnit,
2267 tmp_headheight_, default_unit);
2268 lengthToWidgets(marginsModule->headsepLE,
2269 marginsModule->headsepUnit,
2270 tmp_headsep_, default_unit);
2271 lengthToWidgets(marginsModule->footskipLE,
2272 marginsModule->footskipUnit,
2273 tmp_footskip_, default_unit);
2274 lengthToWidgets(marginsModule->columnsepLE,
2275 marginsModule->columnsepUnit,
2276 tmp_columnsep_, default_unit);
2278 marginsModule->topL->setEnabled(!custom);
2279 marginsModule->topLE->setEnabled(!custom);
2280 marginsModule->topUnit->setEnabled(!custom);
2282 marginsModule->bottomL->setEnabled(!custom);
2283 marginsModule->bottomLE->setEnabled(!custom);
2284 marginsModule->bottomUnit->setEnabled(!custom);
2286 marginsModule->innerL->setEnabled(!custom);
2287 marginsModule->innerLE->setEnabled(!custom);
2288 marginsModule->innerUnit->setEnabled(!custom);
2290 marginsModule->outerL->setEnabled(!custom);
2291 marginsModule->outerLE->setEnabled(!custom);
2292 marginsModule->outerUnit->setEnabled(!custom);
2294 marginsModule->headheightL->setEnabled(!custom);
2295 marginsModule->headheightLE->setEnabled(!custom);
2296 marginsModule->headheightUnit->setEnabled(!custom);
2298 marginsModule->headsepL->setEnabled(!custom);
2299 marginsModule->headsepLE->setEnabled(!custom);
2300 marginsModule->headsepUnit->setEnabled(!custom);
2302 marginsModule->footskipL->setEnabled(!custom);
2303 marginsModule->footskipLE->setEnabled(!custom);
2304 marginsModule->footskipUnit->setEnabled(!custom);
2306 bool const enableColSep = !custom &&
2307 textLayoutModule->twoColumnCB->checkState() == Qt::Checked;
2308 marginsModule->columnsepL->setEnabled(enableColSep);
2309 marginsModule->columnsepLE->setEnabled(enableColSep);
2310 marginsModule->columnsepUnit->setEnabled(enableColSep);
2312 // set some placeholder text that hint on defaults
2313 QString const placeholder = marginsModule->marginCB->isChecked() ?
2314 qt_("Default margins") : qt_("Package defaults");
2315 // set tooltip depending on gemoetry state
2316 QString const tooltip = marginsModule->marginCB->isChecked() ?
2317 qt_("If no value is given, the defaults as set by the class, a package or the preamble are used.")
2318 : qt_("If no value is given, the defaults as set by the geometry package or a package/class overriding geometry's defaults are used.");
2319 marginsModule->topLE->setPlaceholderText(placeholder);
2320 marginsModule->bottomLE->setPlaceholderText(placeholder);
2321 marginsModule->innerLE->setPlaceholderText(placeholder);
2322 marginsModule->outerLE->setPlaceholderText(placeholder);
2323 marginsModule->headheightLE->setPlaceholderText(placeholder);
2324 marginsModule->headsepLE->setPlaceholderText(placeholder);
2325 marginsModule->footskipLE->setPlaceholderText(placeholder);
2326 marginsModule->columnsepLE->setPlaceholderText(placeholder);
2327 marginsModule->topLE->setToolTip(tooltip);
2328 marginsModule->bottomLE->setToolTip(tooltip);
2329 marginsModule->innerLE->setToolTip(tooltip);
2330 marginsModule->outerLE->setToolTip(tooltip);
2331 marginsModule->headheightLE->setToolTip(tooltip);
2332 marginsModule->headsepLE->setToolTip(tooltip);
2333 marginsModule->footskipLE->setToolTip(tooltip);
2334 marginsModule->columnsepLE->setToolTip(tooltip);
2338 void GuiDocument::changeBackgroundColor()
2340 QColor const & newColor = getColor(rgb2qcolor(set_backgroundcolor));
2341 if (!newColor.isValid())
2344 colorModule->pageBackgroundCF->setVisible(true);
2345 colorModule->pageBackgroundCF->setStyleSheet(
2346 colorFrameStyleSheet(newColor));
2348 set_backgroundcolor = rgbFromHexName(fromqstr(newColor.name()));
2349 is_backgroundcolor = true;
2354 void GuiDocument::deleteBackgroundColor()
2356 // set the color back to default by setting an empty StyleSheet
2357 colorModule->pageBackgroundCF->setStyleSheet(QLatin1String(""));
2358 colorModule->pageBackgroundCF->setVisible(false);
2359 // save default color (white)
2360 set_backgroundcolor = rgbFromHexName("#ffffff");
2361 is_backgroundcolor = false;
2366 void GuiDocument::changeFontColor()
2368 QColor const & newColor = getColor(rgb2qcolor(set_fontcolor));
2369 if (!newColor.isValid())
2372 colorModule->mainTextCF->setVisible(true);
2373 colorModule->mainTextCF->setStyleSheet(
2374 colorFrameStyleSheet(newColor));
2376 set_fontcolor = rgbFromHexName(fromqstr(newColor.name()));
2377 is_fontcolor = true;
2382 void GuiDocument::deleteFontColor()
2384 // set the button color back to default by setting an empty StyleSheet
2385 colorModule->mainTextCF->setStyleSheet(QLatin1String(""));
2386 colorModule->mainTextCF->setVisible(false);
2387 // save default color (black)
2388 set_fontcolor = rgbFromHexName("#000000");
2389 is_fontcolor = false;
2394 void GuiDocument::changeNoteFontColor()
2396 QColor const & newColor = getColor(rgb2qcolor(set_notefontcolor));
2397 if (!newColor.isValid())
2400 colorModule->noteFontCF->setStyleSheet(
2401 colorFrameStyleSheet(newColor));
2403 set_notefontcolor = rgbFromHexName(fromqstr(newColor.name()));
2404 is_notefontcolor = true;
2409 void GuiDocument::deleteNoteFontColor()
2411 // set the color back to pref
2412 theApp()->getRgbColor(Color_greyedouttext, set_notefontcolor);
2413 colorModule->noteFontCF->setStyleSheet(
2414 colorFrameStyleSheet(rgb2qcolor(set_notefontcolor)));
2415 is_notefontcolor = false;
2420 void GuiDocument::changeBoxBackgroundColor()
2422 QColor const & newColor = getColor(rgb2qcolor(set_boxbgcolor));
2423 if (!newColor.isValid())
2426 colorModule->boxBackgroundCF->setStyleSheet(
2427 colorFrameStyleSheet(newColor));
2429 set_boxbgcolor = rgbFromHexName(fromqstr(newColor.name()));
2430 is_boxbgcolor = true;
2435 void GuiDocument::deleteBoxBackgroundColor()
2437 // set the color back to pref
2438 theApp()->getRgbColor(Color_shadedbg, set_boxbgcolor);
2439 colorModule->boxBackgroundCF->setStyleSheet(
2440 colorFrameStyleSheet(rgb2qcolor(set_boxbgcolor)));
2441 is_boxbgcolor = false;
2446 void GuiDocument::updateQuoteStyles(bool const set)
2448 Language const * lang = lyx::languages.getLanguage(
2449 fromqstr(langModule->languageCO->itemData(
2450 langModule->languageCO->currentIndex()).toString()));
2452 QuoteStyle def = bp_.getQuoteStyle(lang->quoteStyle());
2454 langModule->quoteStyleCO->clear();
2456 bool has_default = false;
2457 for (int i = 0; i < quoteparams.stylescount(); ++i) {
2458 QuoteStyle qs = QuoteStyle(i);
2459 if (qs == QuoteStyle::Dynamic)
2461 bool const langdef = (qs == def);
2463 // add the default style on top
2464 langModule->quoteStyleCO->insertItem(0,
2465 toqstr(quoteparams.getGuiLabel(qs, langdef)), static_cast<int>(qs));
2469 langModule->quoteStyleCO->addItem(
2470 toqstr(quoteparams.getGuiLabel(qs, langdef)), static_cast<int>(qs));
2472 // Use document serif font to assure quotation marks are distinguishable
2473 QFont comboFont(toqstr(lyxrc.roman_font_name),
2474 langModule->quoteStyleCO->fontInfo().pointSize() * 1.4, -1, false);
2475 QFontMetrics fm(comboFont);
2476 // calculate width of the widest item in the set font
2478 for (int i = 0; i < langModule->quoteStyleCO->count(); ++i) {
2479 langModule->quoteStyleCO->setItemData(i, QVariant(comboFont), Qt::FontRole);
2480 QString str = langModule->quoteStyleCO->itemText(i);
2481 #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
2482 qswidth = max(qswidth, fm.horizontalAdvance(str));
2484 qswidth = max(qswidth, fm.width(str));
2487 // add scrollbar width and margin to width
2488 qswidth += langModule->quoteStyleCO->style()->pixelMetric(QStyle::PM_ScrollBarExtent);
2489 qswidth += langModule->quoteStyleCO->view()->autoScrollMargin();
2490 langModule->quoteStyleCO->view()->setMinimumWidth(qswidth);
2491 if (set && has_default)
2492 // (re)set to the default style
2493 langModule->quoteStyleCO->setCurrentIndex(0);
2497 void GuiDocument::languageChanged(int i)
2499 // some languages only work with Polyglossia
2500 Language const * lang = lyx::languages.getLanguage(
2501 fromqstr(langModule->languageCO->itemData(i).toString()));
2502 if (lang->babel().empty() && !lang->polyglossia().empty()
2503 && lang->required() != "CJK" && lang->required() != "japanese") {
2504 // If we force to switch fontspec on, store
2505 // current state (#8717)
2506 if (fontModule->osFontsCB->isEnabled())
2507 forced_fontspec_activation =
2508 !fontModule->osFontsCB->isChecked();
2509 fontModule->osFontsCB->setChecked(true);
2510 fontModule->osFontsCB->setEnabled(false);
2513 fontModule->osFontsCB->setEnabled(true);
2514 // If we have forced to switch fontspec on,
2515 // restore previous state (#8717)
2516 if (forced_fontspec_activation)
2517 fontModule->osFontsCB->setChecked(false);
2518 forced_fontspec_activation = false;
2521 // set appropriate quotation mark style
2522 updateQuoteStyles(true);
2526 void GuiDocument::osFontsChanged(bool nontexfonts)
2528 bool const tex_fonts = !nontexfonts;
2529 // store current fonts
2530 QString const font_roman = fontModule->fontsRomanCO->getData(
2531 fontModule->fontsRomanCO->currentIndex());
2532 QString const font_sans = fontModule->fontsSansCO->getData(
2533 fontModule->fontsSansCO->currentIndex());
2534 QString const font_typewriter = fontModule->fontsTypewriterCO->getData(
2535 fontModule->fontsTypewriterCO->currentIndex());
2536 QString const font_math = fontModule->fontsMathCO->itemData(
2537 fontModule->fontsMathCO->currentIndex()).toString();
2538 int const font_sf_scale = fontModule->scaleSansSB->value();
2539 int const font_tt_scale = fontModule->scaleTypewriterSB->value();
2542 // store default format
2543 QString const dformat = outputModule->defaultFormatCO->itemData(
2544 outputModule->defaultFormatCO->currentIndex()).toString();
2545 updateDefaultFormat();
2546 // try to restore default format
2547 int index = outputModule->defaultFormatCO->findData(dformat);
2548 // set to default if format is not found
2551 outputModule->defaultFormatCO->setCurrentIndex(index);
2553 // try to restore fonts which were selected two toggles ago
2554 if (!fontModule->font_roman.isEmpty())
2555 fontModule->fontsRomanCO->set(fontModule->font_roman);
2556 if (!fontModule->font_sans.isEmpty())
2557 fontModule->fontsSansCO->set(fontModule->font_sans);
2558 if (!fontModule->font_typewriter.isEmpty())
2559 fontModule->fontsTypewriterCO->set(fontModule->font_typewriter);
2560 index = fontModule->fontsMathCO->findData(fontModule->font_math);
2562 fontModule->fontsMathCO->setCurrentIndex(index);
2563 // save fonts for next next toggle
2564 fontModule->font_roman = font_roman;
2565 fontModule->font_sans = font_sans;
2566 fontModule->font_typewriter = font_typewriter;
2567 fontModule->font_math = font_math;
2568 fontModule->font_sf_scale = font_sf_scale;
2569 fontModule->font_tt_scale = font_tt_scale;
2571 // non-tex fonts override the "\inputencoding" option with "utf8-plain"
2572 langModule->encodingCO->setEnabled(tex_fonts);
2573 inputencodingToDialog();
2575 fontModule->cjkFontLE->setEnabled(tex_fonts);
2576 fontModule->cjkFontLA->setEnabled(tex_fonts);
2578 updateFontOptions();
2580 fontModule->fontencLA->setEnabled(tex_fonts);
2581 fontModule->fontencCO->setEnabled(tex_fonts);
2583 fontModule->fontencLE->setEnabled(false);
2585 fontencChanged(fontModule->fontencCO->currentIndex());
2589 void GuiDocument::encodingSwitched(int i)
2591 bool const tex_fonts = !fontModule->osFontsCB->isChecked();
2592 langModule->unicodeEncodingCO->setEnabled(tex_fonts);
2593 langModule->customEncodingCO->setEnabled(tex_fonts);
2594 langModule->autoEncodingCO->setEnabled(tex_fonts);
2595 langModule->unicodeEncodingCO->setVisible(i == EncodingSets::unicode);
2596 langModule->autoEncodingCO->setVisible(i == EncodingSets::legacy);
2597 langModule->customEncodingCO->setVisible(i == EncodingSets::custom);
2599 case EncodingSets::unicode:
2600 langModule->encodingVariantLA->setBuddy(langModule->unicodeEncodingCO);
2602 case EncodingSets::legacy:
2603 langModule->encodingVariantLA->setBuddy(langModule->autoEncodingCO);
2605 case EncodingSets::custom:
2606 langModule->encodingVariantLA->setBuddy(langModule->customEncodingCO);
2611 langModule->unicodeEncodingCO->setItemText(1, qt_("Direct (No inputenc)"));
2613 langModule->unicodeEncodingCO->setItemText(1, qt_("Direct (XeTeX/LuaTeX)"));
2616 void GuiDocument::inputencodingToDialog()
2618 QString inputenc = toqstr(bp_.inputenc);
2620 if (fontModule->osFontsCB->isChecked()) { // non-tex fonts require utf8-plain
2621 langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
2622 langModule->unicodeEncodingCO->setCurrentIndex(
2623 langModule->unicodeEncodingCO->findData("utf8-plain"));
2624 } else if (inputenc.startsWith("utf8")) {
2625 langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
2626 p = langModule->unicodeEncodingCO->findData(inputenc);
2629 langModule->unicodeEncodingCO->setCurrentIndex(p);
2630 langModule->autoEncodingCO->setCurrentIndex(0);
2631 langModule->customEncodingCO->setCurrentIndex(0);
2632 } else if (inputenc.startsWith("auto")) {
2633 langModule->encodingCO->setCurrentIndex(EncodingSets::legacy);
2634 p = langModule->autoEncodingCO->findData(inputenc);
2637 langModule->unicodeEncodingCO->setCurrentIndex(0);
2638 langModule->autoEncodingCO->setCurrentIndex(p);
2639 langModule->customEncodingCO->setCurrentIndex(0);
2641 langModule->encodingCO->setCurrentIndex(EncodingSets::custom);
2642 p = langModule->customEncodingCO->findData(inputenc);
2645 langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
2647 langModule->unicodeEncodingCO->setCurrentIndex(0);
2648 langModule->autoEncodingCO->setCurrentIndex(0);
2649 langModule->customEncodingCO->setCurrentIndex(p);
2651 encodingSwitched(langModule->encodingCO->currentIndex());
2655 void GuiDocument::mathFontChanged(int)
2657 updateFontOptions();
2660 void GuiDocument::fontOsfToggled(bool state)
2662 if (fontModule->osFontsCB->isChecked())
2664 QString font = fontModule->fontsRomanCO->getData(
2665 fontModule->fontsRomanCO->currentIndex());
2666 if (hasMonolithicExpertSet(font))
2667 fontModule->fontScCB->setChecked(state);
2671 void GuiDocument::fontScToggled(bool state)
2673 if (fontModule->osFontsCB->isChecked())
2675 QString font = fontModule->fontsRomanCO->getData(
2676 fontModule->fontsRomanCO->currentIndex());
2677 if (hasMonolithicExpertSet(font))
2678 fontModule->fontOsfCB->setChecked(state);
2682 void GuiDocument::updateExtraOpts()
2684 QString font = fontModule->fontsRomanCO->getData(
2685 fontModule->fontsRomanCO->currentIndex());
2686 bool const rm_opts = providesExtraOpts(font);
2687 font = fontModule->fontsSansCO->getData(
2688 fontModule->fontsSansCO->currentIndex());
2689 bool const sf_opts = providesExtraOpts(font);
2690 font = fontModule->fontsTypewriterCO->getData(
2691 fontModule->fontsTypewriterCO->currentIndex());
2692 bool const tt_opts = providesExtraOpts(font);
2693 fontModule->fontspecRomanLA->setEnabled(rm_opts);
2694 fontModule->fontspecRomanLE->setEnabled(rm_opts);
2695 fontModule->fontspecSansLA->setEnabled(sf_opts);
2696 fontModule->fontspecSansLE->setEnabled(sf_opts);
2697 fontModule->fontspecTypewriterLA->setEnabled(tt_opts);
2698 fontModule->fontspecTypewriterLE->setEnabled(tt_opts);
2702 void GuiDocument::updateFontOptions()
2704 QString font = fontModule->fontsSansCO->getData(
2705 fontModule->fontsSansCO->currentIndex());
2706 bool scalable = providesScale(font);
2707 fontModule->scaleSansSB->setEnabled(scalable);
2708 fontModule->scaleSansLA->setEnabled(scalable);
2709 fontModule->fontSansOsfCB->setEnabled(providesOSF(font));
2710 font = fontModule->fontsTypewriterCO->getData(
2711 fontModule->fontsTypewriterCO->currentIndex());
2712 scalable = providesScale(font);
2713 fontModule->scaleTypewriterSB->setEnabled(scalable);
2714 fontModule->scaleTypewriterLA->setEnabled(scalable);
2715 fontModule->fontTypewriterOsfCB->setEnabled(providesOSF(font));
2716 font = fontModule->fontsRomanCO->getData(
2717 fontModule->fontsRomanCO->currentIndex());
2718 fontModule->fontScCB->setEnabled(providesSC(font));
2719 fontModule->fontOsfCB->setEnabled(providesOSF(font));
2721 updateMathFonts(font);
2725 void GuiDocument::updateFontsize(string const & items, string const & sel)
2727 fontModule->fontsizeCO->clear();
2728 fontModule->fontsizeCO->addItem(qt_("Default"));
2730 for (int n = 0; !token(items,'|',n).empty(); ++n)
2731 fontModule->fontsizeCO->
2732 addItem(toqstr(token(items,'|',n)));
2734 for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
2735 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
2736 fontModule->fontsizeCO->setCurrentIndex(n);
2743 bool GuiDocument::ot1() const
2745 QString const fontenc =
2746 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
2747 int const i = langModule->languageCO->currentIndex();
2750 QString const langname = langModule->languageCO->itemData(i).toString();
2751 Language const * newlang = lyx::languages.getLanguage(fromqstr(langname));
2752 return (fontenc == "default"
2753 || (fontenc == "auto" && newlang->fontenc(buffer().params()) == "OT1")
2754 || (fontenc == "custom" && fontModule->fontencLE->text() == "OT1"));
2758 bool GuiDocument::completeFontset() const
2760 return (fontModule->fontsSansCO->getData(
2761 fontModule->fontsSansCO->currentIndex()) == "default"
2762 && fontModule->fontsSansCO->getData(
2763 fontModule->fontsTypewriterCO->currentIndex()) == "default");
2767 bool GuiDocument::noMathFont() const
2769 return (fontModule->fontsMathCO->itemData(
2770 fontModule->fontsMathCO->currentIndex()).toString() == "default");
2774 void GuiDocument::updateTexFonts()
2776 LaTeXFonts::TexFontMap texfontmap = theLaTeXFonts().getLaTeXFonts();
2778 LaTeXFonts::TexFontMap::const_iterator it = texfontmap.begin();
2779 LaTeXFonts::TexFontMap::const_iterator end = texfontmap.end();
2780 for (; it != end; ++it) {
2781 LaTeXFont lf = it->second;
2782 if (lf.name().empty()) {
2783 LYXERR0("Error: Unnamed font: " << it->first);
2786 docstring const family = lf.family();
2787 docstring guiname = translateIfPossible(lf.guiname());
2788 if (!lf.available(ot1(), noMathFont()))
2789 guiname += _(" (not installed)");
2791 rmfonts_.insert(toqstr(guiname), toqstr(it->first));
2792 else if (family == "sf")
2793 sffonts_.insert(toqstr(guiname), toqstr(it->first));
2794 else if (family == "tt")
2795 ttfonts_.insert(toqstr(guiname), toqstr(it->first));
2796 else if (family == "math")
2797 mathfonts_.insert(toqstr(guiname), toqstr(it->first));
2802 void GuiDocument::updateFontlist()
2804 // reset the filters of the CategorizedCombos
2805 fontModule->fontsRomanCO->resetFilter();
2806 fontModule->fontsSansCO->resetFilter();
2807 fontModule->fontsTypewriterCO->resetFilter();
2808 fontModule->fontsRomanCO->clear();
2809 fontModule->fontsSansCO->clear();
2810 fontModule->fontsTypewriterCO->clear();
2811 fontModule->fontsMathCO->clear();
2813 // With fontspec (XeTeX, LuaTeX), we have access to all system fonts, but not the LaTeX fonts
2814 if (fontModule->osFontsCB->isChecked()) {
2815 fontModule->fontsRomanCO->addItemSort(QString("default"), qt_("Default"),
2816 QString(), qt_("Default font (as set by class)"),
2817 false, false, false, true, true);
2818 fontModule->fontsSansCO->addItemSort(QString("default"), qt_("Default"),
2819 QString(), qt_("Default font (as set by class)"),
2820 false, false, false, true, true);
2821 fontModule->fontsTypewriterCO->addItemSort(QString("default"), qt_("Default"),
2822 QString(), qt_("Default font (as set by class)"),
2823 false, false, false, true, true);
2824 QString unimath = qt_("Non-TeX Fonts Default");
2825 if (!LaTeXFeatures::isAvailable("unicode-math"))
2826 unimath += qt_(" (not available)");
2827 fontModule->fontsMathCO->addItem(qt_("Class Default (TeX Fonts)"), QString("auto"));
2828 fontModule->fontsMathCO->addItem(unimath, QString("default"));
2830 #if QT_VERSION >= 0x060000
2831 const QStringList families(QFontDatabase::families());
2833 QFontDatabase fontdb;
2834 const QStringList families(fontdb.families());
2836 for (auto const & family : families) {
2837 fontModule->fontsRomanCO->addItemSort(family, family,
2838 QString(), QString(),
2839 false, false, false, true, true);
2840 fontModule->fontsSansCO->addItemSort(family, family,
2841 QString(), QString(),
2842 false, false, false, true, true);
2843 fontModule->fontsTypewriterCO->addItemSort(family, family,
2844 QString(), QString(),
2845 false, false, false, true, true);
2850 if (rmfonts_.empty())
2853 fontModule->fontsRomanCO->addItemSort(QString("default"), qt_("Default"),
2854 QString(), qt_("Default font (as set by class)"),
2855 false, false, false, true, true);
2856 QMap<QString, QString>::const_iterator rmi = rmfonts_.constBegin();
2857 while (rmi != rmfonts_.constEnd()) {
2858 fontModule->fontsRomanCO->addItemSort(rmi.value(), rmi.key(),
2859 QString(), QString(),
2860 false, false, false, true, true);
2864 fontModule->fontsSansCO->addItemSort(QString("default"), qt_("Default"),
2865 QString(), qt_("Default font (as set by class)"),
2866 false, false, false, true, true);
2867 QMap<QString, QString>::const_iterator sfi = sffonts_.constBegin();
2868 while (sfi != sffonts_.constEnd()) {
2869 fontModule->fontsSansCO->addItemSort(sfi.value(), sfi.key(),
2870 QString(), QString(),
2871 false, false, false, true, true);
2875 fontModule->fontsTypewriterCO->addItemSort(QString("default"), qt_("Default"),
2876 QString(), qt_("Default font (as set by class)"),
2877 false, false, false, true, true);
2878 QMap<QString, QString>::const_iterator tti = ttfonts_.constBegin();
2879 while (tti != ttfonts_.constEnd()) {
2880 fontModule->fontsTypewriterCO->addItemSort(tti.value(), tti.key(),
2881 QString(), QString(),
2882 false, false, false, true, true);
2886 fontModule->fontsMathCO->addItem(qt_("Automatic"), QString("auto"));
2887 fontModule->fontsMathCO->addItem(qt_("Class Default"), QString("default"));
2888 QMap<QString, QString>::const_iterator mmi = mathfonts_.constBegin();
2889 while (mmi != mathfonts_.constEnd()) {
2890 fontModule->fontsMathCO->addItem(mmi.key(), mmi.value());
2896 void GuiDocument::fontencChanged(int item)
2898 fontModule->fontencLE->setEnabled(
2899 fontModule->fontencCO->itemData(item).toString() == "custom");
2900 // The availability of TeX fonts depends on the font encoding
2902 updateFontOptions();
2906 void GuiDocument::updateMathFonts(QString const & rm)
2908 if (fontModule->osFontsCB->isChecked())
2910 QString const math =
2911 fontModule->fontsMathCO->itemData(fontModule->fontsMathCO->currentIndex()).toString();
2912 int const i = fontModule->fontsMathCO->findData("default");
2913 if (providesNoMath(rm) && i == -1)
2914 fontModule->fontsMathCO->insertItem(1, qt_("Class Default"), QString("default"));
2915 else if (!providesNoMath(rm) && i != -1) {
2916 int const c = fontModule->fontsMathCO->currentIndex();
2917 fontModule->fontsMathCO->removeItem(i);
2919 fontModule->fontsMathCO->setCurrentIndex(0);
2924 void GuiDocument::romanChanged(int item)
2926 QString const font = fontModule->fontsRomanCO->getData(item);
2927 fontModule->fontOsfCB->setEnabled(providesOSF(font));
2929 if (fontModule->osFontsCB->isChecked())
2931 fontModule->fontScCB->setEnabled(providesSC(font));
2932 updateMathFonts(font);
2936 void GuiDocument::sansChanged(int item)
2938 QString const font = fontModule->fontsSansCO->getData(item);
2939 bool const scalable = providesScale(font);
2940 fontModule->scaleSansSB->setEnabled(scalable);
2941 fontModule->scaleSansLA->setEnabled(scalable);
2942 fontModule->fontSansOsfCB->setEnabled(providesOSF(font));
2947 void GuiDocument::ttChanged(int item)
2949 QString const font = fontModule->fontsTypewriterCO->getData(item);
2950 bool scalable = providesScale(font);
2951 fontModule->scaleTypewriterSB->setEnabled(scalable);
2952 fontModule->scaleTypewriterLA->setEnabled(scalable);
2953 fontModule->fontTypewriterOsfCB->setEnabled(providesOSF(font));
2958 void GuiDocument::updatePagestyle(string const & items, string const & sel)
2961 pageLayoutModule->pagestyleCO->clear();
2962 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
2964 for (int n = 0; !token(items, '|', n).empty(); ++n) {
2965 string style = token(items, '|', n);
2966 QString style_gui = qt_(style);
2967 pagestyles.push_back(pair<string, QString>(style, style_gui));
2968 pageLayoutModule->pagestyleCO->addItem(style_gui);
2971 if (sel == "default") {
2972 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
2978 for (auto const & pagestyle : pagestyles)
2979 if (pagestyle.first == sel)
2980 nn = pageLayoutModule->pagestyleCO->findText(pagestyle.second);
2983 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
2987 void GuiDocument::browseLayout()
2989 QString const label1 = qt_("Lay&outs");
2990 QString const dir1 = toqstr(lyxrc.document_path);
2991 QStringList const filter(qt_("LyX Layout (*.layout)"));
2992 QString file = browseRelToParent(QString(), bufferFilePath(),
2993 qt_("Local layout file"), filter, false,
2996 if (!file.endsWith(".layout"))
2999 FileName layoutFile = support::makeAbsPath(fromqstr(file),
3000 fromqstr(bufferFilePath()));
3002 int const ret = Alert::prompt(_("Local layout file"),
3003 _("The layout file you have selected is a local layout\n"
3004 "file, not one in the system or user directory.\n"
3005 "Your document will not work with this layout if you\n"
3006 "move the layout file to a different directory."),
3007 1, 1, _("&Set Layout"), _("&Cancel"));
3011 // load the layout file
3012 LayoutFileList & bcl = LayoutFileList::get();
3013 string classname = layoutFile.onlyFileName();
3014 // this will update an existing layout if that layout has been loaded before.
3015 LayoutFileIndex name = support::onlyFileName(bcl.addLocalLayout(
3016 classname.substr(0, classname.size() - 7),
3017 layoutFile.onlyPath().absFileName()));
3020 Alert::error(_("Error"),
3021 _("Unable to read local layout file."));
3025 const_cast<Buffer &>(buffer()).setLayoutPos(layoutFile.onlyPath().absFileName());
3027 // do not trigger classChanged if there is no change.
3028 if (latexModule->classCO->currentText() == toqstr(name))
3032 bool const avail = latexModule->classCO->set(toqstr(name));
3034 LayoutFile const & tc = bcl[name];
3035 docstring const guiname = translateIfPossible(from_utf8(tc.description()));
3036 // tooltip sensu "KOMA-Script Article [Class 'scrartcl']"
3037 QString tooltip = toqstr(bformat(_("%1$s [Class '%2$s']"), guiname, from_utf8(tc.latexname())));
3038 tooltip += '\n' + qt_("This is a local layout file.");
3039 latexModule->classCO->addItemSort(toqstr(tc.name()), toqstr(guiname),
3040 toqstr(translateIfPossible(from_utf8(tc.category()))),
3042 true, true, true, true);
3043 latexModule->classCO->set(toqstr(name));
3050 void GuiDocument::browseMaster()
3052 QString const title = qt_("Select master document");
3053 QString const dir1 = toqstr(lyxrc.document_path);
3054 QString const old = latexModule->childDocLE->text();
3055 QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
3056 QStringList const filter(qt_("LyX Files (*.lyx)"));
3057 QString file = browseRelToSub(old, docpath, title, filter, false,
3058 qt_("D&ocuments"), toqstr(lyxrc.document_path));
3060 if (!file.isEmpty())
3061 latexModule->childDocLE->setText(file);
3065 void GuiDocument::classChanged_adaptor()
3067 const_cast<Buffer &>(buffer()).setLayoutPos(string());
3072 void GuiDocument::classChanged()
3074 int idx = latexModule->classCO->currentIndex();
3077 string const classname = fromqstr(latexModule->classCO->getData(idx));
3079 if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
3080 int const ret = Alert::prompt(_("Unapplied changes"),
3081 _("Some changes in the dialog were not yet applied.\n"
3082 "If you do not apply now, they will be lost after this action."),
3083 1, 1, _("&Apply"), _("&Dismiss"));
3088 // We load the TextClass as soon as it is selected. This is
3089 // necessary so that other options in the dialog can be updated
3090 // according to the new class. Note, however, that, if you use
3091 // the scroll wheel when sitting on the combo box, we'll load a
3092 // lot of TextClass objects very quickly....
3093 if (!bp_.setBaseClass(classname, buffer().layoutPos())) {
3094 Alert::error(_("Error"), _("Unable to set document class."));
3097 if (lyxrc.auto_reset_options)
3098 bp_.useClassDefaults();
3100 // With the introduction of modules came a distinction between the base
3101 // class and the document class. The former corresponds to the main layout
3102 // file; the latter is that plus the modules (or the document-specific layout,
3103 // or whatever else there could be). Our parameters come from the document
3104 // class. So when we set the base class, we also need to recreate the document
3105 // class. Otherwise, we still have the old one.
3106 bp_.makeDocumentClass();
3111 void GuiDocument::languagePackageChanged(int i)
3113 langModule->languagePackageLE->setEnabled(
3114 langModule->languagePackageCO->itemData(i).toString() == "custom");
3118 void GuiDocument::biblioChanged()
3120 biblioChanged_ = true;
3125 void GuiDocument::checkPossibleCiteEngines()
3127 // Check if the class provides a specific engine,
3128 // and if so, enforce this.
3129 string force_engine;
3130 if (documentClass().provides("natbib")
3131 || documentClass().provides("natbib-internal"))
3132 force_engine = "natbib";
3133 else if (documentClass().provides("jurabib"))
3134 force_engine = "jurabib";
3135 else if (documentClass().provides("biblatex"))
3136 force_engine = "biblatex";
3137 else if (documentClass().provides("biblatex-natbib"))
3138 force_engine = "biblatex-natbib";
3140 if (!force_engine.empty())
3141 biblioModule->citeEngineCO->setCurrentIndex(
3142 biblioModule->citeEngineCO->findData(toqstr(force_engine)));
3143 biblioModule->citeEngineCO->setEnabled(force_engine.empty());
3147 void GuiDocument::rescanBibFiles()
3150 rescanTexStyles("bbx cbx");
3152 rescanTexStyles("bst");
3156 void GuiDocument::resetDefaultBibfile(string const & which)
3158 QString const engine =
3159 biblioModule->citeEngineCO->itemData(
3160 biblioModule->citeEngineCO->currentIndex()).toString();
3162 CiteEngineType const cet =
3163 CiteEngineType(biblioModule->citeStyleCO->itemData(
3164 biblioModule->citeStyleCO->currentIndex()).toInt());
3166 updateDefaultBiblio(theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet), which);
3170 void GuiDocument::resetDefaultBbxBibfile()
3172 resetDefaultBibfile("bbx");
3176 void GuiDocument::resetDefaultCbxBibfile()
3178 resetDefaultBibfile("cbx");
3182 void GuiDocument::citeEngineChanged(int n)
3184 QString const engine =
3185 biblioModule->citeEngineCO->itemData(n).toString();
3187 vector<string> const engs =
3188 theCiteEnginesList[fromqstr(engine)]->getEngineType();
3190 updateCiteStyles(engs);
3191 updateEngineDependends();
3192 resetDefaultBibfile();
3197 void GuiDocument::updateEngineDependends()
3199 bool const biblatex = isBiblatex();
3201 // These are only useful with BibTeX
3202 biblioModule->defaultBiblioCO->setEnabled(!biblatex);
3203 biblioModule->bibtexStyleLA->setEnabled(!biblatex);
3204 biblioModule->resetDefaultBiblioPB->setEnabled(!biblatex);
3205 biblioModule->bibtopicCB->setEnabled(!biblatex);
3207 // These are only useful with Biblatex
3208 biblioModule->biblatexBbxCO->setEnabled(biblatex);
3209 biblioModule->biblatexBbxLA->setEnabled(biblatex);
3210 biblioModule->biblatexCbxCO->setEnabled(biblatex);
3211 biblioModule->biblatexCbxLA->setEnabled(biblatex);
3212 biblioModule->resetBbxPB->setEnabled(biblatex);
3213 biblioModule->resetCbxPB->setEnabled(biblatex);
3214 biblioModule->matchBbxPB->setEnabled(biblatex);
3216 // These are useful with biblatex, jurabib and natbib
3217 QString const engine =
3218 biblioModule->citeEngineCO->itemData(
3219 biblioModule->citeEngineCO->currentIndex()).toString();
3220 LyXCiteEngine const * ce = theCiteEnginesList[fromqstr(engine)];
3222 bool const citepack = ce->required("biblatex.sty") || ce->required("jurabib.sty")
3223 || ce->required("natbib.sty");
3224 biblioModule->citePackageOptionsLE->setEnabled(citepack);
3225 biblioModule->citePackageOptionsL->setEnabled(citepack);
3229 void GuiDocument::citeStyleChanged()
3231 QString const engine =
3232 biblioModule->citeEngineCO->itemData(
3233 biblioModule->citeEngineCO->currentIndex()).toString();
3234 QString const currentDef = isBiblatex() ?
3235 biblioModule->biblatexBbxCO->currentText()
3236 : biblioModule->defaultBiblioCO->currentText();
3237 if (theCiteEnginesList[fromqstr(engine)]->isDefaultBiblio(fromqstr(currentDef)))
3238 resetDefaultBibfile();
3244 void GuiDocument::bibtexChanged(int n)
3246 biblioModule->bibtexOptionsLE->setEnabled(
3247 biblioModule->bibtexCO->itemData(n).toString() != "default");
3252 void GuiDocument::updateCiteStyles(vector<string> const & engs, CiteEngineType const & sel)
3254 biblioModule->citeStyleCO->clear();
3256 vector<string>::const_iterator it = engs.begin();
3257 vector<string>::const_iterator end = engs.end();
3258 for (; it != end; ++it) {
3259 if (*it == "default")
3260 biblioModule->citeStyleCO->addItem(qt_("Basic numerical"),
3261 ENGINE_TYPE_DEFAULT);
3262 else if (*it == "authoryear")
3263 biblioModule->citeStyleCO->addItem(qt_("Author-year"),
3264 ENGINE_TYPE_AUTHORYEAR);
3265 else if (*it == "numerical")
3266 biblioModule->citeStyleCO->addItem(qt_("Author-number"),
3267 ENGINE_TYPE_NUMERICAL);
3269 int i = biblioModule->citeStyleCO->findData(sel);
3270 if (biblioModule->citeStyleCO->findData(sel) == -1)
3272 biblioModule->citeStyleCO->setCurrentIndex(i);
3274 biblioModule->citationStyleL->setEnabled(engs.size() > 1);
3275 biblioModule->citeStyleCO->setEnabled(engs.size() > 1);
3279 void GuiDocument::updateEngineType(string const & items, CiteEngineType const & sel)
3281 engine_types_.clear();
3283 for (int n = 0; !token(items, '|', n).empty(); ++n) {
3284 string style = token(items, '|', n);
3285 engine_types_.push_back(style);
3288 updateCiteStyles(engine_types_, sel);
3294 // both of these should take a vector<docstring>
3296 // This is an insanely complicated attempt to make this sort of thing
3297 // work with RTL languages.
3298 docstring formatStrVec(vector<string> const & v, docstring const & s)
3300 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
3304 return translateIfPossible(from_utf8(v[0]));
3305 if (v.size() == 2) {
3306 docstring retval = _("%1$s and %2$s");
3307 retval = subst(retval, _("and"), s);
3308 return bformat(retval, translateIfPossible(from_utf8(v[0])),
3309 translateIfPossible(from_utf8(v[1])));
3311 // The idea here is to format all but the last two items...
3312 int const vSize = v.size();
3313 docstring t2 = _("%1$s, %2$s");
3314 docstring retval = translateIfPossible(from_utf8(v[0]));
3315 for (int i = 1; i < vSize - 2; ++i)
3316 retval = bformat(t2, retval, translateIfPossible(from_utf8(v[i])));
3317 //...and then to plug them, and the last two, into this schema
3318 docstring t = _("%1$s, %2$s, and %3$s");
3319 t = subst(t, _("and"), s);
3320 return bformat(t, retval, translateIfPossible(from_utf8(v[vSize - 2])),
3321 translateIfPossible(from_utf8(v[vSize - 1])));
3324 vector<string> idsToNames(vector<string> const & idList)
3326 vector<string> retval;
3327 vector<string>::const_iterator it = idList.begin();
3328 vector<string>::const_iterator end = idList.end();
3329 for (; it != end; ++it) {
3330 LyXModule const * const mod = theModuleList[*it];
3332 retval.push_back(to_utf8(bformat(_("%1$s (unavailable)"),
3333 translateIfPossible(from_utf8(*it)))));
3335 retval.push_back(mod->getName());
3339 } // end anonymous namespace
3342 void GuiDocument::modulesToParams(BufferParams & bp)
3344 // update list of loaded modules
3345 bp.clearLayoutModules();
3346 int const srows = modules_sel_model_.rowCount();
3347 for (int i = 0; i < srows; ++i)
3348 bp.addLayoutModule(modules_sel_model_.getIDString(i));
3349 updateSelectedModules();
3351 // update the list of removed modules
3352 bp.clearRemovedModules();
3353 LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
3354 list<string>::const_iterator rit = reqmods.begin();
3355 list<string>::const_iterator ren = reqmods.end();
3357 // check each of the default modules
3358 for (; rit != ren; ++rit) {
3359 list<string>::const_iterator mit = bp.getModules().begin();
3360 list<string>::const_iterator men = bp.getModules().end();
3362 for (; mit != men; ++mit) {
3369 // the module isn't present so must have been removed by the user
3370 bp.addRemovedModule(*rit);
3375 void GuiDocument::modulesChanged()
3377 modulesToParams(bp_);
3379 if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()
3380 && (nonModuleChanged_ || shellescapeChanged_)) {
3381 int const ret = Alert::prompt(_("Unapplied changes"),
3382 _("Some changes in the dialog were not yet applied.\n"
3383 "If you do not apply now, they will be lost after this action."),
3384 1, 1, _("&Apply"), _("&Dismiss"));
3389 modulesChanged_ = true;
3390 bp_.makeDocumentClass();
3396 void GuiDocument::updateModuleInfo()
3398 selectionManager->update();
3400 //Module description
3401 bool const focus_on_selected = selectionManager->selectedFocused();
3402 QAbstractItemView * lv;
3403 bool category = false;
3404 if (focus_on_selected) {
3405 lv = modulesModule->selectedLV;
3408 lv = modulesModule->availableLV;
3409 if (lv->selectionModel()->selectedIndexes().isEmpty()) {
3410 modulesModule->infoML->document()->clear();
3413 QModelIndex const & idx = lv->selectionModel()->currentIndex();
3418 if (!focus_on_selected
3419 && modules_av_model_.itemFromIndex(idx)->hasChildren()) {
3420 // This is a category header
3421 modulesModule->infoML->document()->clear();
3425 string const modName = focus_on_selected ?
3426 modules_sel_model_.getIDString(idx.row())
3427 : fromqstr(modules_av_model_.data(idx, Qt::UserRole).toString());
3428 docstring desc = getModuleDescription(modName);
3430 LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
3431 if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
3434 desc += _("Module provided by document class.");
3438 docstring cat = getModuleCategory(modName);
3442 desc += bformat(_("<p><b>Category:</b> %1$s.</p>"),
3443 translateIfPossible(cat));
3447 vector<string> pkglist = getPackageList(modName);
3448 docstring pkgdesc = formatStrVec(pkglist, _("and"));
3449 if (!pkgdesc.empty()) {
3452 desc += bformat(_("<p><b>Package(s) required:</b> %1$s.</p>"), pkgdesc);
3455 pkglist = getRequiredList(modName);
3456 if (!pkglist.empty()) {
3457 vector<string> const reqdescs = idsToNames(pkglist);
3458 pkgdesc = formatStrVec(reqdescs, _("or"));
3461 desc += bformat(_("<p><b>Modules required:</b> %1$s.</p>"), pkgdesc);
3464 pkglist = getExcludedList(modName);
3465 if (!pkglist.empty()) {
3466 vector<string> const reqdescs = idsToNames(pkglist);
3467 pkgdesc = formatStrVec(reqdescs, _( "and"));
3470 desc += bformat(_("<p><b>Modules excluded:</b> %1$s.</p>"), pkgdesc);
3475 desc += bformat(_("<p><b>Filename:</b> <tt>%1$s.module</tt>.</p>"), from_utf8(modName));
3477 if (!isModuleAvailable(modName)) {
3480 desc += _("<p><font color=red><b>WARNING: Some required packages are unavailable!</b></font></p>");
3483 modulesModule->infoML->document()->setHtml(toqstr(desc));
3487 void GuiDocument::updateNumbering()
3489 DocumentClass const & tclass = documentClass();
3491 numberingModule->tocTW->setUpdatesEnabled(false);
3492 numberingModule->tocTW->clear();
3494 int const depth = numberingModule->depthSL->value();
3495 int const toc = numberingModule->tocSL->value();
3496 QString const no = qt_("No");
3497 QString const yes = qt_("Yes");
3498 QTreeWidgetItem * item = nullptr;
3500 DocumentClass::const_iterator lit = tclass.begin();
3501 DocumentClass::const_iterator len = tclass.end();
3502 for (; lit != len; ++lit) {
3503 int const toclevel = lit->toclevel;
3504 if (toclevel != Layout::NOT_IN_TOC && !lit->counter.empty()) {
3505 item = new QTreeWidgetItem(numberingModule->tocTW);
3506 item->setText(0, toqstr(translateIfPossible(lit->name())));
3507 item->setText(1, (toclevel <= depth) ? yes : no);
3508 item->setText(2, (toclevel <= toc) ? yes : no);
3512 numberingModule->tocTW->setUpdatesEnabled(true);
3513 numberingModule->tocTW->update();
3517 void GuiDocument::getTableStyles()
3519 // We look for lyx files in the subdirectory dir of
3521 // 2) build_lyxdir (if not empty)
3523 // in this order. Files with a given sub-hierarchy will
3524 // only be listed once.
3525 // We also consider i18n subdirectories and store them separately.
3528 // The three locations to look at.
3529 string const user = addPath(package().user_support().absFileName(), "tabletemplates");
3530 string const build = addPath(package().build_support().absFileName(), "tabletemplates");
3531 string const system = addPath(package().system_support().absFileName(), "tabletemplates");
3533 dirs << toqstr(user)
3537 for (int i = 0; i < dirs.size(); ++i) {
3538 QString const & dir = dirs.at(i);
3539 QDirIterator it(dir, QDir::Files, QDirIterator::Subdirectories);
3540 while (it.hasNext()) {
3541 QString fn = QFileInfo(it.next()).fileName();
3542 if (!fn.endsWith(".lyx") || fn.contains("_1x"))
3544 QString data = fn.left(fn.lastIndexOf(".lyx"));
3545 QString guiname = data;
3546 guiname = toqstr(translateIfPossible(qstring_to_ucs4(guiname.replace('_', ' '))));
3547 QString relpath = toqstr(makeRelPath(qstring_to_ucs4(fn),
3548 qstring_to_ucs4(dir)));
3549 if (textLayoutModule->tableStyleCO->findData(data) == -1)
3550 textLayoutModule->tableStyleCO->addItem(guiname, data);
3556 void GuiDocument::updateDefaultFormat()
3560 // make a copy in order to consider unapplied changes
3561 BufferParams param_copy = buffer().params();
3562 param_copy.useNonTeXFonts = fontModule->osFontsCB->isChecked();
3563 int const idx = latexModule->classCO->currentIndex();
3565 string const classname = fromqstr(latexModule->classCO->getData(idx));
3566 param_copy.setBaseClass(classname, buffer().layoutPos());
3567 param_copy.makeDocumentClass(true);
3569 outputModule->defaultFormatCO->blockSignals(true);
3570 outputModule->defaultFormatCO->clear();
3571 outputModule->defaultFormatCO->addItem(qt_("Default"),
3572 QVariant(QString("default")));
3573 FormatList const & formats =
3574 param_copy.exportableFormats(true);
3575 for (Format const * f : formats)
3576 outputModule->defaultFormatCO->addItem
3577 (toqstr(translateIfPossible(f->prettyname())),
3578 QVariant(toqstr(f->name())));
3579 outputModule->defaultFormatCO->blockSignals(false);
3583 bool GuiDocument::isChildIncluded(string const & child)
3585 if (includeonlys_.empty())
3587 return (std::find(includeonlys_.begin(),
3588 includeonlys_.end(), child) != includeonlys_.end());
3592 void GuiDocument::applyView()
3594 // auto-validate local layout
3595 if (!localLayout->isValid()) {
3596 localLayout->validate();
3597 if (!localLayout->isValid()) {
3598 setApplyStopped(true);
3599 docPS->setCurrentPanel(N_("Local Layout"));
3605 preambleModule->apply(bp_);
3606 localLayout->apply(bp_);
3609 bp_.suppress_date = latexModule->suppressDateCB->isChecked();
3610 bp_.use_refstyle = latexModule->refstyleCB->isChecked();
3611 bp_.use_formatted_ref = latexModule->refFormattedCB->isChecked();
3614 string const engine =
3615 fromqstr(biblioModule->citeEngineCO->itemData(
3616 biblioModule->citeEngineCO->currentIndex()).toString());
3617 bp_.setCiteEngine(engine);
3619 CiteEngineType const style = CiteEngineType(biblioModule->citeStyleCO->itemData(
3620 biblioModule->citeStyleCO->currentIndex()).toInt());
3621 if (theCiteEnginesList[engine]->hasEngineType(style))
3622 bp_.setCiteEngineType(style);
3624 bp_.setCiteEngineType(ENGINE_TYPE_DEFAULT);
3626 bp_.splitbib(biblioModule->bibtopicCB->isChecked());
3628 bp_.multibib = fromqstr(biblioModule->bibunitsCO->itemData(
3629 biblioModule->bibunitsCO->currentIndex()).toString());
3631 bp_.setDefaultBiblioStyle(fromqstr(biblioModule->defaultBiblioCO->currentText()));
3633 bp_.biblatex_bibstyle = fromqstr(biblioModule->biblatexBbxCO->currentText());
3634 bp_.biblatex_citestyle = fromqstr(biblioModule->biblatexCbxCO->currentText());
3635 bp_.biblio_opts = fromqstr(biblioModule->citePackageOptionsLE->text());
3637 string const bibtex_command =
3638 fromqstr(biblioModule->bibtexCO->itemData(
3639 biblioModule->bibtexCO->currentIndex()).toString());
3640 string const bibtex_options =
3641 fromqstr(biblioModule->bibtexOptionsLE->text());
3642 if (bibtex_command == "default" || bibtex_options.empty())
3643 bp_.bibtex_command = bibtex_command;
3645 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
3647 if (biblioChanged_) {
3648 buffer().invalidateBibinfoCache();
3649 buffer().removeBiblioTempFiles();
3653 indicesModule->apply(bp_);
3655 // language & quotes
3656 switch (langModule->encodingCO->currentIndex()) {
3657 case EncodingSets::unicode: {
3658 if (!fontModule->osFontsCB->isChecked())
3659 bp_.inputenc = fromqstr(langModule->unicodeEncodingCO->itemData(
3660 langModule->unicodeEncodingCO->currentIndex()).toString());
3663 case EncodingSets::legacy: {
3664 bp_.inputenc = "auto-legacy";
3665 bp_.inputenc = fromqstr(langModule->autoEncodingCO->itemData(
3666 langModule->autoEncodingCO->currentIndex()).toString());
3669 case EncodingSets::custom: {
3670 bp_.inputenc = fromqstr(langModule->customEncodingCO->itemData(
3671 langModule->customEncodingCO->currentIndex()).toString());
3675 // this should never happen
3676 bp_.inputenc = "utf8";
3678 bp_.quotes_style = QuoteStyle(langModule->quoteStyleCO->itemData(
3679 langModule->quoteStyleCO->currentIndex()).toInt());
3680 bp_.dynamic_quotes = langModule->dynamicQuotesCB->isChecked();
3682 QString const langname = langModule->languageCO->itemData(
3683 langModule->languageCO->currentIndex()).toString();
3684 Language const * newlang = lyx::languages.getLanguage(fromqstr(langname));
3685 Cursor & cur = const_cast<BufferView *>(bufferview())->cursor();
3686 // If current cursor language was the document language, then update it too.
3687 if (cur.current_font.language() == bp_.language) {
3688 cur.current_font.setLanguage(newlang);
3689 cur.real_current_font.setLanguage(newlang);
3691 bp_.language = newlang;
3693 QString const pack = langModule->languagePackageCO->itemData(
3694 langModule->languagePackageCO->currentIndex()).toString();
3695 if (pack == "custom")
3697 fromqstr(langModule->languagePackageLE->text());
3699 bp_.lang_package = fromqstr(pack);
3702 bp_.backgroundcolor = set_backgroundcolor;
3703 bp_.isbackgroundcolor = is_backgroundcolor;
3704 bp_.fontcolor = set_fontcolor;
3705 bp_.isfontcolor = is_fontcolor;
3706 bp_.notefontcolor = set_notefontcolor;
3707 bp_.isnotefontcolor = is_notefontcolor;
3708 if (is_notefontcolor) {
3709 // Set information used in statusbar (#12130)
3710 lcolor.setColor("notefontcolor", lyx::X11hexname(set_notefontcolor));
3711 lcolor.setGUIName("notefontcolor", N_("greyedout inset text"));
3713 bp_.boxbgcolor = set_boxbgcolor;
3714 bp_.isboxbgcolor = is_boxbgcolor;
3717 if (bp_.documentClass().hasTocLevels()) {
3718 bp_.tocdepth = numberingModule->tocSL->value();
3719 bp_.secnumdepth = numberingModule->depthSL->value();
3721 bp_.use_lineno = numberingModule->linenoCB->isChecked();
3722 bp_.lineno_opts = fromqstr(numberingModule->linenoLE->text());
3725 bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
3726 bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
3727 bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
3728 bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
3731 bp_.graphics_driver =
3732 tex_graphics[latexModule->psdriverCO->currentIndex()];
3735 int idx = latexModule->classCO->currentIndex();
3737 string const classname = fromqstr(latexModule->classCO->getData(idx));
3738 bp_.setBaseClass(classname, buffer().layoutPos());
3742 modulesToParams(bp_);
3745 map<string, string> const & packages = BufferParams::auto_packages();
3746 for (map<string, string>::const_iterator it = packages.begin();
3747 it != packages.end(); ++it) {
3748 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
3751 int row = mathsModule->packagesTW->row(item);
3754 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1)->layout()->itemAt(0)->widget();
3755 if (rb->isChecked()) {
3756 bp_.use_package(it->first, BufferParams::package_auto);
3759 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2)->layout()->itemAt(0)->widget();
3760 if (rb->isChecked()) {
3761 bp_.use_package(it->first, BufferParams::package_on);
3764 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3)->layout()->itemAt(0)->widget();
3765 if (rb->isChecked())
3766 bp_.use_package(it->first, BufferParams::package_off);
3768 // if math is indented
3769 bp_.is_math_indent = mathsModule->MathIndentCB->isChecked();
3770 if (bp_.is_math_indent) {
3771 // if formulas are indented
3772 if (mathsModule->MathIndentCO->itemData(mathsModule->MathIndentCO->currentIndex()) == "custom") {
3773 Length mathindent(widgetsToLength(mathsModule->MathIndentLE,
3774 mathsModule->MathIndentLengthCO));
3775 bp_.setMathIndent(mathindent);
3778 bp_.setMathIndent(Length());
3780 switch (mathsModule->MathNumberingPosCO->currentIndex()) {
3782 bp_.math_numbering_side = BufferParams::LEFT;
3785 bp_.math_numbering_side = BufferParams::DEFAULT;
3788 bp_.math_numbering_side = BufferParams::RIGHT;
3791 // this should never happen
3792 bp_.math_numbering_side = BufferParams::DEFAULT;
3797 if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
3798 bp_.pagestyle = "default";
3800 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
3801 for (size_t i = 0; i != pagestyles.size(); ++i)
3802 if (pagestyles[i].second == style_gui)
3803 bp_.pagestyle = pagestyles[i].first;
3807 switch (textLayoutModule->lspacingCO->currentIndex()) {
3809 bp_.spacing().set(Spacing::Single);
3812 bp_.spacing().set(Spacing::Onehalf);
3815 bp_.spacing().set(Spacing::Double);
3818 string s = widgetToDoubleStr(textLayoutModule->lspacingLE);
3820 bp_.spacing().set(Spacing::Single);
3822 bp_.spacing().set(Spacing::Other, s);
3827 if (textLayoutModule->twoColumnCB->isChecked())
3832 bp_.justification = textLayoutModule->justCB->isChecked();
3834 if (textLayoutModule->indentRB->isChecked()) {
3835 // if paragraphs are separated by an indentation
3836 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
3837 if (textLayoutModule->indentCO->itemData(textLayoutModule->indentCO->currentIndex()) == "custom") {
3838 Length parindent(widgetsToLength(textLayoutModule->indentLE,
3839 textLayoutModule->indentLengthCO));
3840 bp_.setParIndent(parindent);
3843 bp_.setParIndent(Length());
3845 // if paragraphs are separated by a skip
3846 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
3847 VSpace::VSpaceKind spacekind =
3848 VSpace::VSpaceKind(textLayoutModule->skipCO->itemData(textLayoutModule->skipCO->currentIndex()).toInt());
3849 switch (spacekind) {
3850 case VSpace::SMALLSKIP:
3851 case VSpace::MEDSKIP:
3852 case VSpace::BIGSKIP:
3853 case VSpace::HALFLINE:
3854 case VSpace::FULLLINE:
3855 bp_.setDefSkip(VSpace(spacekind));
3857 case VSpace::LENGTH: {
3859 widgetsToLength(textLayoutModule->skipLE,
3860 textLayoutModule->skipLengthCO)
3866 // this should never happen
3867 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
3871 bp_.tablestyle = fromqstr(textLayoutModule->tableStyleCO->itemData(
3872 textLayoutModule->tableStyleCO->currentIndex()).toString());
3875 fromqstr(latexModule->optionsLE->text());
3877 bp_.use_default_options =
3878 latexModule->defaultOptionsCB->isChecked();
3880 if (latexModule->childDocGB->isChecked())
3882 fromqstr(latexModule->childDocLE->text());
3884 bp_.master = string();
3887 bp_.clearIncludedChildren();
3888 updateIncludeonlys();
3889 if (masterChildModule->includeonlyRB->isChecked()) {
3890 list<string>::const_iterator it = includeonlys_.begin();
3891 for (; it != includeonlys_.end() ; ++it) {
3892 bp_.addIncludedChildren(*it);
3895 if (masterChildModule->maintainCRNoneRB->isChecked())
3896 bp_.maintain_unincluded_children =
3897 BufferParams::CM_None;
3898 else if (masterChildModule->maintainCRMostlyRB->isChecked())
3899 bp_.maintain_unincluded_children =
3900 BufferParams::CM_Mostly;
3902 bp_.maintain_unincluded_children =
3903 BufferParams::CM_Strict;
3904 updateIncludeonlyDisplay();
3907 bp_.float_placement = floatModule->getPlacement();
3908 bp_.float_alignment = floatModule->getAlignment();
3911 // text should have passed validation
3912 idx = listingsModule->packageCO->currentIndex();
3913 bp_.use_minted = string(lst_packages[idx]) == "Minted";
3914 bp_.listings_params =
3915 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
3918 bp_.default_output_format = fromqstr(outputModule->defaultFormatCO->itemData(
3919 outputModule->defaultFormatCO->currentIndex()).toString());
3921 bool const nontexfonts = fontModule->osFontsCB->isChecked();
3922 bp_.useNonTeXFonts = nontexfonts;
3924 bp_.shell_escape = outputModule->shellescapeCB->isChecked();
3925 if (!bp_.shell_escape)
3926 theSession().shellescapeFiles().remove(buffer().absFileName());
3927 else if (!theSession().shellescapeFiles().find(buffer().absFileName()))
3928 theSession().shellescapeFiles().insert(buffer().absFileName());
3929 Buffer & buf = const_cast<Buffer &>(buffer());
3930 buf.params().shell_escape = bp_.shell_escape;
3932 bp_.output_sync = outputModule->outputsyncCB->isChecked();
3934 bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
3936 int mathfmt = outputModule->mathoutCB->currentIndex();
3939 BufferParams::MathOutput const mo =
3940 static_cast<BufferParams::MathOutput>(mathfmt);
3941 bp_.html_math_output = mo;
3942 bp_.html_be_strict = outputModule->strictCB->isChecked();
3943 bp_.html_css_as_file = outputModule->cssCB->isChecked();
3944 bp_.html_math_img_scale = outputModule->mathimgSB->value();
3945 bp_.display_pixel_ratio = theGuiApp()->pixelRatio();
3947 int tablefmt = outputModule->tableoutCB->currentIndex();
3950 auto const to = static_cast<BufferParams::TableOutput>(tablefmt);
3951 bp_.docbook_table_output = to;
3953 int mathmlprefix = outputModule->mathmlprefixCB->currentIndex();
3954 if (mathmlprefix == -1)
3956 auto const mp = static_cast<BufferParams::MathMLNameSpacePrefix>(mathmlprefix);
3957 bp_.docbook_mathml_prefix = mp;
3959 bp_.save_transient_properties =
3960 outputModule->saveTransientPropertiesCB->isChecked();
3961 bp_.postpone_fragile_content =
3962 outputModule->postponeFragileCB->isChecked();
3965 bp_.fonts_roman[nontexfonts] =
3966 fromqstr(fontModule->fontsRomanCO->
3967 getData(fontModule->fontsRomanCO->currentIndex()));
3968 bp_.fonts_roman[!nontexfonts] = fromqstr(fontModule->font_roman);
3969 bp_.font_roman_opts = fromqstr(fontModule->fontspecRomanLE->text());
3971 bp_.fonts_sans[nontexfonts] =
3972 fromqstr(fontModule->fontsSansCO->
3973 getData(fontModule->fontsSansCO->currentIndex()));
3974 bp_.fonts_sans[!nontexfonts] = fromqstr(fontModule->font_sans);
3975 bp_.font_sans_opts = fromqstr(fontModule->fontspecSansLE->text());
3977 bp_.fonts_typewriter[nontexfonts] =
3978 fromqstr(fontModule->fontsTypewriterCO->
3979 getData(fontModule->fontsTypewriterCO->currentIndex()));
3980 bp_.fonts_typewriter[!nontexfonts] = fromqstr(fontModule->font_typewriter);
3981 bp_.font_typewriter_opts = fromqstr(fontModule->fontspecTypewriterLE->text());
3983 bp_.fonts_math[nontexfonts] =
3984 fromqstr(fontModule->fontsMathCO->
3985 itemData(fontModule->fontsMathCO->currentIndex()).toString());
3986 bp_.fonts_math[!nontexfonts] = fromqstr(fontModule->font_math);
3988 QString const fontenc =
3989 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
3990 if (fontenc == "custom")
3991 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
3993 bp_.fontenc = fromqstr(fontenc);
3996 fromqstr(fontModule->cjkFontLE->text());
3998 bp_.use_microtype = fontModule->microtypeCB->isChecked();
3999 bp_.use_dash_ligatures = !fontModule->dashesCB->isChecked();
4001 bp_.fonts_sans_scale[nontexfonts] = fontModule->scaleSansSB->value();
4002 bp_.fonts_sans_scale[!nontexfonts] = fontModule->font_sf_scale;
4004 bp_.fonts_typewriter_scale[nontexfonts] = fontModule->scaleTypewriterSB->value();
4005 bp_.fonts_typewriter_scale[!nontexfonts] = fontModule->font_tt_scale;
4007 bp_.fonts_expert_sc = fontModule->fontScCB->isChecked();
4009 bp_.fonts_roman_osf = fontModule->fontOsfCB->isChecked();
4010 bp_.fonts_sans_osf = fontModule->fontSansOsfCB->isChecked();
4011 bp_.fonts_typewriter_osf = fontModule->fontTypewriterOsfCB->isChecked();
4013 bp_.fonts_default_family = GuiDocument::fontfamilies[
4014 fontModule->fontsDefaultCO->currentIndex()];
4016 if (fontModule->fontsizeCO->currentIndex() == 0)
4017 bp_.fontsize = "default";
4020 fromqstr(fontModule->fontsizeCO->currentText());
4023 bp_.papersize = PAPER_SIZE(
4024 pageLayoutModule->papersizeCO->currentIndex());
4026 bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
4027 pageLayoutModule->paperwidthUnitCO);
4029 bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
4030 pageLayoutModule->paperheightUnitCO);
4032 if (pageLayoutModule->facingPagesCB->isChecked())
4033 bp_.sides = TwoSides;
4035 bp_.sides = OneSide;
4037 if (pageLayoutModule->landscapeRB->isChecked())
4038 bp_.orientation = ORIENTATION_LANDSCAPE;
4040 bp_.orientation = ORIENTATION_PORTRAIT;
4043 bp_.use_geometry = !marginsModule->marginCB->isChecked();
4045 Ui::MarginsUi const * m = marginsModule;
4047 if (bp_.use_geometry) {
4048 bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
4049 bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
4050 bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
4051 bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
4052 bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
4053 bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
4054 bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
4055 bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
4059 branchesModule->apply(bp_);
4062 PDFOptions & pdf = bp_.pdfoptions();
4063 pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
4064 pdf.title = fromqstr(pdfSupportModule->titleLE->text());
4065 pdf.author = fromqstr(pdfSupportModule->authorLE->text());
4066 pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
4067 pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
4069 pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
4070 pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
4071 pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
4072 pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
4074 pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
4075 pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
4076 pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
4077 pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
4079 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
4080 if (pdfSupportModule->fullscreenCB->isChecked())
4081 pdf.pagemode = pdf.pagemode_fullscreen;
4083 pdf.pagemode.clear();
4084 pdf.quoted_options = pdf.quoted_options_check(
4085 fromqstr(pdfSupportModule->optionsTE->toPlainText()));
4086 bp_.document_metadata = qstring_to_ucs4(pdfSupportModule->metadataTE->toPlainText()
4087 .trimmed().replace(QRegularExpression("\n+"), "\n"));
4090 bp_.track_changes = changesModule->trackChangesCB->isChecked();
4091 bp_.output_changes = changesModule->outputChangesCB->isChecked();
4092 bool const cb_switched_off = (bp_.change_bars
4093 && !changesModule->changeBarsCB->isChecked());
4094 bp_.change_bars = changesModule->changeBarsCB->isChecked();
4095 if (cb_switched_off)
4096 // if change bars have been switched off,
4097 // we need to ditch the aux file
4098 buffer().requireFreshStart(true);
4101 nonModuleChanged_ = false;
4102 shellescapeChanged_ = false;
4106 void GuiDocument::paramsToDialog()
4108 // set the default unit
4109 Length::UNIT const default_unit = Length::defaultUnit();
4112 preambleModule->update(bp_, id());
4113 localLayout->update(bp_, id());
4116 latexModule->suppressDateCB->setChecked(bp_.suppress_date);
4117 latexModule->refstyleCB->setChecked(bp_.use_refstyle);
4118 latexModule->refFormattedCB->setChecked(bp_.use_formatted_ref);
4121 string const cite_engine = bp_.citeEngine();
4123 biblioModule->citeEngineCO->setCurrentIndex(
4124 biblioModule->citeEngineCO->findData(toqstr(cite_engine)));
4126 updateEngineType(documentClass().opt_enginetype(),
4127 bp_.citeEngineType());
4129 checkPossibleCiteEngines();
4131 biblioModule->citeStyleCO->setCurrentIndex(
4132 biblioModule->citeStyleCO->findData(bp_.citeEngineType()));
4134 biblioModule->bibtopicCB->setChecked(bp_.splitbib());
4136 biblioModule->bibunitsCO->clear();
4137 biblioModule->bibunitsCO->addItem(qt_("No"), QString());
4138 if (documentClass().hasLaTeXLayout("part"))
4139 biblioModule->bibunitsCO->addItem(qt_("per part"), toqstr("part"));
4140 if (documentClass().hasLaTeXLayout("chapter"))
4141 biblioModule->bibunitsCO->addItem(qt_("per chapter"), toqstr("chapter"));
4142 if (documentClass().hasLaTeXLayout("section"))
4143 biblioModule->bibunitsCO->addItem(qt_("per section"), toqstr("section"));
4144 if (documentClass().hasLaTeXLayout("subsection"))
4145 biblioModule->bibunitsCO->addItem(qt_("per subsection"), toqstr("subsection"));
4146 biblioModule->bibunitsCO->addItem(qt_("per child document"), toqstr("child"));
4148 int const mbpos = biblioModule->bibunitsCO->findData(toqstr(bp_.multibib));
4150 biblioModule->bibunitsCO->setCurrentIndex(mbpos);
4152 biblioModule->bibunitsCO->setCurrentIndex(0);
4154 updateEngineDependends();
4157 updateDefaultBiblio(bp_.biblatex_bibstyle, "bbx");
4158 updateDefaultBiblio(bp_.biblatex_citestyle, "cbx");
4160 updateDefaultBiblio(bp_.defaultBiblioStyle());
4162 biblioModule->citePackageOptionsLE->setText(toqstr(bp_.biblio_opts));
4166 split(bp_.bibtex_command, command, ' ');
4168 int bpos = biblioModule->bibtexCO->findData(toqstr(command));
4170 // We add and set the unknown compiler, indicating that it is unavailable
4171 // to assure document compilation and for security reasons, a fallback
4172 // will be used on document processing stage
4173 biblioModule->bibtexCO->addItem(toqstr(bformat(_("%1$s (not available)"),
4174 from_utf8(command))), toqstr(command));
4175 bpos = biblioModule->bibtexCO->findData(toqstr(command));
4177 biblioModule->bibtexCO->setCurrentIndex(bpos);
4178 biblioModule->bibtexOptionsLE->setText(toqstr(options).trimmed());
4179 biblioModule->bibtexOptionsLE->setEnabled(
4180 biblioModule->bibtexCO->currentIndex() != 0);
4182 biblioChanged_ = false;
4185 // We may be called when there is no Buffer, e.g., when
4186 // the last view has just been closed.
4187 bool const isReadOnly = isBufferAvailable() ? buffer().isReadonly() : false;
4188 indicesModule->update(bp_, isReadOnly);
4190 // language & quotes
4191 int const pos = langModule->languageCO->findData(toqstr(
4192 bp_.language->lang()));
4193 langModule->languageCO->setCurrentIndex(pos);
4195 updateQuoteStyles();
4197 langModule->quoteStyleCO->setCurrentIndex(
4198 langModule->quoteStyleCO->findData(static_cast<int>(bp_.quotes_style)));
4199 langModule->dynamicQuotesCB->setChecked(bp_.dynamic_quotes);
4201 // LaTeX input encoding: set after the fonts (see below)
4203 int p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
4205 langModule->languagePackageCO->setCurrentIndex(
4206 langModule->languagePackageCO->findData("custom"));
4207 langModule->languagePackageLE->setText(toqstr(bp_.lang_package));
4209 langModule->languagePackageCO->setCurrentIndex(p);
4210 langModule->languagePackageLE->clear();
4214 if (bp_.isfontcolor) {
4215 colorModule->mainTextCF->setStyleSheet(
4216 colorFrameStyleSheet(rgb2qcolor(bp_.fontcolor)));
4217 colorModule->mainTextCF->setVisible(true);
4219 colorModule->mainTextCF->setVisible(false);
4220 set_fontcolor = bp_.fontcolor;
4221 is_fontcolor = bp_.isfontcolor;
4223 colorModule->noteFontCF->setStyleSheet(
4224 colorFrameStyleSheet(rgb2qcolor(bp_.notefontcolor)));
4225 set_notefontcolor = bp_.notefontcolor;
4226 is_notefontcolor = bp_.isnotefontcolor;
4228 if (bp_.isbackgroundcolor) {
4229 colorModule->pageBackgroundCF->setStyleSheet(
4230 colorFrameStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
4231 colorModule->pageBackgroundCF->setVisible(true);
4233 colorModule->pageBackgroundCF->setVisible(false);
4234 set_backgroundcolor = bp_.backgroundcolor;
4235 is_backgroundcolor = bp_.isbackgroundcolor;
4237 colorModule->boxBackgroundCF->setStyleSheet(
4238 colorFrameStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
4239 set_boxbgcolor = bp_.boxbgcolor;
4240 is_boxbgcolor = bp_.isboxbgcolor;
4243 int const min_toclevel = documentClass().min_toclevel();
4244 int const max_toclevel = documentClass().max_toclevel();
4245 if (documentClass().hasTocLevels()) {
4246 numberingModule->setEnabled(true);
4247 numberingModule->depthSL->setMinimum(min_toclevel - 1);
4248 numberingModule->depthSL->setMaximum(max_toclevel);
4249 numberingModule->depthSL->setValue(bp_.secnumdepth);
4250 numberingModule->tocSL->setMaximum(min_toclevel - 1);
4251 numberingModule->tocSL->setMaximum(max_toclevel);
4252 numberingModule->tocSL->setValue(bp_.tocdepth);
4255 numberingModule->setEnabled(false);
4256 numberingModule->tocTW->clear();
4259 numberingModule->linenoCB->setChecked(bp_.use_lineno);
4260 numberingModule->linenoLE->setEnabled(bp_.use_lineno);
4261 numberingModule->linenoLA->setEnabled(bp_.use_lineno);
4262 numberingModule->linenoLE->setText(toqstr(bp_.lineno_opts));
4265 bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
4266 bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
4267 bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
4268 bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
4269 bulletsModule->init();
4272 int nitem = findToken(tex_graphics, bp_.graphics_driver);
4274 latexModule->psdriverCO->setCurrentIndex(nitem);
4278 mathsModule->MathIndentCB->setChecked(bp_.is_math_indent);
4279 if (bp_.is_math_indent) {
4280 Length const mathindent = bp_.getMathIndent();
4282 if (!mathindent.empty()) {
4283 lengthToWidgets(mathsModule->MathIndentLE,
4284 mathsModule->MathIndentLengthCO,
4285 mathindent, default_unit);
4288 mathsModule->MathIndentCO->setCurrentIndex(indent);
4289 enableMathIndent(indent);
4291 switch(bp_.math_numbering_side) {
4292 case BufferParams::LEFT:
4293 mathsModule->MathNumberingPosCO->setCurrentIndex(0);
4295 case BufferParams::DEFAULT:
4296 mathsModule->MathNumberingPosCO->setCurrentIndex(1);
4298 case BufferParams::RIGHT:
4299 mathsModule->MathNumberingPosCO->setCurrentIndex(2);
4302 map<string, string> const & packages = BufferParams::auto_packages();
4303 for (map<string, string>::const_iterator it = packages.begin();
4304 it != packages.end(); ++it) {
4305 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
4308 int row = mathsModule->packagesTW->row(item);
4309 switch (bp_.use_package(it->first)) {
4310 case BufferParams::package_off: {
4312 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3)->layout()->itemAt(0)->widget();
4313 rb->setChecked(true);
4316 case BufferParams::package_on: {
4318 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2)->layout()->itemAt(0)->widget();
4319 rb->setChecked(true);
4322 case BufferParams::package_auto: {
4324 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1)->layout()->itemAt(0)->widget();
4325 rb->setChecked(true);
4331 switch (bp_.spacing().getSpace()) {
4332 case Spacing::Other: nitem = 3; break;
4333 case Spacing::Double: nitem = 2; break;
4334 case Spacing::Onehalf: nitem = 1; break;
4335 case Spacing::Default: case Spacing::Single: nitem = 0; break;
4339 string const & layoutID = bp_.baseClassID();
4340 setLayoutComboByIDString(layoutID);
4342 updatePagestyle(documentClass().opt_pagestyle(),
4345 textLayoutModule->lspacingCO->setCurrentIndex(nitem);
4346 if (bp_.spacing().getSpace() == Spacing::Other) {
4347 doubleToWidget(textLayoutModule->lspacingLE,
4348 bp_.spacing().getValueAsString());
4351 int ts = textLayoutModule->tableStyleCO->findData(toqstr(bp_.tablestyle));
4353 textLayoutModule->tableStyleCO->setCurrentIndex(ts);
4355 if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
4356 textLayoutModule->indentRB->setChecked(true);
4357 string parindent = bp_.getParIndent().asString();
4358 QString indent = toqstr("default");
4359 if (!parindent.empty()) {
4360 lengthToWidgets(textLayoutModule->indentLE,
4361 textLayoutModule->indentLengthCO,
4362 parindent, default_unit);
4363 indent = toqstr("custom");
4365 textLayoutModule->indentCO->setCurrentIndex(textLayoutModule->indentCO->findData(indent));
4366 setIndent(textLayoutModule->indentCO->currentIndex());
4368 textLayoutModule->skipRB->setChecked(true);
4369 VSpace::VSpaceKind skip = bp_.getDefSkip().kind();
4370 textLayoutModule->skipCO->setCurrentIndex(textLayoutModule->skipCO->findData(skip));
4371 if (skip == VSpace::LENGTH) {
4372 string const length = bp_.getDefSkip().asLyXCommand();
4373 lengthToWidgets(textLayoutModule->skipLE,
4374 textLayoutModule->skipLengthCO,
4375 length, default_unit);
4377 setSkip(textLayoutModule->skipCO->currentIndex());
4380 textLayoutModule->twoColumnCB->setChecked(
4382 textLayoutModule->justCB->setChecked(bp_.justification);
4384 if (!bp_.options.empty()) {
4385 latexModule->optionsLE->setText(
4386 toqstr(bp_.options));
4388 latexModule->optionsLE->setText(QString());
4392 latexModule->defaultOptionsCB->setChecked(
4393 bp_.use_default_options);
4394 updateSelectedModules();
4395 selectionManager->updateProvidedModules(
4396 bp_.baseClass()->providedModules());
4397 selectionManager->updateExcludedModules(
4398 bp_.baseClass()->excludedModules());
4400 if (!documentClass().options().empty()) {
4401 latexModule->defaultOptionsLE->setText(
4402 toqstr(documentClass().options()));
4404 latexModule->defaultOptionsLE->setText(
4405 toqstr(_("[No options predefined]")));
4408 latexModule->defaultOptionsLE->setEnabled(
4409 bp_.use_default_options
4410 && !documentClass().options().empty());
4412 latexModule->defaultOptionsCB->setEnabled(
4413 !documentClass().options().empty());
4415 if (!bp_.master.empty()) {
4416 latexModule->childDocGB->setChecked(true);
4417 latexModule->childDocLE->setText(
4418 toqstr(bp_.master));
4420 latexModule->childDocLE->setText(QString());
4421 latexModule->childDocGB->setChecked(false);
4425 if (!bufferview() || !buffer().hasChildren()) {
4426 masterChildModule->childrenTW->clear();
4427 includeonlys_.clear();
4428 docPS->showPanel("Child Documents", false);
4429 if (docPS->isCurrentPanel("Child Documents"))
4430 docPS->setCurrentPanel("Document Class");
4432 docPS->showPanel("Child Documents", true);
4433 masterChildModule->setEnabled(true);
4434 includeonlys_ = bp_.getIncludedChildren();
4435 updateIncludeonlys();
4436 updateIncludeonlyDisplay();
4438 switch (bp_.maintain_unincluded_children) {
4439 case BufferParams::CM_None:
4440 masterChildModule->maintainCRNoneRB->setChecked(true);
4442 case BufferParams::CM_Mostly:
4443 masterChildModule->maintainCRMostlyRB->setChecked(true);
4445 case BufferParams::CM_Strict:
4447 masterChildModule->maintainCRStrictRB->setChecked(true);
4452 floatModule->setPlacement(bp_.float_placement);
4453 floatModule->setAlignment(bp_.float_alignment);
4456 // break listings_params to multiple lines
4458 InsetListingsParams(bp_.listings_params).separatedParams();
4459 listingsModule->listingsED->setPlainText(toqstr(lstparams));
4460 int nn = findToken(lst_packages, bp_.use_minted ? "Minted" : "Listings");
4462 listingsModule->packageCO->setCurrentIndex(nn);
4465 // some languages only work with Polyglossia (which requires non-TeX fonts)
4466 Language const * lang = lyx::languages.getLanguage(
4467 fromqstr(langModule->languageCO->itemData(
4468 langModule->languageCO->currentIndex()).toString()));
4469 bool const need_fontspec =
4470 lang->babel().empty() && !lang->polyglossia().empty()
4471 && lang->required() != "CJK" && lang->required() != "japanese";
4472 bool const os_fonts_available =
4473 bp_.baseClass()->outputType() == lyx::LATEX
4474 && LaTeXFeatures::isAvailable("fontspec");
4475 fontModule->osFontsCB->setEnabled(os_fonts_available && !need_fontspec);
4476 fontModule->osFontsCB->setChecked(
4477 (os_fonts_available && bp_.useNonTeXFonts) || need_fontspec);
4478 updateFontsize(documentClass().opt_fontsize(),
4481 QString font = toqstr(bp_.fontsRoman());
4482 bool foundfont = fontModule->fontsRomanCO->set(font, false);
4484 fontModule->fontsRomanCO->addItemSort(font, font + qt_(" (not installed)"),
4485 qt_("Uninstalled used fonts"),
4486 qt_("This font is not installed and won't be used in output"),
4487 false, false, false, true);
4488 fontModule->fontsRomanCO->set(font);
4490 fontModule->font_roman = toqstr(bp_.fonts_roman[!bp_.useNonTeXFonts]);
4492 font = toqstr(bp_.fontsSans());
4493 foundfont = fontModule->fontsSansCO->set(font, false);
4495 fontModule->fontsSansCO->addItemSort(font, font + qt_(" (not installed)"),
4496 qt_("Uninstalled used fonts"),
4497 qt_("This font is not installed and won't be used in output"),
4498 false, false, false, true);
4499 fontModule->fontsSansCO->set(font);
4501 fontModule->font_sans = toqstr(bp_.fonts_sans[!bp_.useNonTeXFonts]);
4503 font = toqstr(bp_.fontsTypewriter());
4504 foundfont = fontModule->fontsTypewriterCO->set(font, false);
4506 fontModule->fontsTypewriterCO->addItemSort(font, font + qt_(" (not installed)"),
4507 qt_("Uninstalled used fonts"),
4508 qt_("This font is not installed and won't be used in output"),
4509 false, false, false, true);
4510 fontModule->fontsTypewriterCO->set(font);
4512 fontModule->font_typewriter = toqstr(bp_.fonts_typewriter[!bp_.useNonTeXFonts]);
4514 font = toqstr(bp_.fontsMath());
4515 int mpos = fontModule->fontsMathCO->findData(font);
4517 mpos = fontModule->fontsMathCO->count();
4518 fontModule->fontsMathCO->addItem(font + qt_(" (not installed)"), font);
4520 fontModule->fontsMathCO->setCurrentIndex(mpos);
4521 fontModule->font_math = toqstr(bp_.fonts_math[!bp_.useNonTeXFonts]);
4523 if (bp_.useNonTeXFonts && os_fonts_available) {
4524 fontModule->fontencLA->setEnabled(false);
4525 fontModule->fontencCO->setEnabled(false);
4526 fontModule->fontencLE->setEnabled(false);
4528 fontModule->fontencLA->setEnabled(true);
4529 fontModule->fontencCO->setEnabled(true);
4530 fontModule->fontencLE->setEnabled(true);
4531 romanChanged(fontModule->fontsRomanCO->currentIndex());
4532 sansChanged(fontModule->fontsSansCO->currentIndex());
4533 ttChanged(fontModule->fontsTypewriterCO->currentIndex());
4535 // Handle options enabling
4536 updateFontOptions();
4538 if (!bp_.fonts_cjk.empty())
4539 fontModule->cjkFontLE->setText(
4540 toqstr(bp_.fonts_cjk));
4542 fontModule->cjkFontLE->setText(QString());
4544 fontModule->microtypeCB->setChecked(bp_.use_microtype);
4545 fontModule->dashesCB->setChecked(!bp_.use_dash_ligatures);
4547 fontModule->fontScCB->setChecked(bp_.fonts_expert_sc);
4548 fontModule->fontOsfCB->setChecked(bp_.fonts_roman_osf);
4549 fontModule->fontSansOsfCB->setChecked(bp_.fonts_sans_osf);
4550 fontModule->fontTypewriterOsfCB->setChecked(bp_.fonts_typewriter_osf);
4551 fontModule->scaleSansSB->setValue(bp_.fontsSansScale());
4552 fontModule->font_sf_scale = bp_.fonts_sans_scale[!bp_.useNonTeXFonts];
4553 fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale());
4554 fontModule->font_tt_scale = bp_.fonts_typewriter_scale[!bp_.useNonTeXFonts];
4555 if (!bp_.font_roman_opts.empty())
4556 fontModule->fontspecRomanLE->setText(
4557 toqstr(bp_.font_roman_opts));
4559 fontModule->fontspecRomanLE->setText(QString());
4560 if (!bp_.font_sans_opts.empty())
4561 fontModule->fontspecSansLE->setText(
4562 toqstr(bp_.font_sans_opts));
4564 fontModule->fontspecSansLE->setText(QString());
4565 if (!bp_.font_typewriter_opts.empty())
4566 fontModule->fontspecTypewriterLE->setText(
4567 toqstr(bp_.font_typewriter_opts));
4569 fontModule->fontspecTypewriterLE->setText(QString());
4571 nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
4573 fontModule->fontsDefaultCO->setCurrentIndex(nn);
4575 if (bp_.fontenc == "auto" || bp_.fontenc == "default") {
4576 fontModule->fontencCO->setCurrentIndex(
4577 fontModule->fontencCO->findData(toqstr(bp_.fontenc)));
4578 fontModule->fontencLE->setEnabled(false);
4580 fontModule->fontencCO->setCurrentIndex(
4581 fontModule->fontencCO->findData("custom"));
4582 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
4585 // LaTeX input encoding
4586 // Set after fonts because non-tex fonts override "\inputencoding".
4587 inputencodingToDialog();
4590 // This must be set _after_ fonts since updateDefaultFormat()
4591 // checks osFontsCB settings.
4592 // update combobox with formats
4593 updateDefaultFormat();
4594 int index = outputModule->defaultFormatCO->findData(toqstr(
4595 bp_.default_output_format));
4596 // set to default if format is not found
4599 outputModule->defaultFormatCO->setCurrentIndex(index);
4601 outputModule->shellescapeCB->setChecked(bp_.shell_escape);
4602 outputModule->outputsyncCB->setChecked(bp_.output_sync);
4603 outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
4604 outputModule->synccustomCB->setEnabled(bp_.output_sync);
4605 outputModule->synccustomLA->setEnabled(bp_.output_sync);
4607 outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
4608 outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
4609 outputModule->strictCB->setChecked(bp_.html_be_strict);
4610 outputModule->cssCB->setChecked(bp_.html_css_as_file);
4612 outputModule->tableoutCB->setCurrentIndex(bp_.docbook_table_output);
4613 outputModule->mathmlprefixCB->setCurrentIndex(bp_.docbook_mathml_prefix);
4615 outputModule->saveTransientPropertiesCB
4616 ->setChecked(bp_.save_transient_properties);
4617 outputModule->postponeFragileCB
4618 ->setChecked(bp_.postpone_fragile_content);
4621 bool const extern_geometry =
4622 documentClass().provides("geometry");
4623 int const psize = bp_.papersize;
4624 pageLayoutModule->papersizeCO->setCurrentIndex(psize);
4625 setCustomPapersize(!extern_geometry && psize == 1);
4626 pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
4628 bool const landscape =
4629 bp_.orientation == ORIENTATION_LANDSCAPE;
4630 pageLayoutModule->landscapeRB->setChecked(landscape);
4631 pageLayoutModule->portraitRB->setChecked(!landscape);
4632 pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
4633 pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
4635 pageLayoutModule->facingPagesCB->setChecked(
4636 bp_.sides == TwoSides);
4638 lengthToWidgets(pageLayoutModule->paperwidthLE,
4639 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, default_unit);
4640 lengthToWidgets(pageLayoutModule->paperheightLE,
4641 pageLayoutModule->paperheightUnitCO, bp_.paperheight, default_unit);
4644 Ui::MarginsUi * m = marginsModule;
4646 tmp_leftmargin_ = bp_.leftmargin;
4647 tmp_topmargin_ = bp_.topmargin;
4648 tmp_rightmargin_ = bp_.rightmargin;
4649 tmp_bottommargin_ = bp_.bottommargin;
4650 tmp_headheight_ = bp_.headheight;
4651 tmp_headsep_ = bp_.headsep;
4652 tmp_footskip_ = bp_.footskip;
4653 tmp_columnsep_ = bp_.columnsep;
4655 lengthToWidgets(m->topLE, m->topUnit,
4656 bp_.topmargin, default_unit);
4657 lengthToWidgets(m->bottomLE, m->bottomUnit,
4658 bp_.bottommargin, default_unit);
4659 lengthToWidgets(m->innerLE, m->innerUnit,
4660 bp_.leftmargin, default_unit);
4661 lengthToWidgets(m->outerLE, m->outerUnit,
4662 bp_.rightmargin, default_unit);
4663 lengthToWidgets(m->headheightLE, m->headheightUnit,
4664 bp_.headheight, default_unit);
4665 lengthToWidgets(m->headsepLE, m->headsepUnit,
4666 bp_.headsep, default_unit);
4667 lengthToWidgets(m->footskipLE, m->footskipUnit,
4668 bp_.footskip, default_unit);
4669 lengthToWidgets(m->columnsepLE, m->columnsepUnit,
4670 bp_.columnsep, default_unit);
4675 updateUnknownBranches();
4676 branchesModule->update(bp_);
4679 PDFOptions const & pdf = bp_.pdfoptions();
4680 pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
4681 if (bp_.documentClass().provides("hyperref"))
4682 pdfSupportModule->use_hyperrefGB->setTitle(qt_("C&ustomize Hyperref Options"));
4684 pdfSupportModule->use_hyperrefGB->setTitle(qt_("&Use Hyperref Support"));
4685 pdfSupportModule->titleLE->setText(toqstr(pdf.title));
4686 pdfSupportModule->authorLE->setText(toqstr(pdf.author));
4687 pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
4688 pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
4690 pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
4691 pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
4692 pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
4694 pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
4695 pdfSupportModule->bookmarksopenlevelSB->setEnabled(pdf.bookmarksopen);
4696 pdfSupportModule->bookmarksopenlevelLA->setEnabled(pdf.bookmarksopen);
4698 pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
4699 pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
4700 pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
4701 pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
4703 nn = findToken(backref_opts, pdf.backref);
4705 pdfSupportModule->backrefCO->setCurrentIndex(nn);
4707 pdfSupportModule->fullscreenCB->setChecked
4708 (pdf.pagemode == pdf.pagemode_fullscreen);
4710 pdfSupportModule->optionsTE->setPlainText(
4711 toqstr(pdf.quoted_options));
4713 pdfSupportModule->metadataTE->setPlainText(
4714 toqstr(rtrim(bp_.document_metadata, "\n")));
4717 changesModule->trackChangesCB->setChecked(bp_.track_changes);
4718 changesModule->outputChangesCB->setChecked(bp_.output_changes);
4719 changesModule->changeBarsCB->setChecked(bp_.change_bars);
4720 changesModule->changeBarsCB->setEnabled(bp_.output_changes);
4722 // Make sure that the bc is in the INITIAL state
4723 if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
4726 // clear changed branches cache
4727 changedBranches_.clear();
4729 // re-initiate module filter
4730 if (!filter_->text().isEmpty())
4731 moduleFilterPressed();
4734 nonModuleChanged_ = false;
4735 shellescapeChanged_ = false;
4739 void GuiDocument::saveDocDefault()
4741 // we have to apply the params first
4747 void GuiDocument::updateAvailableModules()
4749 modules_av_model_.clear();
4750 list<modInfoStruct> modInfoList = getModuleInfo();
4751 // Sort names according to the locale
4752 modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
4753 return 0 < b.name.localeAwareCompare(a.name);
4755 QIcon user_icon(guiApp ? guiApp->getScaledPixmap("images/", "lyxfiles-user")
4756 : getPixmap("images/", "lyxfiles-user", "svgz,png"));
4757 QIcon system_icon(guiApp ? guiApp->getScaledPixmap("images/", "lyxfiles-system")
4758 : getPixmap("images/", "lyxfiles-system", "svgz,png"));
4761 catfont.setBold(true);
4763 unavbrush.setColor(Qt::gray);
4764 for (modInfoStruct const & m : modInfoList) {
4765 QStandardItem * item = new QStandardItem();
4766 QStandardItem * catItem;
4767 QString const catname = m.category;
4768 QList<QStandardItem *> fcats = modules_av_model_.findItems(catname, Qt::MatchExactly);
4770 catItem = fcats.first();
4772 catItem = new QStandardItem();
4773 catItem->setText(catname);
4774 catItem->setFont(catfont);
4775 modules_av_model_.insertRow(i, catItem);
4778 item->setEditable(false);
4779 catItem->setEditable(false);
4780 item->setData(m.name, Qt::DisplayRole);
4782 item->setForeground(unavbrush);
4783 item->setData(toqstr(m.id), Qt::UserRole);
4784 item->setData(m.description, Qt::ToolTipRole);
4786 item->setIcon(user_icon);
4788 item->setIcon(system_icon);
4789 catItem->appendRow(item);
4791 modules_av_model_.sort(0);
4795 void GuiDocument::updateSelectedModules()
4797 modules_sel_model_.clear();
4798 list<modInfoStruct> const selModList = getSelectedModules();
4800 for (modInfoStruct const & m : selModList) {
4801 modules_sel_model_.insertRow(i, m.name, m.id, m.description);
4807 void GuiDocument::updateIncludeonlyDisplay()
4809 if (includeonlys_.empty()) {
4810 masterChildModule->includeallRB->setChecked(true);
4811 masterChildModule->childrenTW->setEnabled(false);
4812 masterChildModule->maintainGB->setEnabled(false);
4814 masterChildModule->includeonlyRB->setChecked(true);
4815 masterChildModule->childrenTW->setEnabled(true);
4816 masterChildModule->maintainGB->setEnabled(true);
4821 void GuiDocument::updateIncludeonlys(bool const cleanup)
4823 masterChildModule->childrenTW->clear();
4824 QString const no = qt_("No");
4825 QString const yes = qt_("Yes");
4827 ListOfBuffers children = buffer().getChildren();
4828 ListOfBuffers::const_iterator it = children.begin();
4829 ListOfBuffers::const_iterator end = children.end();
4830 bool has_unincluded = false;
4831 bool all_unincluded = true;
4832 for (; it != end; ++it) {
4833 QTreeWidgetItem * item = new QTreeWidgetItem(masterChildModule->childrenTW);
4836 to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
4837 from_utf8(buffer().filePath())));
4838 item->setText(0, toqstr(name));
4839 item->setText(1, isChildIncluded(name) ? yes : no);
4840 if (!isChildIncluded(name))
4841 has_unincluded = true;
4843 all_unincluded = false;
4845 // Both if all children are included and if none is included
4846 // is equal to "include all" (i.e., omit \includeonly).
4847 if (cleanup && (!has_unincluded || all_unincluded))
4848 includeonlys_.clear();
4852 bool GuiDocument::isBiblatex() const
4854 QString const engine =
4855 biblioModule->citeEngineCO->itemData(
4856 biblioModule->citeEngineCO->currentIndex()).toString();
4858 // this can happen if the cite engine is unknown, which can happen
4859 // if one is using a file that came from someone else, etc. in that
4860 // case, we crash if we proceed.
4861 if (engine.isEmpty())
4864 return theCiteEnginesList[fromqstr(engine)]->getCiteFramework() == "biblatex";
4868 void GuiDocument::updateDefaultBiblio(string const & style,
4869 string const & which)
4871 QString const bibstyle = toqstr(style);
4872 biblioModule->defaultBiblioCO->clear();
4877 if (which != "cbx") {
4878 // First the bbx styles
4879 biblioModule->biblatexBbxCO->clear();
4880 QStringList str = texFileList("bbxFiles.lst");
4881 // test whether we have a valid list, otherwise run rescan
4882 if (str.isEmpty()) {
4883 rescanTexStyles("bbx");
4884 str = texFileList("bbxFiles.lst");
4886 for (int i = 0; i != str.size(); ++i)
4887 str[i] = onlyFileName(str[i]);
4888 // sort on filename only (no path)
4891 for (int i = 0; i != str.count(); ++i) {
4892 QString item = changeExtension(str[i], "");
4893 if (item == bibstyle)
4895 biblioModule->biblatexBbxCO->addItem(item);
4898 if (item_nr == -1 && !bibstyle.isEmpty()) {
4899 biblioModule->biblatexBbxCO->addItem(bibstyle);
4900 item_nr = biblioModule->biblatexBbxCO->count() - 1;
4904 biblioModule->biblatexBbxCO->setCurrentIndex(item_nr);
4906 biblioModule->biblatexBbxCO->clearEditText();
4909 if (which != "bbx") {
4910 // now the cbx styles
4911 biblioModule->biblatexCbxCO->clear();
4912 QStringList str = texFileList("cbxFiles.lst");
4913 // test whether we have a valid list, otherwise run rescan
4914 if (str.isEmpty()) {
4915 rescanTexStyles("cbx");
4916 str = texFileList("cbxFiles.lst");
4918 for (int i = 0; i != str.size(); ++i)
4919 str[i] = onlyFileName(str[i]);
4920 // sort on filename only (no path)
4923 for (int i = 0; i != str.count(); ++i) {
4924 QString item = changeExtension(str[i], "");
4925 if (item == bibstyle)
4927 biblioModule->biblatexCbxCO->addItem(item);
4930 if (item_nr == -1 && !bibstyle.isEmpty()) {
4931 biblioModule->biblatexCbxCO->addItem(bibstyle);
4932 item_nr = biblioModule->biblatexCbxCO->count() - 1;
4936 biblioModule->biblatexCbxCO->setCurrentIndex(item_nr);
4938 biblioModule->biblatexCbxCO->clearEditText();
4941 biblioModule->biblatexBbxCO->clear();
4942 biblioModule->biblatexCbxCO->clear();
4943 QStringList str = texFileList("bstFiles.lst");
4944 // test whether we have a valid list, otherwise run rescan
4945 if (str.isEmpty()) {
4946 rescanTexStyles("bst");
4947 str = texFileList("bstFiles.lst");
4949 for (int i = 0; i != str.size(); ++i)
4950 str[i] = onlyFileName(str[i]);
4951 // sort on filename only (no path)
4954 for (int i = 0; i != str.count(); ++i) {
4955 QString item = changeExtension(str[i], "");
4956 if (item == bibstyle)
4958 biblioModule->defaultBiblioCO->addItem(item);
4961 if (item_nr == -1 && !bibstyle.isEmpty()) {
4962 biblioModule->defaultBiblioCO->addItem(bibstyle);
4963 item_nr = biblioModule->defaultBiblioCO->count() - 1;
4967 biblioModule->defaultBiblioCO->setCurrentIndex(item_nr);
4969 biblioModule->defaultBiblioCO->clearEditText();
4972 updateResetDefaultBiblio();
4976 void GuiDocument::updateResetDefaultBiblio()
4978 QString const engine =
4979 biblioModule->citeEngineCO->itemData(
4980 biblioModule->citeEngineCO->currentIndex()).toString();
4981 CiteEngineType const cet =
4982 CiteEngineType(biblioModule->citeStyleCO->itemData(
4983 biblioModule->citeStyleCO->currentIndex()).toInt());
4985 string const defbib = theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet);
4987 QString const bbx = biblioModule->biblatexBbxCO->currentText();
4988 QString const cbx = biblioModule->biblatexCbxCO->currentText();
4989 biblioModule->resetCbxPB->setEnabled(defbib != fromqstr(cbx));
4990 biblioModule->resetBbxPB->setEnabled(defbib != fromqstr(bbx));
4991 biblioModule->matchBbxPB->setEnabled(bbx != cbx && !cbx.isEmpty()
4992 && biblioModule->biblatexBbxCO->findText(cbx) != -1);
4994 biblioModule->resetDefaultBiblioPB->setEnabled(
4995 defbib != fromqstr(biblioModule->defaultBiblioCO->currentText()));
4999 void GuiDocument::matchBiblatexStyles()
5001 updateDefaultBiblio(fromqstr(biblioModule->biblatexCbxCO->currentText()), "bbx");
5006 void GuiDocument::updateContents()
5008 // Nothing to do here as the document settings is not cursor dependent.
5013 void GuiDocument::useClassDefaults()
5015 if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
5016 int const ret = Alert::prompt(_("Unapplied changes"),
5017 _("Some changes in the dialog were not yet applied.\n"
5018 "If you do not apply now, they will be lost after this action."),
5019 1, 1, _("&Apply"), _("&Dismiss"));
5024 int idx = latexModule->classCO->currentIndex();
5025 string const classname = fromqstr(latexModule->classCO->getData(idx));
5026 if (!bp_.setBaseClass(classname, buffer().layoutPos())) {
5027 Alert::error(_("Error"), _("Unable to set document class."));
5030 bp_.useClassDefaults();
5036 void GuiDocument::setLayoutComboByIDString(string const & idString)
5038 if (!latexModule->classCO->set(toqstr(idString)))
5039 Alert::warning(_("Can't set layout!"),
5040 bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
5044 bool GuiDocument::isValid()
5046 bool const listings_valid = validateListingsParameters().isEmpty();
5047 bool const local_layout_valid = !localLayout->editing();
5048 bool const preamble_valid = !preambleModule->editing();
5050 docPS->markPanelValid(N_("Listings[[inset]]"), listings_valid);
5051 docPS->markPanelValid(N_("Local Layout"), local_layout_valid && localLayout->isValid());
5052 docPS->markPanelValid(N_("LaTeX Preamble"), preamble_valid);
5054 return listings_valid && local_layout_valid && preamble_valid;
5058 char const * const GuiDocument::fontfamilies[5] = {
5059 "default", "rmdefault", "sfdefault", "ttdefault", ""
5063 char const * GuiDocument::fontfamilies_gui[5] = {
5064 N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
5068 bool GuiDocument::initialiseParams(string const &)
5070 BufferView const * view = bufferview();
5072 bp_ = BufferParams();
5076 prev_buffer_filename_ = view->buffer().absFileName();
5077 bp_ = view->buffer().params();
5079 updateAvailableModules();
5080 //FIXME It'd be nice to make sure here that the selected
5081 //modules are consistent: That required modules are actually
5082 //selected, and that we don't have conflicts. If so, we could
5083 //at least pop up a warning.
5089 void GuiDocument::clearParams()
5091 bp_ = BufferParams();
5095 BufferId GuiDocument::id() const
5097 BufferView const * const view = bufferview();
5098 return view? &view->buffer() : nullptr;
5102 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
5104 return moduleNames_;
5108 list<GuiDocument::modInfoStruct> const
5109 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
5111 list<modInfoStruct> mInfo;
5112 for (string const & name : mods) {
5114 LyXModule const * const mod = theModuleList[name];
5119 m.name = toqstr(name + " (") + qt_("Not Found") + toqstr(")");
5121 m.missingreqs = true;
5129 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
5131 return makeModuleInfo(params().getModules());
5135 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
5137 return makeModuleInfo(params().baseClass()->providedModules());
5141 DocumentClass const & GuiDocument::documentClass() const
5143 return bp_.documentClass();
5147 static void dispatch_bufferparams(Dialog const & dialog,
5148 BufferParams const & bp, FuncCode lfun, Buffer const * buf)
5151 ss << "\\begin_header\n";
5152 bp.writeFile(ss, buf);
5153 ss << "\\end_header\n";
5154 dialog.dispatch(FuncRequest(lfun, ss.str()));
5158 void GuiDocument::dispatchParams()
5160 // We need a non-const buffer object.
5161 Buffer & buf = const_cast<BufferView *>(bufferview())->buffer();
5162 // There may be several undo records; group them (bug #8998)
5163 // This handles undo groups automagically
5164 UndoGroupHelper ugh(&buf);
5166 // This must come first so that a language change is correctly noticed
5169 // We need to load the master before we formally update the params,
5170 // since otherwise we run updateBuffer, etc, before the child's master
5172 if (!params().master.empty()) {
5173 FileName const master_file = support::makeAbsPath(params().master,
5174 support::onlyPath(buffer().absFileName()));
5175 if (isLyXFileName(master_file.absFileName())) {
5176 Buffer * master = checkAndLoadLyXFile(master_file, true);
5178 if (master->isChild(const_cast<Buffer *>(&buffer())))
5179 const_cast<Buffer &>(buffer()).setParent(master);
5181 Alert::warning(_("Assigned master does not include this file"),
5182 bformat(_("You must include this file in the document\n"
5183 "'%1$s' in order to use the master document\n"
5184 "feature."), from_utf8(params().master)));
5186 Alert::warning(_("Could not load master"),
5187 bformat(_("The master document '%1$s'\n"
5188 "could not be loaded."),
5189 from_utf8(params().master)));
5193 // Apply the BufferParams. Note that this will set the base class
5194 // and then update the buffer's layout.
5195 dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY, &buffer());
5197 // Generate the colours requested by each new branch.
5198 BranchList & branchlist = params().branchlist();
5199 if (!branchlist.empty()) {
5200 BranchList::const_iterator it = branchlist.begin();
5201 BranchList::const_iterator const end = branchlist.end();
5202 for (; it != end; ++it) {
5203 docstring const & current_branch = it->branch();
5204 Branch const * branch = branchlist.find(current_branch);
5205 string const bcolor = branch->color();
5207 if (bcolor.size() == 7 && bcolor[0] == '#')
5208 rgbcol = lyx::rgbFromHexName(bcolor);
5210 guiApp->getRgbColor(lcolor.getFromLyXName(bcolor), rgbcol);
5211 string const x11hexname = X11hexname(rgbcol);
5212 // display the new color
5213 docstring const str = current_branch + ' ' + from_ascii(x11hexname);
5214 dispatch(FuncRequest(LFUN_SET_COLOR, str));
5217 // rename branches in the document
5218 executeBranchRenaming();
5219 // and clear changed branches cache
5220 changedBranches_.clear();
5222 // Generate the colours requested by indices.
5223 IndicesList & indiceslist = params().indiceslist();
5224 if (!indiceslist.empty()) {
5225 IndicesList::const_iterator it = indiceslist.begin();
5226 IndicesList::const_iterator const end = indiceslist.end();
5227 for (; it != end; ++it) {
5228 docstring const & current_index = it->shortcut();
5229 Index const * index = indiceslist.findShortcut(current_index);
5230 string const x11hexname = X11hexname(index->color());
5231 // display the new color
5232 docstring const str = current_index + ' ' + from_ascii(x11hexname);
5233 dispatch(FuncRequest(LFUN_SET_COLOR, str));
5237 // If we used an LFUN, we would not need these two lines:
5238 BufferView * bv = const_cast<BufferView *>(bufferview());
5239 bv->processUpdateFlags(Update::Force | Update::FitCursor);
5243 void GuiDocument::setLanguage() const
5245 Language const * const newL = bp_.language;
5246 if (buffer().params().language == newL)
5249 string const & lang_name = newL->lang();
5250 dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
5254 void GuiDocument::saveAsDefault() const
5256 dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT, &buffer());
5260 bool GuiDocument::providesOSF(QString const & font) const
5262 if (fontModule->osFontsCB->isChecked())
5263 // FIXME: we should check if the fonts really
5264 // have OSF support. But how?
5265 return font != "default";
5266 return theLaTeXFonts().getLaTeXFont(
5267 qstring_to_ucs4(font)).providesOSF(ot1(),
5273 bool GuiDocument::providesSC(QString const & font) const
5275 if (fontModule->osFontsCB->isChecked())
5277 return theLaTeXFonts().getLaTeXFont(
5278 qstring_to_ucs4(font)).providesSC(ot1(),
5284 bool GuiDocument::providesScale(QString const & font) const
5286 if (fontModule->osFontsCB->isChecked())
5287 return font != "default";
5288 return theLaTeXFonts().getLaTeXFont(
5289 qstring_to_ucs4(font)).providesScale(ot1(),
5295 bool GuiDocument::providesExtraOpts(QString const & font) const
5297 if (fontModule->osFontsCB->isChecked())
5298 return font != "default";
5299 return theLaTeXFonts().getLaTeXFont(
5300 qstring_to_ucs4(font)).providesMoreOptions(ot1(),
5306 bool GuiDocument::providesNoMath(QString const & font) const
5308 if (fontModule->osFontsCB->isChecked())
5310 return theLaTeXFonts().getLaTeXFont(
5311 qstring_to_ucs4(font)).providesNoMath(ot1(),
5316 bool GuiDocument::hasMonolithicExpertSet(QString const & font) const
5318 if (fontModule->osFontsCB->isChecked())
5320 return theLaTeXFonts().getLaTeXFont(
5321 qstring_to_ucs4(font)).hasMonolithicExpertSet(ot1(),
5328 GuiDocument::modInfoStruct GuiDocument::modInfo(LyXModule const & mod)
5330 // FIXME Unicode: docstrings would be better for these parameters but this
5331 // change requires a lot of others
5334 QString const guiname = toqstr(translateIfPossible(from_utf8(mod.getName())));
5335 m.missingreqs = !isModuleAvailable(mod.getID());
5336 if (m.missingreqs) {
5337 m.name = qt_("%1 (missing req.)").arg(guiname);
5340 m.category = mod.category().empty() ? qt_("Miscellaneous")
5341 : toqstr(translateIfPossible(from_utf8(mod.category())));
5342 QString desc = toqstr(translateIfPossible(from_utf8(mod.getDescription())));
5343 // Find the first sentence of the description
5344 QTextBoundaryFinder bf(QTextBoundaryFinder::Sentence, desc);
5345 int pos = bf.toNextBoundary();
5348 m.local = mod.isLocal();
5349 QString const mtype = m.local ? qt_("personal module") : qt_("distributed module");
5350 QString modulename = qt_("<b>Module name:</b> <i>%1</i> (%2)").arg(toqstr(m.id)).arg(mtype);
5351 // Tooltip is the desc followed by the module name and the type
5352 m.description = QString("%1%2")
5353 .arg(desc.isEmpty() ? QString() : QString("<p>%1</p>").arg(desc),
5356 m.description += QString("<p>%1</p>").arg(qt_("<b>Note:</b> Some requirements for this module are missing!"));
5361 void GuiDocument::loadModuleInfo()
5363 moduleNames_.clear();
5364 for (LyXModule const & mod : theModuleList)
5365 moduleNames_.push_back(modInfo(mod));
5369 void GuiDocument::updateUnknownBranches()
5373 list<docstring> used_branches;
5374 buffer().getUsedBranches(used_branches);
5375 list<docstring>::const_iterator it = used_branches.begin();
5376 QStringList unknown_branches;
5377 for (; it != used_branches.end() ; ++it) {
5378 if (!buffer().params().branchlist().find(*it))
5379 unknown_branches.append(toqstr(*it));
5381 branchesModule->setUnknownBranches(unknown_branches);
5385 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
5387 map<docstring, docstring>::iterator it = changedBranches_.begin();
5388 for (; it != changedBranches_.end() ; ++it) {
5389 if (it->second == oldname) {
5390 // branch has already been renamed
5391 it->second = newname;
5396 changedBranches_[oldname] = newname;
5400 void GuiDocument::executeBranchRenaming() const
5402 map<docstring, docstring>::const_iterator it = changedBranches_.begin();
5403 for (; it != changedBranches_.end() ; ++it) {
5404 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
5405 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
5410 void GuiDocument::allPackagesAuto()
5416 void GuiDocument::allPackagesAlways()
5422 void GuiDocument::allPackagesNot()
5428 void GuiDocument::allPackages(int col)
5430 for (int row = 0; row < mathsModule->packagesTW->rowCount(); ++row) {
5432 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, col)->layout()->itemAt(0)->widget();
5433 rb->setChecked(true);
5438 void GuiDocument::linenoToggled(bool on)
5440 numberingModule->linenoLE->setEnabled(on);
5441 numberingModule->linenoLA->setEnabled(on);
5445 void GuiDocument::outputChangesToggled(bool on)
5447 changesModule->changeBarsCB->setEnabled(on);
5451 void GuiDocument::setOutputSync(bool on)
5453 outputModule->synccustomCB->setEnabled(on);
5454 outputModule->synccustomLA->setEnabled(on);
5459 bool GuiDocument::eventFilter(QObject * sender, QEvent * event)
5461 if (event->type() == QEvent::ApplicationPaletteChange) {
5462 // mode switch: colors need to be updated
5463 // and the highlighting redone
5464 if (pdf_options_highlighter_) {
5465 pdf_options_highlighter_->setupColors();
5466 pdf_options_highlighter_->rehighlight();
5468 if (pdf_metadata_highlighter_) {
5469 pdf_metadata_highlighter_->setupColors();
5470 pdf_metadata_highlighter_->rehighlight();
5473 return QWidget::eventFilter(sender, event);
5477 } // namespace frontend
5480 #include "moc_GuiDocument.cpp"