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::onClosing(int const id)
1854 if (!guiApp || !guiApp->currentView()
1855 || guiApp->currentView()->id() != id
1856 || !bc().policy().buttonStatus(ButtonPolicy::RESTORE))
1860 int const ret = Alert::prompt(_("Unapplied changes"),
1861 _("Some changes in the document were not yet applied.\n"
1862 "Do you want to apply them before closing or dismiss the changes?"),
1863 1, 1, _("&Apply"), _("&Dismiss Changes"));
1869 void GuiDocument::onBufferViewChanged()
1872 // We are just switching back. Nothing to do.
1873 switchback_ = false;
1876 BufferView const * view = bufferview();
1877 string const new_filename = view ? view->buffer().absFileName() : string();
1878 // If we switched buffer really and the previous file name is different to
1879 // the current one, we ask on unapplied changes (#9369)
1880 // FIXME: This is more complicated than it should be. Why do we need these to cycles?
1881 // And ideally, we should propose to apply without having to switch back
1882 // (e.g., via a LFUN_BUFFER_PARAMS_APPLY_OTHER)
1883 if (!prev_buffer_filename_.empty() && prev_buffer_filename_ != new_filename
1884 && buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
1885 // Only ask if we haven't yet in this cycle
1886 int const ret = prompted_ ? 3 : Alert::prompt(_("Unapplied changes"),
1887 _("Some changes in the previous document were not yet applied.\n"
1888 "Do you want to switch back in order to apply them or dismiss the changes?"),
1889 1, 1, _("&Switch Back"), _("&Dismiss Changes"));
1891 // Switch to previous buffer view and apply
1893 // Record that we have asked.
1895 lyx::dispatch(FuncRequest(LFUN_BUFFER_SWITCH, prev_buffer_filename_));
1897 } else if (ret == 3) {
1898 // We are in the second cycle. Set back.
1904 if (isVisibleView())
1905 initialiseParams("");
1909 void GuiDocument::saveDefaultClicked()
1915 void GuiDocument::useDefaultsClicked()
1921 void GuiDocument::change_adaptor()
1923 nonModuleChanged_ = true;
1928 void GuiDocument::shellescapeChanged()
1930 shellescapeChanged_ = true;
1934 void GuiDocument::bookmarksopenChanged(bool state)
1936 pdfSupportModule->bookmarksopenlevelSB->setEnabled(state);
1937 pdfSupportModule->bookmarksopenlevelLA->setEnabled(state);
1941 void GuiDocument::changeTrackingChanged(bool state)
1943 // This is triggered if the CT state is toggled outside
1944 // the document dialog (e.g., menu).
1945 changesModule->trackChangesCB->setChecked(state);
1949 void GuiDocument::slotApply()
1951 bool only_shellescape_changed = !nonModuleChanged_ && !modulesChanged_;
1952 bool wasclean = buffer().isClean();
1953 GuiDialog::slotApply();
1954 if (wasclean && only_shellescape_changed)
1955 buffer().markClean();
1956 modulesChanged_ = false;
1961 void GuiDocument::slotOK()
1963 bool only_shellescape_changed = !nonModuleChanged_ && !modulesChanged_;
1964 bool wasclean = buffer().isClean();
1965 GuiDialog::slotOK();
1966 if (wasclean && only_shellescape_changed)
1967 buffer().markClean();
1968 modulesChanged_ = false;
1972 void GuiDocument::slotButtonBox(QAbstractButton * button)
1974 switch (buttonBox->standardButton(button)) {
1975 case QDialogButtonBox::Ok:
1978 case QDialogButtonBox::Apply:
1981 case QDialogButtonBox::Cancel:
1984 case QDialogButtonBox::Reset:
1985 case QDialogButtonBox::RestoreDefaults:
1994 void GuiDocument::filterModules(QString const & str)
1996 updateAvailableModules();
2000 modules_av_model_.clear();
2001 list<modInfoStruct> modInfoList = getModuleInfo();
2002 // Sort names according to the locale
2003 modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
2004 return 0 < b.name.localeAwareCompare(a.name);
2007 QIcon user_icon(guiApp ? guiApp->getScaledPixmap("images/", "lyxfiles-user")
2008 : getPixmap("images/", "lyxfiles-user", "svgz,png"));
2009 QIcon system_icon(guiApp ? guiApp->getScaledPixmap("images/", "lyxfiles-system")
2010 : getPixmap("images/", "lyxfiles-system", "svgz,png"));
2013 for (modInfoStruct const & m : modInfoList) {
2014 if (m.name.contains(str, Qt::CaseInsensitive) || contains(m.id, fromqstr(str))) {
2015 QStandardItem * item = new QStandardItem();
2016 item->setData(m.name, Qt::DisplayRole);
2017 item->setData(toqstr(m.id), Qt::UserRole);
2018 item->setData(m.description, Qt::ToolTipRole);
2019 item->setEditable(false);
2021 item->setIcon(user_icon);
2023 item->setIcon(system_icon);
2024 modules_av_model_.insertRow(i, item);
2031 void GuiDocument::moduleFilterChanged(const QString & text)
2033 if (!text.isEmpty()) {
2034 filterModules(filter_->text());
2037 filterModules(filter_->text());
2038 filter_->setFocus();
2042 void GuiDocument::moduleFilterPressed()
2044 filterModules(filter_->text());
2048 void GuiDocument::resetModuleFilter()
2050 filter_->setText(QString());
2051 filterModules(filter_->text());
2055 void GuiDocument::includeonlyClicked(QTreeWidgetItem * item, int)
2057 if (item == nullptr)
2060 string child = fromqstr(item->text(0));
2065 if (isChildIncluded(child))
2066 includeonlys_.remove(child);
2068 includeonlys_.push_back(child);
2070 updateIncludeonlys(false);
2075 QString GuiDocument::validateListingsParameters()
2077 if (listingsModule->bypassCB->isChecked())
2079 string const package =
2080 lst_packages[listingsModule->packageCO->currentIndex()];
2081 string params = fromqstr(listingsModule->listingsED->toPlainText());
2082 InsetListingsParams lstparams(params);
2083 lstparams.setMinted(package == "Minted");
2084 return toqstr(lstparams.validate());
2088 void GuiDocument::setListingsMessage()
2091 static bool isOK = true;
2092 QString msg = validateListingsParameters();
2093 if (msg.isEmpty()) {
2094 listingsModule->listingsTB->setTextColor(QColor());
2098 listingsModule->listingsTB->setPlainText(
2099 qt_("Input listings parameters below. "
2100 "Enter ? for a list of parameters."));
2103 listingsModule->listingsTB->setTextColor(QColor(255, 0, 0));
2104 listingsModule->listingsTB->setPlainText(msg);
2109 void GuiDocument::listingsPackageChanged(int index)
2111 string const package = lst_packages[index];
2112 if (package == "Minted" && lyxrc.pygmentize_command.empty()) {
2113 Alert::warning(_("Pygments driver command not found!"),
2114 _("The driver command necessary to use the minted package\n"
2115 "(pygmentize) has not been found. Make sure you have\n"
2116 "the python-pygments module installed or, if the driver\n"
2117 "is named differently, to add the following line to the\n"
2118 "document preamble:\n\n"
2119 "\\AtBeginDocument{\\renewcommand{\\MintedPygmentize}{driver}}\n\n"
2120 "where 'driver' is name of the driver command."));
2125 void GuiDocument::setLSpacing(int item)
2127 textLayoutModule->lspacingLE->setEnabled(item == 3);
2131 void GuiDocument::setIndent(int item)
2133 bool const enable = (textLayoutModule->indentCO->itemData(item) == "custom");
2134 textLayoutModule->indentLE->setEnabled(enable);
2135 textLayoutModule->indentLengthCO->setEnabled(enable);
2136 textLayoutModule->skipLE->setEnabled(false);
2137 textLayoutModule->skipLengthCO->setEnabled(false);
2138 // needed to catch empty custom case
2144 void GuiDocument::enableIndent(bool indent)
2146 textLayoutModule->skipLE->setEnabled(!indent);
2147 textLayoutModule->skipLengthCO->setEnabled(!indent);
2149 setIndent(textLayoutModule->indentCO->currentIndex());
2153 void GuiDocument::setSkip(int item)
2155 VSpace::VSpaceKind kind =
2156 VSpace::VSpaceKind(textLayoutModule->skipCO->itemData(item).toInt());
2157 bool const enable = (kind == VSpace::LENGTH);
2158 textLayoutModule->skipLE->setEnabled(enable);
2159 textLayoutModule->skipLengthCO->setEnabled(enable);
2160 // needed to catch empty custom case
2166 void GuiDocument::enableSkip(bool skip)
2168 textLayoutModule->indentLE->setEnabled(!skip);
2169 textLayoutModule->indentLengthCO->setEnabled(!skip);
2171 setSkip(textLayoutModule->skipCO->currentIndex());
2174 void GuiDocument::allowMathIndent() {
2175 // only disable when not checked, checked does not always allow enabling
2176 if (!mathsModule->MathIndentCB->isChecked()) {
2177 mathsModule->MathIndentLE->setEnabled(false);
2178 mathsModule->MathIndentLengthCO->setEnabled(false);
2180 if (mathsModule->MathIndentCB->isChecked()
2181 && mathsModule->MathIndentCO->itemData(mathsModule->MathIndentCO->currentIndex()) == "custom") {
2182 mathsModule->MathIndentLE->setEnabled(true);
2183 mathsModule->MathIndentLengthCO->setEnabled(true);
2188 void GuiDocument::enableMathIndent(int item)
2190 bool const enable = (item == 1);
2191 mathsModule->MathIndentLE->setEnabled(enable);
2192 mathsModule->MathIndentLengthCO->setEnabled(enable);
2193 // needed to catch empty custom case
2199 void GuiDocument::setMargins()
2201 bool const extern_geometry =
2202 documentClass().provides("geometry");
2203 marginsModule->marginCB->setEnabled(!extern_geometry);
2204 if (extern_geometry) {
2205 marginsModule->marginCB->setChecked(false);
2206 setCustomMargins(true);
2208 marginsModule->marginCB->setChecked(!bp_.use_geometry);
2209 setCustomMargins(!bp_.use_geometry);
2214 void GuiDocument::papersizeChanged(int paper_size)
2216 setCustomPapersize(paper_size == 1);
2220 void GuiDocument::setCustomPapersize(bool custom)
2222 pageLayoutModule->paperwidthL->setEnabled(custom);
2223 pageLayoutModule->paperwidthLE->setEnabled(custom);
2224 pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
2225 pageLayoutModule->paperheightL->setEnabled(custom);
2226 pageLayoutModule->paperheightLE->setEnabled(custom);
2227 pageLayoutModule->paperheightLE->setFocus();
2228 pageLayoutModule->paperheightUnitCO->setEnabled(custom);
2232 void GuiDocument::setColSep()
2234 setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
2238 void GuiDocument::setCustomMargins(bool cb_checked)
2240 bool const custom_margins = !cb_checked;
2241 if (custom_margins) {
2242 Length::UNIT const default_unit = Length::defaultUnit();
2243 // fill with chached values
2244 lengthToWidgets(marginsModule->topLE,
2245 marginsModule->topUnit,
2246 tmp_topmargin_, default_unit);
2247 lengthToWidgets(marginsModule->bottomLE,
2248 marginsModule->bottomUnit,
2249 tmp_bottommargin_, default_unit);
2250 lengthToWidgets(marginsModule->innerLE,
2251 marginsModule->innerUnit,
2252 tmp_leftmargin_, default_unit);
2253 lengthToWidgets(marginsModule->outerLE,
2254 marginsModule->outerUnit,
2255 tmp_rightmargin_, default_unit);
2256 lengthToWidgets(marginsModule->headheightLE,
2257 marginsModule->headheightUnit,
2258 tmp_headheight_, default_unit);
2259 lengthToWidgets(marginsModule->headsepLE,
2260 marginsModule->headsepUnit,
2261 tmp_headsep_, default_unit);
2262 lengthToWidgets(marginsModule->footskipLE,
2263 marginsModule->footskipUnit,
2264 tmp_footskip_, default_unit);
2265 lengthToWidgets(marginsModule->columnsepLE,
2266 marginsModule->columnsepUnit,
2267 tmp_columnsep_, default_unit);
2268 } else { // default margins
2269 // Cache current values
2270 tmp_leftmargin_ = widgetsToLength(marginsModule->innerLE,
2271 marginsModule->innerUnit);
2272 tmp_topmargin_ = widgetsToLength(marginsModule->topLE,
2273 marginsModule->topUnit);
2274 tmp_rightmargin_ = widgetsToLength(marginsModule->outerLE,
2275 marginsModule->outerUnit);
2276 tmp_bottommargin_ = widgetsToLength(marginsModule->bottomLE,
2277 marginsModule->bottomUnit);
2278 tmp_headheight_ = widgetsToLength(marginsModule->headheightLE,
2279 marginsModule->headheightUnit);
2280 tmp_headsep_ = widgetsToLength(marginsModule->headsepLE,
2281 marginsModule->headsepUnit);
2282 tmp_footskip_ = widgetsToLength(marginsModule->footskipLE,
2283 marginsModule->footskipUnit);
2284 tmp_columnsep_ = widgetsToLength(marginsModule->columnsepLE,
2285 marginsModule->columnsepUnit);
2287 marginsModule->topLE->clear();
2288 marginsModule->bottomLE->clear();
2289 marginsModule->innerLE->clear();
2290 marginsModule->outerLE->clear();
2291 marginsModule->headheightLE->clear();
2292 marginsModule->headsepLE->clear();
2293 marginsModule->footskipLE->clear();
2294 marginsModule->columnsepLE->clear();
2297 marginsModule->topL->setEnabled(custom_margins);
2298 marginsModule->topLE->setEnabled(custom_margins);
2299 marginsModule->topUnit->setEnabled(custom_margins);
2301 marginsModule->bottomL->setEnabled(custom_margins);
2302 marginsModule->bottomLE->setEnabled(custom_margins);
2303 marginsModule->bottomUnit->setEnabled(custom_margins);
2305 marginsModule->innerL->setEnabled(custom_margins);
2306 marginsModule->innerLE->setEnabled(custom_margins);
2307 marginsModule->innerUnit->setEnabled(custom_margins);
2309 marginsModule->outerL->setEnabled(custom_margins);
2310 marginsModule->outerLE->setEnabled(custom_margins);
2311 marginsModule->outerUnit->setEnabled(custom_margins);
2313 marginsModule->headheightL->setEnabled(custom_margins);
2314 marginsModule->headheightLE->setEnabled(custom_margins);
2315 marginsModule->headheightUnit->setEnabled(custom_margins);
2317 marginsModule->headsepL->setEnabled(custom_margins);
2318 marginsModule->headsepLE->setEnabled(custom_margins);
2319 marginsModule->headsepUnit->setEnabled(custom_margins);
2321 marginsModule->footskipL->setEnabled(custom_margins);
2322 marginsModule->footskipLE->setEnabled(custom_margins);
2323 marginsModule->footskipUnit->setEnabled(custom_margins);
2325 bool const enableColSep = custom_margins &&
2326 textLayoutModule->twoColumnCB->isChecked();
2327 marginsModule->columnsepL->setEnabled(enableColSep);
2328 marginsModule->columnsepLE->setEnabled(enableColSep);
2329 marginsModule->columnsepUnit->setEnabled(enableColSep);
2331 // set some placeholder text that hint on defaults
2332 QString const placeholder = marginsModule->marginCB->isChecked() ?
2333 qt_("Default margins") : qt_("Package defaults");
2334 // set tooltip depending on gemoetry state
2335 QString const tooltip = marginsModule->marginCB->isChecked() ?
2336 qt_("If no value is given, the defaults as set by the class, a package or the preamble are used.")
2337 : qt_("If no value is given, the defaults as set by the geometry package or a package/class overriding geometry's defaults are used.");
2338 marginsModule->topLE->setPlaceholderText(placeholder);
2339 marginsModule->bottomLE->setPlaceholderText(placeholder);
2340 marginsModule->innerLE->setPlaceholderText(placeholder);
2341 marginsModule->outerLE->setPlaceholderText(placeholder);
2342 marginsModule->headheightLE->setPlaceholderText(placeholder);
2343 marginsModule->headsepLE->setPlaceholderText(placeholder);
2344 marginsModule->footskipLE->setPlaceholderText(placeholder);
2345 marginsModule->columnsepLE->setPlaceholderText(placeholder);
2346 marginsModule->topLE->setToolTip(tooltip);
2347 marginsModule->bottomLE->setToolTip(tooltip);
2348 marginsModule->innerLE->setToolTip(tooltip);
2349 marginsModule->outerLE->setToolTip(tooltip);
2350 marginsModule->headheightLE->setToolTip(tooltip);
2351 marginsModule->headsepLE->setToolTip(tooltip);
2352 marginsModule->footskipLE->setToolTip(tooltip);
2353 marginsModule->columnsepLE->setToolTip(tooltip);
2357 void GuiDocument::changeBackgroundColor()
2359 QColor const & newColor = getColor(rgb2qcolor(set_backgroundcolor));
2360 if (!newColor.isValid())
2363 colorModule->pageBackgroundCF->setVisible(true);
2364 colorModule->pageBackgroundCF->setStyleSheet(
2365 colorFrameStyleSheet(newColor));
2367 set_backgroundcolor = rgbFromHexName(fromqstr(newColor.name()));
2368 is_backgroundcolor = true;
2373 void GuiDocument::deleteBackgroundColor()
2375 // set the color back to default by setting an empty StyleSheet
2376 colorModule->pageBackgroundCF->setStyleSheet(QLatin1String(""));
2377 colorModule->pageBackgroundCF->setVisible(false);
2378 // save default color (white)
2379 set_backgroundcolor = rgbFromHexName("#ffffff");
2380 is_backgroundcolor = false;
2385 void GuiDocument::changeFontColor()
2387 QColor const & newColor = getColor(rgb2qcolor(set_fontcolor));
2388 if (!newColor.isValid())
2391 colorModule->mainTextCF->setVisible(true);
2392 colorModule->mainTextCF->setStyleSheet(
2393 colorFrameStyleSheet(newColor));
2395 set_fontcolor = rgbFromHexName(fromqstr(newColor.name()));
2396 is_fontcolor = true;
2401 void GuiDocument::deleteFontColor()
2403 // set the button color back to default by setting an empty StyleSheet
2404 colorModule->mainTextCF->setStyleSheet(QLatin1String(""));
2405 colorModule->mainTextCF->setVisible(false);
2406 // save default color (black)
2407 set_fontcolor = rgbFromHexName("#000000");
2408 is_fontcolor = false;
2413 void GuiDocument::changeNoteFontColor()
2415 QColor const & newColor = getColor(rgb2qcolor(set_notefontcolor));
2416 if (!newColor.isValid())
2419 colorModule->noteFontCF->setStyleSheet(
2420 colorFrameStyleSheet(newColor));
2422 set_notefontcolor = rgbFromHexName(fromqstr(newColor.name()));
2423 is_notefontcolor = true;
2428 void GuiDocument::deleteNoteFontColor()
2430 // set the color back to pref
2431 theApp()->getRgbColor(Color_greyedouttext, set_notefontcolor);
2432 colorModule->noteFontCF->setStyleSheet(
2433 colorFrameStyleSheet(rgb2qcolor(set_notefontcolor)));
2434 is_notefontcolor = false;
2439 void GuiDocument::changeBoxBackgroundColor()
2441 QColor const & newColor = getColor(rgb2qcolor(set_boxbgcolor));
2442 if (!newColor.isValid())
2445 colorModule->boxBackgroundCF->setStyleSheet(
2446 colorFrameStyleSheet(newColor));
2448 set_boxbgcolor = rgbFromHexName(fromqstr(newColor.name()));
2449 is_boxbgcolor = true;
2454 void GuiDocument::deleteBoxBackgroundColor()
2456 // set the color back to pref
2457 theApp()->getRgbColor(Color_shadedbg, set_boxbgcolor);
2458 colorModule->boxBackgroundCF->setStyleSheet(
2459 colorFrameStyleSheet(rgb2qcolor(set_boxbgcolor)));
2460 is_boxbgcolor = false;
2465 void GuiDocument::updateQuoteStyles(bool const set)
2467 Language const * lang = lyx::languages.getLanguage(
2468 fromqstr(langModule->languageCO->itemData(
2469 langModule->languageCO->currentIndex()).toString()));
2471 QuoteStyle def = bp_.getQuoteStyle(lang->quoteStyle());
2473 langModule->quoteStyleCO->clear();
2475 bool has_default = false;
2476 for (int i = 0; i < quoteparams.stylescount(); ++i) {
2477 QuoteStyle qs = QuoteStyle(i);
2478 if (qs == QuoteStyle::Dynamic)
2480 bool const langdef = (qs == def);
2482 // add the default style on top
2483 langModule->quoteStyleCO->insertItem(0,
2484 toqstr(quoteparams.getGuiLabel(qs, langdef)), static_cast<int>(qs));
2488 langModule->quoteStyleCO->addItem(
2489 toqstr(quoteparams.getGuiLabel(qs, langdef)), static_cast<int>(qs));
2491 // Use document serif font to assure quotation marks are distinguishable
2492 QFont comboFont(toqstr(lyxrc.roman_font_name),
2493 langModule->quoteStyleCO->fontInfo().pointSize() * 1.4, -1, false);
2494 QFontMetrics fm(comboFont);
2495 // calculate width of the widest item in the set font
2497 for (int i = 0; i < langModule->quoteStyleCO->count(); ++i) {
2498 langModule->quoteStyleCO->setItemData(i, QVariant(comboFont), Qt::FontRole);
2499 QString str = langModule->quoteStyleCO->itemText(i);
2500 #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
2501 qswidth = max(qswidth, fm.horizontalAdvance(str));
2503 qswidth = max(qswidth, fm.width(str));
2506 // add scrollbar width and margin to width
2507 qswidth += langModule->quoteStyleCO->style()->pixelMetric(QStyle::PM_ScrollBarExtent);
2508 qswidth += langModule->quoteStyleCO->view()->autoScrollMargin();
2509 langModule->quoteStyleCO->view()->setMinimumWidth(qswidth);
2510 if (set && has_default)
2511 // (re)set to the default style
2512 langModule->quoteStyleCO->setCurrentIndex(0);
2516 void GuiDocument::languageChanged(int i)
2518 // some languages only work with Polyglossia
2519 Language const * lang = lyx::languages.getLanguage(
2520 fromqstr(langModule->languageCO->itemData(i).toString()));
2521 if (lang->babel().empty() && !lang->polyglossia().empty()
2522 && lang->required() != "CJK" && lang->required() != "japanese") {
2523 // If we force to switch fontspec on, store
2524 // current state (#8717)
2525 if (fontModule->osFontsCB->isEnabled())
2526 forced_fontspec_activation =
2527 !fontModule->osFontsCB->isChecked();
2528 fontModule->osFontsCB->setChecked(true);
2529 fontModule->osFontsCB->setEnabled(false);
2532 fontModule->osFontsCB->setEnabled(true);
2533 // If we have forced to switch fontspec on,
2534 // restore previous state (#8717)
2535 if (forced_fontspec_activation)
2536 fontModule->osFontsCB->setChecked(false);
2537 forced_fontspec_activation = false;
2540 // set appropriate quotation mark style
2541 updateQuoteStyles(true);
2545 void GuiDocument::osFontsChanged(bool nontexfonts)
2547 bool const tex_fonts = !nontexfonts;
2548 // store current fonts
2549 QString const font_roman = fontModule->fontsRomanCO->getData(
2550 fontModule->fontsRomanCO->currentIndex());
2551 QString const font_sans = fontModule->fontsSansCO->getData(
2552 fontModule->fontsSansCO->currentIndex());
2553 QString const font_typewriter = fontModule->fontsTypewriterCO->getData(
2554 fontModule->fontsTypewriterCO->currentIndex());
2555 QString const font_math = fontModule->fontsMathCO->itemData(
2556 fontModule->fontsMathCO->currentIndex()).toString();
2557 int const font_sf_scale = fontModule->scaleSansSB->value();
2558 int const font_tt_scale = fontModule->scaleTypewriterSB->value();
2561 // store default format
2562 QString const dformat = outputModule->defaultFormatCO->itemData(
2563 outputModule->defaultFormatCO->currentIndex()).toString();
2564 updateDefaultFormat();
2565 // try to restore default format
2566 int index = outputModule->defaultFormatCO->findData(dformat);
2567 // set to default if format is not found
2570 outputModule->defaultFormatCO->setCurrentIndex(index);
2572 // try to restore fonts which were selected two toggles ago
2573 if (!fontModule->font_roman.isEmpty())
2574 fontModule->fontsRomanCO->set(fontModule->font_roman);
2575 if (!fontModule->font_sans.isEmpty())
2576 fontModule->fontsSansCO->set(fontModule->font_sans);
2577 if (!fontModule->font_typewriter.isEmpty())
2578 fontModule->fontsTypewriterCO->set(fontModule->font_typewriter);
2579 index = fontModule->fontsMathCO->findData(fontModule->font_math);
2581 fontModule->fontsMathCO->setCurrentIndex(index);
2582 // save fonts for next next toggle
2583 fontModule->font_roman = font_roman;
2584 fontModule->font_sans = font_sans;
2585 fontModule->font_typewriter = font_typewriter;
2586 fontModule->font_math = font_math;
2587 fontModule->font_sf_scale = font_sf_scale;
2588 fontModule->font_tt_scale = font_tt_scale;
2590 // non-tex fonts override the "\inputencoding" option with "utf8-plain"
2591 langModule->encodingCO->setEnabled(tex_fonts);
2592 inputencodingToDialog();
2594 fontModule->cjkFontLE->setEnabled(tex_fonts);
2595 fontModule->cjkFontLA->setEnabled(tex_fonts);
2597 updateFontOptions();
2599 fontModule->fontencLA->setEnabled(tex_fonts);
2600 fontModule->fontencCO->setEnabled(tex_fonts);
2602 fontModule->fontencLE->setEnabled(false);
2604 fontencChanged(fontModule->fontencCO->currentIndex());
2608 void GuiDocument::encodingSwitched(int i)
2610 bool const tex_fonts = !fontModule->osFontsCB->isChecked();
2611 langModule->unicodeEncodingCO->setEnabled(tex_fonts);
2612 langModule->customEncodingCO->setEnabled(tex_fonts);
2613 langModule->autoEncodingCO->setEnabled(tex_fonts);
2614 langModule->unicodeEncodingCO->setVisible(i == EncodingSets::unicode);
2615 langModule->autoEncodingCO->setVisible(i == EncodingSets::legacy);
2616 langModule->customEncodingCO->setVisible(i == EncodingSets::custom);
2618 case EncodingSets::unicode:
2619 langModule->encodingVariantLA->setBuddy(langModule->unicodeEncodingCO);
2621 case EncodingSets::legacy:
2622 langModule->encodingVariantLA->setBuddy(langModule->autoEncodingCO);
2624 case EncodingSets::custom:
2625 langModule->encodingVariantLA->setBuddy(langModule->customEncodingCO);
2630 langModule->unicodeEncodingCO->setItemText(1, qt_("Direct (No inputenc)"));
2632 langModule->unicodeEncodingCO->setItemText(1, qt_("Direct (XeTeX/LuaTeX)"));
2635 void GuiDocument::inputencodingToDialog()
2637 QString inputenc = toqstr(bp_.inputenc);
2639 if (fontModule->osFontsCB->isChecked()) { // non-tex fonts require utf8-plain
2640 langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
2641 langModule->unicodeEncodingCO->setCurrentIndex(
2642 langModule->unicodeEncodingCO->findData("utf8-plain"));
2643 } else if (inputenc.startsWith("utf8")) {
2644 langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
2645 p = langModule->unicodeEncodingCO->findData(inputenc);
2648 langModule->unicodeEncodingCO->setCurrentIndex(p);
2649 langModule->autoEncodingCO->setCurrentIndex(0);
2650 langModule->customEncodingCO->setCurrentIndex(0);
2651 } else if (inputenc.startsWith("auto")) {
2652 langModule->encodingCO->setCurrentIndex(EncodingSets::legacy);
2653 p = langModule->autoEncodingCO->findData(inputenc);
2656 langModule->unicodeEncodingCO->setCurrentIndex(0);
2657 langModule->autoEncodingCO->setCurrentIndex(p);
2658 langModule->customEncodingCO->setCurrentIndex(0);
2660 langModule->encodingCO->setCurrentIndex(EncodingSets::custom);
2661 p = langModule->customEncodingCO->findData(inputenc);
2664 langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
2666 langModule->unicodeEncodingCO->setCurrentIndex(0);
2667 langModule->autoEncodingCO->setCurrentIndex(0);
2668 langModule->customEncodingCO->setCurrentIndex(p);
2670 encodingSwitched(langModule->encodingCO->currentIndex());
2674 void GuiDocument::mathFontChanged(int)
2676 updateFontOptions();
2679 void GuiDocument::fontOsfToggled(bool state)
2681 if (fontModule->osFontsCB->isChecked())
2683 QString font = fontModule->fontsRomanCO->getData(
2684 fontModule->fontsRomanCO->currentIndex());
2685 if (hasMonolithicExpertSet(font))
2686 fontModule->fontScCB->setChecked(state);
2690 void GuiDocument::fontScToggled(bool state)
2692 if (fontModule->osFontsCB->isChecked())
2694 QString font = fontModule->fontsRomanCO->getData(
2695 fontModule->fontsRomanCO->currentIndex());
2696 if (hasMonolithicExpertSet(font))
2697 fontModule->fontOsfCB->setChecked(state);
2701 void GuiDocument::updateExtraOpts()
2703 QString font = fontModule->fontsRomanCO->getData(
2704 fontModule->fontsRomanCO->currentIndex());
2705 bool const rm_opts = providesExtraOpts(font);
2706 font = fontModule->fontsSansCO->getData(
2707 fontModule->fontsSansCO->currentIndex());
2708 bool const sf_opts = providesExtraOpts(font);
2709 font = fontModule->fontsTypewriterCO->getData(
2710 fontModule->fontsTypewriterCO->currentIndex());
2711 bool const tt_opts = providesExtraOpts(font);
2712 fontModule->fontspecRomanLA->setEnabled(rm_opts);
2713 fontModule->fontspecRomanLE->setEnabled(rm_opts);
2714 fontModule->fontspecSansLA->setEnabled(sf_opts);
2715 fontModule->fontspecSansLE->setEnabled(sf_opts);
2716 fontModule->fontspecTypewriterLA->setEnabled(tt_opts);
2717 fontModule->fontspecTypewriterLE->setEnabled(tt_opts);
2721 void GuiDocument::updateFontOptions()
2723 QString font = fontModule->fontsSansCO->getData(
2724 fontModule->fontsSansCO->currentIndex());
2725 bool scalable = providesScale(font);
2726 fontModule->scaleSansSB->setEnabled(scalable);
2727 fontModule->scaleSansLA->setEnabled(scalable);
2728 fontModule->fontSansOsfCB->setEnabled(providesOSF(font));
2729 font = fontModule->fontsTypewriterCO->getData(
2730 fontModule->fontsTypewriterCO->currentIndex());
2731 scalable = providesScale(font);
2732 fontModule->scaleTypewriterSB->setEnabled(scalable);
2733 fontModule->scaleTypewriterLA->setEnabled(scalable);
2734 fontModule->fontTypewriterOsfCB->setEnabled(providesOSF(font));
2735 font = fontModule->fontsRomanCO->getData(
2736 fontModule->fontsRomanCO->currentIndex());
2737 fontModule->fontScCB->setEnabled(providesSC(font));
2738 fontModule->fontOsfCB->setEnabled(providesOSF(font));
2740 updateMathFonts(font);
2744 void GuiDocument::updateFontsize(string const & items, string const & sel)
2746 fontModule->fontsizeCO->clear();
2747 fontModule->fontsizeCO->addItem(qt_("Default"));
2749 for (int n = 0; !token(items,'|',n).empty(); ++n)
2750 fontModule->fontsizeCO->
2751 addItem(toqstr(token(items,'|',n)));
2753 for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
2754 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
2755 fontModule->fontsizeCO->setCurrentIndex(n);
2762 bool GuiDocument::ot1() const
2764 QString const fontenc =
2765 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
2766 int const i = langModule->languageCO->currentIndex();
2769 QString const langname = langModule->languageCO->itemData(i).toString();
2770 Language const * newlang = lyx::languages.getLanguage(fromqstr(langname));
2771 return (fontenc == "default"
2772 || (fontenc == "auto" && newlang->fontenc(buffer().params()) == "OT1")
2773 || (fontenc == "custom" && fontModule->fontencLE->text() == "OT1"));
2777 bool GuiDocument::completeFontset() const
2779 return (fontModule->fontsSansCO->getData(
2780 fontModule->fontsSansCO->currentIndex()) == "default"
2781 && fontModule->fontsSansCO->getData(
2782 fontModule->fontsTypewriterCO->currentIndex()) == "default");
2786 bool GuiDocument::noMathFont() const
2788 return (fontModule->fontsMathCO->itemData(
2789 fontModule->fontsMathCO->currentIndex()).toString() == "default");
2793 void GuiDocument::updateTexFonts()
2795 LaTeXFonts::TexFontMap texfontmap = theLaTeXFonts().getLaTeXFonts();
2797 LaTeXFonts::TexFontMap::const_iterator it = texfontmap.begin();
2798 LaTeXFonts::TexFontMap::const_iterator end = texfontmap.end();
2799 for (; it != end; ++it) {
2800 LaTeXFont lf = it->second;
2801 if (lf.name().empty()) {
2802 LYXERR0("Error: Unnamed font: " << it->first);
2805 docstring const family = lf.family();
2806 docstring guiname = translateIfPossible(lf.guiname());
2807 if (!lf.available(ot1(), noMathFont()))
2808 guiname += _(" (not installed)");
2810 rmfonts_.insert(toqstr(guiname), toqstr(it->first));
2811 else if (family == "sf")
2812 sffonts_.insert(toqstr(guiname), toqstr(it->first));
2813 else if (family == "tt")
2814 ttfonts_.insert(toqstr(guiname), toqstr(it->first));
2815 else if (family == "math")
2816 mathfonts_.insert(toqstr(guiname), toqstr(it->first));
2821 void GuiDocument::updateFontlist()
2823 // reset the filters of the CategorizedCombos
2824 fontModule->fontsRomanCO->resetFilter();
2825 fontModule->fontsSansCO->resetFilter();
2826 fontModule->fontsTypewriterCO->resetFilter();
2827 fontModule->fontsRomanCO->clear();
2828 fontModule->fontsSansCO->clear();
2829 fontModule->fontsTypewriterCO->clear();
2830 fontModule->fontsMathCO->clear();
2832 // With fontspec (XeTeX, LuaTeX), we have access to all system fonts, but not the LaTeX fonts
2833 if (fontModule->osFontsCB->isChecked()) {
2834 fontModule->fontsRomanCO->addItemSort(QString("default"), qt_("Default"),
2835 QString(), qt_("Default font (as set by class)"),
2836 false, false, false, true, true);
2837 fontModule->fontsSansCO->addItemSort(QString("default"), qt_("Default"),
2838 QString(), qt_("Default font (as set by class)"),
2839 false, false, false, true, true);
2840 fontModule->fontsTypewriterCO->addItemSort(QString("default"), qt_("Default"),
2841 QString(), qt_("Default font (as set by class)"),
2842 false, false, false, true, true);
2843 QString unimath = qt_("Non-TeX Fonts Default");
2844 if (!LaTeXFeatures::isAvailable("unicode-math"))
2845 unimath += qt_(" (not available)");
2846 fontModule->fontsMathCO->addItem(qt_("Class Default (TeX Fonts)"), QString("auto"));
2847 fontModule->fontsMathCO->addItem(unimath, QString("default"));
2849 #if QT_VERSION >= 0x060000
2850 const QStringList families(QFontDatabase::families());
2852 QFontDatabase fontdb;
2853 const QStringList families(fontdb.families());
2855 for (auto const & family : families) {
2856 fontModule->fontsRomanCO->addItemSort(family, family,
2857 QString(), QString(),
2858 false, false, false, true, true);
2859 fontModule->fontsSansCO->addItemSort(family, family,
2860 QString(), QString(),
2861 false, false, false, true, true);
2862 fontModule->fontsTypewriterCO->addItemSort(family, family,
2863 QString(), QString(),
2864 false, false, false, true, true);
2869 if (rmfonts_.empty())
2872 fontModule->fontsRomanCO->addItemSort(QString("default"), qt_("Default"),
2873 QString(), qt_("Default font (as set by class)"),
2874 false, false, false, true, true);
2875 QMap<QString, QString>::const_iterator rmi = rmfonts_.constBegin();
2876 while (rmi != rmfonts_.constEnd()) {
2877 fontModule->fontsRomanCO->addItemSort(rmi.value(), rmi.key(),
2878 QString(), QString(),
2879 false, false, false, true, true);
2883 fontModule->fontsSansCO->addItemSort(QString("default"), qt_("Default"),
2884 QString(), qt_("Default font (as set by class)"),
2885 false, false, false, true, true);
2886 QMap<QString, QString>::const_iterator sfi = sffonts_.constBegin();
2887 while (sfi != sffonts_.constEnd()) {
2888 fontModule->fontsSansCO->addItemSort(sfi.value(), sfi.key(),
2889 QString(), QString(),
2890 false, false, false, true, true);
2894 fontModule->fontsTypewriterCO->addItemSort(QString("default"), qt_("Default"),
2895 QString(), qt_("Default font (as set by class)"),
2896 false, false, false, true, true);
2897 QMap<QString, QString>::const_iterator tti = ttfonts_.constBegin();
2898 while (tti != ttfonts_.constEnd()) {
2899 fontModule->fontsTypewriterCO->addItemSort(tti.value(), tti.key(),
2900 QString(), QString(),
2901 false, false, false, true, true);
2905 fontModule->fontsMathCO->addItem(qt_("Automatic"), QString("auto"));
2906 fontModule->fontsMathCO->addItem(qt_("Class Default"), QString("default"));
2907 QMap<QString, QString>::const_iterator mmi = mathfonts_.constBegin();
2908 while (mmi != mathfonts_.constEnd()) {
2909 fontModule->fontsMathCO->addItem(mmi.key(), mmi.value());
2915 void GuiDocument::fontencChanged(int item)
2917 fontModule->fontencLE->setEnabled(
2918 fontModule->fontencCO->itemData(item).toString() == "custom");
2919 // The availability of TeX fonts depends on the font encoding
2921 updateFontOptions();
2925 void GuiDocument::updateMathFonts(QString const & rm)
2927 if (fontModule->osFontsCB->isChecked())
2929 QString const math =
2930 fontModule->fontsMathCO->itemData(fontModule->fontsMathCO->currentIndex()).toString();
2931 int const i = fontModule->fontsMathCO->findData("default");
2932 if (providesNoMath(rm) && i == -1)
2933 fontModule->fontsMathCO->insertItem(1, qt_("Class Default"), QString("default"));
2934 else if (!providesNoMath(rm) && i != -1) {
2935 int const c = fontModule->fontsMathCO->currentIndex();
2936 fontModule->fontsMathCO->removeItem(i);
2938 fontModule->fontsMathCO->setCurrentIndex(0);
2943 void GuiDocument::romanChanged(int item)
2945 QString const font = fontModule->fontsRomanCO->getData(item);
2946 fontModule->fontOsfCB->setEnabled(providesOSF(font));
2948 if (fontModule->osFontsCB->isChecked())
2950 fontModule->fontScCB->setEnabled(providesSC(font));
2951 updateMathFonts(font);
2955 void GuiDocument::sansChanged(int item)
2957 QString const font = fontModule->fontsSansCO->getData(item);
2958 bool const scalable = providesScale(font);
2959 fontModule->scaleSansSB->setEnabled(scalable);
2960 fontModule->scaleSansLA->setEnabled(scalable);
2961 fontModule->fontSansOsfCB->setEnabled(providesOSF(font));
2966 void GuiDocument::ttChanged(int item)
2968 QString const font = fontModule->fontsTypewriterCO->getData(item);
2969 bool scalable = providesScale(font);
2970 fontModule->scaleTypewriterSB->setEnabled(scalable);
2971 fontModule->scaleTypewriterLA->setEnabled(scalable);
2972 fontModule->fontTypewriterOsfCB->setEnabled(providesOSF(font));
2977 void GuiDocument::updatePagestyle(string const & items, string const & sel)
2980 pageLayoutModule->pagestyleCO->clear();
2981 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
2983 for (int n = 0; !token(items, '|', n).empty(); ++n) {
2984 string style = token(items, '|', n);
2985 QString style_gui = qt_(style);
2986 pagestyles.push_back(pair<string, QString>(style, style_gui));
2987 pageLayoutModule->pagestyleCO->addItem(style_gui);
2990 if (sel == "default") {
2991 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
2997 for (auto const & pagestyle : pagestyles)
2998 if (pagestyle.first == sel)
2999 nn = pageLayoutModule->pagestyleCO->findText(pagestyle.second);
3002 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
3006 void GuiDocument::browseLayout()
3008 QString const label1 = qt_("Lay&outs");
3009 QString const dir1 = toqstr(lyxrc.document_path);
3010 QStringList const filter(qt_("LyX Layout (*.layout)"));
3011 QString file = browseRelToParent(QString(), bufferFilePath(),
3012 qt_("Local layout file"), filter, false,
3015 if (!file.endsWith(".layout"))
3018 FileName layoutFile = support::makeAbsPath(fromqstr(file),
3019 fromqstr(bufferFilePath()));
3021 int const ret = Alert::prompt(_("Local layout file"),
3022 _("The layout file you have selected is a local layout\n"
3023 "file, not one in the system or user directory.\n"
3024 "Your document will not work with this layout if you\n"
3025 "move the layout file to a different directory."),
3026 1, 1, _("&Set Layout"), _("&Cancel"));
3030 // load the layout file
3031 LayoutFileList & bcl = LayoutFileList::get();
3032 string classname = layoutFile.onlyFileName();
3033 // this will update an existing layout if that layout has been loaded before.
3034 LayoutFileIndex name = support::onlyFileName(bcl.addLocalLayout(
3035 classname.substr(0, classname.size() - 7),
3036 layoutFile.onlyPath().absFileName()));
3039 Alert::error(_("Error"),
3040 _("Unable to read local layout file."));
3044 const_cast<Buffer &>(buffer()).setLayoutPos(layoutFile.onlyPath().absFileName());
3046 // do not trigger classChanged if there is no change.
3047 if (latexModule->classCO->currentText() == toqstr(name))
3051 bool const avail = latexModule->classCO->set(toqstr(name));
3053 LayoutFile const & tc = bcl[name];
3054 docstring const guiname = translateIfPossible(from_utf8(tc.description()));
3055 // tooltip sensu "KOMA-Script Article [Class 'scrartcl']"
3056 QString tooltip = toqstr(bformat(_("%1$s [Class '%2$s']"), guiname, from_utf8(tc.latexname())));
3057 tooltip += '\n' + qt_("This is a local layout file.");
3058 latexModule->classCO->addItemSort(toqstr(tc.name()), toqstr(guiname),
3059 toqstr(translateIfPossible(from_utf8(tc.category()))),
3061 true, true, true, true);
3062 latexModule->classCO->set(toqstr(name));
3069 void GuiDocument::browseMaster()
3071 QString const title = qt_("Select master document");
3072 QString const dir1 = toqstr(lyxrc.document_path);
3073 QString const old = latexModule->childDocLE->text();
3074 QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
3075 QStringList const filter(qt_("LyX Files (*.lyx)"));
3076 QString file = browseRelToSub(old, docpath, title, filter, false,
3077 qt_("D&ocuments"), toqstr(lyxrc.document_path));
3079 if (!file.isEmpty())
3080 latexModule->childDocLE->setText(file);
3084 void GuiDocument::classChanged_adaptor()
3086 const_cast<Buffer &>(buffer()).setLayoutPos(string());
3091 void GuiDocument::classChanged()
3093 int idx = latexModule->classCO->currentIndex();
3096 string const classname = fromqstr(latexModule->classCO->getData(idx));
3098 if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
3099 int const ret = Alert::prompt(_("Unapplied changes"),
3100 _("Some changes in the dialog were not yet applied.\n"
3101 "If you do not apply now, they will be lost after this action."),
3102 1, 1, _("&Apply"), _("&Dismiss"));
3107 // We load the TextClass as soon as it is selected. This is
3108 // necessary so that other options in the dialog can be updated
3109 // according to the new class. Note, however, that, if you use
3110 // the scroll wheel when sitting on the combo box, we'll load a
3111 // lot of TextClass objects very quickly....
3112 if (!bp_.setBaseClass(classname, buffer().layoutPos())) {
3113 Alert::error(_("Error"), _("Unable to set document class."));
3116 if (lyxrc.auto_reset_options)
3117 bp_.useClassDefaults();
3119 // With the introduction of modules came a distinction between the base
3120 // class and the document class. The former corresponds to the main layout
3121 // file; the latter is that plus the modules (or the document-specific layout,
3122 // or whatever else there could be). Our parameters come from the document
3123 // class. So when we set the base class, we also need to recreate the document
3124 // class. Otherwise, we still have the old one.
3125 bp_.makeDocumentClass();
3130 void GuiDocument::languagePackageChanged(int i)
3132 langModule->languagePackageLE->setEnabled(
3133 langModule->languagePackageCO->itemData(i).toString() == "custom");
3137 void GuiDocument::biblioChanged()
3139 biblioChanged_ = true;
3144 void GuiDocument::checkPossibleCiteEngines()
3146 // Check if the class provides a specific engine,
3147 // and if so, enforce this.
3148 string force_engine;
3149 if (documentClass().provides("natbib")
3150 || documentClass().provides("natbib-internal"))
3151 force_engine = "natbib";
3152 else if (documentClass().provides("jurabib"))
3153 force_engine = "jurabib";
3154 else if (documentClass().provides("biblatex"))
3155 force_engine = "biblatex";
3156 else if (documentClass().provides("biblatex-natbib"))
3157 force_engine = "biblatex-natbib";
3159 if (!force_engine.empty())
3160 biblioModule->citeEngineCO->setCurrentIndex(
3161 biblioModule->citeEngineCO->findData(toqstr(force_engine)));
3162 biblioModule->citeEngineCO->setEnabled(force_engine.empty());
3166 void GuiDocument::rescanBibFiles()
3169 rescanTexStyles("bbx cbx");
3171 rescanTexStyles("bst");
3175 void GuiDocument::resetDefaultBibfile(string const & which)
3177 QString const engine =
3178 biblioModule->citeEngineCO->itemData(
3179 biblioModule->citeEngineCO->currentIndex()).toString();
3181 CiteEngineType const cet =
3182 CiteEngineType(biblioModule->citeStyleCO->itemData(
3183 biblioModule->citeStyleCO->currentIndex()).toInt());
3185 updateDefaultBiblio(theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet), which);
3189 void GuiDocument::resetDefaultBbxBibfile()
3191 resetDefaultBibfile("bbx");
3195 void GuiDocument::resetDefaultCbxBibfile()
3197 resetDefaultBibfile("cbx");
3201 void GuiDocument::citeEngineChanged(int n)
3203 QString const engine =
3204 biblioModule->citeEngineCO->itemData(n).toString();
3206 vector<string> const engs =
3207 theCiteEnginesList[fromqstr(engine)]->getEngineType();
3209 updateCiteStyles(engs);
3210 updateEngineDependends();
3211 resetDefaultBibfile();
3216 void GuiDocument::updateEngineDependends()
3218 bool const biblatex = isBiblatex();
3220 // These are only useful with BibTeX
3221 biblioModule->defaultBiblioCO->setEnabled(!biblatex);
3222 biblioModule->bibtexStyleLA->setEnabled(!biblatex);
3223 biblioModule->resetDefaultBiblioPB->setEnabled(!biblatex);
3224 biblioModule->bibtopicCB->setEnabled(!biblatex);
3226 // These are only useful with Biblatex
3227 biblioModule->biblatexBbxCO->setEnabled(biblatex);
3228 biblioModule->biblatexBbxLA->setEnabled(biblatex);
3229 biblioModule->biblatexCbxCO->setEnabled(biblatex);
3230 biblioModule->biblatexCbxLA->setEnabled(biblatex);
3231 biblioModule->resetBbxPB->setEnabled(biblatex);
3232 biblioModule->resetCbxPB->setEnabled(biblatex);
3233 biblioModule->matchBbxPB->setEnabled(biblatex);
3235 // These are useful with biblatex, jurabib and natbib
3236 QString const engine =
3237 biblioModule->citeEngineCO->itemData(
3238 biblioModule->citeEngineCO->currentIndex()).toString();
3239 LyXCiteEngine const * ce = theCiteEnginesList[fromqstr(engine)];
3241 bool const citepack = ce->required("biblatex.sty") || ce->required("jurabib.sty")
3242 || ce->required("natbib.sty");
3243 biblioModule->citePackageOptionsLE->setEnabled(citepack);
3244 biblioModule->citePackageOptionsL->setEnabled(citepack);
3248 void GuiDocument::citeStyleChanged()
3250 QString const engine =
3251 biblioModule->citeEngineCO->itemData(
3252 biblioModule->citeEngineCO->currentIndex()).toString();
3253 QString const currentDef = isBiblatex() ?
3254 biblioModule->biblatexBbxCO->currentText()
3255 : biblioModule->defaultBiblioCO->currentText();
3256 if (theCiteEnginesList[fromqstr(engine)]->isDefaultBiblio(fromqstr(currentDef)))
3257 resetDefaultBibfile();
3263 void GuiDocument::bibtexChanged(int n)
3265 biblioModule->bibtexOptionsLE->setEnabled(
3266 biblioModule->bibtexCO->itemData(n).toString() != "default");
3271 void GuiDocument::updateCiteStyles(vector<string> const & engs, CiteEngineType const & sel)
3273 biblioModule->citeStyleCO->clear();
3275 vector<string>::const_iterator it = engs.begin();
3276 vector<string>::const_iterator end = engs.end();
3277 for (; it != end; ++it) {
3278 if (*it == "default")
3279 biblioModule->citeStyleCO->addItem(qt_("Basic numerical"),
3280 ENGINE_TYPE_DEFAULT);
3281 else if (*it == "authoryear")
3282 biblioModule->citeStyleCO->addItem(qt_("Author-year"),
3283 ENGINE_TYPE_AUTHORYEAR);
3284 else if (*it == "numerical")
3285 biblioModule->citeStyleCO->addItem(qt_("Author-number"),
3286 ENGINE_TYPE_NUMERICAL);
3288 int i = biblioModule->citeStyleCO->findData(sel);
3289 if (biblioModule->citeStyleCO->findData(sel) == -1)
3291 biblioModule->citeStyleCO->setCurrentIndex(i);
3293 biblioModule->citationStyleL->setEnabled(engs.size() > 1);
3294 biblioModule->citeStyleCO->setEnabled(engs.size() > 1);
3298 void GuiDocument::updateEngineType(string const & items, CiteEngineType const & sel)
3300 engine_types_.clear();
3302 for (int n = 0; !token(items, '|', n).empty(); ++n) {
3303 string style = token(items, '|', n);
3304 engine_types_.push_back(style);
3307 updateCiteStyles(engine_types_, sel);
3313 // both of these should take a vector<docstring>
3315 // This is an insanely complicated attempt to make this sort of thing
3316 // work with RTL languages.
3317 docstring formatStrVec(vector<string> const & v, docstring const & s)
3319 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
3323 return translateIfPossible(from_utf8(v[0]));
3324 if (v.size() == 2) {
3325 docstring retval = _("%1$s and %2$s");
3326 retval = subst(retval, _("and"), s);
3327 return bformat(retval, translateIfPossible(from_utf8(v[0])),
3328 translateIfPossible(from_utf8(v[1])));
3330 // The idea here is to format all but the last two items...
3331 int const vSize = v.size();
3332 docstring t2 = _("%1$s, %2$s");
3333 docstring retval = translateIfPossible(from_utf8(v[0]));
3334 for (int i = 1; i < vSize - 2; ++i)
3335 retval = bformat(t2, retval, translateIfPossible(from_utf8(v[i])));
3336 //...and then to plug them, and the last two, into this schema
3337 docstring t = _("%1$s, %2$s, and %3$s");
3338 t = subst(t, _("and"), s);
3339 return bformat(t, retval, translateIfPossible(from_utf8(v[vSize - 2])),
3340 translateIfPossible(from_utf8(v[vSize - 1])));
3343 vector<string> idsToNames(vector<string> const & idList)
3345 vector<string> retval;
3346 vector<string>::const_iterator it = idList.begin();
3347 vector<string>::const_iterator end = idList.end();
3348 for (; it != end; ++it) {
3349 LyXModule const * const mod = theModuleList[*it];
3351 retval.push_back(to_utf8(bformat(_("%1$s (unavailable)"),
3352 translateIfPossible(from_utf8(*it)))));
3354 retval.push_back(mod->getName());
3358 } // end anonymous namespace
3361 void GuiDocument::modulesToParams(BufferParams & bp)
3363 // update list of loaded modules
3364 bp.clearLayoutModules();
3365 int const srows = modules_sel_model_.rowCount();
3366 for (int i = 0; i < srows; ++i)
3367 bp.addLayoutModule(modules_sel_model_.getIDString(i));
3368 updateSelectedModules();
3370 // update the list of removed modules
3371 bp.clearRemovedModules();
3372 LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
3373 list<string>::const_iterator rit = reqmods.begin();
3374 list<string>::const_iterator ren = reqmods.end();
3376 // check each of the default modules
3377 for (; rit != ren; ++rit) {
3378 list<string>::const_iterator mit = bp.getModules().begin();
3379 list<string>::const_iterator men = bp.getModules().end();
3381 for (; mit != men; ++mit) {
3388 // the module isn't present so must have been removed by the user
3389 bp.addRemovedModule(*rit);
3394 void GuiDocument::modulesChanged()
3396 modulesToParams(bp_);
3398 if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()
3399 && (nonModuleChanged_ || shellescapeChanged_)) {
3400 int const ret = Alert::prompt(_("Unapplied changes"),
3401 _("Some changes in the dialog were not yet applied.\n"
3402 "If you do not apply now, they will be lost after this action."),
3403 1, 1, _("&Apply"), _("&Dismiss"));
3408 modulesChanged_ = true;
3409 bp_.makeDocumentClass();
3415 void GuiDocument::updateModuleInfo()
3417 selectionManager->update();
3419 //Module description
3420 bool const focus_on_selected = selectionManager->selectedFocused();
3421 QAbstractItemView * lv;
3422 bool category = false;
3423 if (focus_on_selected) {
3424 lv = modulesModule->selectedLV;
3427 lv = modulesModule->availableLV;
3428 if (lv->selectionModel()->selectedIndexes().isEmpty()) {
3429 modulesModule->infoML->document()->clear();
3432 QModelIndex const & idx = lv->selectionModel()->currentIndex();
3437 if (!focus_on_selected
3438 && modules_av_model_.itemFromIndex(idx)->hasChildren()) {
3439 // This is a category header
3440 modulesModule->infoML->document()->clear();
3444 string const modName = focus_on_selected ?
3445 modules_sel_model_.getIDString(idx.row())
3446 : fromqstr(modules_av_model_.data(idx, Qt::UserRole).toString());
3447 docstring desc = getModuleDescription(modName);
3449 LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
3450 if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
3453 desc += _("Module provided by document class.");
3457 docstring cat = getModuleCategory(modName);
3461 desc += bformat(_("<p><b>Category:</b> %1$s.</p>"),
3462 translateIfPossible(cat));
3466 vector<string> pkglist = getPackageList(modName);
3467 docstring pkgdesc = formatStrVec(pkglist, _("and"));
3468 if (!pkgdesc.empty()) {
3471 desc += bformat(_("<p><b>Package(s) required:</b> %1$s.</p>"), pkgdesc);
3474 pkglist = getRequiredList(modName);
3475 if (!pkglist.empty()) {
3476 vector<string> const reqdescs = idsToNames(pkglist);
3477 pkgdesc = formatStrVec(reqdescs, _("or"));
3480 desc += bformat(_("<p><b>Modules required:</b> %1$s.</p>"), pkgdesc);
3483 pkglist = getExcludedList(modName);
3484 if (!pkglist.empty()) {
3485 vector<string> const reqdescs = idsToNames(pkglist);
3486 pkgdesc = formatStrVec(reqdescs, _( "and"));
3489 desc += bformat(_("<p><b>Modules excluded:</b> %1$s.</p>"), pkgdesc);
3494 desc += bformat(_("<p><b>Filename:</b> <tt>%1$s.module</tt>.</p>"), from_utf8(modName));
3496 if (!isModuleAvailable(modName)) {
3499 desc += _("<p><font color=red><b>WARNING: Some required packages are unavailable!</b></font></p>");
3502 modulesModule->infoML->document()->setHtml(toqstr(desc));
3506 void GuiDocument::updateNumbering()
3508 DocumentClass const & tclass = documentClass();
3510 numberingModule->tocTW->setUpdatesEnabled(false);
3511 numberingModule->tocTW->clear();
3513 int const depth = numberingModule->depthSL->value();
3514 int const toc = numberingModule->tocSL->value();
3515 QString const no = qt_("No");
3516 QString const yes = qt_("Yes");
3517 QTreeWidgetItem * item = nullptr;
3519 DocumentClass::const_iterator lit = tclass.begin();
3520 DocumentClass::const_iterator len = tclass.end();
3521 for (; lit != len; ++lit) {
3522 int const toclevel = lit->toclevel;
3523 if (toclevel != Layout::NOT_IN_TOC && !lit->counter.empty()) {
3524 item = new QTreeWidgetItem(numberingModule->tocTW);
3525 item->setText(0, toqstr(translateIfPossible(lit->name())));
3526 item->setText(1, (toclevel <= depth) ? yes : no);
3527 item->setText(2, (toclevel <= toc) ? yes : no);
3531 numberingModule->tocTW->setUpdatesEnabled(true);
3532 numberingModule->tocTW->update();
3536 void GuiDocument::getTableStyles()
3538 // We look for lyx files in the subdirectory dir of
3540 // 2) build_lyxdir (if not empty)
3542 // in this order. Files with a given sub-hierarchy will
3543 // only be listed once.
3544 // We also consider i18n subdirectories and store them separately.
3547 // The three locations to look at.
3548 string const user = addPath(package().user_support().absFileName(), "tabletemplates");
3549 string const build = addPath(package().build_support().absFileName(), "tabletemplates");
3550 string const system = addPath(package().system_support().absFileName(), "tabletemplates");
3552 dirs << toqstr(user)
3556 for (int i = 0; i < dirs.size(); ++i) {
3557 QString const & dir = dirs.at(i);
3558 QDirIterator it(dir, QDir::Files, QDirIterator::Subdirectories);
3559 while (it.hasNext()) {
3560 QString fn = QFileInfo(it.next()).fileName();
3561 if (!fn.endsWith(".lyx") || fn.contains("_1x"))
3563 QString data = fn.left(fn.lastIndexOf(".lyx"));
3564 QString guiname = data;
3565 guiname = toqstr(translateIfPossible(qstring_to_ucs4(guiname.replace('_', ' '))));
3566 QString relpath = toqstr(makeRelPath(qstring_to_ucs4(fn),
3567 qstring_to_ucs4(dir)));
3568 if (textLayoutModule->tableStyleCO->findData(data) == -1)
3569 textLayoutModule->tableStyleCO->addItem(guiname, data);
3575 void GuiDocument::updateDefaultFormat()
3579 // make a copy in order to consider unapplied changes
3580 BufferParams param_copy = buffer().params();
3581 param_copy.useNonTeXFonts = fontModule->osFontsCB->isChecked();
3582 int const idx = latexModule->classCO->currentIndex();
3584 string const classname = fromqstr(latexModule->classCO->getData(idx));
3585 param_copy.setBaseClass(classname, buffer().layoutPos());
3586 param_copy.makeDocumentClass(true);
3588 outputModule->defaultFormatCO->blockSignals(true);
3589 outputModule->defaultFormatCO->clear();
3590 outputModule->defaultFormatCO->addItem(qt_("Default"),
3591 QVariant(QString("default")));
3592 FormatList const & formats =
3593 param_copy.exportableFormats(true);
3594 for (Format const * f : formats)
3595 outputModule->defaultFormatCO->addItem
3596 (toqstr(translateIfPossible(f->prettyname())),
3597 QVariant(toqstr(f->name())));
3598 outputModule->defaultFormatCO->blockSignals(false);
3602 bool GuiDocument::isChildIncluded(string const & child)
3604 if (includeonlys_.empty())
3606 return (std::find(includeonlys_.begin(),
3607 includeonlys_.end(), child) != includeonlys_.end());
3611 void GuiDocument::applyView()
3613 // auto-validate local layout
3614 if (!localLayout->isValid()) {
3615 localLayout->validate();
3616 if (!localLayout->isValid()) {
3617 setApplyStopped(true);
3618 docPS->setCurrentPanel(N_("Local Layout"));
3624 preambleModule->apply(bp_);
3625 localLayout->apply(bp_);
3628 bp_.suppress_date = latexModule->suppressDateCB->isChecked();
3629 bp_.use_refstyle = latexModule->refstyleCB->isChecked();
3630 bp_.use_formatted_ref = latexModule->refFormattedCB->isChecked();
3633 string const engine =
3634 fromqstr(biblioModule->citeEngineCO->itemData(
3635 biblioModule->citeEngineCO->currentIndex()).toString());
3636 bp_.setCiteEngine(engine);
3638 CiteEngineType const style = CiteEngineType(biblioModule->citeStyleCO->itemData(
3639 biblioModule->citeStyleCO->currentIndex()).toInt());
3640 if (theCiteEnginesList[engine]->hasEngineType(style))
3641 bp_.setCiteEngineType(style);
3643 bp_.setCiteEngineType(ENGINE_TYPE_DEFAULT);
3645 bp_.splitbib(biblioModule->bibtopicCB->isChecked());
3647 bp_.multibib = fromqstr(biblioModule->bibunitsCO->itemData(
3648 biblioModule->bibunitsCO->currentIndex()).toString());
3650 bp_.setDefaultBiblioStyle(fromqstr(biblioModule->defaultBiblioCO->currentText()));
3652 bp_.biblatex_bibstyle = fromqstr(biblioModule->biblatexBbxCO->currentText());
3653 bp_.biblatex_citestyle = fromqstr(biblioModule->biblatexCbxCO->currentText());
3654 bp_.biblio_opts = fromqstr(biblioModule->citePackageOptionsLE->text());
3656 string const bibtex_command =
3657 fromqstr(biblioModule->bibtexCO->itemData(
3658 biblioModule->bibtexCO->currentIndex()).toString());
3659 string const bibtex_options =
3660 fromqstr(biblioModule->bibtexOptionsLE->text());
3661 if (bibtex_command == "default" || bibtex_options.empty())
3662 bp_.bibtex_command = bibtex_command;
3664 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
3666 if (biblioChanged_) {
3667 buffer().invalidateBibinfoCache();
3668 buffer().removeBiblioTempFiles();
3672 indicesModule->apply(bp_);
3674 // language & quotes
3675 switch (langModule->encodingCO->currentIndex()) {
3676 case EncodingSets::unicode: {
3677 if (!fontModule->osFontsCB->isChecked())
3678 bp_.inputenc = fromqstr(langModule->unicodeEncodingCO->itemData(
3679 langModule->unicodeEncodingCO->currentIndex()).toString());
3682 case EncodingSets::legacy: {
3683 bp_.inputenc = "auto-legacy";
3684 bp_.inputenc = fromqstr(langModule->autoEncodingCO->itemData(
3685 langModule->autoEncodingCO->currentIndex()).toString());
3688 case EncodingSets::custom: {
3689 bp_.inputenc = fromqstr(langModule->customEncodingCO->itemData(
3690 langModule->customEncodingCO->currentIndex()).toString());
3694 // this should never happen
3695 bp_.inputenc = "utf8";
3697 bp_.quotes_style = QuoteStyle(langModule->quoteStyleCO->itemData(
3698 langModule->quoteStyleCO->currentIndex()).toInt());
3699 bp_.dynamic_quotes = langModule->dynamicQuotesCB->isChecked();
3701 QString const langname = langModule->languageCO->itemData(
3702 langModule->languageCO->currentIndex()).toString();
3703 Language const * newlang = lyx::languages.getLanguage(fromqstr(langname));
3704 Cursor & cur = const_cast<BufferView *>(bufferview())->cursor();
3705 // If current cursor language was the document language, then update it too.
3706 if (cur.current_font.language() == bp_.language) {
3707 cur.current_font.setLanguage(newlang);
3708 cur.real_current_font.setLanguage(newlang);
3710 bp_.language = newlang;
3712 QString const pack = langModule->languagePackageCO->itemData(
3713 langModule->languagePackageCO->currentIndex()).toString();
3714 if (pack == "custom")
3716 fromqstr(langModule->languagePackageLE->text());
3718 bp_.lang_package = fromqstr(pack);
3721 bp_.backgroundcolor = set_backgroundcolor;
3722 bp_.isbackgroundcolor = is_backgroundcolor;
3723 bp_.fontcolor = set_fontcolor;
3724 bp_.isfontcolor = is_fontcolor;
3725 bp_.notefontcolor = set_notefontcolor;
3726 bp_.isnotefontcolor = is_notefontcolor;
3727 if (is_notefontcolor) {
3728 // Set information used in statusbar (#12130)
3729 lcolor.setColor("notefontcolor", lyx::X11hexname(set_notefontcolor));
3730 lcolor.setGUIName("notefontcolor", N_("greyedout inset text"));
3732 bp_.boxbgcolor = set_boxbgcolor;
3733 bp_.isboxbgcolor = is_boxbgcolor;
3736 if (bp_.documentClass().hasTocLevels()) {
3737 bp_.tocdepth = numberingModule->tocSL->value();
3738 bp_.secnumdepth = numberingModule->depthSL->value();
3740 bp_.use_lineno = numberingModule->linenoCB->isChecked();
3741 bp_.lineno_opts = fromqstr(numberingModule->linenoLE->text());
3744 bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
3745 bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
3746 bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
3747 bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
3750 bp_.graphics_driver =
3751 tex_graphics[latexModule->psdriverCO->currentIndex()];
3754 int idx = latexModule->classCO->currentIndex();
3756 string const classname = fromqstr(latexModule->classCO->getData(idx));
3757 bp_.setBaseClass(classname, buffer().layoutPos());
3761 modulesToParams(bp_);
3764 map<string, string> const & packages = BufferParams::auto_packages();
3765 for (map<string, string>::const_iterator it = packages.begin();
3766 it != packages.end(); ++it) {
3767 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
3770 int row = mathsModule->packagesTW->row(item);
3773 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1)->layout()->itemAt(0)->widget();
3774 if (rb->isChecked()) {
3775 bp_.use_package(it->first, BufferParams::package_auto);
3778 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2)->layout()->itemAt(0)->widget();
3779 if (rb->isChecked()) {
3780 bp_.use_package(it->first, BufferParams::package_on);
3783 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3)->layout()->itemAt(0)->widget();
3784 if (rb->isChecked())
3785 bp_.use_package(it->first, BufferParams::package_off);
3787 // if math is indented
3788 bp_.is_math_indent = mathsModule->MathIndentCB->isChecked();
3789 if (bp_.is_math_indent) {
3790 // if formulas are indented
3791 if (mathsModule->MathIndentCO->itemData(mathsModule->MathIndentCO->currentIndex()) == "custom") {
3792 Length mathindent(widgetsToLength(mathsModule->MathIndentLE,
3793 mathsModule->MathIndentLengthCO));
3794 bp_.setMathIndent(mathindent);
3797 bp_.setMathIndent(Length());
3799 switch (mathsModule->MathNumberingPosCO->currentIndex()) {
3801 bp_.math_numbering_side = BufferParams::LEFT;
3804 bp_.math_numbering_side = BufferParams::DEFAULT;
3807 bp_.math_numbering_side = BufferParams::RIGHT;
3810 // this should never happen
3811 bp_.math_numbering_side = BufferParams::DEFAULT;
3816 if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
3817 bp_.pagestyle = "default";
3819 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
3820 for (size_t i = 0; i != pagestyles.size(); ++i)
3821 if (pagestyles[i].second == style_gui)
3822 bp_.pagestyle = pagestyles[i].first;
3826 switch (textLayoutModule->lspacingCO->currentIndex()) {
3828 bp_.spacing().set(Spacing::Single);
3831 bp_.spacing().set(Spacing::Onehalf);
3834 bp_.spacing().set(Spacing::Double);
3837 string s = widgetToDoubleStr(textLayoutModule->lspacingLE);
3839 bp_.spacing().set(Spacing::Single);
3841 bp_.spacing().set(Spacing::Other, s);
3846 if (textLayoutModule->twoColumnCB->isChecked())
3851 bp_.justification = textLayoutModule->justCB->isChecked();
3853 if (textLayoutModule->indentRB->isChecked()) {
3854 // if paragraphs are separated by an indentation
3855 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
3856 if (textLayoutModule->indentCO->itemData(textLayoutModule->indentCO->currentIndex()) == "custom") {
3857 Length parindent(widgetsToLength(textLayoutModule->indentLE,
3858 textLayoutModule->indentLengthCO));
3859 bp_.setParIndent(parindent);
3862 bp_.setParIndent(Length());
3864 // if paragraphs are separated by a skip
3865 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
3866 VSpace::VSpaceKind spacekind =
3867 VSpace::VSpaceKind(textLayoutModule->skipCO->itemData(textLayoutModule->skipCO->currentIndex()).toInt());
3868 switch (spacekind) {
3869 case VSpace::SMALLSKIP:
3870 case VSpace::MEDSKIP:
3871 case VSpace::BIGSKIP:
3872 case VSpace::HALFLINE:
3873 case VSpace::FULLLINE:
3874 bp_.setDefSkip(VSpace(spacekind));
3876 case VSpace::LENGTH: {
3878 widgetsToLength(textLayoutModule->skipLE,
3879 textLayoutModule->skipLengthCO)
3885 // this should never happen
3886 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
3890 bp_.tablestyle = fromqstr(textLayoutModule->tableStyleCO->itemData(
3891 textLayoutModule->tableStyleCO->currentIndex()).toString());
3894 fromqstr(latexModule->optionsLE->text());
3896 bp_.use_default_options =
3897 latexModule->defaultOptionsCB->isChecked();
3899 if (latexModule->childDocGB->isChecked())
3901 fromqstr(latexModule->childDocLE->text());
3903 bp_.master = string();
3906 bp_.clearIncludedChildren();
3907 updateIncludeonlys();
3908 if (masterChildModule->includeonlyRB->isChecked()) {
3909 list<string>::const_iterator it = includeonlys_.begin();
3910 for (; it != includeonlys_.end() ; ++it) {
3911 bp_.addIncludedChildren(*it);
3914 if (masterChildModule->maintainCRNoneRB->isChecked())
3915 bp_.maintain_unincluded_children =
3916 BufferParams::CM_None;
3917 else if (masterChildModule->maintainCRMostlyRB->isChecked())
3918 bp_.maintain_unincluded_children =
3919 BufferParams::CM_Mostly;
3921 bp_.maintain_unincluded_children =
3922 BufferParams::CM_Strict;
3923 updateIncludeonlyDisplay();
3926 bp_.float_placement = floatModule->getPlacement();
3927 bp_.float_alignment = floatModule->getAlignment();
3930 // text should have passed validation
3931 idx = listingsModule->packageCO->currentIndex();
3932 bp_.use_minted = string(lst_packages[idx]) == "Minted";
3933 bp_.listings_params =
3934 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
3937 bp_.default_output_format = fromqstr(outputModule->defaultFormatCO->itemData(
3938 outputModule->defaultFormatCO->currentIndex()).toString());
3940 bool const nontexfonts = fontModule->osFontsCB->isChecked();
3941 bp_.useNonTeXFonts = nontexfonts;
3943 bp_.shell_escape = outputModule->shellescapeCB->isChecked();
3944 if (!bp_.shell_escape)
3945 theSession().shellescapeFiles().remove(buffer().absFileName());
3946 else if (!theSession().shellescapeFiles().find(buffer().absFileName()))
3947 theSession().shellescapeFiles().insert(buffer().absFileName());
3948 Buffer & buf = const_cast<Buffer &>(buffer());
3949 buf.params().shell_escape = bp_.shell_escape;
3951 bp_.output_sync = outputModule->outputsyncCB->isChecked();
3953 bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
3955 int mathfmt = outputModule->mathoutCB->currentIndex();
3958 BufferParams::MathOutput const mo =
3959 static_cast<BufferParams::MathOutput>(mathfmt);
3960 bp_.html_math_output = mo;
3961 bp_.html_be_strict = outputModule->strictCB->isChecked();
3962 bp_.html_css_as_file = outputModule->cssCB->isChecked();
3963 bp_.html_math_img_scale = outputModule->mathimgSB->value();
3964 bp_.display_pixel_ratio = theGuiApp()->pixelRatio();
3966 int tablefmt = outputModule->tableoutCB->currentIndex();
3969 auto const to = static_cast<BufferParams::TableOutput>(tablefmt);
3970 bp_.docbook_table_output = to;
3972 int mathmlprefix = outputModule->mathmlprefixCB->currentIndex();
3973 if (mathmlprefix == -1)
3975 auto const mp = static_cast<BufferParams::MathMLNameSpacePrefix>(mathmlprefix);
3976 bp_.docbook_mathml_prefix = mp;
3978 bp_.save_transient_properties =
3979 outputModule->saveTransientPropertiesCB->isChecked();
3980 bp_.postpone_fragile_content =
3981 outputModule->postponeFragileCB->isChecked();
3984 bp_.fonts_roman[nontexfonts] =
3985 fromqstr(fontModule->fontsRomanCO->
3986 getData(fontModule->fontsRomanCO->currentIndex()));
3987 bp_.fonts_roman[!nontexfonts] = fromqstr(fontModule->font_roman);
3988 bp_.font_roman_opts = fromqstr(fontModule->fontspecRomanLE->text());
3990 bp_.fonts_sans[nontexfonts] =
3991 fromqstr(fontModule->fontsSansCO->
3992 getData(fontModule->fontsSansCO->currentIndex()));
3993 bp_.fonts_sans[!nontexfonts] = fromqstr(fontModule->font_sans);
3994 bp_.font_sans_opts = fromqstr(fontModule->fontspecSansLE->text());
3996 bp_.fonts_typewriter[nontexfonts] =
3997 fromqstr(fontModule->fontsTypewriterCO->
3998 getData(fontModule->fontsTypewriterCO->currentIndex()));
3999 bp_.fonts_typewriter[!nontexfonts] = fromqstr(fontModule->font_typewriter);
4000 bp_.font_typewriter_opts = fromqstr(fontModule->fontspecTypewriterLE->text());
4002 bp_.fonts_math[nontexfonts] =
4003 fromqstr(fontModule->fontsMathCO->
4004 itemData(fontModule->fontsMathCO->currentIndex()).toString());
4005 bp_.fonts_math[!nontexfonts] = fromqstr(fontModule->font_math);
4007 QString const fontenc =
4008 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
4009 if (fontenc == "custom")
4010 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
4012 bp_.fontenc = fromqstr(fontenc);
4015 fromqstr(fontModule->cjkFontLE->text());
4017 bp_.use_microtype = fontModule->microtypeCB->isChecked();
4018 bp_.use_dash_ligatures = !fontModule->dashesCB->isChecked();
4020 bp_.fonts_sans_scale[nontexfonts] = fontModule->scaleSansSB->value();
4021 bp_.fonts_sans_scale[!nontexfonts] = fontModule->font_sf_scale;
4023 bp_.fonts_typewriter_scale[nontexfonts] = fontModule->scaleTypewriterSB->value();
4024 bp_.fonts_typewriter_scale[!nontexfonts] = fontModule->font_tt_scale;
4026 bp_.fonts_expert_sc = fontModule->fontScCB->isChecked();
4028 bp_.fonts_roman_osf = fontModule->fontOsfCB->isChecked();
4029 bp_.fonts_sans_osf = fontModule->fontSansOsfCB->isChecked();
4030 bp_.fonts_typewriter_osf = fontModule->fontTypewriterOsfCB->isChecked();
4032 bp_.fonts_default_family = GuiDocument::fontfamilies[
4033 fontModule->fontsDefaultCO->currentIndex()];
4035 if (fontModule->fontsizeCO->currentIndex() == 0)
4036 bp_.fontsize = "default";
4039 fromqstr(fontModule->fontsizeCO->currentText());
4042 bp_.papersize = PAPER_SIZE(
4043 pageLayoutModule->papersizeCO->currentIndex());
4045 bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
4046 pageLayoutModule->paperwidthUnitCO);
4048 bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
4049 pageLayoutModule->paperheightUnitCO);
4051 if (pageLayoutModule->facingPagesCB->isChecked())
4052 bp_.sides = TwoSides;
4054 bp_.sides = OneSide;
4056 if (pageLayoutModule->landscapeRB->isChecked())
4057 bp_.orientation = ORIENTATION_LANDSCAPE;
4059 bp_.orientation = ORIENTATION_PORTRAIT;
4062 bp_.use_geometry = !marginsModule->marginCB->isChecked();
4064 Ui::MarginsUi const * m = marginsModule;
4066 if (bp_.use_geometry) {
4067 bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
4068 bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
4069 bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
4070 bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
4071 bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
4072 bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
4073 bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
4074 bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
4078 branchesModule->apply(bp_);
4081 PDFOptions & pdf = bp_.pdfoptions();
4082 pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
4083 pdf.title = fromqstr(pdfSupportModule->titleLE->text());
4084 pdf.author = fromqstr(pdfSupportModule->authorLE->text());
4085 pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
4086 pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
4088 pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
4089 pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
4090 pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
4091 pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
4093 pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
4094 pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
4095 pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
4096 pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
4098 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
4099 if (pdfSupportModule->fullscreenCB->isChecked())
4100 pdf.pagemode = pdf.pagemode_fullscreen;
4102 pdf.pagemode.clear();
4103 pdf.quoted_options = pdf.quoted_options_check(
4104 fromqstr(pdfSupportModule->optionsTE->toPlainText()));
4105 bp_.document_metadata = qstring_to_ucs4(pdfSupportModule->metadataTE->toPlainText()
4106 .trimmed().replace(QRegularExpression("\n+"), "\n"));
4109 bp_.track_changes = changesModule->trackChangesCB->isChecked();
4110 bp_.output_changes = changesModule->outputChangesCB->isChecked();
4111 bool const cb_switched_off = (bp_.change_bars
4112 && !changesModule->changeBarsCB->isChecked());
4113 bp_.change_bars = changesModule->changeBarsCB->isChecked();
4114 if (cb_switched_off)
4115 // if change bars have been switched off,
4116 // we need to ditch the aux file
4117 buffer().requireFreshStart(true);
4120 nonModuleChanged_ = false;
4121 shellescapeChanged_ = false;
4125 void GuiDocument::paramsToDialog()
4127 // set the default unit
4128 Length::UNIT const default_unit = Length::defaultUnit();
4131 preambleModule->update(bp_, id());
4132 localLayout->update(bp_, id());
4135 latexModule->suppressDateCB->setChecked(bp_.suppress_date);
4136 latexModule->refstyleCB->setChecked(bp_.use_refstyle);
4137 latexModule->refFormattedCB->setChecked(bp_.use_formatted_ref);
4140 string const cite_engine = bp_.citeEngine();
4142 biblioModule->citeEngineCO->setCurrentIndex(
4143 biblioModule->citeEngineCO->findData(toqstr(cite_engine)));
4145 updateEngineType(documentClass().opt_enginetype(),
4146 bp_.citeEngineType());
4148 checkPossibleCiteEngines();
4150 biblioModule->citeStyleCO->setCurrentIndex(
4151 biblioModule->citeStyleCO->findData(bp_.citeEngineType()));
4153 biblioModule->bibtopicCB->setChecked(bp_.splitbib());
4155 biblioModule->bibunitsCO->clear();
4156 biblioModule->bibunitsCO->addItem(qt_("No"), QString());
4157 if (documentClass().hasLaTeXLayout("part"))
4158 biblioModule->bibunitsCO->addItem(qt_("per part"), toqstr("part"));
4159 if (documentClass().hasLaTeXLayout("chapter"))
4160 biblioModule->bibunitsCO->addItem(qt_("per chapter"), toqstr("chapter"));
4161 if (documentClass().hasLaTeXLayout("section"))
4162 biblioModule->bibunitsCO->addItem(qt_("per section"), toqstr("section"));
4163 if (documentClass().hasLaTeXLayout("subsection"))
4164 biblioModule->bibunitsCO->addItem(qt_("per subsection"), toqstr("subsection"));
4165 biblioModule->bibunitsCO->addItem(qt_("per child document"), toqstr("child"));
4167 int const mbpos = biblioModule->bibunitsCO->findData(toqstr(bp_.multibib));
4169 biblioModule->bibunitsCO->setCurrentIndex(mbpos);
4171 biblioModule->bibunitsCO->setCurrentIndex(0);
4173 updateEngineDependends();
4176 updateDefaultBiblio(bp_.biblatex_bibstyle, "bbx");
4177 updateDefaultBiblio(bp_.biblatex_citestyle, "cbx");
4179 updateDefaultBiblio(bp_.defaultBiblioStyle());
4181 biblioModule->citePackageOptionsLE->setText(toqstr(bp_.biblio_opts));
4185 split(bp_.bibtex_command, command, ' ');
4187 int bpos = biblioModule->bibtexCO->findData(toqstr(command));
4189 // We add and set the unknown compiler, indicating that it is unavailable
4190 // to assure document compilation and for security reasons, a fallback
4191 // will be used on document processing stage
4192 biblioModule->bibtexCO->addItem(toqstr(bformat(_("%1$s (not available)"),
4193 from_utf8(command))), toqstr(command));
4194 bpos = biblioModule->bibtexCO->findData(toqstr(command));
4196 biblioModule->bibtexCO->setCurrentIndex(bpos);
4197 biblioModule->bibtexOptionsLE->setText(toqstr(options).trimmed());
4198 biblioModule->bibtexOptionsLE->setEnabled(
4199 biblioModule->bibtexCO->currentIndex() != 0);
4201 biblioChanged_ = false;
4204 // We may be called when there is no Buffer, e.g., when
4205 // the last view has just been closed.
4206 bool const isReadOnly = isBufferAvailable() ? buffer().isReadonly() : false;
4207 indicesModule->update(bp_, isReadOnly);
4209 // language & quotes
4210 int const pos = langModule->languageCO->findData(toqstr(
4211 bp_.language->lang()));
4212 langModule->languageCO->setCurrentIndex(pos);
4214 updateQuoteStyles();
4216 langModule->quoteStyleCO->setCurrentIndex(
4217 langModule->quoteStyleCO->findData(static_cast<int>(bp_.quotes_style)));
4218 langModule->dynamicQuotesCB->setChecked(bp_.dynamic_quotes);
4220 // LaTeX input encoding: set after the fonts (see below)
4222 int p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
4224 langModule->languagePackageCO->setCurrentIndex(
4225 langModule->languagePackageCO->findData("custom"));
4226 langModule->languagePackageLE->setText(toqstr(bp_.lang_package));
4228 langModule->languagePackageCO->setCurrentIndex(p);
4229 langModule->languagePackageLE->clear();
4233 if (bp_.isfontcolor) {
4234 colorModule->mainTextCF->setStyleSheet(
4235 colorFrameStyleSheet(rgb2qcolor(bp_.fontcolor)));
4236 colorModule->mainTextCF->setVisible(true);
4238 colorModule->mainTextCF->setVisible(false);
4239 set_fontcolor = bp_.fontcolor;
4240 is_fontcolor = bp_.isfontcolor;
4242 colorModule->noteFontCF->setStyleSheet(
4243 colorFrameStyleSheet(rgb2qcolor(bp_.notefontcolor)));
4244 set_notefontcolor = bp_.notefontcolor;
4245 is_notefontcolor = bp_.isnotefontcolor;
4247 if (bp_.isbackgroundcolor) {
4248 colorModule->pageBackgroundCF->setStyleSheet(
4249 colorFrameStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
4250 colorModule->pageBackgroundCF->setVisible(true);
4252 colorModule->pageBackgroundCF->setVisible(false);
4253 set_backgroundcolor = bp_.backgroundcolor;
4254 is_backgroundcolor = bp_.isbackgroundcolor;
4256 colorModule->boxBackgroundCF->setStyleSheet(
4257 colorFrameStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
4258 set_boxbgcolor = bp_.boxbgcolor;
4259 is_boxbgcolor = bp_.isboxbgcolor;
4262 int const min_toclevel = documentClass().min_toclevel();
4263 int const max_toclevel = documentClass().max_toclevel();
4264 if (documentClass().hasTocLevels()) {
4265 numberingModule->setEnabled(true);
4266 numberingModule->depthSL->setMinimum(min_toclevel - 1);
4267 numberingModule->depthSL->setMaximum(max_toclevel);
4268 numberingModule->depthSL->setValue(bp_.secnumdepth);
4269 numberingModule->tocSL->setMaximum(min_toclevel - 1);
4270 numberingModule->tocSL->setMaximum(max_toclevel);
4271 numberingModule->tocSL->setValue(bp_.tocdepth);
4274 numberingModule->setEnabled(false);
4275 numberingModule->tocTW->clear();
4278 numberingModule->linenoCB->setChecked(bp_.use_lineno);
4279 numberingModule->linenoLE->setEnabled(bp_.use_lineno);
4280 numberingModule->linenoLA->setEnabled(bp_.use_lineno);
4281 numberingModule->linenoLE->setText(toqstr(bp_.lineno_opts));
4284 bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
4285 bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
4286 bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
4287 bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
4288 bulletsModule->init();
4291 int nitem = findToken(tex_graphics, bp_.graphics_driver);
4293 latexModule->psdriverCO->setCurrentIndex(nitem);
4297 mathsModule->MathIndentCB->setChecked(bp_.is_math_indent);
4298 if (bp_.is_math_indent) {
4299 Length const mathindent = bp_.getMathIndent();
4301 if (!mathindent.empty()) {
4302 lengthToWidgets(mathsModule->MathIndentLE,
4303 mathsModule->MathIndentLengthCO,
4304 mathindent, default_unit);
4307 mathsModule->MathIndentCO->setCurrentIndex(indent);
4308 enableMathIndent(indent);
4310 switch(bp_.math_numbering_side) {
4311 case BufferParams::LEFT:
4312 mathsModule->MathNumberingPosCO->setCurrentIndex(0);
4314 case BufferParams::DEFAULT:
4315 mathsModule->MathNumberingPosCO->setCurrentIndex(1);
4317 case BufferParams::RIGHT:
4318 mathsModule->MathNumberingPosCO->setCurrentIndex(2);
4321 map<string, string> const & packages = BufferParams::auto_packages();
4322 for (map<string, string>::const_iterator it = packages.begin();
4323 it != packages.end(); ++it) {
4324 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
4327 int row = mathsModule->packagesTW->row(item);
4328 switch (bp_.use_package(it->first)) {
4329 case BufferParams::package_off: {
4331 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3)->layout()->itemAt(0)->widget();
4332 rb->setChecked(true);
4335 case BufferParams::package_on: {
4337 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2)->layout()->itemAt(0)->widget();
4338 rb->setChecked(true);
4341 case BufferParams::package_auto: {
4343 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1)->layout()->itemAt(0)->widget();
4344 rb->setChecked(true);
4350 switch (bp_.spacing().getSpace()) {
4351 case Spacing::Other: nitem = 3; break;
4352 case Spacing::Double: nitem = 2; break;
4353 case Spacing::Onehalf: nitem = 1; break;
4354 case Spacing::Default: case Spacing::Single: nitem = 0; break;
4358 string const & layoutID = bp_.baseClassID();
4359 setLayoutComboByIDString(layoutID);
4361 updatePagestyle(documentClass().opt_pagestyle(),
4364 textLayoutModule->lspacingCO->setCurrentIndex(nitem);
4365 if (bp_.spacing().getSpace() == Spacing::Other) {
4366 doubleToWidget(textLayoutModule->lspacingLE,
4367 bp_.spacing().getValueAsString());
4370 int ts = textLayoutModule->tableStyleCO->findData(toqstr(bp_.tablestyle));
4372 textLayoutModule->tableStyleCO->setCurrentIndex(ts);
4374 if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
4375 textLayoutModule->indentRB->setChecked(true);
4376 string parindent = bp_.getParIndent().asString();
4377 QString indent = toqstr("default");
4378 if (!parindent.empty()) {
4379 lengthToWidgets(textLayoutModule->indentLE,
4380 textLayoutModule->indentLengthCO,
4381 parindent, default_unit);
4382 indent = toqstr("custom");
4384 textLayoutModule->indentCO->setCurrentIndex(textLayoutModule->indentCO->findData(indent));
4385 setIndent(textLayoutModule->indentCO->currentIndex());
4387 textLayoutModule->skipRB->setChecked(true);
4388 VSpace::VSpaceKind skip = bp_.getDefSkip().kind();
4389 textLayoutModule->skipCO->setCurrentIndex(textLayoutModule->skipCO->findData(skip));
4390 if (skip == VSpace::LENGTH) {
4391 string const length = bp_.getDefSkip().asLyXCommand();
4392 lengthToWidgets(textLayoutModule->skipLE,
4393 textLayoutModule->skipLengthCO,
4394 length, default_unit);
4396 setSkip(textLayoutModule->skipCO->currentIndex());
4399 textLayoutModule->twoColumnCB->setChecked(
4401 textLayoutModule->justCB->setChecked(bp_.justification);
4403 if (!bp_.options.empty()) {
4404 latexModule->optionsLE->setText(
4405 toqstr(bp_.options));
4407 latexModule->optionsLE->setText(QString());
4411 latexModule->defaultOptionsCB->setChecked(
4412 bp_.use_default_options);
4413 updateSelectedModules();
4414 selectionManager->updateProvidedModules(
4415 bp_.baseClass()->providedModules());
4416 selectionManager->updateExcludedModules(
4417 bp_.baseClass()->excludedModules());
4419 if (!documentClass().options().empty()) {
4420 latexModule->defaultOptionsLE->setText(
4421 toqstr(documentClass().options()));
4423 latexModule->defaultOptionsLE->setText(
4424 toqstr(_("[No options predefined]")));
4427 latexModule->defaultOptionsLE->setEnabled(
4428 bp_.use_default_options
4429 && !documentClass().options().empty());
4431 latexModule->defaultOptionsCB->setEnabled(
4432 !documentClass().options().empty());
4434 if (!bp_.master.empty()) {
4435 latexModule->childDocGB->setChecked(true);
4436 latexModule->childDocLE->setText(
4437 toqstr(bp_.master));
4439 latexModule->childDocLE->setText(QString());
4440 latexModule->childDocGB->setChecked(false);
4444 if (!bufferview() || !buffer().hasChildren()) {
4445 masterChildModule->childrenTW->clear();
4446 includeonlys_.clear();
4447 docPS->showPanel("Child Documents", false);
4448 if (docPS->isCurrentPanel("Child Documents"))
4449 docPS->setCurrentPanel("Document Class");
4451 docPS->showPanel("Child Documents", true);
4452 masterChildModule->setEnabled(true);
4453 includeonlys_ = bp_.getIncludedChildren();
4454 updateIncludeonlys();
4455 updateIncludeonlyDisplay();
4457 switch (bp_.maintain_unincluded_children) {
4458 case BufferParams::CM_None:
4459 masterChildModule->maintainCRNoneRB->setChecked(true);
4461 case BufferParams::CM_Mostly:
4462 masterChildModule->maintainCRMostlyRB->setChecked(true);
4464 case BufferParams::CM_Strict:
4466 masterChildModule->maintainCRStrictRB->setChecked(true);
4471 floatModule->setPlacement(bp_.float_placement);
4472 floatModule->setAlignment(bp_.float_alignment);
4475 // break listings_params to multiple lines
4477 InsetListingsParams(bp_.listings_params).separatedParams();
4478 listingsModule->listingsED->setPlainText(toqstr(lstparams));
4479 int nn = findToken(lst_packages, bp_.use_minted ? "Minted" : "Listings");
4481 listingsModule->packageCO->setCurrentIndex(nn);
4484 // some languages only work with Polyglossia (which requires non-TeX fonts)
4485 Language const * lang = lyx::languages.getLanguage(
4486 fromqstr(langModule->languageCO->itemData(
4487 langModule->languageCO->currentIndex()).toString()));
4488 bool const need_fontspec =
4489 lang->babel().empty() && !lang->polyglossia().empty()
4490 && lang->required() != "CJK" && lang->required() != "japanese";
4491 bool const os_fonts_available =
4492 bp_.baseClass()->outputType() == lyx::LATEX
4493 && LaTeXFeatures::isAvailable("fontspec");
4494 fontModule->osFontsCB->setEnabled(os_fonts_available && !need_fontspec);
4495 fontModule->osFontsCB->setChecked(
4496 (os_fonts_available && bp_.useNonTeXFonts) || need_fontspec);
4497 updateFontsize(documentClass().opt_fontsize(),
4500 QString font = toqstr(bp_.fontsRoman());
4501 bool foundfont = fontModule->fontsRomanCO->set(font, false);
4503 fontModule->fontsRomanCO->addItemSort(font, font + qt_(" (not installed)"),
4504 qt_("Uninstalled used fonts"),
4505 qt_("This font is not installed and won't be used in output"),
4506 false, false, false, true);
4507 fontModule->fontsRomanCO->set(font);
4509 fontModule->font_roman = toqstr(bp_.fonts_roman[!bp_.useNonTeXFonts]);
4511 font = toqstr(bp_.fontsSans());
4512 foundfont = fontModule->fontsSansCO->set(font, false);
4514 fontModule->fontsSansCO->addItemSort(font, font + qt_(" (not installed)"),
4515 qt_("Uninstalled used fonts"),
4516 qt_("This font is not installed and won't be used in output"),
4517 false, false, false, true);
4518 fontModule->fontsSansCO->set(font);
4520 fontModule->font_sans = toqstr(bp_.fonts_sans[!bp_.useNonTeXFonts]);
4522 font = toqstr(bp_.fontsTypewriter());
4523 foundfont = fontModule->fontsTypewriterCO->set(font, false);
4525 fontModule->fontsTypewriterCO->addItemSort(font, font + qt_(" (not installed)"),
4526 qt_("Uninstalled used fonts"),
4527 qt_("This font is not installed and won't be used in output"),
4528 false, false, false, true);
4529 fontModule->fontsTypewriterCO->set(font);
4531 fontModule->font_typewriter = toqstr(bp_.fonts_typewriter[!bp_.useNonTeXFonts]);
4533 font = toqstr(bp_.fontsMath());
4534 int mpos = fontModule->fontsMathCO->findData(font);
4536 mpos = fontModule->fontsMathCO->count();
4537 fontModule->fontsMathCO->addItem(font + qt_(" (not installed)"), font);
4539 fontModule->fontsMathCO->setCurrentIndex(mpos);
4540 fontModule->font_math = toqstr(bp_.fonts_math[!bp_.useNonTeXFonts]);
4542 if (bp_.useNonTeXFonts && os_fonts_available) {
4543 fontModule->fontencLA->setEnabled(false);
4544 fontModule->fontencCO->setEnabled(false);
4545 fontModule->fontencLE->setEnabled(false);
4547 fontModule->fontencLA->setEnabled(true);
4548 fontModule->fontencCO->setEnabled(true);
4549 fontModule->fontencLE->setEnabled(true);
4550 romanChanged(fontModule->fontsRomanCO->currentIndex());
4551 sansChanged(fontModule->fontsSansCO->currentIndex());
4552 ttChanged(fontModule->fontsTypewriterCO->currentIndex());
4554 // Handle options enabling
4555 updateFontOptions();
4557 if (!bp_.fonts_cjk.empty())
4558 fontModule->cjkFontLE->setText(
4559 toqstr(bp_.fonts_cjk));
4561 fontModule->cjkFontLE->setText(QString());
4563 fontModule->microtypeCB->setChecked(bp_.use_microtype);
4564 fontModule->dashesCB->setChecked(!bp_.use_dash_ligatures);
4566 fontModule->fontScCB->setChecked(bp_.fonts_expert_sc);
4567 fontModule->fontOsfCB->setChecked(bp_.fonts_roman_osf);
4568 fontModule->fontSansOsfCB->setChecked(bp_.fonts_sans_osf);
4569 fontModule->fontTypewriterOsfCB->setChecked(bp_.fonts_typewriter_osf);
4570 fontModule->scaleSansSB->setValue(bp_.fontsSansScale());
4571 fontModule->font_sf_scale = bp_.fonts_sans_scale[!bp_.useNonTeXFonts];
4572 fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale());
4573 fontModule->font_tt_scale = bp_.fonts_typewriter_scale[!bp_.useNonTeXFonts];
4574 if (!bp_.font_roman_opts.empty())
4575 fontModule->fontspecRomanLE->setText(
4576 toqstr(bp_.font_roman_opts));
4578 fontModule->fontspecRomanLE->setText(QString());
4579 if (!bp_.font_sans_opts.empty())
4580 fontModule->fontspecSansLE->setText(
4581 toqstr(bp_.font_sans_opts));
4583 fontModule->fontspecSansLE->setText(QString());
4584 if (!bp_.font_typewriter_opts.empty())
4585 fontModule->fontspecTypewriterLE->setText(
4586 toqstr(bp_.font_typewriter_opts));
4588 fontModule->fontspecTypewriterLE->setText(QString());
4590 nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
4592 fontModule->fontsDefaultCO->setCurrentIndex(nn);
4594 if (bp_.fontenc == "auto" || bp_.fontenc == "default") {
4595 fontModule->fontencCO->setCurrentIndex(
4596 fontModule->fontencCO->findData(toqstr(bp_.fontenc)));
4597 fontModule->fontencLE->setEnabled(false);
4599 fontModule->fontencCO->setCurrentIndex(
4600 fontModule->fontencCO->findData("custom"));
4601 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
4604 // LaTeX input encoding
4605 // Set after fonts because non-tex fonts override "\inputencoding".
4606 inputencodingToDialog();
4609 // This must be set _after_ fonts since updateDefaultFormat()
4610 // checks osFontsCB settings.
4611 // update combobox with formats
4612 updateDefaultFormat();
4613 int index = outputModule->defaultFormatCO->findData(toqstr(
4614 bp_.default_output_format));
4615 // set to default if format is not found
4618 outputModule->defaultFormatCO->setCurrentIndex(index);
4620 outputModule->shellescapeCB->setChecked(bp_.shell_escape);
4621 outputModule->outputsyncCB->setChecked(bp_.output_sync);
4622 outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
4623 outputModule->synccustomCB->setEnabled(bp_.output_sync);
4624 outputModule->synccustomLA->setEnabled(bp_.output_sync);
4626 outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
4627 outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
4628 outputModule->strictCB->setChecked(bp_.html_be_strict);
4629 outputModule->cssCB->setChecked(bp_.html_css_as_file);
4631 outputModule->tableoutCB->setCurrentIndex(bp_.docbook_table_output);
4632 outputModule->mathmlprefixCB->setCurrentIndex(bp_.docbook_mathml_prefix);
4634 outputModule->saveTransientPropertiesCB
4635 ->setChecked(bp_.save_transient_properties);
4636 outputModule->postponeFragileCB
4637 ->setChecked(bp_.postpone_fragile_content);
4640 bool const extern_geometry =
4641 documentClass().provides("geometry");
4642 int const psize = bp_.papersize;
4643 pageLayoutModule->papersizeCO->setCurrentIndex(psize);
4644 setCustomPapersize(!extern_geometry && psize == 1);
4645 pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
4647 bool const landscape =
4648 bp_.orientation == ORIENTATION_LANDSCAPE;
4649 pageLayoutModule->landscapeRB->setChecked(landscape);
4650 pageLayoutModule->portraitRB->setChecked(!landscape);
4651 pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
4652 pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
4654 pageLayoutModule->facingPagesCB->setChecked(
4655 bp_.sides == TwoSides);
4657 lengthToWidgets(pageLayoutModule->paperwidthLE,
4658 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, default_unit);
4659 lengthToWidgets(pageLayoutModule->paperheightLE,
4660 pageLayoutModule->paperheightUnitCO, bp_.paperheight, default_unit);
4663 Ui::MarginsUi * m = marginsModule;
4665 tmp_leftmargin_ = bp_.leftmargin;
4666 tmp_topmargin_ = bp_.topmargin;
4667 tmp_rightmargin_ = bp_.rightmargin;
4668 tmp_bottommargin_ = bp_.bottommargin;
4669 tmp_headheight_ = bp_.headheight;
4670 tmp_headsep_ = bp_.headsep;
4671 tmp_footskip_ = bp_.footskip;
4672 tmp_columnsep_ = bp_.columnsep;
4674 lengthToWidgets(m->topLE, m->topUnit,
4675 bp_.topmargin, default_unit);
4676 lengthToWidgets(m->bottomLE, m->bottomUnit,
4677 bp_.bottommargin, default_unit);
4678 lengthToWidgets(m->innerLE, m->innerUnit,
4679 bp_.leftmargin, default_unit);
4680 lengthToWidgets(m->outerLE, m->outerUnit,
4681 bp_.rightmargin, default_unit);
4682 lengthToWidgets(m->headheightLE, m->headheightUnit,
4683 bp_.headheight, default_unit);
4684 lengthToWidgets(m->headsepLE, m->headsepUnit,
4685 bp_.headsep, default_unit);
4686 lengthToWidgets(m->footskipLE, m->footskipUnit,
4687 bp_.footskip, default_unit);
4688 lengthToWidgets(m->columnsepLE, m->columnsepUnit,
4689 bp_.columnsep, default_unit);
4694 updateUnknownBranches();
4695 branchesModule->update(bp_);
4698 PDFOptions const & pdf = bp_.pdfoptions();
4699 pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
4700 if (bp_.documentClass().provides("hyperref"))
4701 pdfSupportModule->use_hyperrefGB->setTitle(qt_("C&ustomize Hyperref Options"));
4703 pdfSupportModule->use_hyperrefGB->setTitle(qt_("&Use Hyperref Support"));
4704 pdfSupportModule->titleLE->setText(toqstr(pdf.title));
4705 pdfSupportModule->authorLE->setText(toqstr(pdf.author));
4706 pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
4707 pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
4709 pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
4710 pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
4711 pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
4713 pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
4714 pdfSupportModule->bookmarksopenlevelSB->setEnabled(pdf.bookmarksopen);
4715 pdfSupportModule->bookmarksopenlevelLA->setEnabled(pdf.bookmarksopen);
4717 pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
4718 pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
4719 pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
4720 pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
4722 nn = findToken(backref_opts, pdf.backref);
4724 pdfSupportModule->backrefCO->setCurrentIndex(nn);
4726 pdfSupportModule->fullscreenCB->setChecked
4727 (pdf.pagemode == pdf.pagemode_fullscreen);
4729 pdfSupportModule->optionsTE->setPlainText(
4730 toqstr(pdf.quoted_options));
4732 pdfSupportModule->metadataTE->setPlainText(
4733 toqstr(rtrim(bp_.document_metadata, "\n")));
4736 changesModule->trackChangesCB->setChecked(bp_.track_changes);
4737 changesModule->outputChangesCB->setChecked(bp_.output_changes);
4738 changesModule->changeBarsCB->setChecked(bp_.change_bars);
4739 changesModule->changeBarsCB->setEnabled(bp_.output_changes);
4741 // Make sure that the bc is in the INITIAL state
4742 if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
4745 // clear changed branches cache
4746 changedBranches_.clear();
4748 // re-initiate module filter
4749 if (!filter_->text().isEmpty())
4750 moduleFilterPressed();
4753 nonModuleChanged_ = false;
4754 shellescapeChanged_ = false;
4758 void GuiDocument::saveDocDefault()
4760 // we have to apply the params first
4766 void GuiDocument::updateAvailableModules()
4768 modules_av_model_.clear();
4769 list<modInfoStruct> modInfoList = getModuleInfo();
4770 // Sort names according to the locale
4771 modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
4772 return 0 < b.name.localeAwareCompare(a.name);
4774 QIcon user_icon(guiApp ? guiApp->getScaledPixmap("images/", "lyxfiles-user")
4775 : getPixmap("images/", "lyxfiles-user", "svgz,png"));
4776 QIcon system_icon(guiApp ? guiApp->getScaledPixmap("images/", "lyxfiles-system")
4777 : getPixmap("images/", "lyxfiles-system", "svgz,png"));
4780 catfont.setBold(true);
4782 unavbrush.setColor(Qt::gray);
4783 for (modInfoStruct const & m : modInfoList) {
4784 QStandardItem * item = new QStandardItem();
4785 QStandardItem * catItem;
4786 QString const catname = m.category;
4787 QList<QStandardItem *> fcats = modules_av_model_.findItems(catname, Qt::MatchExactly);
4789 catItem = fcats.first();
4791 catItem = new QStandardItem();
4792 catItem->setText(catname);
4793 catItem->setFont(catfont);
4794 modules_av_model_.insertRow(i, catItem);
4797 item->setEditable(false);
4798 catItem->setEditable(false);
4799 item->setData(m.name, Qt::DisplayRole);
4801 item->setForeground(unavbrush);
4802 item->setData(toqstr(m.id), Qt::UserRole);
4803 item->setData(m.description, Qt::ToolTipRole);
4805 item->setIcon(user_icon);
4807 item->setIcon(system_icon);
4808 catItem->appendRow(item);
4810 modules_av_model_.sort(0);
4814 void GuiDocument::updateSelectedModules()
4816 modules_sel_model_.clear();
4817 list<modInfoStruct> const selModList = getSelectedModules();
4819 for (modInfoStruct const & m : selModList) {
4820 modules_sel_model_.insertRow(i, m.name, m.id, m.description);
4826 void GuiDocument::updateIncludeonlyDisplay()
4828 if (includeonlys_.empty()) {
4829 masterChildModule->includeallRB->setChecked(true);
4830 masterChildModule->childrenTW->setEnabled(false);
4831 masterChildModule->maintainGB->setEnabled(false);
4833 masterChildModule->includeonlyRB->setChecked(true);
4834 masterChildModule->childrenTW->setEnabled(true);
4835 masterChildModule->maintainGB->setEnabled(true);
4840 void GuiDocument::updateIncludeonlys(bool const cleanup)
4842 masterChildModule->childrenTW->clear();
4843 QString const no = qt_("No");
4844 QString const yes = qt_("Yes");
4846 ListOfBuffers children = buffer().getChildren();
4847 ListOfBuffers::const_iterator it = children.begin();
4848 ListOfBuffers::const_iterator end = children.end();
4849 bool has_unincluded = false;
4850 bool all_unincluded = true;
4851 for (; it != end; ++it) {
4852 QTreeWidgetItem * item = new QTreeWidgetItem(masterChildModule->childrenTW);
4855 to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
4856 from_utf8(buffer().filePath())));
4857 item->setText(0, toqstr(name));
4858 item->setText(1, isChildIncluded(name) ? yes : no);
4859 if (!isChildIncluded(name))
4860 has_unincluded = true;
4862 all_unincluded = false;
4864 // Both if all children are included and if none is included
4865 // is equal to "include all" (i.e., omit \includeonly).
4866 if (cleanup && (!has_unincluded || all_unincluded))
4867 includeonlys_.clear();
4871 bool GuiDocument::isBiblatex() const
4873 QString const engine =
4874 biblioModule->citeEngineCO->itemData(
4875 biblioModule->citeEngineCO->currentIndex()).toString();
4877 // this can happen if the cite engine is unknown, which can happen
4878 // if one is using a file that came from someone else, etc. in that
4879 // case, we crash if we proceed.
4880 if (engine.isEmpty())
4883 return theCiteEnginesList[fromqstr(engine)]->getCiteFramework() == "biblatex";
4887 void GuiDocument::updateDefaultBiblio(string const & style,
4888 string const & which)
4890 QString const bibstyle = toqstr(style);
4891 biblioModule->defaultBiblioCO->clear();
4896 if (which != "cbx") {
4897 // First the bbx styles
4898 biblioModule->biblatexBbxCO->clear();
4899 QStringList str = texFileList("bbxFiles.lst");
4900 // test whether we have a valid list, otherwise run rescan
4901 if (str.isEmpty()) {
4902 rescanTexStyles("bbx");
4903 str = texFileList("bbxFiles.lst");
4905 for (int i = 0; i != str.size(); ++i)
4906 str[i] = onlyFileName(str[i]);
4907 // sort on filename only (no path)
4910 for (int i = 0; i != str.count(); ++i) {
4911 QString item = changeExtension(str[i], "");
4912 if (item == bibstyle)
4914 biblioModule->biblatexBbxCO->addItem(item);
4917 if (item_nr == -1 && !bibstyle.isEmpty()) {
4918 biblioModule->biblatexBbxCO->addItem(bibstyle);
4919 item_nr = biblioModule->biblatexBbxCO->count() - 1;
4923 biblioModule->biblatexBbxCO->setCurrentIndex(item_nr);
4925 biblioModule->biblatexBbxCO->clearEditText();
4928 if (which != "bbx") {
4929 // now the cbx styles
4930 biblioModule->biblatexCbxCO->clear();
4931 QStringList str = texFileList("cbxFiles.lst");
4932 // test whether we have a valid list, otherwise run rescan
4933 if (str.isEmpty()) {
4934 rescanTexStyles("cbx");
4935 str = texFileList("cbxFiles.lst");
4937 for (int i = 0; i != str.size(); ++i)
4938 str[i] = onlyFileName(str[i]);
4939 // sort on filename only (no path)
4942 for (int i = 0; i != str.count(); ++i) {
4943 QString item = changeExtension(str[i], "");
4944 if (item == bibstyle)
4946 biblioModule->biblatexCbxCO->addItem(item);
4949 if (item_nr == -1 && !bibstyle.isEmpty()) {
4950 biblioModule->biblatexCbxCO->addItem(bibstyle);
4951 item_nr = biblioModule->biblatexCbxCO->count() - 1;
4955 biblioModule->biblatexCbxCO->setCurrentIndex(item_nr);
4957 biblioModule->biblatexCbxCO->clearEditText();
4960 biblioModule->biblatexBbxCO->clear();
4961 biblioModule->biblatexCbxCO->clear();
4962 QStringList str = texFileList("bstFiles.lst");
4963 // test whether we have a valid list, otherwise run rescan
4964 if (str.isEmpty()) {
4965 rescanTexStyles("bst");
4966 str = texFileList("bstFiles.lst");
4968 for (int i = 0; i != str.size(); ++i)
4969 str[i] = onlyFileName(str[i]);
4970 // sort on filename only (no path)
4973 for (int i = 0; i != str.count(); ++i) {
4974 QString item = changeExtension(str[i], "");
4975 if (item == bibstyle)
4977 biblioModule->defaultBiblioCO->addItem(item);
4980 if (item_nr == -1 && !bibstyle.isEmpty()) {
4981 biblioModule->defaultBiblioCO->addItem(bibstyle);
4982 item_nr = biblioModule->defaultBiblioCO->count() - 1;
4986 biblioModule->defaultBiblioCO->setCurrentIndex(item_nr);
4988 biblioModule->defaultBiblioCO->clearEditText();
4991 updateResetDefaultBiblio();
4995 void GuiDocument::updateResetDefaultBiblio()
4997 QString const engine =
4998 biblioModule->citeEngineCO->itemData(
4999 biblioModule->citeEngineCO->currentIndex()).toString();
5000 CiteEngineType const cet =
5001 CiteEngineType(biblioModule->citeStyleCO->itemData(
5002 biblioModule->citeStyleCO->currentIndex()).toInt());
5004 string const defbib = theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet);
5006 QString const bbx = biblioModule->biblatexBbxCO->currentText();
5007 QString const cbx = biblioModule->biblatexCbxCO->currentText();
5008 biblioModule->resetCbxPB->setEnabled(defbib != fromqstr(cbx));
5009 biblioModule->resetBbxPB->setEnabled(defbib != fromqstr(bbx));
5010 biblioModule->matchBbxPB->setEnabled(bbx != cbx && !cbx.isEmpty()
5011 && biblioModule->biblatexBbxCO->findText(cbx) != -1);
5013 biblioModule->resetDefaultBiblioPB->setEnabled(
5014 defbib != fromqstr(biblioModule->defaultBiblioCO->currentText()));
5018 void GuiDocument::matchBiblatexStyles()
5020 updateDefaultBiblio(fromqstr(biblioModule->biblatexCbxCO->currentText()), "bbx");
5025 void GuiDocument::updateContents()
5027 // Nothing to do here as the document settings is not cursor dependent.
5032 void GuiDocument::useClassDefaults()
5034 if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
5035 int const ret = Alert::prompt(_("Unapplied changes"),
5036 _("Some changes in the dialog were not yet applied.\n"
5037 "If you do not apply now, they will be lost after this action."),
5038 1, 1, _("&Apply"), _("&Dismiss"));
5043 int idx = latexModule->classCO->currentIndex();
5044 string const classname = fromqstr(latexModule->classCO->getData(idx));
5045 if (!bp_.setBaseClass(classname, buffer().layoutPos())) {
5046 Alert::error(_("Error"), _("Unable to set document class."));
5049 bp_.useClassDefaults();
5055 void GuiDocument::setLayoutComboByIDString(string const & idString)
5057 if (!latexModule->classCO->set(toqstr(idString)))
5058 Alert::warning(_("Can't set layout!"),
5059 bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
5063 bool GuiDocument::isValid()
5065 bool const listings_valid = validateListingsParameters().isEmpty();
5066 bool const local_layout_valid = !localLayout->editing();
5067 bool const preamble_valid = !preambleModule->editing();
5069 docPS->markPanelValid(N_("Listings[[inset]]"), listings_valid);
5070 docPS->markPanelValid(N_("Local Layout"), local_layout_valid && localLayout->isValid());
5071 docPS->markPanelValid(N_("LaTeX Preamble"), preamble_valid);
5073 return listings_valid && local_layout_valid && preamble_valid;
5077 char const * const GuiDocument::fontfamilies[5] = {
5078 "default", "rmdefault", "sfdefault", "ttdefault", ""
5082 char const * GuiDocument::fontfamilies_gui[5] = {
5083 N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
5087 bool GuiDocument::initialiseParams(string const &)
5089 BufferView const * view = bufferview();
5091 bp_ = BufferParams();
5095 prev_buffer_filename_ = view->buffer().absFileName();
5096 bp_ = view->buffer().params();
5098 updateAvailableModules();
5099 //FIXME It'd be nice to make sure here that the selected
5100 //modules are consistent: That required modules are actually
5101 //selected, and that we don't have conflicts. If so, we could
5102 //at least pop up a warning.
5108 void GuiDocument::clearParams()
5110 bp_ = BufferParams();
5114 BufferId GuiDocument::id() const
5116 BufferView const * const view = bufferview();
5117 return view? &view->buffer() : nullptr;
5121 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
5123 return moduleNames_;
5127 list<GuiDocument::modInfoStruct> const
5128 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
5130 list<modInfoStruct> mInfo;
5131 for (string const & name : mods) {
5133 LyXModule const * const mod = theModuleList[name];
5138 m.name = toqstr(name + " (") + qt_("Not Found") + toqstr(")");
5140 m.missingreqs = true;
5148 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
5150 return makeModuleInfo(params().getModules());
5154 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
5156 return makeModuleInfo(params().baseClass()->providedModules());
5160 DocumentClass const & GuiDocument::documentClass() const
5162 return bp_.documentClass();
5166 static void dispatch_bufferparams(Dialog const & dialog,
5167 BufferParams const & bp, FuncCode lfun, Buffer const * buf)
5170 ss << "\\begin_header\n";
5171 bp.writeFile(ss, buf);
5172 ss << "\\end_header\n";
5173 dialog.dispatch(FuncRequest(lfun, ss.str()));
5177 void GuiDocument::dispatchParams()
5179 // We need a non-const buffer object.
5180 Buffer & buf = const_cast<BufferView *>(bufferview())->buffer();
5181 // There may be several undo records; group them (bug #8998)
5182 // This handles undo groups automagically
5183 UndoGroupHelper ugh(&buf);
5185 // This must come first so that a language change is correctly noticed
5188 // We need to load the master before we formally update the params,
5189 // since otherwise we run updateBuffer, etc, before the child's master
5191 if (!params().master.empty()) {
5192 FileName const master_file = support::makeAbsPath(params().master,
5193 support::onlyPath(buffer().absFileName()));
5194 if (isLyXFileName(master_file.absFileName())) {
5195 Buffer * master = checkAndLoadLyXFile(master_file, true);
5197 if (master->isChild(const_cast<Buffer *>(&buffer())))
5198 const_cast<Buffer &>(buffer()).setParent(master);
5200 Alert::warning(_("Assigned master does not include this file"),
5201 bformat(_("You must include this file in the document\n"
5202 "'%1$s' in order to use the master document\n"
5203 "feature."), from_utf8(params().master)));
5205 Alert::warning(_("Could not load master"),
5206 bformat(_("The master document '%1$s'\n"
5207 "could not be loaded."),
5208 from_utf8(params().master)));
5212 // Apply the BufferParams. Note that this will set the base class
5213 // and then update the buffer's layout.
5214 dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY, &buffer());
5216 // Generate the colours requested by each new branch.
5217 BranchList & branchlist = params().branchlist();
5218 if (!branchlist.empty()) {
5219 BranchList::const_iterator it = branchlist.begin();
5220 BranchList::const_iterator const end = branchlist.end();
5221 for (; it != end; ++it) {
5222 docstring const & current_branch = it->branch();
5223 Branch const * branch = branchlist.find(current_branch);
5224 string const bcolor = branch->color();
5226 if (bcolor.size() == 7 && bcolor[0] == '#')
5227 rgbcol = lyx::rgbFromHexName(bcolor);
5229 guiApp->getRgbColor(lcolor.getFromLyXName(bcolor), rgbcol);
5230 string const x11hexname = X11hexname(rgbcol);
5231 // display the new color
5232 docstring const str = current_branch + ' ' + from_ascii(x11hexname);
5233 dispatch(FuncRequest(LFUN_SET_COLOR, str));
5236 // rename branches in the document
5237 executeBranchRenaming();
5238 // and clear changed branches cache
5239 changedBranches_.clear();
5241 // Generate the colours requested by indices.
5242 IndicesList & indiceslist = params().indiceslist();
5243 if (!indiceslist.empty()) {
5244 IndicesList::const_iterator it = indiceslist.begin();
5245 IndicesList::const_iterator const end = indiceslist.end();
5246 for (; it != end; ++it) {
5247 docstring const & current_index = it->shortcut();
5248 Index const * index = indiceslist.findShortcut(current_index);
5249 string const x11hexname = X11hexname(index->color());
5250 // display the new color
5251 docstring const str = current_index + ' ' + from_ascii(x11hexname);
5252 dispatch(FuncRequest(LFUN_SET_COLOR, str));
5256 // If we used an LFUN, we would not need these two lines:
5257 BufferView * bv = const_cast<BufferView *>(bufferview());
5258 bv->processUpdateFlags(Update::Force | Update::FitCursor);
5262 void GuiDocument::setLanguage() const
5264 Language const * const newL = bp_.language;
5265 if (buffer().params().language == newL)
5268 string const & lang_name = newL->lang();
5269 dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
5273 void GuiDocument::saveAsDefault() const
5275 dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT, &buffer());
5279 bool GuiDocument::providesOSF(QString const & font) const
5281 if (fontModule->osFontsCB->isChecked())
5282 // FIXME: we should check if the fonts really
5283 // have OSF support. But how?
5284 return font != "default";
5285 return theLaTeXFonts().getLaTeXFont(
5286 qstring_to_ucs4(font)).providesOSF(ot1(),
5292 bool GuiDocument::providesSC(QString const & font) const
5294 if (fontModule->osFontsCB->isChecked())
5296 return theLaTeXFonts().getLaTeXFont(
5297 qstring_to_ucs4(font)).providesSC(ot1(),
5303 bool GuiDocument::providesScale(QString const & font) const
5305 if (fontModule->osFontsCB->isChecked())
5306 return font != "default";
5307 return theLaTeXFonts().getLaTeXFont(
5308 qstring_to_ucs4(font)).providesScale(ot1(),
5314 bool GuiDocument::providesExtraOpts(QString const & font) const
5316 if (fontModule->osFontsCB->isChecked())
5317 return font != "default";
5318 return theLaTeXFonts().getLaTeXFont(
5319 qstring_to_ucs4(font)).providesMoreOptions(ot1(),
5325 bool GuiDocument::providesNoMath(QString const & font) const
5327 if (fontModule->osFontsCB->isChecked())
5329 return theLaTeXFonts().getLaTeXFont(
5330 qstring_to_ucs4(font)).providesNoMath(ot1(),
5335 bool GuiDocument::hasMonolithicExpertSet(QString const & font) const
5337 if (fontModule->osFontsCB->isChecked())
5339 return theLaTeXFonts().getLaTeXFont(
5340 qstring_to_ucs4(font)).hasMonolithicExpertSet(ot1(),
5347 GuiDocument::modInfoStruct GuiDocument::modInfo(LyXModule const & mod)
5349 // FIXME Unicode: docstrings would be better for these parameters but this
5350 // change requires a lot of others
5353 QString const guiname = toqstr(translateIfPossible(from_utf8(mod.getName())));
5354 m.missingreqs = !isModuleAvailable(mod.getID());
5355 if (m.missingreqs) {
5356 m.name = qt_("%1 (missing req.)").arg(guiname);
5359 m.category = mod.category().empty() ? qt_("Miscellaneous")
5360 : toqstr(translateIfPossible(from_utf8(mod.category())));
5361 QString desc = toqstr(translateIfPossible(from_utf8(mod.getDescription())));
5362 // Find the first sentence of the description
5363 QTextBoundaryFinder bf(QTextBoundaryFinder::Sentence, desc);
5364 int pos = bf.toNextBoundary();
5367 m.local = mod.isLocal();
5368 QString const mtype = m.local ? qt_("personal module") : qt_("distributed module");
5369 QString modulename = qt_("<b>Module name:</b> <i>%1</i> (%2)").arg(toqstr(m.id)).arg(mtype);
5370 // Tooltip is the desc followed by the module name and the type
5371 m.description = QString("%1%2")
5372 .arg(desc.isEmpty() ? QString() : QString("<p>%1</p>").arg(desc),
5375 m.description += QString("<p>%1</p>").arg(qt_("<b>Note:</b> Some requirements for this module are missing!"));
5380 void GuiDocument::loadModuleInfo()
5382 moduleNames_.clear();
5383 for (LyXModule const & mod : theModuleList)
5384 moduleNames_.push_back(modInfo(mod));
5388 void GuiDocument::updateUnknownBranches()
5392 list<docstring> used_branches;
5393 buffer().getUsedBranches(used_branches);
5394 list<docstring>::const_iterator it = used_branches.begin();
5395 QStringList unknown_branches;
5396 for (; it != used_branches.end() ; ++it) {
5397 if (!buffer().params().branchlist().find(*it))
5398 unknown_branches.append(toqstr(*it));
5400 branchesModule->setUnknownBranches(unknown_branches);
5404 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
5406 map<docstring, docstring>::iterator it = changedBranches_.begin();
5407 for (; it != changedBranches_.end() ; ++it) {
5408 if (it->second == oldname) {
5409 // branch has already been renamed
5410 it->second = newname;
5415 changedBranches_[oldname] = newname;
5419 void GuiDocument::executeBranchRenaming() const
5421 map<docstring, docstring>::const_iterator it = changedBranches_.begin();
5422 for (; it != changedBranches_.end() ; ++it) {
5423 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
5424 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
5429 void GuiDocument::allPackagesAuto()
5435 void GuiDocument::allPackagesAlways()
5441 void GuiDocument::allPackagesNot()
5447 void GuiDocument::allPackages(int col)
5449 for (int row = 0; row < mathsModule->packagesTW->rowCount(); ++row) {
5451 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, col)->layout()->itemAt(0)->widget();
5452 rb->setChecked(true);
5457 void GuiDocument::linenoToggled(bool on)
5459 numberingModule->linenoLE->setEnabled(on);
5460 numberingModule->linenoLA->setEnabled(on);
5464 void GuiDocument::outputChangesToggled(bool on)
5466 changesModule->changeBarsCB->setEnabled(on);
5470 void GuiDocument::setOutputSync(bool on)
5472 outputModule->synccustomCB->setEnabled(on);
5473 outputModule->synccustomLA->setEnabled(on);
5478 bool GuiDocument::eventFilter(QObject * sender, QEvent * event)
5480 if (event->type() == QEvent::ApplicationPaletteChange) {
5481 // mode switch: colors need to be updated
5482 // and the highlighting redone
5483 if (pdf_options_highlighter_) {
5484 pdf_options_highlighter_->setupColors();
5485 pdf_options_highlighter_->rehighlight();
5487 if (pdf_metadata_highlighter_) {
5488 pdf_metadata_highlighter_->setupColors();
5489 pdf_metadata_highlighter_->rehighlight();
5492 return QWidget::eventFilter(sender, event);
5496 } // namespace frontend
5499 #include "moc_GuiDocument.cpp"