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 "LaTeXHighlighter.h"
25 #include "Validator.h"
27 #include "LayoutFile.h"
28 #include "BranchList.h"
29 #include "buffer_funcs.h"
31 #include "BufferView.h"
32 #include "CiteEnginesList.h"
34 #include "ColorCache.h"
35 #include "Converter.h"
38 #include "FloatPlacement.h"
40 #include "FuncRequest.h"
41 #include "IndicesList.h"
43 #include "LaTeXFeatures.h"
44 #include "LaTeXFonts.h"
46 #include "LayoutEnums.h"
47 #include "LayoutModuleList.h"
49 #include "ModuleList.h"
50 #include "PDFOptions.h"
51 #include "qt_helpers.h"
54 #include "TextClass.h"
58 #include "insets/InsetListingsParams.h"
59 #include "insets/InsetQuotes.h"
61 #include "support/debug.h"
62 #include "support/docstream.h"
63 #include "support/FileName.h"
64 #include "support/filetools.h"
65 #include "support/gettext.h"
66 #include "support/lassert.h"
67 #include "support/lstrings.h"
68 #include "support/Package.h"
69 #include "support/TempFile.h"
71 #include "frontends/alert.h"
73 #include <QAbstractItemModel>
74 #include <QButtonGroup>
76 #include <QColorDialog>
77 #include <QCloseEvent>
78 #include <QDirIterator>
79 #include <QFontDatabase>
80 #include <QHeaderView>
83 #include <QTextBoundaryFinder>
84 #include <QTextCursor>
90 // a style sheet for color frame widgets
91 static inline QString colorFrameStyleSheet(QColor const & bgColor)
93 if (bgColor.isValid()) {
94 QString rc = QLatin1String("background-color:");
103 using namespace lyx::support;
108 char const * const tex_graphics[] =
110 "default", "dvialw", "dvilaser", "dvipdf", "dvipdfm", "dvipdfmx",
111 "dvips", "dvipsone", "dvitops", "dviwin", "dviwindo", "dvi2ps", "emtex",
112 "ln", "oztex", "pctexhp", "pctexps", "pctexwin", "pctex32", "pdftex",
113 "psprint", "pubps", "tcidvi", "textures", "truetex", "vtex", "xdvi",
118 char const * const tex_graphics_gui[] =
120 N_("Default"), "dvialw", "DviLaser", "dvipdf", "DVIPDFM", "DVIPDFMx",
121 "Dvips", "DVIPSONE", "DVItoPS", "DVIWIN", "DVIWindo", "dvi2ps", "EmTeX",
122 "LN", "OzTeX", "pctexhp", "pctexps", "pctexwin", "PCTeX32", "pdfTeX",
123 "psprint", "pubps", "tcidvi", "Textures", "TrueTeX", "VTeX", "xdvi",
124 "XeTeX", N_("None"), ""
128 char const * backref_opts[] =
130 "false", "section", "slide", "page", ""
134 char const * backref_opts_gui[] =
136 N_("Off"), N_("Section"), N_("Slide"), N_("Page"), ""
140 char const * lst_packages[] =
142 "Listings", "Minted", ""
146 vector<string> engine_types_;
147 vector<pair<string, QString> > pagestyles;
149 QMap<QString, QString> rmfonts_;
150 QMap<QString, QString> sffonts_;
151 QMap<QString, QString> ttfonts_;
152 QMap<QString, QString> mathfonts_;
160 lyx::RGBColor set_backgroundcolor;
161 bool is_backgroundcolor;
162 lyx::RGBColor set_fontcolor;
164 lyx::RGBColor set_notefontcolor;
165 bool is_notefontcolor;
166 lyx::RGBColor set_boxbgcolor;
168 bool forced_fontspec_activation;
170 } // anonymous namespace
175 // used when sorting the textclass list.
176 class less_textclass_avail_desc
179 bool operator()(string const & lhs, string const & rhs) const
181 // Ordering criteria:
182 // 1. Availability of text class
183 // 2. Description (lexicographic)
184 LayoutFile const & tc1 = LayoutFileList::get()[lhs];
185 LayoutFile const & tc2 = LayoutFileList::get()[rhs];
186 int const order = compare_no_case(
187 translateIfPossible(from_utf8(tc1.description())),
188 translateIfPossible(from_utf8(tc2.description())));
189 return (tc1.isTeXClassAvailable() && !tc2.isTeXClassAvailable()) ||
190 (tc1.isTeXClassAvailable() == tc2.isTeXClassAvailable() && order < 0);
199 vector<string> getRequiredList(string const & modName)
201 LyXModule const * const mod = theModuleList[modName];
203 return vector<string>(); //empty such thing
204 return mod->getRequiredModules();
208 vector<string> getExcludedList(string const & modName)
210 LyXModule const * const mod = theModuleList[modName];
212 return vector<string>(); //empty such thing
213 return mod->getExcludedModules();
217 docstring getModuleCategory(string const & modName)
219 LyXModule const * const mod = theModuleList[modName];
222 return from_utf8(mod->category());
226 docstring getModuleDescription(string const & modName)
228 LyXModule const * const mod = theModuleList[modName];
230 return _("Module not found!");
232 return translateIfPossible(from_utf8(mod->getDescription()));
236 vector<string> getPackageList(string const & modName)
238 LyXModule const * const mod = theModuleList[modName];
240 return vector<string>(); //empty such thing
241 return mod->getPackageList();
245 bool isModuleAvailable(string const & modName)
247 LyXModule const * const mod = theModuleList[modName];
250 return mod->isAvailable();
253 } // anonymous namespace
256 /////////////////////////////////////////////////////////////////////
258 // ModuleSelectionManager
260 /////////////////////////////////////////////////////////////////////
262 /// SelectionManager for use with modules
263 class ModuleSelectionManager : public GuiSelectionManager
267 ModuleSelectionManager(QObject * parent,
268 QTreeView * availableLVarg,
269 QTreeView * selectedLVarg,
270 QPushButton * addPBarg,
271 QPushButton * delPBarg,
272 QPushButton * upPBarg,
273 QPushButton * downPBarg,
274 QStandardItemModel * availableModelarg,
275 GuiIdListModel * selectedModelarg,
276 GuiDocument const * container)
277 : GuiSelectionManager(parent, availableLVarg, selectedLVarg, addPBarg, delPBarg,
278 upPBarg, downPBarg, availableModelarg, selectedModelarg),
279 container_(container)
282 void updateProvidedModules(LayoutModuleList const & pm)
283 { provided_modules_ = pm.list(); }
285 void updateExcludedModules(LayoutModuleList const & em)
286 { excluded_modules_ = em.list(); }
289 void updateAddPB() override;
291 void updateUpPB() override;
293 void updateDownPB() override;
295 void updateDelPB() override;
296 /// returns availableModel as a GuiIdListModel
297 QStandardItemModel * getAvailableModel()
299 return dynamic_cast<QStandardItemModel *>(availableModel);
301 /// returns selectedModel as a GuiIdListModel
302 GuiIdListModel * getSelectedModel()
304 return dynamic_cast<GuiIdListModel *>(selectedModel);
306 /// keeps a list of the modules the text class provides
307 list<string> provided_modules_;
309 list<string> excluded_modules_;
311 GuiDocument const * container_;
314 void ModuleSelectionManager::updateAddPB()
316 int const arows = availableModel->rowCount();
317 QModelIndexList const avail_sels =
318 availableLV->selectionModel()->selectedRows(0);
320 // disable if there aren't any modules (?), if none of them is chosen
321 // in the dialog, or if the chosen one is already selected for use.
322 if (arows == 0 || avail_sels.isEmpty() || isSelected(avail_sels.first())) {
323 addPB->setEnabled(false);
327 QModelIndex const & idx = availableLV->selectionModel()->currentIndex();
332 if (getAvailableModel()->itemFromIndex(idx)->hasChildren()) {
333 // This is a category header
334 addPB->setEnabled(false);
338 string const modname = fromqstr(getAvailableModel()->data(idx, Qt::UserRole).toString());
341 container_->params().layoutModuleCanBeAdded(modname);
342 addPB->setEnabled(enable);
346 void ModuleSelectionManager::updateDownPB()
348 int const srows = selectedModel->rowCount();
350 downPB->setEnabled(false);
353 QModelIndex const & curidx = selectedLV->selectionModel()->currentIndex();
354 int const curRow = curidx.row();
355 if (curRow < 0 || curRow >= srows - 1) { // invalid or last item
356 downPB->setEnabled(false);
360 // determine whether immediately succeeding element requires this one
361 string const curmodname = getSelectedModel()->getIDString(curRow);
362 string const nextmodname = getSelectedModel()->getIDString(curRow + 1);
364 vector<string> reqs = getRequiredList(nextmodname);
366 // if it doesn't require anything....
368 downPB->setEnabled(true);
372 // Enable it if this module isn't required.
373 // FIXME This should perhaps be more flexible and check whether, even
374 // if the next one is required, there is also an earlier one that will do.
376 find(reqs.begin(), reqs.end(), curmodname) == reqs.end());
379 void ModuleSelectionManager::updateUpPB()
381 int const srows = selectedModel->rowCount();
383 upPB->setEnabled(false);
387 QModelIndex const & curIdx = selectedLV->selectionModel()->currentIndex();
388 int curRow = curIdx.row();
389 if (curRow <= 0 || curRow > srows - 1) { // first item or invalid
390 upPB->setEnabled(false);
393 string const curmodname = getSelectedModel()->getIDString(curRow);
395 // determine whether immediately preceding element is required by this one
396 vector<string> reqs = getRequiredList(curmodname);
398 // if this one doesn't require anything....
400 upPB->setEnabled(true);
405 // Enable it if the preceding module isn't required.
406 // NOTE This is less flexible than it might be. We could check whether, even
407 // if the previous one is required, there is an earlier one that would do.
408 string const premod = getSelectedModel()->getIDString(curRow - 1);
409 upPB->setEnabled(find(reqs.begin(), reqs.end(), premod) == reqs.end());
412 void ModuleSelectionManager::updateDelPB()
414 int const srows = selectedModel->rowCount();
416 deletePB->setEnabled(false);
420 QModelIndex const & curidx =
421 selectedLV->selectionModel()->currentIndex();
422 int const curRow = curidx.row();
423 if (curRow < 0 || curRow >= srows) { // invalid index?
424 deletePB->setEnabled(false);
428 string const curmodname = getSelectedModel()->getIDString(curRow);
430 // We're looking here for a reason NOT to enable the button. If we
431 // find one, we disable it and return. If we don't, we'll end up at
432 // the end of the function, and then we enable it.
433 for (int i = curRow + 1; i < srows; ++i) {
434 string const thisMod = getSelectedModel()->getIDString(i);
435 vector<string> reqs = getRequiredList(thisMod);
436 //does this one require us?
437 if (find(reqs.begin(), reqs.end(), curmodname) == reqs.end())
441 // OK, so this module requires us
442 // is there an EARLIER module that also satisfies the require?
443 // NOTE We demand that it be earlier to keep the list of modules
444 // consistent with the rule that a module must be proceeded by a
445 // required module. There would be more flexible ways to proceed,
446 // but that would be a lot more complicated, and the logic here is
447 // already complicated. (That's why I've left the debugging code.)
448 // lyxerr << "Testing " << thisMod << endl;
449 bool foundone = false;
450 for (int j = 0; j < curRow; ++j) {
451 string const mod = getSelectedModel()->getIDString(j);
452 // lyxerr << "In loop: Testing " << mod << endl;
453 // do we satisfy the require?
454 if (find(reqs.begin(), reqs.end(), mod) != reqs.end()) {
455 // lyxerr << mod << " does the trick." << endl;
460 // did we find a module to satisfy the require?
462 // lyxerr << "No matching module found." << endl;
463 deletePB->setEnabled(false);
467 // lyxerr << "All's well that ends well." << endl;
468 deletePB->setEnabled(true);
472 /////////////////////////////////////////////////////////////////////
476 /////////////////////////////////////////////////////////////////////
478 PreambleModule::PreambleModule(QWidget * parent)
479 : UiWidget<Ui::PreambleUi>(parent), current_id_(nullptr)
481 // This is not a memory leak. The object will be destroyed
483 // @ is letter in the LyX user preamble
484 (void) new LaTeXHighlighter(preambleTE->document(), true);
485 preambleTE->setFont(guiApp->typewriterSystemFont());
486 preambleTE->setWordWrapMode(QTextOption::NoWrap);
487 setFocusProxy(preambleTE);
488 // Install event filter on find line edit to capture return/enter key
489 findLE->installEventFilter(this);
490 connect(preambleTE, SIGNAL(textChanged()), this, SIGNAL(changed()));
491 connect(findLE, SIGNAL(textEdited(const QString &)), this, SLOT(checkFindButton()));
492 connect(findButtonPB, SIGNAL(clicked()), this, SLOT(findText()));
493 connect(editPB, SIGNAL(clicked()), this, SLOT(editExternal()));
494 connect(findLE, SIGNAL(returnPressed()), this, SLOT(findText()));
496 int const tabStop = 4;
497 QFontMetrics metrics(preambleTE->currentFont());
498 #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
499 // horizontalAdvance() is available starting in 5.11.0
500 // setTabStopDistance() is available starting in 5.10.0
501 preambleTE->setTabStopDistance(tabStop * metrics.horizontalAdvance(' '));
503 preambleTE->setTabStopWidth(tabStop * metrics.width(' '));
508 bool PreambleModule::eventFilter(QObject * sender, QEvent * event)
510 if (sender == findLE) {
511 if (event->type()==QEvent::KeyPress) {
512 QKeyEvent * key = static_cast<QKeyEvent *>(event);
513 if ( (key->key()==Qt::Key_Enter) || (key->key()==Qt::Key_Return) ) {
515 // Return true to filter out the event
520 return QWidget::eventFilter(sender, event);
525 void PreambleModule::checkFindButton()
527 findButtonPB->setEnabled(!findLE->text().isEmpty());
531 void PreambleModule::findText()
533 bool const found = preambleTE->find(findLE->text());
536 QTextCursor qtcur = preambleTE->textCursor();
537 qtcur.movePosition(QTextCursor::Start);
538 preambleTE->setTextCursor(qtcur);
539 preambleTE->find(findLE->text());
544 void PreambleModule::update(BufferParams const & params, BufferId id)
546 QString preamble = toqstr(params.preamble);
547 // Nothing to do if the params and preamble are unchanged.
548 if (id == current_id_
549 && preamble == preambleTE->document()->toPlainText())
552 QTextCursor cur = preambleTE->textCursor();
553 // Save the coords before switching to the new one.
554 preamble_coords_[current_id_] =
555 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
557 // Save the params address for further use.
559 preambleTE->document()->setPlainText(preamble);
560 Coords::const_iterator it = preamble_coords_.find(current_id_);
561 if (it == preamble_coords_.end())
562 // First time we open this one.
563 preamble_coords_[current_id_] = make_pair(0, 0);
565 // Restore saved coords.
566 cur = preambleTE->textCursor();
567 cur.setPosition(it->second.first);
568 preambleTE->setTextCursor(cur);
569 preambleTE->verticalScrollBar()->setValue(it->second.second);
574 void PreambleModule::apply(BufferParams & params)
576 params.preamble = qstring_to_ucs4(preambleTE->document()->toPlainText());
580 void PreambleModule::closeEvent(QCloseEvent * e)
582 // Save the coords before closing.
583 QTextCursor cur = preambleTE->textCursor();
584 preamble_coords_[current_id_] =
585 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
590 void PreambleModule::editExternal() {
595 preambleTE->setReadOnly(false);
596 FileName const tempfilename = tempfile_->name();
597 docstring const s = tempfilename.fileContents("UTF-8");
598 preambleTE->document()->setPlainText(toqstr(s));
600 editPB->setText(qt_("&Edit Externally"));
601 editPB->setIcon(QIcon());
606 string const format =
607 current_id_->params().documentClass().outputFormat();
608 string const ext = theFormats().extension(format);
609 tempfile_.reset(new TempFile("preamble_editXXXXXX." + ext));
610 FileName const tempfilename = tempfile_->name();
611 string const name = tempfilename.toFilesystemEncoding();
612 ofdocstream os(name.c_str());
613 os << qstring_to_ucs4(preambleTE->document()->toPlainText());
615 preambleTE->setReadOnly(true);
616 theFormats().edit(*current_id_, tempfilename, format);
617 editPB->setText(qt_("&End Edit"));
618 QIcon warn(guiApp ? guiApp->getScaledPixmap("images/", "emblem-shellescape-user")
619 : getPixmap("images/", "emblem-shellescape", "svgz,png"));
620 editPB->setIcon(warn);
624 /////////////////////////////////////////////////////////////////////
628 /////////////////////////////////////////////////////////////////////
631 LocalLayout::LocalLayout(QWidget * parent)
632 : UiWidget<Ui::LocalLayoutUi>(parent), current_id_(nullptr), validated_(false)
634 locallayoutTE->setFont(guiApp->typewriterSystemFont());
635 locallayoutTE->setWordWrapMode(QTextOption::NoWrap);
636 connect(locallayoutTE, SIGNAL(textChanged()), this, SLOT(textChanged()));
637 connect(validatePB, SIGNAL(clicked()), this, SLOT(validatePressed()));
638 connect(convertPB, SIGNAL(clicked()), this, SLOT(convertPressed()));
639 connect(editPB, SIGNAL(clicked()), this, SLOT(editExternal()));
640 int const tabStop = 4;
641 QFontMetrics metrics(locallayoutTE->currentFont());
642 #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
643 // horizontalAdvance() is available starting in 5.11.0
644 // setTabStopDistance() is available starting in 5.10.0
645 locallayoutTE->setTabStopDistance(tabStop * metrics.horizontalAdvance(' '));
647 locallayoutTE->setTabStopWidth(tabStop * metrics.width(' '));
652 void LocalLayout::update(BufferParams const & params, BufferId id)
654 QString layout = toqstr(params.getLocalLayout(false));
655 // Nothing to do if the params and preamble are unchanged.
656 if (id == current_id_
657 && layout == locallayoutTE->document()->toPlainText())
660 // Save the params address for further use.
662 locallayoutTE->document()->setPlainText(layout);
667 void LocalLayout::apply(BufferParams & params)
669 docstring const layout =
670 qstring_to_ucs4(locallayoutTE->document()->toPlainText());
671 params.setLocalLayout(layout, false);
675 void LocalLayout::hideConvert()
677 convertPB->setEnabled(false);
678 convertLB->setText("");
684 void LocalLayout::textChanged()
686 validLB->setText("");
687 string const layout =
688 fromqstr(locallayoutTE->document()->toPlainText().trimmed());
690 if (layout.empty()) {
692 validatePB->setEnabled(false);
695 } else if (!validatePB->isEnabled()) {
696 // if that's already enabled, we shouldn't need to do anything.
698 validatePB->setEnabled(true);
705 void LocalLayout::convert() {
706 string const layout =
707 fromqstr(locallayoutTE->document()->toPlainText().trimmed());
708 string const newlayout = TextClass::convert(layout);
709 if (!newlayout.empty())
710 locallayoutTE->setPlainText(toqstr(newlayout));
715 void LocalLayout::convertPressed() {
722 void LocalLayout::validate() {
724 static const QString vpar("<p style=\"font-weight: bold; text-align:left\">%1</p>");
725 // Flashy red bold text
726 static const QString ivpar("<p style=\"color: #c00000; font-weight: bold; text-align:left\">"
728 string const layout =
729 fromqstr(locallayoutTE->document()->toPlainText().trimmed());
730 if (!layout.empty()) {
731 TextClass::ReturnValues const ret = TextClass::validate(layout);
732 validated_ = (ret == TextClass::OK) || (ret == TextClass::OK_OLDFORMAT);
733 validatePB->setEnabled(false);
734 validLB->setText(validated_ ? vpar.arg(qt_("Layout is valid!"))
735 : ivpar.arg(qt_("Layout is invalid!")));
736 if (ret == TextClass::OK_OLDFORMAT) {
738 // Testing conversion to LYXFILE_LAYOUT_FORMAT at this point
740 if (TextClass::convert(layout).empty()) {
741 // Conversion failed. If LAYOUT_FORMAT > LYXFILE_LAYOUT_FORMAT,
742 // then maybe the layout is still valid, but its format is more
743 // recent than LYXFILE_LAYOUT_FORMAT. However, if LAYOUT_FORMAT
744 // == LYXFILE_LAYOUT_FORMAT then something is definitely wrong.
745 convertPB->setEnabled(false);
746 const QString text = (LAYOUT_FORMAT == LYXFILE_LAYOUT_FORMAT)
747 ? ivpar.arg(qt_("Conversion to current format impossible!"))
748 : vpar.arg(qt_("Conversion to current stable format "
750 convertLB->setText(text);
752 convertPB->setEnabled(true);
753 convertLB->setText(qt_("Convert to current format"));
764 void LocalLayout::validatePressed() {
770 void LocalLayout::editExternal() {
775 locallayoutTE->setReadOnly(false);
776 FileName const tempfilename = tempfile_->name();
777 docstring const s = tempfilename.fileContents("UTF-8");
778 locallayoutTE->document()->setPlainText(toqstr(s));
780 editPB->setText(qt_("&Edit Externally"));
781 editPB->setIcon(QIcon());
786 string const format =
787 current_id_->params().documentClass().outputFormat();
788 string const ext = theFormats().extension(format);
789 tempfile_.reset(new TempFile("preamble_editXXXXXX." + ext));
790 FileName const tempfilename = tempfile_->name();
791 string const name = tempfilename.toFilesystemEncoding();
792 ofdocstream os(name.c_str());
793 os << qstring_to_ucs4(locallayoutTE->document()->toPlainText());
795 locallayoutTE->setReadOnly(true);
796 theFormats().edit(*current_id_, tempfilename, format);
797 editPB->setText(qt_("&End Edit"));
798 QIcon warn(guiApp ? guiApp->getScaledPixmap("images/", "emblem-shellescape-user")
799 : getPixmap("images/", "emblem-shellescape", "svgz,png"));
800 editPB->setIcon(warn);
801 validatePB->setEnabled(false);
806 /////////////////////////////////////////////////////////////////////
810 /////////////////////////////////////////////////////////////////////
813 GuiDocument::GuiDocument(GuiView & lv)
814 : GuiDialog(lv, "document", qt_("Document Settings")),
815 biblioChanged_(false), nonModuleChanged_(false),
816 modulesChanged_(false), shellescapeChanged_(false),
817 switchback_(false), prompted_(false)
821 connect(buttonBox, SIGNAL(clicked(QAbstractButton *)),
822 this, SLOT(slotButtonBox(QAbstractButton *)));
824 connect(savePB, SIGNAL(clicked()), this, SLOT(saveDefaultClicked()));
825 connect(defaultPB, SIGNAL(clicked()), this, SLOT(useDefaultsClicked()));
827 // Manage the restore, ok, apply, restore and cancel/close buttons
828 bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
829 bc().setOK(buttonBox->button(QDialogButtonBox::Ok));
830 bc().setApply(buttonBox->button(QDialogButtonBox::Apply));
831 bc().setCancel(buttonBox->button(QDialogButtonBox::Cancel));
832 bc().setRestore(buttonBox->button(QDialogButtonBox::Reset));
836 textLayoutModule = new UiWidget<Ui::TextLayoutUi>(this);
837 connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
838 this, SLOT(change_adaptor()));
839 connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
840 this, SLOT(setLSpacing(int)));
841 connect(textLayoutModule->lspacingLE, SIGNAL(textChanged(const QString &)),
842 this, SLOT(change_adaptor()));
844 connect(textLayoutModule->indentRB, SIGNAL(clicked()),
845 this, SLOT(change_adaptor()));
846 connect(textLayoutModule->indentRB, SIGNAL(toggled(bool)),
847 textLayoutModule->indentCO, SLOT(setEnabled(bool)));
848 connect(textLayoutModule->indentCO, SIGNAL(activated(int)),
849 this, SLOT(change_adaptor()));
850 connect(textLayoutModule->indentCO, SIGNAL(activated(int)),
851 this, SLOT(setIndent(int)));
852 connect(textLayoutModule->indentLE, SIGNAL(textChanged(const QString &)),
853 this, SLOT(change_adaptor()));
854 connect(textLayoutModule->indentLengthCO, SIGNAL(activated(int)),
855 this, SLOT(change_adaptor()));
857 connect(textLayoutModule->skipRB, SIGNAL(clicked()),
858 this, SLOT(change_adaptor()));
859 connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
860 textLayoutModule->skipCO, SLOT(setEnabled(bool)));
861 connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
862 this, SLOT(change_adaptor()));
863 connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
864 this, SLOT(setSkip(int)));
865 connect(textLayoutModule->skipLE, SIGNAL(textChanged(const QString &)),
866 this, SLOT(change_adaptor()));
867 connect(textLayoutModule->skipLengthCO, SIGNAL(activated(int)),
868 this, SLOT(change_adaptor()));
870 connect(textLayoutModule->indentRB, SIGNAL(toggled(bool)),
871 this, SLOT(enableIndent(bool)));
872 connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
873 this, SLOT(enableSkip(bool)));
875 connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
876 this, SLOT(change_adaptor()));
877 connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
878 this, SLOT(setColSep()));
879 connect(textLayoutModule->justCB, SIGNAL(clicked()),
880 this, SLOT(change_adaptor()));
882 connect(textLayoutModule->tableStyleCO, SIGNAL(activated(int)),
883 this, SLOT(change_adaptor()));
885 textLayoutModule->lspacingLE->setValidator(new QDoubleValidator(
886 textLayoutModule->lspacingLE));
887 textLayoutModule->indentLE->setValidator(new LengthValidator(
888 textLayoutModule->indentLE, false));
889 textLayoutModule->skipLE->setValidator(new LengthValidator(
890 textLayoutModule->skipLE, false));
892 textLayoutModule->indentCO->addItem(qt_("Default"), toqstr("default"));
893 textLayoutModule->indentCO->addItem(qt_("Custom"), toqstr("custom"));
894 textLayoutModule->skipCO->addItem(qt_("Half line height"), VSpace::HALFLINE);
895 textLayoutModule->skipCO->addItem(qt_("Line height"), VSpace::FULLLINE);
896 textLayoutModule->skipCO->addItem(qt_("Small Skip"), VSpace::SMALLSKIP);
897 textLayoutModule->skipCO->addItem(qt_("Medium Skip"), VSpace::MEDSKIP);
898 textLayoutModule->skipCO->addItem(qt_("Big Skip"), VSpace::BIGSKIP);
899 textLayoutModule->skipCO->addItem(qt_("Custom"), VSpace::LENGTH);
900 textLayoutModule->lspacingCO->insertItem(
901 Spacing::Single, qt_("Single"));
902 textLayoutModule->lspacingCO->insertItem(
903 Spacing::Onehalf, qt_("OneHalf"));
904 textLayoutModule->lspacingCO->insertItem(
905 Spacing::Double, qt_("Double"));
906 textLayoutModule->lspacingCO->insertItem(
907 Spacing::Other, qt_("Custom"));
908 // initialize the length validator
909 bc().addCheckedLineEdit(textLayoutModule->indentLE, textLayoutModule->indentRB);
910 bc().addCheckedLineEditPanel(textLayoutModule->indentLE, docPS, N_("Text Layout"));
911 bc().addCheckedLineEdit(textLayoutModule->skipLE, textLayoutModule->skipRB);
912 bc().addCheckedLineEditPanel(textLayoutModule->skipLE, docPS, N_("Text Layout"));
914 textLayoutModule->tableStyleCO->addItem(qt_("Default"), toqstr("default"));
918 // master/child handling
919 masterChildModule = new UiWidget<Ui::MasterChildUi>(this);
921 connect(masterChildModule->childrenTW, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),
922 this, SLOT(includeonlyClicked(QTreeWidgetItem *, int)));
923 connect(masterChildModule->includeonlyRB, SIGNAL(toggled(bool)),
924 masterChildModule->childrenTW, SLOT(setEnabled(bool)));
925 connect(masterChildModule->includeonlyRB, SIGNAL(toggled(bool)),
926 masterChildModule->maintainGB, SLOT(setEnabled(bool)));
927 connect(masterChildModule->includeallRB, SIGNAL(clicked()),
928 this, SLOT(change_adaptor()));
929 connect(masterChildModule->includeonlyRB, SIGNAL(clicked()),
930 this, SLOT(change_adaptor()));
931 connect(masterChildModule->maintainCRNoneRB, SIGNAL(clicked()),
932 this, SLOT(change_adaptor()));
933 connect(masterChildModule->maintainCRMostlyRB, SIGNAL(clicked()),
934 this, SLOT(change_adaptor()));
935 connect(masterChildModule->maintainCRStrictRB, SIGNAL(clicked()),
936 this, SLOT(change_adaptor()));
937 masterChildModule->childrenTW->setColumnCount(2);
938 masterChildModule->childrenTW->headerItem()->setText(0, qt_("Child Document"));
939 masterChildModule->childrenTW->headerItem()->setText(1, qt_("Include to Output"));
940 masterChildModule->childrenTW->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
941 masterChildModule->childrenTW->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
944 outputModule = new UiWidget<Ui::OutputUi>(this);
946 connect(outputModule->defaultFormatCO, SIGNAL(activated(int)),
947 this, SLOT(change_adaptor()));
948 connect(outputModule->mathimgSB, SIGNAL(valueChanged(double)),
949 this, SLOT(change_adaptor()));
950 connect(outputModule->strictCB, SIGNAL(stateChanged(int)),
951 this, SLOT(change_adaptor()));
952 connect(outputModule->cssCB, SIGNAL(stateChanged(int)),
953 this, SLOT(change_adaptor()));
954 connect(outputModule->mathoutCB, SIGNAL(currentIndexChanged(int)),
955 this, SLOT(change_adaptor()));
956 connect(outputModule->tableoutCB, SIGNAL(currentIndexChanged(int)),
957 this, SLOT(change_adaptor()));
958 connect(outputModule->mathmlprefixCB, SIGNAL(currentIndexChanged(int)),
959 this, SLOT(change_adaptor()));
961 connect(outputModule->shellescapeCB, SIGNAL(stateChanged(int)),
962 this, SLOT(shellescapeChanged()));
963 connect(outputModule->outputsyncCB, SIGNAL(toggled(bool)),
964 this, SLOT(setOutputSync(bool)));
965 connect(outputModule->synccustomCB, SIGNAL(editTextChanged(QString)),
966 this, SLOT(change_adaptor()));
967 outputModule->synccustomCB->addItem("");
968 outputModule->synccustomCB->addItem("\\synctex=1");
969 outputModule->synccustomCB->addItem("\\synctex=-1");
970 outputModule->synccustomCB->addItem("\\usepackage[active]{srcltx}");
972 outputModule->synccustomCB->lineEdit()->setValidator(new NoNewLineValidator(
973 outputModule->synccustomCB));
975 connect(outputModule->saveTransientPropertiesCB, SIGNAL(clicked()),
976 this, SLOT(change_adaptor()));
977 connect(outputModule->postponeFragileCB, SIGNAL(clicked()),
978 this, SLOT(change_adaptor()));
982 // this must precede font, since fonts depend on this
983 langModule = new UiWidget<Ui::LanguageUi>(this);
984 connect(langModule->languageCO, SIGNAL(activated(int)),
985 this, SLOT(change_adaptor()));
986 connect(langModule->languageCO, SIGNAL(activated(int)),
987 this, SLOT(languageChanged(int)));
988 connect(langModule->encodingCO, SIGNAL(activated(int)),
989 this, SLOT(change_adaptor()));
990 connect(langModule->encodingCO, SIGNAL(activated(int)),
991 this, SLOT(encodingSwitched(int)));
992 connect(langModule->unicodeEncodingCO, SIGNAL(activated(int)),
993 this, SLOT(change_adaptor()));
994 connect(langModule->autoEncodingCO, SIGNAL(activated(int)),
995 this, SLOT(change_adaptor()));
996 connect(langModule->customEncodingCO, SIGNAL(activated(int)),
997 this, SLOT(change_adaptor()));
998 connect(langModule->quoteStyleCO, SIGNAL(activated(int)),
999 this, SLOT(change_adaptor()));
1000 connect(langModule->languagePackageCO, SIGNAL(activated(int)),
1001 this, SLOT(change_adaptor()));
1002 connect(langModule->languagePackageLE, SIGNAL(textChanged(QString)),
1003 this, SLOT(change_adaptor()));
1004 connect(langModule->languagePackageCO, SIGNAL(currentIndexChanged(int)),
1005 this, SLOT(languagePackageChanged(int)));
1006 connect(langModule->dynamicQuotesCB, SIGNAL(clicked()),
1007 this, SLOT(change_adaptor()));
1009 langModule->languagePackageLE->setValidator(new NoNewLineValidator(
1010 langModule->languagePackageLE));
1012 QAbstractItemModel * language_model = guiApp->languageModel();
1013 // FIXME: it would be nice if sorting was enabled/disabled via a checkbox.
1014 language_model->sort(0);
1015 langModule->languageCO->setModel(language_model);
1016 langModule->languageCO->setModelColumn(0);
1018 langModule->encodingCO->addItem(qt_("Unicode (utf8)"));
1019 langModule->encodingCO->addItem(qt_("Traditional (auto-selected)"));
1020 langModule->encodingCO->addItem(qt_("Custom"));
1021 langModule->encodingCO->setItemData(EncodingSets::unicode,
1022 qt_("Select Unicode (utf8) encoding."), Qt::ToolTipRole);
1023 langModule->encodingCO->setItemData(EncodingSets::legacy,
1024 qt_("Use language-dependent traditional encodings."), Qt::ToolTipRole);
1025 langModule->encodingCO->setItemData(EncodingSets::custom,
1026 qt_("Select a custom, document-wide encoding."), Qt::ToolTipRole);
1028 // basic Unicode encodings: keep order
1029 const QStringList utf8_base_encodings = {"utf8", "utf8-plain", "utf8x"};
1030 for (auto const & i : utf8_base_encodings) {
1031 langModule->unicodeEncodingCO->addItem(
1032 qt_(encodings.fromLyXName(fromqstr(i))->guiName()), i);
1034 langModule->unicodeEncodingCO->setItemData(0,
1035 qt_("Standard Unicode support by the ``inputenc'' package."),
1037 langModule->unicodeEncodingCO->setItemData(1,
1038 qt_("Use UTF-8 'as-is': do not load any supporting packages, "
1039 "do not convert any characters to LaTeX macros. "
1040 "For use with non-TeX fonts (XeTeX/LuaTeX) or custom preamble code."),
1042 langModule->unicodeEncodingCO->setItemData(2,
1043 qt_("Load ``inputenc'' with option 'utf8x' "
1044 "for extended Unicode support by the ``ucs'' package."),
1046 langModule->autoEncodingCO->addItem(qt_("Language Default"), toqstr("auto-legacy"));
1047 langModule->autoEncodingCO->addItem(qt_("Language Default (no inputenc)"), toqstr("auto-legacy-plain"));
1048 langModule->autoEncodingCO->setItemData(0,
1049 qt_("Use the traditional default encoding of the text language. Switch encoding "
1050 "if a text part is set to a language with different default."),
1052 langModule->autoEncodingCO->setItemData(1,
1053 qt_("Do not load the 'inputenc' package. Switch encoding if required "
1054 "but do not write input encoding switch commands to the source."),
1057 QMap<QString,QString> encodingmap;
1058 QMap<QString,QString> encodingmap_utf8;
1059 for (auto const & encvar : encodings) {
1060 if (encvar.unsafe() ||encvar.guiName().empty()
1061 || utf8_base_encodings.contains(toqstr(encvar.name())))
1063 if (encvar.name().find("utf8") == 0)
1064 encodingmap_utf8.insert(qt_(encvar.guiName()), toqstr(encvar.name()));
1066 encodingmap.insert(qt_(encvar.guiName()), toqstr(encvar.name()));
1068 for (auto const & i : encodingmap_utf8.keys()) {
1069 langModule->unicodeEncodingCO->addItem(i, encodingmap_utf8.value(i));
1071 for (auto const & i : encodingmap.keys()) {
1072 langModule->customEncodingCO->addItem(i, encodingmap.value(i));
1074 // equalise the width of encoding selectors
1075 langModule->autoEncodingCO->setMinimumSize(
1076 langModule->unicodeEncodingCO->minimumSizeHint());
1077 langModule->customEncodingCO->setMinimumSize(
1078 langModule->unicodeEncodingCO->minimumSizeHint());
1080 langModule->languagePackageCO->addItem(
1081 qt_("Default"), toqstr("default"));
1082 langModule->languagePackageCO->addItem(
1083 qt_("Automatic"), toqstr("auto"));
1084 langModule->languagePackageCO->addItem(
1085 qt_("Always Babel"), toqstr("babel"));
1086 langModule->languagePackageCO->addItem(
1087 qt_("Custom"), toqstr("custom"));
1088 langModule->languagePackageCO->addItem(
1089 qt_("None[[language package]]"), toqstr("none"));
1093 fontModule = new FontModule(this);
1094 connect(fontModule->osFontsCB, SIGNAL(clicked()),
1095 this, SLOT(change_adaptor()));
1096 connect(fontModule->osFontsCB, SIGNAL(toggled(bool)),
1097 this, SLOT(osFontsChanged(bool)));
1098 connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
1099 this, SLOT(change_adaptor()));
1100 connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
1101 this, SLOT(romanChanged(int)));
1102 connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
1103 this, SLOT(change_adaptor()));
1104 connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
1105 this, SLOT(sansChanged(int)));
1106 connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
1107 this, SLOT(change_adaptor()));
1108 connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
1109 this, SLOT(ttChanged(int)));
1110 connect(fontModule->fontsMathCO, SIGNAL(activated(int)),
1111 this, SLOT(change_adaptor()));
1112 connect(fontModule->fontsMathCO, SIGNAL(activated(int)),
1113 this, SLOT(mathFontChanged(int)));
1114 connect(fontModule->fontsDefaultCO, SIGNAL(activated(int)),
1115 this, SLOT(change_adaptor()));
1116 connect(fontModule->fontencCO, SIGNAL(activated(int)),
1117 this, SLOT(change_adaptor()));
1118 connect(fontModule->fontencCO, SIGNAL(activated(int)),
1119 this, SLOT(fontencChanged(int)));
1120 connect(fontModule->fontencLE, SIGNAL(textChanged(const QString &)),
1121 this, SLOT(change_adaptor()));
1122 connect(fontModule->fontsizeCO, SIGNAL(activated(int)),
1123 this, SLOT(change_adaptor()));
1124 connect(fontModule->cjkFontLE, SIGNAL(textChanged(const QString &)),
1125 this, SLOT(change_adaptor()));
1126 connect(fontModule->microtypeCB, SIGNAL(clicked()),
1127 this, SLOT(change_adaptor()));
1128 connect(fontModule->dashesCB, SIGNAL(clicked()),
1129 this, SLOT(change_adaptor()));
1130 connect(fontModule->scaleSansSB, SIGNAL(valueChanged(int)),
1131 this, SLOT(change_adaptor()));
1132 connect(fontModule->scaleTypewriterSB, SIGNAL(valueChanged(int)),
1133 this, SLOT(change_adaptor()));
1134 connect(fontModule->fontScCB, SIGNAL(clicked()),
1135 this, SLOT(change_adaptor()));
1136 connect(fontModule->fontScCB, SIGNAL(toggled(bool)),
1137 this, SLOT(fontScToggled(bool)));
1138 connect(fontModule->fontOsfCB, SIGNAL(clicked()),
1139 this, SLOT(change_adaptor()));
1140 connect(fontModule->fontOsfCB, SIGNAL(toggled(bool)),
1141 this, SLOT(fontOsfToggled(bool)));
1142 connect(fontModule->fontSansOsfCB, SIGNAL(clicked()),
1143 this, SLOT(change_adaptor()));
1144 connect(fontModule->fontTypewriterOsfCB, SIGNAL(clicked()),
1145 this, SLOT(change_adaptor()));
1146 connect(fontModule->fontspecRomanLE, SIGNAL(textChanged(const QString &)),
1147 this, SLOT(change_adaptor()));
1148 connect(fontModule->fontspecSansLE, SIGNAL(textChanged(const QString &)),
1149 this, SLOT(change_adaptor()));
1150 connect(fontModule->fontspecTypewriterLE, SIGNAL(textChanged(const QString &)),
1151 this, SLOT(change_adaptor()));
1153 fontModule->fontencLE->setValidator(new NoNewLineValidator(
1154 fontModule->fontencLE));
1155 fontModule->cjkFontLE->setValidator(new NoNewLineValidator(
1156 fontModule->cjkFontLE));
1157 fontModule->fontspecRomanLE->setValidator(new NoNewLineValidator(
1158 fontModule->fontspecRomanLE));
1159 fontModule->fontspecSansLE->setValidator(new NoNewLineValidator(
1160 fontModule->fontspecSansLE));
1161 fontModule->fontspecTypewriterLE->setValidator(new NoNewLineValidator(
1162 fontModule->fontspecTypewriterLE));
1166 fontModule->fontsizeCO->addItem(qt_("Default"));
1167 fontModule->fontsizeCO->addItem(qt_("10"));
1168 fontModule->fontsizeCO->addItem(qt_("11"));
1169 fontModule->fontsizeCO->addItem(qt_("12"));
1171 fontModule->fontencCO->addItem(qt_("Automatic[[encoding]]"), QString("auto"));
1172 fontModule->fontencCO->addItem(qt_("Class Default"), QString("default"));
1173 fontModule->fontencCO->addItem(qt_("Custom"), QString("custom"));
1175 for (int n = 0; GuiDocument::fontfamilies_gui[n][0]; ++n)
1176 fontModule->fontsDefaultCO->addItem(
1177 qt_(GuiDocument::fontfamilies_gui[n]));
1179 if (!LaTeXFeatures::isAvailable("fontspec"))
1180 fontModule->osFontsCB->setToolTip(
1181 qt_("Use OpenType and TrueType fonts directly (requires XeTeX or LuaTeX)\n"
1182 "You need to install the package \"fontspec\" to use this feature"));
1186 pageLayoutModule = new UiWidget<Ui::PageLayoutUi>(this);
1187 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
1188 this, SLOT(papersizeChanged(int)));
1189 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
1190 this, SLOT(papersizeChanged(int)));
1191 connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
1192 this, SLOT(change_adaptor()));
1193 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
1194 this, SLOT(change_adaptor()));
1195 connect(pageLayoutModule->paperheightLE, SIGNAL(textChanged(const QString &)),
1196 this, SLOT(change_adaptor()));
1197 connect(pageLayoutModule->paperwidthLE, SIGNAL(textChanged(const QString &)),
1198 this, SLOT(change_adaptor()));
1199 connect(pageLayoutModule->paperwidthUnitCO, SIGNAL(activated(int)),
1200 this, SLOT(change_adaptor()));
1201 connect(pageLayoutModule->paperheightUnitCO, SIGNAL(activated(int)),
1202 this, SLOT(change_adaptor()));
1203 connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
1204 this, SLOT(change_adaptor()));
1205 connect(pageLayoutModule->landscapeRB, SIGNAL(clicked()),
1206 this, SLOT(change_adaptor()));
1207 connect(pageLayoutModule->facingPagesCB, SIGNAL(clicked()),
1208 this, SLOT(change_adaptor()));
1209 connect(pageLayoutModule->pagestyleCO, SIGNAL(activated(int)),
1210 this, SLOT(change_adaptor()));
1212 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1213 pageLayoutModule->pagestyleCO->addItem(qt_("empty"));
1214 pageLayoutModule->pagestyleCO->addItem(qt_("plain"));
1215 pageLayoutModule->pagestyleCO->addItem(qt_("headings"));
1216 pageLayoutModule->pagestyleCO->addItem(qt_("fancy"));
1217 bc().addCheckedLineEdit(pageLayoutModule->paperheightLE,
1218 pageLayoutModule->paperheightL);
1219 bc().addCheckedLineEditPanel(pageLayoutModule->paperheightLE, docPS, N_("Page Layout"));
1220 bc().addCheckedLineEdit(pageLayoutModule->paperwidthLE,
1221 pageLayoutModule->paperwidthL);
1222 bc().addCheckedLineEditPanel(pageLayoutModule->paperwidthLE, docPS, N_("Page Layout"));
1224 QComboBox * cb = pageLayoutModule->papersizeCO;
1225 cb->addItem(qt_("Default"));
1226 cb->addItem(qt_("Custom"));
1227 cb->addItem(qt_("US letter"));
1228 cb->addItem(qt_("US legal"));
1229 cb->addItem(qt_("US executive"));
1230 cb->addItem(qt_("A0"));
1231 cb->addItem(qt_("A1"));
1232 cb->addItem(qt_("A2"));
1233 cb->addItem(qt_("A3"));
1234 cb->addItem(qt_("A4"));
1235 cb->addItem(qt_("A5"));
1236 cb->addItem(qt_("A6"));
1237 cb->addItem(qt_("B0"));
1238 cb->addItem(qt_("B1"));
1239 cb->addItem(qt_("B2"));
1240 cb->addItem(qt_("B3"));
1241 cb->addItem(qt_("B4"));
1242 cb->addItem(qt_("B5"));
1243 cb->addItem(qt_("B6"));
1244 cb->addItem(qt_("C0"));
1245 cb->addItem(qt_("C1"));
1246 cb->addItem(qt_("C2"));
1247 cb->addItem(qt_("C3"));
1248 cb->addItem(qt_("C4"));
1249 cb->addItem(qt_("C5"));
1250 cb->addItem(qt_("C6"));
1251 cb->addItem(qt_("JIS B0"));
1252 cb->addItem(qt_("JIS B1"));
1253 cb->addItem(qt_("JIS B2"));
1254 cb->addItem(qt_("JIS B3"));
1255 cb->addItem(qt_("JIS B4"));
1256 cb->addItem(qt_("JIS B5"));
1257 cb->addItem(qt_("JIS B6"));
1258 // remove the %-items from the unit choice
1259 pageLayoutModule->paperwidthUnitCO->noPercents();
1260 pageLayoutModule->paperheightUnitCO->noPercents();
1261 pageLayoutModule->paperheightLE->setValidator(unsignedLengthValidator(
1262 pageLayoutModule->paperheightLE));
1263 pageLayoutModule->paperwidthLE->setValidator(unsignedLengthValidator(
1264 pageLayoutModule->paperwidthLE));
1268 marginsModule = new UiWidget<Ui::MarginsUi>(this);
1269 connect(marginsModule->marginCB, SIGNAL(toggled(bool)),
1270 this, SLOT(setCustomMargins(bool)));
1271 connect(marginsModule->marginCB, SIGNAL(clicked()),
1272 this, SLOT(change_adaptor()));
1273 connect(marginsModule->topLE, SIGNAL(textChanged(QString)),
1274 this, SLOT(change_adaptor()));
1275 connect(marginsModule->topUnit, SIGNAL(activated(int)),
1276 this, SLOT(change_adaptor()));
1277 connect(marginsModule->bottomLE, SIGNAL(textChanged(QString)),
1278 this, SLOT(change_adaptor()));
1279 connect(marginsModule->bottomUnit, SIGNAL(activated(int)),
1280 this, SLOT(change_adaptor()));
1281 connect(marginsModule->innerLE, SIGNAL(textChanged(QString)),
1282 this, SLOT(change_adaptor()));
1283 connect(marginsModule->innerUnit, SIGNAL(activated(int)),
1284 this, SLOT(change_adaptor()));
1285 connect(marginsModule->outerLE, SIGNAL(textChanged(QString)),
1286 this, SLOT(change_adaptor()));
1287 connect(marginsModule->outerUnit, SIGNAL(activated(int)),
1288 this, SLOT(change_adaptor()));
1289 connect(marginsModule->headheightLE, SIGNAL(textChanged(QString)),
1290 this, SLOT(change_adaptor()));
1291 connect(marginsModule->headheightUnit, SIGNAL(activated(int)),
1292 this, SLOT(change_adaptor()));
1293 connect(marginsModule->headsepLE, SIGNAL(textChanged(QString)),
1294 this, SLOT(change_adaptor()));
1295 connect(marginsModule->headsepUnit, SIGNAL(activated(int)),
1296 this, SLOT(change_adaptor()));
1297 connect(marginsModule->footskipLE, SIGNAL(textChanged(QString)),
1298 this, SLOT(change_adaptor()));
1299 connect(marginsModule->footskipUnit, SIGNAL(activated(int)),
1300 this, SLOT(change_adaptor()));
1301 connect(marginsModule->columnsepLE, SIGNAL(textChanged(QString)),
1302 this, SLOT(change_adaptor()));
1303 connect(marginsModule->columnsepUnit, SIGNAL(activated(int)),
1304 this, SLOT(change_adaptor()));
1305 marginsModule->topLE->setValidator(new LengthValidator(
1306 marginsModule->topLE));
1307 marginsModule->bottomLE->setValidator(new LengthValidator(
1308 marginsModule->bottomLE));
1309 marginsModule->innerLE->setValidator(new LengthValidator(
1310 marginsModule->innerLE));
1311 marginsModule->outerLE->setValidator(new LengthValidator(
1312 marginsModule->outerLE));
1313 marginsModule->headsepLE->setValidator(new LengthValidator(
1314 marginsModule->headsepLE));
1315 marginsModule->headheightLE->setValidator(new LengthValidator(
1316 marginsModule->headheightLE));
1317 marginsModule->footskipLE->setValidator(new LengthValidator(
1318 marginsModule->footskipLE));
1319 marginsModule->columnsepLE->setValidator(new LengthValidator(
1320 marginsModule->columnsepLE));
1322 bc().addCheckedLineEdit(marginsModule->topLE,
1323 marginsModule->topL);
1324 bc().addCheckedLineEditPanel(marginsModule->topLE,
1325 docPS, N_("Page Margins"));
1326 bc().addCheckedLineEdit(marginsModule->bottomLE,
1327 marginsModule->bottomL);
1328 bc().addCheckedLineEditPanel(marginsModule->bottomLE,
1329 docPS, N_("Page Margins"));
1330 bc().addCheckedLineEdit(marginsModule->innerLE,
1331 marginsModule->innerL);
1332 bc().addCheckedLineEditPanel(marginsModule->innerLE,
1333 docPS, N_("Page Margins"));
1334 bc().addCheckedLineEdit(marginsModule->outerLE,
1335 marginsModule->outerL);
1336 bc().addCheckedLineEditPanel(marginsModule->outerLE,
1337 docPS, N_("Page Margins"));
1338 bc().addCheckedLineEdit(marginsModule->headsepLE,
1339 marginsModule->headsepL);
1340 bc().addCheckedLineEditPanel(marginsModule->headsepLE,
1341 docPS, N_("Page Margins"));
1342 bc().addCheckedLineEdit(marginsModule->headheightLE,
1343 marginsModule->headheightL);
1344 bc().addCheckedLineEditPanel(marginsModule->headheightLE,
1345 docPS, N_("Page Margins"));
1346 bc().addCheckedLineEdit(marginsModule->footskipLE,
1347 marginsModule->footskipL);
1348 bc().addCheckedLineEditPanel(marginsModule->footskipLE,
1349 docPS, N_("Page Margins"));
1350 bc().addCheckedLineEdit(marginsModule->columnsepLE,
1351 marginsModule->columnsepL);
1352 bc().addCheckedLineEditPanel(marginsModule->columnsepLE,
1353 docPS, N_("Page Margins"));
1357 colorModule = new UiWidget<Ui::ColorUi>(this);
1358 connect(colorModule->fontColorPB, SIGNAL(clicked()),
1359 this, SLOT(changeFontColor()));
1360 connect(colorModule->delFontColorTB, SIGNAL(clicked()),
1361 this, SLOT(deleteFontColor()));
1362 connect(colorModule->noteFontColorPB, SIGNAL(clicked()),
1363 this, SLOT(changeNoteFontColor()));
1364 connect(colorModule->delNoteFontColorTB, SIGNAL(clicked()),
1365 this, SLOT(deleteNoteFontColor()));
1366 connect(colorModule->backgroundPB, SIGNAL(clicked()),
1367 this, SLOT(changeBackgroundColor()));
1368 connect(colorModule->delBackgroundTB, SIGNAL(clicked()),
1369 this, SLOT(deleteBackgroundColor()));
1370 connect(colorModule->boxBackgroundPB, SIGNAL(clicked()),
1371 this, SLOT(changeBoxBackgroundColor()));
1372 connect(colorModule->delBoxBackgroundTB, SIGNAL(clicked()),
1373 this, SLOT(deleteBoxBackgroundColor()));
1377 changesModule = new UiWidget<Ui::ChangeTrackingUi>(this);
1378 connect(changesModule->trackChangesCB, SIGNAL(clicked()),
1379 this, SLOT(change_adaptor()));
1380 connect(changesModule->outputChangesCB, SIGNAL(toggled(bool)),
1381 this, SLOT(outputChangesToggled(bool)));
1382 connect(changesModule->changeBarsCB, SIGNAL(clicked()),
1383 this, SLOT(change_adaptor()));
1384 connect(&lv, SIGNAL(changeTrackingToggled(bool)),
1385 this, SLOT(changeTrackingChanged(bool)));
1389 numberingModule = new UiWidget<Ui::NumberingUi>(this);
1390 connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
1391 this, SLOT(change_adaptor()));
1392 connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
1393 this, SLOT(change_adaptor()));
1394 connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
1395 this, SLOT(updateNumbering()));
1396 connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
1397 this, SLOT(updateNumbering()));
1398 numberingModule->tocTW->setColumnCount(3);
1399 numberingModule->tocTW->headerItem()->setText(0, qt_("Example"));
1400 numberingModule->tocTW->headerItem()->setText(1, qt_("Numbered"));
1401 numberingModule->tocTW->headerItem()->setText(2, qt_("Appears in TOC"));
1402 numberingModule->tocTW->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
1403 connect(numberingModule->linenoCB, SIGNAL(toggled(bool)),
1404 this, SLOT(linenoToggled(bool)));
1405 connect(numberingModule->linenoCB, SIGNAL(clicked()),
1406 this, SLOT(change_adaptor()));
1407 connect(numberingModule->linenoLE, SIGNAL(textChanged(QString)),
1408 this, SLOT(change_adaptor()));
1412 biblioModule = new UiWidget<Ui::BiblioUi>(this);
1413 connect(biblioModule->citeEngineCO, SIGNAL(activated(int)),
1414 this, SLOT(citeEngineChanged(int)));
1415 connect(biblioModule->citeStyleCO, SIGNAL(activated(int)),
1416 this, SLOT(citeStyleChanged()));
1417 connect(biblioModule->bibtopicCB, SIGNAL(clicked()),
1418 this, SLOT(biblioChanged()));
1419 connect(biblioModule->bibunitsCO, SIGNAL(activated(int)),
1420 this, SLOT(biblioChanged()));
1421 connect(biblioModule->bibtexCO, SIGNAL(activated(int)),
1422 this, SLOT(bibtexChanged(int)));
1423 connect(biblioModule->bibtexOptionsLE, SIGNAL(textChanged(QString)),
1424 this, SLOT(biblioChanged()));
1425 connect(biblioModule->citePackageOptionsLE, SIGNAL(textChanged(QString)),
1426 this, SLOT(biblioChanged()));
1427 connect(biblioModule->defaultBiblioCO, SIGNAL(activated(int)),
1428 this, SLOT(biblioChanged()));
1429 connect(biblioModule->defaultBiblioCO, SIGNAL(editTextChanged(QString)),
1430 this, SLOT(biblioChanged()));
1431 connect(biblioModule->defaultBiblioCO, SIGNAL(editTextChanged(QString)),
1432 this, SLOT(updateResetDefaultBiblio()));
1433 connect(biblioModule->biblatexBbxCO, SIGNAL(activated(int)),
1434 this, SLOT(biblioChanged()));
1435 connect(biblioModule->biblatexBbxCO, SIGNAL(editTextChanged(QString)),
1436 this, SLOT(biblioChanged()));
1437 connect(biblioModule->biblatexBbxCO, SIGNAL(editTextChanged(QString)),
1438 this, SLOT(updateResetDefaultBiblio()));
1439 connect(biblioModule->biblatexCbxCO, SIGNAL(activated(int)),
1440 this, SLOT(biblioChanged()));
1441 connect(biblioModule->biblatexCbxCO, SIGNAL(editTextChanged(QString)),
1442 this, SLOT(biblioChanged()));
1443 connect(biblioModule->biblatexCbxCO, SIGNAL(editTextChanged(QString)),
1444 this, SLOT(updateResetDefaultBiblio()));
1445 connect(biblioModule->rescanBibliosPB, SIGNAL(clicked()),
1446 this, SLOT(rescanBibFiles()));
1447 connect(biblioModule->resetDefaultBiblioPB, SIGNAL(clicked()),
1448 this, SLOT(resetDefaultBibfile()));
1449 connect(biblioModule->resetCbxPB, SIGNAL(clicked()),
1450 this, SLOT(resetDefaultCbxBibfile()));
1451 connect(biblioModule->resetBbxPB, SIGNAL(clicked()),
1452 this, SLOT(resetDefaultBbxBibfile()));
1453 connect(biblioModule->matchBbxPB, SIGNAL(clicked()),
1454 this, SLOT(matchBiblatexStyles()));
1456 biblioModule->citeEngineCO->clear();
1457 for (LyXCiteEngine const & cet : theCiteEnginesList) {
1458 biblioModule->citeEngineCO->addItem(qt_(cet.getName()), toqstr(cet.getID()));
1459 int const i = biblioModule->citeEngineCO->findData(toqstr(cet.getID()));
1460 biblioModule->citeEngineCO->setItemData(i, qt_(cet.getDescription()),
1464 biblioModule->bibtexOptionsLE->setValidator(new NoNewLineValidator(
1465 biblioModule->bibtexOptionsLE));
1466 biblioModule->defaultBiblioCO->lineEdit()->setValidator(new NoNewLineValidator(
1467 biblioModule->defaultBiblioCO->lineEdit()));
1468 biblioModule->citePackageOptionsLE->setValidator(new NoNewLineValidator(
1469 biblioModule->citePackageOptionsLE));
1471 // NOTE: we do not provide "custom" here for security reasons!
1472 biblioModule->bibtexCO->clear();
1473 biblioModule->bibtexCO->addItem(qt_("Default"), QString("default"));
1474 for (auto const & alts : lyxrc.bibtex_alternatives) {
1475 QString const command = toqstr(alts).left(toqstr(alts).indexOf(" "));
1476 biblioModule->bibtexCO->addItem(command, command);
1481 indicesModule = new GuiIndices;
1482 connect(indicesModule, SIGNAL(changed()),
1483 this, SLOT(change_adaptor()));
1487 mathsModule = new UiWidget<Ui::MathsUi>(this);
1488 QStringList headers;
1489 headers << qt_("Package") << qt_("Load automatically")
1490 << qt_("Load always") << qt_("Do not load");
1491 mathsModule->packagesTW->setHorizontalHeaderLabels(headers);
1492 mathsModule->packagesTW->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
1493 map<string, string> const & packages = BufferParams::auto_packages();
1494 mathsModule->packagesTW->setRowCount(packages.size());
1496 for (auto const & pkgvar : packages) {
1497 docstring const package = from_ascii(pkgvar.first);
1498 QString autoTooltip = qt_(pkgvar.second);
1499 QString alwaysTooltip;
1500 if (package == "amsmath")
1502 qt_("The AMS LaTeX packages are always used");
1504 alwaysTooltip = toqstr(bformat(
1505 _("The LaTeX package %1$s is always used"),
1507 QString neverTooltip;
1508 if (package == "amsmath")
1510 qt_("The AMS LaTeX packages are never used");
1512 neverTooltip = toqstr(bformat(
1513 _("The LaTeX package %1$s is never used"),
1515 QRadioButton * autoRB = new QRadioButton(mathsModule);
1516 QRadioButton * alwaysRB = new QRadioButton(mathsModule);
1517 QRadioButton * neverRB = new QRadioButton(mathsModule);
1518 QButtonGroup * packageGroup = new QButtonGroup(mathsModule);
1519 packageGroup->addButton(autoRB);
1520 packageGroup->addButton(alwaysRB);
1521 packageGroup->addButton(neverRB);
1522 autoRB->setToolTip(autoTooltip);
1523 alwaysRB->setToolTip(alwaysTooltip);
1524 neverRB->setToolTip(neverTooltip);
1526 // Pack the buttons in a layout in order to get proper alignment
1527 QWidget * autoRBWidget = new QWidget();
1528 QHBoxLayout * autoRBLayout = new QHBoxLayout(autoRBWidget);
1529 autoRBLayout->addWidget(autoRB);
1530 autoRBLayout->setAlignment(Qt::AlignCenter);
1531 autoRBLayout->setContentsMargins(0, 0, 0, 0);
1532 autoRBWidget->setLayout(autoRBLayout);
1534 QWidget * alwaysRBWidget = new QWidget();
1535 QHBoxLayout * alwaysRBLayout = new QHBoxLayout(alwaysRBWidget);
1536 alwaysRBLayout->addWidget(alwaysRB);
1537 alwaysRBLayout->setAlignment(Qt::AlignCenter);
1538 alwaysRBLayout->setContentsMargins(0, 0, 0, 0);
1539 alwaysRBWidget->setLayout(alwaysRBLayout);
1541 QWidget * neverRBWidget = new QWidget();
1542 QHBoxLayout * neverRBLayout = new QHBoxLayout(neverRBWidget);
1543 neverRBLayout->addWidget(neverRB);
1544 neverRBLayout->setAlignment(Qt::AlignCenter);
1545 neverRBLayout->setContentsMargins(0, 0, 0, 0);
1546 neverRBWidget->setLayout(neverRBLayout);
1548 QTableWidgetItem * pack = new QTableWidgetItem(toqstr(package));
1549 mathsModule->packagesTW->setItem(packnum, 0, pack);
1550 mathsModule->packagesTW->setCellWidget(packnum, 1, autoRBWidget);
1551 mathsModule->packagesTW->setCellWidget(packnum, 2, alwaysRBWidget);
1552 mathsModule->packagesTW->setCellWidget(packnum, 3, neverRBWidget);
1554 connect(autoRB, SIGNAL(clicked()),
1555 this, SLOT(change_adaptor()));
1556 connect(alwaysRB, SIGNAL(clicked()),
1557 this, SLOT(change_adaptor()));
1558 connect(neverRB, SIGNAL(clicked()),
1559 this, SLOT(change_adaptor()));
1562 connect(mathsModule->allPackagesAutoPB, SIGNAL(clicked()),
1563 this, SLOT(allPackagesAuto()));
1564 connect(mathsModule->allPackagesAlwaysPB, SIGNAL(clicked()),
1565 this, SLOT(allPackagesAlways()));
1566 connect(mathsModule->allPackagesNotPB, SIGNAL(clicked()),
1567 this, SLOT(allPackagesNot()));
1568 connect(mathsModule->allPackagesAutoPB, SIGNAL(clicked()),
1569 this, SLOT(change_adaptor()));
1570 connect(mathsModule->allPackagesAlwaysPB, SIGNAL(clicked()),
1571 this, SLOT(change_adaptor()));
1572 connect(mathsModule->allPackagesNotPB, SIGNAL(clicked()),
1573 this, SLOT(change_adaptor()));
1574 connect(mathsModule->MathNumberingPosCO, SIGNAL(activated(int)),
1575 this, SLOT(change_adaptor()));
1577 connect(mathsModule->MathIndentCB, SIGNAL(toggled(bool)),
1578 this, SLOT(allowMathIndent()));
1579 connect(mathsModule->MathIndentCB, SIGNAL(toggled(bool)),
1580 this, SLOT(change_adaptor()));
1581 connect(mathsModule->MathIndentCO, SIGNAL(activated(int)),
1582 this, SLOT(enableMathIndent(int)));
1583 connect(mathsModule->MathIndentCO, SIGNAL(activated(int)),
1584 this, SLOT(change_adaptor()));
1585 connect(mathsModule->MathIndentLE, SIGNAL(textChanged(const QString &)),
1586 this, SLOT(change_adaptor()));
1587 connect(mathsModule->MathIndentLengthCO, SIGNAL(activated(int)),
1588 this, SLOT(change_adaptor()));
1591 mathsModule->MathIndentCO->addItem(qt_("Default"), toqstr("default"));
1592 mathsModule->MathIndentCO->addItem(qt_("Custom"), toqstr("custom"));
1593 mathsModule->MathIndentLE->setValidator(new LengthValidator(
1594 mathsModule->MathIndentLE, false));
1595 // initialize the length validator
1596 bc().addCheckedLineEdit(mathsModule->MathIndentLE, mathsModule->MathIndentCB);
1597 bc().addCheckedLineEditPanel(mathsModule->MathIndentLE, docPS, N_("Math Options"));
1598 mathsModule->MathNumberingPosCO->addItem(qt_("Left"));
1599 mathsModule->MathNumberingPosCO->addItem(qt_("Default"));
1600 mathsModule->MathNumberingPosCO->addItem(qt_("Right"));
1601 mathsModule->MathNumberingPosCO->setCurrentIndex(1);
1605 latexModule = new UiWidget<Ui::LaTeXUi>(this);
1606 connect(latexModule->optionsLE, SIGNAL(textChanged(QString)),
1607 this, SLOT(change_adaptor()));
1608 connect(latexModule->defaultOptionsCB, SIGNAL(clicked()),
1609 this, SLOT(change_adaptor()));
1610 connect(latexModule->psdriverCO, SIGNAL(activated(int)),
1611 this, SLOT(change_adaptor()));
1612 connect(latexModule->classCO, SIGNAL(activated(int)),
1613 this, SLOT(classChanged_adaptor()));
1614 connect(latexModule->classCO, SIGNAL(activated(int)),
1615 this, SLOT(change_adaptor()));
1616 connect(latexModule->layoutPB, SIGNAL(clicked()),
1617 this, SLOT(browseLayout()));
1618 connect(latexModule->layoutPB, SIGNAL(clicked()),
1619 this, SLOT(change_adaptor()));
1620 connect(latexModule->childDocGB, SIGNAL(clicked()),
1621 this, SLOT(change_adaptor()));
1622 connect(latexModule->childDocLE, SIGNAL(textChanged(QString)),
1623 this, SLOT(change_adaptor()));
1624 connect(latexModule->childDocPB, SIGNAL(clicked()),
1625 this, SLOT(browseMaster()));
1626 connect(latexModule->suppressDateCB, SIGNAL(clicked()),
1627 this, SLOT(change_adaptor()));
1628 connect(latexModule->refstyleCB, SIGNAL(clicked()),
1629 this, SLOT(change_adaptor()));
1631 latexModule->optionsLE->setValidator(new NoNewLineValidator(
1632 latexModule->optionsLE));
1633 latexModule->childDocLE->setValidator(new NoNewLineValidator(
1634 latexModule->childDocLE));
1636 // postscript drivers
1637 for (int n = 0; tex_graphics[n][0]; ++n) {
1638 QString enc = qt_(tex_graphics_gui[n]);
1639 latexModule->psdriverCO->addItem(enc);
1642 LayoutFileList const & bcl = LayoutFileList::get();
1643 vector<LayoutFileIndex> classList = bcl.classList();
1644 sort(classList.begin(), classList.end(), less_textclass_avail_desc());
1646 for (auto const & cvar : classList) {
1647 LayoutFile const & tc = bcl[cvar];
1648 bool const available = tc.isTeXClassAvailable();
1649 docstring const guiname = translateIfPossible(from_utf8(tc.description()));
1650 // tooltip sensu "KOMA-Script Article [Class 'scrartcl']"
1651 QString tooltip = toqstr(bformat(_("%1$s [Class '%2$s']"), guiname, from_utf8(tc.latexname())));
1653 docstring const output_type = _("LaTeX");
1654 tooltip += '\n' + toqstr(bformat(_("Class not found by LyX. "
1655 "Please check if you have the matching %1$s class "
1656 "and all required packages (%2$s) installed."),
1657 output_type, from_utf8(tc.prerequisites(", "))));
1659 latexModule->classCO->addItemSort(toqstr(tc.name()),
1661 toqstr(translateIfPossible(from_utf8(tc.category()))),
1663 true, true, true, available);
1668 branchesModule = new GuiBranches(this);
1669 connect(branchesModule, SIGNAL(changed()),
1670 this, SLOT(change_adaptor()));
1671 connect(branchesModule, SIGNAL(renameBranches(docstring const &, docstring const &)),
1672 this, SLOT(branchesRename(docstring const &, docstring const &)));
1673 connect(branchesModule, SIGNAL(okPressed()), this, SLOT(slotOK()));
1674 updateUnknownBranches();
1678 preambleModule = new PreambleModule(this);
1679 connect(preambleModule, SIGNAL(changed()),
1680 this, SLOT(change_adaptor()));
1682 localLayout = new LocalLayout(this);
1683 connect(localLayout, SIGNAL(changed()),
1684 this, SLOT(change_adaptor()));
1688 bulletsModule = new BulletsModule(this);
1689 connect(bulletsModule, SIGNAL(changed()),
1690 this, SLOT(change_adaptor()));
1694 modulesModule = new UiWidget<Ui::ModulesUi>(this);
1695 modulesModule->availableLV->header()->setVisible(false);
1696 modulesModule->availableLV->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
1697 modulesModule->availableLV->header()->setStretchLastSection(false);
1698 modulesModule->selectedLV->header()->setVisible(false);
1699 modulesModule->selectedLV->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
1700 modulesModule->selectedLV->header()->setStretchLastSection(false);
1702 new ModuleSelectionManager(this, modulesModule->availableLV,
1703 modulesModule->selectedLV,
1704 modulesModule->addPB,
1705 modulesModule->deletePB,
1706 modulesModule->upPB,
1707 modulesModule->downPB,
1708 availableModel(), selectedModel(), this);
1709 connect(selectionManager, SIGNAL(updateHook()),
1710 this, SLOT(updateModuleInfo()));
1711 connect(selectionManager, SIGNAL(selectionChanged()),
1712 this, SLOT(modulesChanged()));
1714 filter_ = new FancyLineEdit(this);
1715 filter_->setClearButton(true);
1716 filter_->setPlaceholderText(qt_("All avail. modules"));
1717 modulesModule->moduleFilterBarL->addWidget(filter_, 0);
1718 modulesModule->findModulesLA->setBuddy(filter_);
1720 connect(filter_, SIGNAL(rightButtonClicked()),
1721 this, SLOT(resetModuleFilter()));
1722 connect(filter_, SIGNAL(textEdited(QString)),
1723 this, SLOT(moduleFilterChanged(QString)));
1724 connect(filter_, SIGNAL(returnPressed()),
1725 this, SLOT(moduleFilterPressed()));
1726 connect(filter_, &FancyLineEdit::downPressed,
1727 modulesModule->availableLV, [this](){ focusAndHighlight(modulesModule->availableLV); });
1731 pdfSupportModule = new UiWidget<Ui::PDFSupportUi>(this);
1732 connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
1733 this, SLOT(change_adaptor()));
1734 connect(pdfSupportModule->titleLE, SIGNAL(textChanged(QString)),
1735 this, SLOT(change_adaptor()));
1736 connect(pdfSupportModule->authorLE, SIGNAL(textChanged(QString)),
1737 this, SLOT(change_adaptor()));
1738 connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(QString)),
1739 this, SLOT(change_adaptor()));
1740 connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(QString)),
1741 this, SLOT(change_adaptor()));
1742 connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
1743 this, SLOT(change_adaptor()));
1744 connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
1745 this, SLOT(change_adaptor()));
1746 connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
1747 this, SLOT(change_adaptor()));
1748 connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
1749 this, SLOT(bookmarksopenChanged(bool)));
1750 connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
1751 this, SLOT(change_adaptor()));
1752 connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
1753 this, SLOT(change_adaptor()));
1754 connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
1755 this, SLOT(change_adaptor()));
1756 connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
1757 this, SLOT(change_adaptor()));
1758 connect(pdfSupportModule->backrefCO, SIGNAL(activated(int)),
1759 this, SLOT(change_adaptor()));
1760 connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
1761 this, SLOT(change_adaptor()));
1762 connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
1763 this, SLOT(change_adaptor()));
1764 connect(pdfSupportModule->optionsTE, SIGNAL(textChanged()),
1765 this, SLOT(change_adaptor()));
1766 connect(pdfSupportModule->metadataTE, SIGNAL(textChanged()),
1767 this, SLOT(change_adaptor()));
1769 pdfSupportModule->titleLE->setValidator(new NoNewLineValidator(
1770 pdfSupportModule->titleLE));
1771 pdfSupportModule->authorLE->setValidator(new NoNewLineValidator(
1772 pdfSupportModule->authorLE));
1773 pdfSupportModule->subjectLE->setValidator(new NoNewLineValidator(
1774 pdfSupportModule->subjectLE));
1775 pdfSupportModule->keywordsLE->setValidator(new NoNewLineValidator(
1776 pdfSupportModule->keywordsLE));
1777 (void) new LaTeXHighlighter(pdfSupportModule->optionsTE->document(), true, true);
1778 (void) new LaTeXHighlighter(pdfSupportModule->metadataTE->document(), true, true);
1780 for (int i = 0; backref_opts[i][0]; ++i)
1781 pdfSupportModule->backrefCO->addItem(qt_(backref_opts_gui[i]));
1785 floatModule = new FloatPlacement;
1786 connect(floatModule, SIGNAL(changed()),
1787 this, SLOT(change_adaptor()));
1791 listingsModule = new UiWidget<Ui::ListingsSettingsUi>(this);
1792 connect(listingsModule->listingsED, SIGNAL(textChanged()),
1793 this, SLOT(change_adaptor()));
1794 connect(listingsModule->bypassCB, SIGNAL(clicked()),
1795 this, SLOT(change_adaptor()));
1796 connect(listingsModule->bypassCB, SIGNAL(clicked()),
1797 this, SLOT(setListingsMessage()));
1798 connect(listingsModule->packageCO, SIGNAL(activated(int)),
1799 this, SLOT(change_adaptor()));
1800 connect(listingsModule->packageCO, SIGNAL(activated(int)),
1801 this, SLOT(listingsPackageChanged(int)));
1802 connect(listingsModule->listingsED, SIGNAL(textChanged()),
1803 this, SLOT(setListingsMessage()));
1804 listingsModule->listingsTB->setPlainText(
1805 qt_("Input listings parameters below. Enter ? for a list of parameters."));
1807 for (int i = 0; lst_packages[i][0]; ++i)
1808 listingsModule->packageCO->addItem(lst_packages[i]);
1812 docPS->addPanel(latexModule, N_("Document Class"));
1813 docPS->addPanel(masterChildModule, N_("Child Documents"));
1814 docPS->addPanel(modulesModule, N_("Modules"));
1815 docPS->addPanel(localLayout, N_("Local Layout"));
1816 docPS->addPanel(fontModule, N_("Fonts"));
1817 docPS->addPanel(textLayoutModule, N_("Text Layout"));
1818 docPS->addPanel(pageLayoutModule, N_("Page Layout"));
1819 docPS->addPanel(marginsModule, N_("Page Margins"));
1820 docPS->addPanel(langModule, N_("Language"));
1821 docPS->addPanel(colorModule, N_("Colors"));
1822 docPS->addPanel(changesModule, N_("Change Tracking"));
1823 docPS->addPanel(numberingModule, N_("Numbering & TOC"));
1824 docPS->addPanel(biblioModule, N_("Bibliography"));
1825 docPS->addPanel(indicesModule, N_("Indexes"));
1826 docPS->addPanel(pdfSupportModule, N_("PDF Properties"));
1827 docPS->addPanel(mathsModule, N_("Math Options"));
1828 docPS->addPanel(floatModule, N_("Float Settings"));
1829 docPS->addPanel(listingsModule, N_("Listings[[inset]]"));
1830 docPS->addPanel(bulletsModule, N_("Bullets"));
1831 docPS->addPanel(branchesModule, N_("Branches"));
1832 docPS->addPanel(outputModule, N_("Output"));
1833 docPS->addPanel(preambleModule, N_("LaTeX Preamble"));
1834 docPS->setCurrentPanel("Document Class");
1838 void GuiDocument::onBufferViewChanged()
1841 // We are just switching back. Nothing to do.
1842 switchback_ = false;
1845 BufferView const * view = bufferview();
1846 string const new_filename = view ? view->buffer().absFileName() : string();
1847 // If we switched buffer really and the previous file name is different to
1848 // the current one, we ask on unapplied changes (#9369)
1849 // FIXME: This is more complicated than it should be. Why do we need these to cycles?
1850 // And ideally, we should propose to apply without having to switch back
1851 // (e.g., via a LFUN_BUFFER_PARAMS_APPLY_OTHER)
1852 if (!prev_buffer_filename_.empty() && prev_buffer_filename_ != new_filename
1853 && buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
1854 // Only ask if we haven't yet in this cycle
1855 int const ret = prompted_ ? 3 : Alert::prompt(_("Unapplied changes"),
1856 _("Some changes in the previous document were not yet applied.\n"
1857 "Do you want to switch back and apply them?"),
1858 1, 1, _("Yes, &Switch Back"), _("No, &Dismiss Changes"));
1860 // Switch to previous buffer view and apply
1862 // Record that we have asked.
1864 lyx::dispatch(FuncRequest(LFUN_BUFFER_SWITCH, prev_buffer_filename_));
1866 } else if (ret == 3) {
1867 // We are in the second cycle. Set back.
1873 if (isVisibleView())
1874 initialiseParams("");
1878 void GuiDocument::saveDefaultClicked()
1884 void GuiDocument::useDefaultsClicked()
1890 void GuiDocument::change_adaptor()
1892 nonModuleChanged_ = true;
1897 void GuiDocument::shellescapeChanged()
1899 shellescapeChanged_ = true;
1903 void GuiDocument::bookmarksopenChanged(bool state)
1905 pdfSupportModule->bookmarksopenlevelSB->setEnabled(state);
1906 pdfSupportModule->bookmarksopenlevelLA->setEnabled(state);
1910 void GuiDocument::changeTrackingChanged(bool state)
1912 // This is triggered if the CT state is toggled outside
1913 // the document dialog (e.g., menu).
1914 changesModule->trackChangesCB->setChecked(state);
1918 void GuiDocument::slotApply()
1920 bool only_shellescape_changed = !nonModuleChanged_ && !modulesChanged_;
1921 bool wasclean = buffer().isClean();
1922 GuiDialog::slotApply();
1923 if (wasclean && only_shellescape_changed)
1924 buffer().markClean();
1925 modulesChanged_ = false;
1930 void GuiDocument::slotOK()
1932 bool only_shellescape_changed = !nonModuleChanged_ && !modulesChanged_;
1933 bool wasclean = buffer().isClean();
1934 GuiDialog::slotOK();
1935 if (wasclean && only_shellescape_changed)
1936 buffer().markClean();
1937 modulesChanged_ = false;
1941 void GuiDocument::slotButtonBox(QAbstractButton * button)
1943 switch (buttonBox->standardButton(button)) {
1944 case QDialogButtonBox::Ok:
1947 case QDialogButtonBox::Apply:
1950 case QDialogButtonBox::Cancel:
1953 case QDialogButtonBox::Reset:
1954 case QDialogButtonBox::RestoreDefaults:
1963 void GuiDocument::filterModules(QString const & str)
1965 updateAvailableModules();
1969 modules_av_model_.clear();
1970 list<modInfoStruct> modInfoList = getModuleInfo();
1971 // Sort names according to the locale
1972 modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
1973 return 0 < b.name.localeAwareCompare(a.name);
1976 QIcon user_icon(guiApp ? guiApp->getScaledPixmap("images/", "lyxfiles-user")
1977 : getPixmap("images/", "lyxfiles-user", "svgz,png"));
1978 QIcon system_icon(guiApp ? guiApp->getScaledPixmap("images/", "lyxfiles-system")
1979 : getPixmap("images/", "lyxfiles-system", "svgz,png"));
1982 for (modInfoStruct const & m : modInfoList) {
1983 if (m.name.contains(str, Qt::CaseInsensitive) || contains(m.id, fromqstr(str))) {
1984 QStandardItem * item = new QStandardItem();
1985 item->setData(m.name, Qt::DisplayRole);
1986 item->setData(toqstr(m.id), Qt::UserRole);
1987 item->setData(m.description, Qt::ToolTipRole);
1988 item->setEditable(false);
1990 item->setIcon(user_icon);
1992 item->setIcon(system_icon);
1993 modules_av_model_.insertRow(i, item);
2000 void GuiDocument::moduleFilterChanged(const QString & text)
2002 if (!text.isEmpty()) {
2003 filterModules(filter_->text());
2006 filterModules(filter_->text());
2007 filter_->setFocus();
2011 void GuiDocument::moduleFilterPressed()
2013 filterModules(filter_->text());
2017 void GuiDocument::resetModuleFilter()
2019 filter_->setText(QString());
2020 filterModules(filter_->text());
2024 void GuiDocument::includeonlyClicked(QTreeWidgetItem * item, int)
2026 if (item == nullptr)
2029 string child = fromqstr(item->text(0));
2034 if (isChildIncluded(child))
2035 includeonlys_.remove(child);
2037 includeonlys_.push_back(child);
2039 updateIncludeonlys(false);
2044 QString GuiDocument::validateListingsParameters()
2046 if (listingsModule->bypassCB->isChecked())
2048 string const package =
2049 lst_packages[listingsModule->packageCO->currentIndex()];
2050 string params = fromqstr(listingsModule->listingsED->toPlainText());
2051 InsetListingsParams lstparams(params);
2052 lstparams.setMinted(package == "Minted");
2053 return toqstr(lstparams.validate());
2057 void GuiDocument::setListingsMessage()
2060 static bool isOK = true;
2061 QString msg = validateListingsParameters();
2062 if (msg.isEmpty()) {
2063 listingsModule->listingsTB->setTextColor(QColor());
2067 listingsModule->listingsTB->setPlainText(
2068 qt_("Input listings parameters below. "
2069 "Enter ? for a list of parameters."));
2072 listingsModule->listingsTB->setTextColor(QColor(255, 0, 0));
2073 listingsModule->listingsTB->setPlainText(msg);
2078 void GuiDocument::listingsPackageChanged(int index)
2080 string const package = lst_packages[index];
2081 if (package == "Minted" && lyxrc.pygmentize_command.empty()) {
2082 Alert::warning(_("Pygments driver command not found!"),
2083 _("The driver command necessary to use the minted package\n"
2084 "(pygmentize) has not been found. Make sure you have\n"
2085 "the python-pygments module installed or, if the driver\n"
2086 "is named differently, to add the following line to the\n"
2087 "document preamble:\n\n"
2088 "\\AtBeginDocument{\\renewcommand{\\MintedPygmentize}{driver}}\n\n"
2089 "where 'driver' is name of the driver command."));
2094 void GuiDocument::setLSpacing(int item)
2096 textLayoutModule->lspacingLE->setEnabled(item == 3);
2100 void GuiDocument::setIndent(int item)
2102 bool const enable = (textLayoutModule->indentCO->itemData(item) == "custom");
2103 textLayoutModule->indentLE->setEnabled(enable);
2104 textLayoutModule->indentLengthCO->setEnabled(enable);
2105 textLayoutModule->skipLE->setEnabled(false);
2106 textLayoutModule->skipLengthCO->setEnabled(false);
2107 // needed to catch empty custom case
2113 void GuiDocument::enableIndent(bool indent)
2115 textLayoutModule->skipLE->setEnabled(!indent);
2116 textLayoutModule->skipLengthCO->setEnabled(!indent);
2118 setIndent(textLayoutModule->indentCO->currentIndex());
2122 void GuiDocument::setSkip(int item)
2124 VSpace::VSpaceKind kind =
2125 VSpace::VSpaceKind(textLayoutModule->skipCO->itemData(item).toInt());
2126 bool const enable = (kind == VSpace::LENGTH);
2127 textLayoutModule->skipLE->setEnabled(enable);
2128 textLayoutModule->skipLengthCO->setEnabled(enable);
2129 // needed to catch empty custom case
2135 void GuiDocument::enableSkip(bool skip)
2137 textLayoutModule->indentLE->setEnabled(!skip);
2138 textLayoutModule->indentLengthCO->setEnabled(!skip);
2140 setSkip(textLayoutModule->skipCO->currentIndex());
2143 void GuiDocument::allowMathIndent() {
2144 // only disable when not checked, checked does not always allow enabling
2145 if (!mathsModule->MathIndentCB->isChecked()) {
2146 mathsModule->MathIndentLE->setEnabled(false);
2147 mathsModule->MathIndentLengthCO->setEnabled(false);
2149 if (mathsModule->MathIndentCB->isChecked()
2150 && mathsModule->MathIndentCO->itemData(mathsModule->MathIndentCO->currentIndex()) == "custom") {
2151 mathsModule->MathIndentLE->setEnabled(true);
2152 mathsModule->MathIndentLengthCO->setEnabled(true);
2157 void GuiDocument::enableMathIndent(int item)
2159 bool const enable = (item == 1);
2160 mathsModule->MathIndentLE->setEnabled(enable);
2161 mathsModule->MathIndentLengthCO->setEnabled(enable);
2162 // needed to catch empty custom case
2168 void GuiDocument::setMargins()
2170 bool const extern_geometry =
2171 documentClass().provides("geometry");
2172 marginsModule->marginCB->setEnabled(!extern_geometry);
2173 if (extern_geometry) {
2174 marginsModule->marginCB->setChecked(false);
2175 setCustomMargins(true);
2177 marginsModule->marginCB->setChecked(!bp_.use_geometry);
2178 setCustomMargins(!bp_.use_geometry);
2181 // set some placeholder text that hint on defaults
2182 QString const placeholder = marginsModule->marginCB->isChecked() ?
2183 qt_("Class defaults") : qt_("Package defaults");
2184 // set tooltip depending on gemoetry state
2185 QString const tooltip = marginsModule->marginCB->isChecked() ?
2186 qt_("If no value is given, the defaults as set by the class are used.")
2187 : qt_("If no value is given, the defaults as set by the geometry package or a package/class overriding geometry's defaults are used.");
2188 marginsModule->topLE->setPlaceholderText(placeholder);
2189 marginsModule->bottomLE->setPlaceholderText(placeholder);
2190 marginsModule->innerLE->setPlaceholderText(placeholder);
2191 marginsModule->outerLE->setPlaceholderText(placeholder);
2192 marginsModule->headheightLE->setPlaceholderText(placeholder);
2193 marginsModule->headsepLE->setPlaceholderText(placeholder);
2194 marginsModule->footskipLE->setPlaceholderText(placeholder);
2195 marginsModule->columnsepLE->setPlaceholderText(placeholder);
2196 marginsModule->topLE->setToolTip(tooltip);
2197 marginsModule->bottomLE->setToolTip(tooltip);
2198 marginsModule->innerLE->setToolTip(tooltip);
2199 marginsModule->outerLE->setToolTip(tooltip);
2200 marginsModule->headheightLE->setToolTip(tooltip);
2201 marginsModule->headsepLE->setToolTip(tooltip);
2202 marginsModule->footskipLE->setToolTip(tooltip);
2203 marginsModule->columnsepLE->setToolTip(tooltip);
2207 void GuiDocument::papersizeChanged(int paper_size)
2209 setCustomPapersize(paper_size == 1);
2213 void GuiDocument::setCustomPapersize(bool custom)
2215 pageLayoutModule->paperwidthL->setEnabled(custom);
2216 pageLayoutModule->paperwidthLE->setEnabled(custom);
2217 pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
2218 pageLayoutModule->paperheightL->setEnabled(custom);
2219 pageLayoutModule->paperheightLE->setEnabled(custom);
2220 pageLayoutModule->paperheightLE->setFocus();
2221 pageLayoutModule->paperheightUnitCO->setEnabled(custom);
2225 void GuiDocument::setColSep()
2227 setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
2231 void GuiDocument::setCustomMargins(bool custom)
2233 marginsModule->topL->setEnabled(!custom);
2234 marginsModule->topLE->setEnabled(!custom);
2235 marginsModule->topUnit->setEnabled(!custom);
2237 marginsModule->bottomL->setEnabled(!custom);
2238 marginsModule->bottomLE->setEnabled(!custom);
2239 marginsModule->bottomUnit->setEnabled(!custom);
2241 marginsModule->innerL->setEnabled(!custom);
2242 marginsModule->innerLE->setEnabled(!custom);
2243 marginsModule->innerUnit->setEnabled(!custom);
2245 marginsModule->outerL->setEnabled(!custom);
2246 marginsModule->outerLE->setEnabled(!custom);
2247 marginsModule->outerUnit->setEnabled(!custom);
2249 marginsModule->headheightL->setEnabled(!custom);
2250 marginsModule->headheightLE->setEnabled(!custom);
2251 marginsModule->headheightUnit->setEnabled(!custom);
2253 marginsModule->headsepL->setEnabled(!custom);
2254 marginsModule->headsepLE->setEnabled(!custom);
2255 marginsModule->headsepUnit->setEnabled(!custom);
2257 marginsModule->footskipL->setEnabled(!custom);
2258 marginsModule->footskipLE->setEnabled(!custom);
2259 marginsModule->footskipUnit->setEnabled(!custom);
2261 bool const enableColSep = !custom &&
2262 textLayoutModule->twoColumnCB->checkState() == Qt::Checked;
2263 marginsModule->columnsepL->setEnabled(enableColSep);
2264 marginsModule->columnsepLE->setEnabled(enableColSep);
2265 marginsModule->columnsepUnit->setEnabled(enableColSep);
2267 // set some placeholder text that hint on defaults
2268 QString const placeholder = marginsModule->marginCB->isChecked() ?
2269 qt_("Class defaults") : qt_("Package defaults");
2270 // set tooltip depending on gemoetry state
2271 QString const tooltip = marginsModule->marginCB->isChecked() ?
2272 qt_("If no value is given, the defaults as set by the class are used.")
2273 : qt_("If no value is given, the defaults as set by the geometry package or a package/class overriding geometry's defaults are used.");
2274 marginsModule->topLE->setPlaceholderText(placeholder);
2275 marginsModule->bottomLE->setPlaceholderText(placeholder);
2276 marginsModule->innerLE->setPlaceholderText(placeholder);
2277 marginsModule->outerLE->setPlaceholderText(placeholder);
2278 marginsModule->headheightLE->setPlaceholderText(placeholder);
2279 marginsModule->headsepLE->setPlaceholderText(placeholder);
2280 marginsModule->footskipLE->setPlaceholderText(placeholder);
2281 marginsModule->columnsepLE->setPlaceholderText(placeholder);
2282 marginsModule->topLE->setToolTip(tooltip);
2283 marginsModule->bottomLE->setToolTip(tooltip);
2284 marginsModule->innerLE->setToolTip(tooltip);
2285 marginsModule->outerLE->setToolTip(tooltip);
2286 marginsModule->headheightLE->setToolTip(tooltip);
2287 marginsModule->headsepLE->setToolTip(tooltip);
2288 marginsModule->footskipLE->setToolTip(tooltip);
2289 marginsModule->columnsepLE->setToolTip(tooltip);
2294 void GuiDocument::changeBackgroundColor()
2296 QColor const & newColor = QColorDialog::getColor(
2297 rgb2qcolor(set_backgroundcolor), asQWidget());
2298 if (!newColor.isValid())
2301 colorModule->pageBackgroundCF->setVisible(true);
2302 colorModule->pageBackgroundCF->setStyleSheet(
2303 colorFrameStyleSheet(newColor));
2305 set_backgroundcolor = rgbFromHexName(fromqstr(newColor.name()));
2306 is_backgroundcolor = true;
2311 void GuiDocument::deleteBackgroundColor()
2313 // set the color back to default by setting an empty StyleSheet
2314 colorModule->pageBackgroundCF->setStyleSheet(QLatin1String(""));
2315 colorModule->pageBackgroundCF->setVisible(false);
2316 // save default color (white)
2317 set_backgroundcolor = rgbFromHexName("#ffffff");
2318 is_backgroundcolor = false;
2323 void GuiDocument::changeFontColor()
2325 QColor const & newColor = QColorDialog::getColor(
2326 rgb2qcolor(set_fontcolor), asQWidget());
2327 if (!newColor.isValid())
2330 colorModule->mainTextCF->setVisible(true);
2331 colorModule->mainTextCF->setStyleSheet(
2332 colorFrameStyleSheet(newColor));
2334 set_fontcolor = rgbFromHexName(fromqstr(newColor.name()));
2335 is_fontcolor = true;
2340 void GuiDocument::deleteFontColor()
2342 // set the button color back to default by setting an empty StyleSheet
2343 colorModule->mainTextCF->setStyleSheet(QLatin1String(""));
2344 colorModule->mainTextCF->setVisible(false);
2345 // save default color (black)
2346 set_fontcolor = rgbFromHexName("#000000");
2347 is_fontcolor = false;
2352 void GuiDocument::changeNoteFontColor()
2354 QColor const & newColor = QColorDialog::getColor(
2355 rgb2qcolor(set_notefontcolor), asQWidget());
2356 if (!newColor.isValid())
2359 colorModule->noteFontCF->setStyleSheet(
2360 colorFrameStyleSheet(newColor));
2362 set_notefontcolor = rgbFromHexName(fromqstr(newColor.name()));
2363 is_notefontcolor = true;
2368 void GuiDocument::deleteNoteFontColor()
2370 // set the color back to pref
2371 theApp()->getRgbColor(Color_greyedouttext, set_notefontcolor);
2372 colorModule->noteFontCF->setStyleSheet(
2373 colorFrameStyleSheet(rgb2qcolor(set_notefontcolor)));
2374 is_notefontcolor = false;
2379 void GuiDocument::changeBoxBackgroundColor()
2381 QColor const & newColor = QColorDialog::getColor(
2382 rgb2qcolor(set_boxbgcolor), asQWidget());
2383 if (!newColor.isValid())
2386 colorModule->boxBackgroundCF->setStyleSheet(
2387 colorFrameStyleSheet(newColor));
2389 set_boxbgcolor = rgbFromHexName(fromqstr(newColor.name()));
2390 is_boxbgcolor = true;
2395 void GuiDocument::deleteBoxBackgroundColor()
2397 // set the color back to pref
2398 theApp()->getRgbColor(Color_shadedbg, set_boxbgcolor);
2399 colorModule->boxBackgroundCF->setStyleSheet(
2400 colorFrameStyleSheet(rgb2qcolor(set_boxbgcolor)));
2401 is_boxbgcolor = false;
2406 void GuiDocument::updateQuoteStyles(bool const set)
2408 Language const * lang = lyx::languages.getLanguage(
2409 fromqstr(langModule->languageCO->itemData(
2410 langModule->languageCO->currentIndex()).toString()));
2412 QuoteStyle def = bp_.getQuoteStyle(lang->quoteStyle());
2414 langModule->quoteStyleCO->clear();
2416 bool has_default = false;
2417 for (int i = 0; i < quoteparams.stylescount(); ++i) {
2418 QuoteStyle qs = QuoteStyle(i);
2419 if (qs == QuoteStyle::Dynamic)
2421 bool const langdef = (qs == def);
2423 // add the default style on top
2424 langModule->quoteStyleCO->insertItem(0,
2425 toqstr(quoteparams.getGuiLabel(qs, langdef)), static_cast<int>(qs));
2429 langModule->quoteStyleCO->addItem(
2430 toqstr(quoteparams.getGuiLabel(qs, langdef)), static_cast<int>(qs));
2432 if (set && has_default)
2433 // (re)set to the default style
2434 langModule->quoteStyleCO->setCurrentIndex(0);
2438 void GuiDocument::languageChanged(int i)
2440 // some languages only work with Polyglossia
2441 Language const * lang = lyx::languages.getLanguage(
2442 fromqstr(langModule->languageCO->itemData(i).toString()));
2443 if (lang->babel().empty() && !lang->polyglossia().empty()
2444 && lang->required() != "CJK" && lang->required() != "japanese") {
2445 // If we force to switch fontspec on, store
2446 // current state (#8717)
2447 if (fontModule->osFontsCB->isEnabled())
2448 forced_fontspec_activation =
2449 !fontModule->osFontsCB->isChecked();
2450 fontModule->osFontsCB->setChecked(true);
2451 fontModule->osFontsCB->setEnabled(false);
2454 fontModule->osFontsCB->setEnabled(true);
2455 // If we have forced to switch fontspec on,
2456 // restore previous state (#8717)
2457 if (forced_fontspec_activation)
2458 fontModule->osFontsCB->setChecked(false);
2459 forced_fontspec_activation = false;
2462 // set appropriate quotation mark style
2463 updateQuoteStyles(true);
2467 void GuiDocument::osFontsChanged(bool nontexfonts)
2469 bool const tex_fonts = !nontexfonts;
2470 // store current fonts
2471 QString const font_roman = fontModule->fontsRomanCO->getData(
2472 fontModule->fontsRomanCO->currentIndex());
2473 QString const font_sans = fontModule->fontsSansCO->getData(
2474 fontModule->fontsSansCO->currentIndex());
2475 QString const font_typewriter = fontModule->fontsTypewriterCO->getData(
2476 fontModule->fontsTypewriterCO->currentIndex());
2477 QString const font_math = fontModule->fontsMathCO->itemData(
2478 fontModule->fontsMathCO->currentIndex()).toString();
2479 int const font_sf_scale = fontModule->scaleSansSB->value();
2480 int const font_tt_scale = fontModule->scaleTypewriterSB->value();
2483 // store default format
2484 QString const dformat = outputModule->defaultFormatCO->itemData(
2485 outputModule->defaultFormatCO->currentIndex()).toString();
2486 updateDefaultFormat();
2487 // try to restore default format
2488 int index = outputModule->defaultFormatCO->findData(dformat);
2489 // set to default if format is not found
2492 outputModule->defaultFormatCO->setCurrentIndex(index);
2494 // try to restore fonts which were selected two toggles ago
2495 if (!fontModule->font_roman.isEmpty())
2496 fontModule->fontsRomanCO->set(fontModule->font_roman);
2497 if (!fontModule->font_sans.isEmpty())
2498 fontModule->fontsSansCO->set(fontModule->font_sans);
2499 if (!fontModule->font_typewriter.isEmpty())
2500 fontModule->fontsTypewriterCO->set(fontModule->font_typewriter);
2501 index = fontModule->fontsMathCO->findData(fontModule->font_math);
2503 fontModule->fontsMathCO->setCurrentIndex(index);
2504 // save fonts for next next toggle
2505 fontModule->font_roman = font_roman;
2506 fontModule->font_sans = font_sans;
2507 fontModule->font_typewriter = font_typewriter;
2508 fontModule->font_math = font_math;
2509 fontModule->font_sf_scale = font_sf_scale;
2510 fontModule->font_tt_scale = font_tt_scale;
2512 // non-tex fonts override the "\inputencoding" option with "utf8-plain"
2513 langModule->encodingCO->setEnabled(tex_fonts);
2514 inputencodingToDialog();
2516 fontModule->cjkFontLE->setEnabled(tex_fonts);
2517 fontModule->cjkFontLA->setEnabled(tex_fonts);
2519 updateFontOptions();
2521 fontModule->fontencLA->setEnabled(tex_fonts);
2522 fontModule->fontencCO->setEnabled(tex_fonts);
2524 fontModule->fontencLE->setEnabled(false);
2526 fontencChanged(fontModule->fontencCO->currentIndex());
2530 void GuiDocument::encodingSwitched(int i)
2532 bool const tex_fonts = !fontModule->osFontsCB->isChecked();
2533 langModule->unicodeEncodingCO->setEnabled(tex_fonts);
2534 langModule->customEncodingCO->setEnabled(tex_fonts);
2535 langModule->autoEncodingCO->setEnabled(tex_fonts);
2536 langModule->unicodeEncodingCO->setVisible(i == EncodingSets::unicode);
2537 langModule->autoEncodingCO->setVisible(i == EncodingSets::legacy);
2538 langModule->customEncodingCO->setVisible(i == EncodingSets::custom);
2540 case EncodingSets::unicode:
2541 langModule->encodingVariantLA->setBuddy(langModule->unicodeEncodingCO);
2543 case EncodingSets::legacy:
2544 langModule->encodingVariantLA->setBuddy(langModule->autoEncodingCO);
2546 case EncodingSets::custom:
2547 langModule->encodingVariantLA->setBuddy(langModule->customEncodingCO);
2552 langModule->unicodeEncodingCO->setItemText(1, qt_("Direct (No inputenc)"));
2554 langModule->unicodeEncodingCO->setItemText(1, qt_("Direct (XeTeX/LuaTeX)"));
2557 void GuiDocument::inputencodingToDialog()
2559 QString inputenc = toqstr(bp_.inputenc);
2561 if (fontModule->osFontsCB->isChecked()) { // non-tex fonts require utf8-plain
2562 langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
2563 langModule->unicodeEncodingCO->setCurrentIndex(
2564 langModule->unicodeEncodingCO->findData("utf8-plain"));
2565 } else if (inputenc.startsWith("utf8")) {
2566 langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
2567 p = langModule->unicodeEncodingCO->findData(inputenc);
2570 langModule->unicodeEncodingCO->setCurrentIndex(p);
2571 langModule->autoEncodingCO->setCurrentIndex(0);
2572 langModule->customEncodingCO->setCurrentIndex(0);
2573 } else if (inputenc.startsWith("auto")) {
2574 langModule->encodingCO->setCurrentIndex(EncodingSets::legacy);
2575 p = langModule->autoEncodingCO->findData(inputenc);
2578 langModule->unicodeEncodingCO->setCurrentIndex(0);
2579 langModule->autoEncodingCO->setCurrentIndex(p);
2580 langModule->customEncodingCO->setCurrentIndex(0);
2582 langModule->encodingCO->setCurrentIndex(EncodingSets::custom);
2583 p = langModule->customEncodingCO->findData(inputenc);
2586 langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
2588 langModule->unicodeEncodingCO->setCurrentIndex(0);
2589 langModule->autoEncodingCO->setCurrentIndex(0);
2590 langModule->customEncodingCO->setCurrentIndex(p);
2592 encodingSwitched(langModule->encodingCO->currentIndex());
2596 void GuiDocument::mathFontChanged(int)
2598 updateFontOptions();
2601 void GuiDocument::fontOsfToggled(bool state)
2603 if (fontModule->osFontsCB->isChecked())
2605 QString font = fontModule->fontsRomanCO->getData(
2606 fontModule->fontsRomanCO->currentIndex());
2607 if (hasMonolithicExpertSet(font))
2608 fontModule->fontScCB->setChecked(state);
2612 void GuiDocument::fontScToggled(bool state)
2614 if (fontModule->osFontsCB->isChecked())
2616 QString font = fontModule->fontsRomanCO->getData(
2617 fontModule->fontsRomanCO->currentIndex());
2618 if (hasMonolithicExpertSet(font))
2619 fontModule->fontOsfCB->setChecked(state);
2623 void GuiDocument::updateExtraOpts()
2625 bool const tex_fonts = !fontModule->osFontsCB->isChecked();
2628 font = fontModule->fontsRomanCO->getData(
2629 fontModule->fontsRomanCO->currentIndex());
2630 bool const rm_opts = providesExtraOpts(font);
2632 font = fontModule->fontsSansCO->getData(
2633 fontModule->fontsSansCO->currentIndex());
2634 bool const sf_opts = providesExtraOpts(font);
2636 font = fontModule->fontsTypewriterCO->getData(
2637 fontModule->fontsTypewriterCO->currentIndex());
2638 bool const tt_opts = providesExtraOpts(font);
2639 fontModule->fontspecRomanLA->setEnabled(!tex_fonts || rm_opts);
2640 fontModule->fontspecRomanLE->setEnabled(!tex_fonts || rm_opts);
2641 fontModule->fontspecSansLA->setEnabled(!tex_fonts || sf_opts);
2642 fontModule->fontspecSansLE->setEnabled(!tex_fonts || sf_opts);
2643 fontModule->fontspecTypewriterLA->setEnabled(!tex_fonts || tt_opts);
2644 fontModule->fontspecTypewriterLE->setEnabled(!tex_fonts || tt_opts);
2648 void GuiDocument::updateFontOptions()
2650 bool const tex_fonts = !fontModule->osFontsCB->isChecked();
2653 font = fontModule->fontsSansCO->getData(
2654 fontModule->fontsSansCO->currentIndex());
2655 bool scalable = providesScale(font);
2656 fontModule->scaleSansSB->setEnabled(scalable);
2657 fontModule->scaleSansLA->setEnabled(scalable);
2658 fontModule->fontSansOsfCB->setEnabled(providesOSF(font));
2660 font = fontModule->fontsTypewriterCO->getData(
2661 fontModule->fontsTypewriterCO->currentIndex());
2662 scalable = providesScale(font);
2663 fontModule->scaleTypewriterSB->setEnabled(scalable);
2664 fontModule->scaleTypewriterLA->setEnabled(scalable);
2665 fontModule->fontTypewriterOsfCB->setEnabled(providesOSF(font));
2667 font = fontModule->fontsRomanCO->getData(
2668 fontModule->fontsRomanCO->currentIndex());
2669 fontModule->fontScCB->setEnabled(providesSC(font));
2670 fontModule->fontOsfCB->setEnabled(providesOSF(font));
2672 updateMathFonts(font);
2676 void GuiDocument::updateFontsize(string const & items, string const & sel)
2678 fontModule->fontsizeCO->clear();
2679 fontModule->fontsizeCO->addItem(qt_("Default"));
2681 for (int n = 0; !token(items,'|',n).empty(); ++n)
2682 fontModule->fontsizeCO->
2683 addItem(toqstr(token(items,'|',n)));
2685 for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
2686 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
2687 fontModule->fontsizeCO->setCurrentIndex(n);
2694 bool GuiDocument::ot1() const
2696 QString const fontenc =
2697 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
2698 int const i = langModule->languageCO->currentIndex();
2701 QString const langname = langModule->languageCO->itemData(i).toString();
2702 Language const * newlang = lyx::languages.getLanguage(fromqstr(langname));
2703 return (fontenc == "default"
2704 || (fontenc == "auto" && newlang->fontenc(buffer().params()) == "OT1")
2705 || (fontenc == "custom" && fontModule->fontencLE->text() == "OT1"));
2709 bool GuiDocument::completeFontset() const
2711 return (fontModule->fontsSansCO->getData(
2712 fontModule->fontsSansCO->currentIndex()) == "default"
2713 && fontModule->fontsSansCO->getData(
2714 fontModule->fontsTypewriterCO->currentIndex()) == "default");
2718 bool GuiDocument::noMathFont() const
2720 return (fontModule->fontsMathCO->itemData(
2721 fontModule->fontsMathCO->currentIndex()).toString() == "default");
2725 void GuiDocument::updateTexFonts()
2727 LaTeXFonts::TexFontMap texfontmap = theLaTeXFonts().getLaTeXFonts();
2729 LaTeXFonts::TexFontMap::const_iterator it = texfontmap.begin();
2730 LaTeXFonts::TexFontMap::const_iterator end = texfontmap.end();
2731 for (; it != end; ++it) {
2732 LaTeXFont lf = it->second;
2733 if (lf.name().empty()) {
2734 LYXERR0("Error: Unnamed font: " << it->first);
2737 docstring const family = lf.family();
2738 docstring guiname = translateIfPossible(lf.guiname());
2739 if (!lf.available(ot1(), noMathFont()))
2740 guiname += _(" (not installed)");
2742 rmfonts_.insert(toqstr(guiname), toqstr(it->first));
2743 else if (family == "sf")
2744 sffonts_.insert(toqstr(guiname), toqstr(it->first));
2745 else if (family == "tt")
2746 ttfonts_.insert(toqstr(guiname), toqstr(it->first));
2747 else if (family == "math")
2748 mathfonts_.insert(toqstr(guiname), toqstr(it->first));
2753 void GuiDocument::updateFontlist()
2755 // reset the filters of the CategorizedCombos
2756 fontModule->fontsRomanCO->resetFilter();
2757 fontModule->fontsSansCO->resetFilter();
2758 fontModule->fontsTypewriterCO->resetFilter();
2759 fontModule->fontsRomanCO->clear();
2760 fontModule->fontsSansCO->clear();
2761 fontModule->fontsTypewriterCO->clear();
2762 fontModule->fontsMathCO->clear();
2764 // With fontspec (XeTeX, LuaTeX), we have access to all system fonts, but not the LaTeX fonts
2765 if (fontModule->osFontsCB->isChecked()) {
2766 fontModule->fontsRomanCO->addItemSort(QString("default"), qt_("Default"),
2767 QString(), qt_("Default font (as set by class)"),
2768 false, false, false, true, true);
2769 fontModule->fontsSansCO->addItemSort(QString("default"), qt_("Default"),
2770 QString(), qt_("Default font (as set by class)"),
2771 false, false, false, true, true);
2772 fontModule->fontsTypewriterCO->addItemSort(QString("default"), qt_("Default"),
2773 QString(), qt_("Default font (as set by class)"),
2774 false, false, false, true, true);
2775 QString unimath = qt_("Non-TeX Fonts Default");
2776 if (!LaTeXFeatures::isAvailable("unicode-math"))
2777 unimath += qt_(" (not available)");
2778 fontModule->fontsMathCO->addItem(qt_("Class Default (TeX Fonts)"), QString("auto"));
2779 fontModule->fontsMathCO->addItem(unimath, QString("default"));
2781 #if QT_VERSION >= 0x060000
2782 const QStringList families(QFontDatabase::families());
2784 QFontDatabase fontdb;
2785 const QStringList families(fontdb.families());
2787 for (auto const & family : families) {
2788 fontModule->fontsRomanCO->addItemSort(family, family,
2789 QString(), QString(),
2790 false, false, false, true, true);
2791 fontModule->fontsSansCO->addItemSort(family, family,
2792 QString(), QString(),
2793 false, false, false, true, true);
2794 fontModule->fontsTypewriterCO->addItemSort(family, family,
2795 QString(), QString(),
2796 false, false, false, true, true);
2801 if (rmfonts_.empty())
2804 fontModule->fontsRomanCO->addItemSort(QString("default"), qt_("Default"),
2805 QString(), qt_("Default font (as set by class)"),
2806 false, false, false, true, true);
2807 QMap<QString, QString>::const_iterator rmi = rmfonts_.constBegin();
2808 while (rmi != rmfonts_.constEnd()) {
2809 fontModule->fontsRomanCO->addItemSort(rmi.value(), rmi.key(),
2810 QString(), QString(),
2811 false, false, false, true, true);
2815 fontModule->fontsSansCO->addItemSort(QString("default"), qt_("Default"),
2816 QString(), qt_("Default font (as set by class)"),
2817 false, false, false, true, true);
2818 QMap<QString, QString>::const_iterator sfi = sffonts_.constBegin();
2819 while (sfi != sffonts_.constEnd()) {
2820 fontModule->fontsSansCO->addItemSort(sfi.value(), sfi.key(),
2821 QString(), QString(),
2822 false, false, false, true, true);
2826 fontModule->fontsTypewriterCO->addItemSort(QString("default"), qt_("Default"),
2827 QString(), qt_("Default font (as set by class)"),
2828 false, false, false, true, true);
2829 QMap<QString, QString>::const_iterator tti = ttfonts_.constBegin();
2830 while (tti != ttfonts_.constEnd()) {
2831 fontModule->fontsTypewriterCO->addItemSort(tti.value(), tti.key(),
2832 QString(), QString(),
2833 false, false, false, true, true);
2837 fontModule->fontsMathCO->addItem(qt_("Automatic"), QString("auto"));
2838 fontModule->fontsMathCO->addItem(qt_("Class Default"), QString("default"));
2839 QMap<QString, QString>::const_iterator mmi = mathfonts_.constBegin();
2840 while (mmi != mathfonts_.constEnd()) {
2841 fontModule->fontsMathCO->addItem(mmi.key(), mmi.value());
2847 void GuiDocument::fontencChanged(int item)
2849 fontModule->fontencLE->setEnabled(
2850 fontModule->fontencCO->itemData(item).toString() == "custom");
2851 // The availability of TeX fonts depends on the font encoding
2853 updateFontOptions();
2857 void GuiDocument::updateMathFonts(QString const & rm)
2859 if (fontModule->osFontsCB->isChecked())
2861 QString const math =
2862 fontModule->fontsMathCO->itemData(fontModule->fontsMathCO->currentIndex()).toString();
2863 int const i = fontModule->fontsMathCO->findData("default");
2864 if (providesNoMath(rm) && i == -1)
2865 fontModule->fontsMathCO->insertItem(1, qt_("Class Default"), QString("default"));
2866 else if (!providesNoMath(rm) && i != -1) {
2867 int const c = fontModule->fontsMathCO->currentIndex();
2868 fontModule->fontsMathCO->removeItem(i);
2870 fontModule->fontsMathCO->setCurrentIndex(0);
2875 void GuiDocument::romanChanged(int item)
2877 if (fontModule->osFontsCB->isChecked())
2879 QString const font = fontModule->fontsRomanCO->getData(item);
2880 fontModule->fontScCB->setEnabled(providesSC(font));
2881 fontModule->fontOsfCB->setEnabled(providesOSF(font));
2883 updateMathFonts(font);
2887 void GuiDocument::sansChanged(int item)
2889 if (fontModule->osFontsCB->isChecked())
2891 QString const font = fontModule->fontsSansCO->getData(item);
2892 bool const scalable = providesScale(font);
2893 fontModule->scaleSansSB->setEnabled(scalable);
2894 fontModule->scaleSansLA->setEnabled(scalable);
2895 fontModule->fontSansOsfCB->setEnabled(providesOSF(font));
2900 void GuiDocument::ttChanged(int item)
2902 if (fontModule->osFontsCB->isChecked())
2904 QString const font = fontModule->fontsTypewriterCO->getData(item);
2905 bool scalable = providesScale(font);
2906 fontModule->scaleTypewriterSB->setEnabled(scalable);
2907 fontModule->scaleTypewriterLA->setEnabled(scalable);
2908 fontModule->fontTypewriterOsfCB->setEnabled(providesOSF(font));
2913 void GuiDocument::updatePagestyle(string const & items, string const & sel)
2916 pageLayoutModule->pagestyleCO->clear();
2917 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
2919 for (int n = 0; !token(items, '|', n).empty(); ++n) {
2920 string style = token(items, '|', n);
2921 QString style_gui = qt_(style);
2922 pagestyles.push_back(pair<string, QString>(style, style_gui));
2923 pageLayoutModule->pagestyleCO->addItem(style_gui);
2926 if (sel == "default") {
2927 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
2933 for (auto const & pagestyle : pagestyles)
2934 if (pagestyle.first == sel)
2935 nn = pageLayoutModule->pagestyleCO->findText(pagestyle.second);
2938 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
2942 void GuiDocument::browseLayout()
2944 QString const label1 = qt_("Lay&outs");
2945 QString const dir1 = toqstr(lyxrc.document_path);
2946 QStringList const filter(qt_("LyX Layout (*.layout)"));
2947 QString file = browseRelToParent(QString(), bufferFilePath(),
2948 qt_("Local layout file"), filter, false,
2951 if (!file.endsWith(".layout"))
2954 FileName layoutFile = support::makeAbsPath(fromqstr(file),
2955 fromqstr(bufferFilePath()));
2957 int const ret = Alert::prompt(_("Local layout file"),
2958 _("The layout file you have selected is a local layout\n"
2959 "file, not one in the system or user directory.\n"
2960 "Your document will not work with this layout if you\n"
2961 "move the layout file to a different directory."),
2962 1, 1, _("&Set Layout"), _("&Cancel"));
2966 // load the layout file
2967 LayoutFileList & bcl = LayoutFileList::get();
2968 string classname = layoutFile.onlyFileName();
2969 // this will update an existing layout if that layout has been loaded before.
2970 LayoutFileIndex name = support::onlyFileName(bcl.addLocalLayout(
2971 classname.substr(0, classname.size() - 7),
2972 layoutFile.onlyPath().absFileName()));
2975 Alert::error(_("Error"),
2976 _("Unable to read local layout file."));
2980 const_cast<Buffer &>(buffer()).setLayoutPos(layoutFile.onlyPath().absFileName());
2982 // do not trigger classChanged if there is no change.
2983 if (latexModule->classCO->currentText() == toqstr(name))
2987 bool const avail = latexModule->classCO->set(toqstr(name));
2989 LayoutFile const & tc = bcl[name];
2990 docstring const guiname = translateIfPossible(from_utf8(tc.description()));
2991 // tooltip sensu "KOMA-Script Article [Class 'scrartcl']"
2992 QString tooltip = toqstr(bformat(_("%1$s [Class '%2$s']"), guiname, from_utf8(tc.latexname())));
2993 tooltip += '\n' + qt_("This is a local layout file.");
2994 latexModule->classCO->addItemSort(toqstr(tc.name()), toqstr(guiname),
2995 toqstr(translateIfPossible(from_utf8(tc.category()))),
2997 true, true, true, true);
2998 latexModule->classCO->set(toqstr(name));
3005 void GuiDocument::browseMaster()
3007 QString const title = qt_("Select master document");
3008 QString const dir1 = toqstr(lyxrc.document_path);
3009 QString const old = latexModule->childDocLE->text();
3010 QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
3011 QStringList const filter(qt_("LyX Files (*.lyx)"));
3012 QString file = browseRelToSub(old, docpath, title, filter, false,
3013 qt_("D&ocuments"), toqstr(lyxrc.document_path));
3015 if (!file.isEmpty())
3016 latexModule->childDocLE->setText(file);
3020 void GuiDocument::classChanged_adaptor()
3022 const_cast<Buffer &>(buffer()).setLayoutPos(string());
3027 void GuiDocument::classChanged()
3029 int idx = latexModule->classCO->currentIndex();
3032 string const classname = fromqstr(latexModule->classCO->getData(idx));
3034 if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
3035 int const ret = Alert::prompt(_("Unapplied changes"),
3036 _("Some changes in the dialog were not yet applied.\n"
3037 "If you do not apply now, they will be lost after this action."),
3038 1, 1, _("&Apply"), _("&Dismiss"));
3043 // We load the TextClass as soon as it is selected. This is
3044 // necessary so that other options in the dialog can be updated
3045 // according to the new class. Note, however, that, if you use
3046 // the scroll wheel when sitting on the combo box, we'll load a
3047 // lot of TextClass objects very quickly....
3048 if (!bp_.setBaseClass(classname, buffer().layoutPos())) {
3049 Alert::error(_("Error"), _("Unable to set document class."));
3052 if (lyxrc.auto_reset_options)
3053 bp_.useClassDefaults();
3055 // With the introduction of modules came a distinction between the base
3056 // class and the document class. The former corresponds to the main layout
3057 // file; the latter is that plus the modules (or the document-specific layout,
3058 // or whatever else there could be). Our parameters come from the document
3059 // class. So when we set the base class, we also need to recreate the document
3060 // class. Otherwise, we still have the old one.
3061 bp_.makeDocumentClass();
3066 void GuiDocument::languagePackageChanged(int i)
3068 langModule->languagePackageLE->setEnabled(
3069 langModule->languagePackageCO->itemData(i).toString() == "custom");
3073 void GuiDocument::biblioChanged()
3075 biblioChanged_ = true;
3080 void GuiDocument::checkPossibleCiteEngines()
3082 // Check if the class provides a specific engine,
3083 // and if so, enforce this.
3084 string force_engine;
3085 if (documentClass().provides("natbib")
3086 || documentClass().provides("natbib-internal"))
3087 force_engine = "natbib";
3088 else if (documentClass().provides("jurabib"))
3089 force_engine = "jurabib";
3090 else if (documentClass().provides("biblatex"))
3091 force_engine = "biblatex";
3092 else if (documentClass().provides("biblatex-natbib"))
3093 force_engine = "biblatex-natbib";
3095 if (!force_engine.empty())
3096 biblioModule->citeEngineCO->setCurrentIndex(
3097 biblioModule->citeEngineCO->findData(toqstr(force_engine)));
3098 biblioModule->citeEngineCO->setEnabled(force_engine.empty());
3102 void GuiDocument::rescanBibFiles()
3105 rescanTexStyles("bbx cbx");
3107 rescanTexStyles("bst");
3111 void GuiDocument::resetDefaultBibfile(string const & which)
3113 QString const engine =
3114 biblioModule->citeEngineCO->itemData(
3115 biblioModule->citeEngineCO->currentIndex()).toString();
3117 CiteEngineType const cet =
3118 CiteEngineType(biblioModule->citeStyleCO->itemData(
3119 biblioModule->citeStyleCO->currentIndex()).toInt());
3121 updateDefaultBiblio(theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet), which);
3125 void GuiDocument::resetDefaultBbxBibfile()
3127 resetDefaultBibfile("bbx");
3131 void GuiDocument::resetDefaultCbxBibfile()
3133 resetDefaultBibfile("cbx");
3137 void GuiDocument::citeEngineChanged(int n)
3139 QString const engine =
3140 biblioModule->citeEngineCO->itemData(n).toString();
3142 vector<string> const engs =
3143 theCiteEnginesList[fromqstr(engine)]->getEngineType();
3145 updateCiteStyles(engs);
3146 updateEngineDependends();
3147 resetDefaultBibfile();
3152 void GuiDocument::updateEngineDependends()
3154 bool const biblatex = isBiblatex();
3156 // These are only useful with BibTeX
3157 biblioModule->defaultBiblioCO->setEnabled(!biblatex);
3158 biblioModule->bibtexStyleLA->setEnabled(!biblatex);
3159 biblioModule->resetDefaultBiblioPB->setEnabled(!biblatex);
3160 biblioModule->bibtopicCB->setEnabled(!biblatex);
3162 // These are only useful with Biblatex
3163 biblioModule->biblatexBbxCO->setEnabled(biblatex);
3164 biblioModule->biblatexBbxLA->setEnabled(biblatex);
3165 biblioModule->biblatexCbxCO->setEnabled(biblatex);
3166 biblioModule->biblatexCbxLA->setEnabled(biblatex);
3167 biblioModule->resetBbxPB->setEnabled(biblatex);
3168 biblioModule->resetCbxPB->setEnabled(biblatex);
3169 biblioModule->matchBbxPB->setEnabled(biblatex);
3171 // These are useful with biblatex, jurabib and natbib
3172 QString const engine =
3173 biblioModule->citeEngineCO->itemData(
3174 biblioModule->citeEngineCO->currentIndex()).toString();
3175 LyXCiteEngine const * ce = theCiteEnginesList[fromqstr(engine)];
3177 bool const citepack = ce->required("biblatex.sty") || ce->required("jurabib.sty")
3178 || ce->required("natbib.sty");
3179 biblioModule->citePackageOptionsLE->setEnabled(citepack);
3180 biblioModule->citePackageOptionsL->setEnabled(citepack);
3184 void GuiDocument::citeStyleChanged()
3186 QString const engine =
3187 biblioModule->citeEngineCO->itemData(
3188 biblioModule->citeEngineCO->currentIndex()).toString();
3189 QString const currentDef = isBiblatex() ?
3190 biblioModule->biblatexBbxCO->currentText()
3191 : biblioModule->defaultBiblioCO->currentText();
3192 if (theCiteEnginesList[fromqstr(engine)]->isDefaultBiblio(fromqstr(currentDef)))
3193 resetDefaultBibfile();
3199 void GuiDocument::bibtexChanged(int n)
3201 biblioModule->bibtexOptionsLE->setEnabled(
3202 biblioModule->bibtexCO->itemData(n).toString() != "default");
3207 void GuiDocument::updateCiteStyles(vector<string> const & engs, CiteEngineType const & sel)
3209 biblioModule->citeStyleCO->clear();
3211 vector<string>::const_iterator it = engs.begin();
3212 vector<string>::const_iterator end = engs.end();
3213 for (; it != end; ++it) {
3214 if (*it == "default")
3215 biblioModule->citeStyleCO->addItem(qt_("Basic numerical"),
3216 ENGINE_TYPE_DEFAULT);
3217 else if (*it == "authoryear")
3218 biblioModule->citeStyleCO->addItem(qt_("Author-year"),
3219 ENGINE_TYPE_AUTHORYEAR);
3220 else if (*it == "numerical")
3221 biblioModule->citeStyleCO->addItem(qt_("Author-number"),
3222 ENGINE_TYPE_NUMERICAL);
3224 int i = biblioModule->citeStyleCO->findData(sel);
3225 if (biblioModule->citeStyleCO->findData(sel) == -1)
3227 biblioModule->citeStyleCO->setCurrentIndex(i);
3229 biblioModule->citationStyleL->setEnabled(engs.size() > 1);
3230 biblioModule->citeStyleCO->setEnabled(engs.size() > 1);
3234 void GuiDocument::updateEngineType(string const & items, CiteEngineType const & sel)
3236 engine_types_.clear();
3238 for (int n = 0; !token(items, '|', n).empty(); ++n) {
3239 string style = token(items, '|', n);
3240 engine_types_.push_back(style);
3243 updateCiteStyles(engine_types_, sel);
3249 // both of these should take a vector<docstring>
3251 // This is an insanely complicated attempt to make this sort of thing
3252 // work with RTL languages.
3253 docstring formatStrVec(vector<string> const & v, docstring const & s)
3255 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
3259 return translateIfPossible(from_utf8(v[0]));
3260 if (v.size() == 2) {
3261 docstring retval = _("%1$s and %2$s");
3262 retval = subst(retval, _("and"), s);
3263 return bformat(retval, translateIfPossible(from_utf8(v[0])),
3264 translateIfPossible(from_utf8(v[1])));
3266 // The idea here is to format all but the last two items...
3267 int const vSize = v.size();
3268 docstring t2 = _("%1$s, %2$s");
3269 docstring retval = translateIfPossible(from_utf8(v[0]));
3270 for (int i = 1; i < vSize - 2; ++i)
3271 retval = bformat(t2, retval, translateIfPossible(from_utf8(v[i])));
3272 //...and then to plug them, and the last two, into this schema
3273 docstring t = _("%1$s, %2$s, and %3$s");
3274 t = subst(t, _("and"), s);
3275 return bformat(t, retval, translateIfPossible(from_utf8(v[vSize - 2])),
3276 translateIfPossible(from_utf8(v[vSize - 1])));
3279 vector<string> idsToNames(vector<string> const & idList)
3281 vector<string> retval;
3282 vector<string>::const_iterator it = idList.begin();
3283 vector<string>::const_iterator end = idList.end();
3284 for (; it != end; ++it) {
3285 LyXModule const * const mod = theModuleList[*it];
3287 retval.push_back(to_utf8(bformat(_("%1$s (unavailable)"),
3288 translateIfPossible(from_utf8(*it)))));
3290 retval.push_back(mod->getName());
3294 } // end anonymous namespace
3297 void GuiDocument::modulesToParams(BufferParams & bp)
3299 // update list of loaded modules
3300 bp.clearLayoutModules();
3301 int const srows = modules_sel_model_.rowCount();
3302 for (int i = 0; i < srows; ++i)
3303 bp.addLayoutModule(modules_sel_model_.getIDString(i));
3304 updateSelectedModules();
3306 // update the list of removed modules
3307 bp.clearRemovedModules();
3308 LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
3309 list<string>::const_iterator rit = reqmods.begin();
3310 list<string>::const_iterator ren = reqmods.end();
3312 // check each of the default modules
3313 for (; rit != ren; ++rit) {
3314 list<string>::const_iterator mit = bp.getModules().begin();
3315 list<string>::const_iterator men = bp.getModules().end();
3317 for (; mit != men; ++mit) {
3324 // the module isn't present so must have been removed by the user
3325 bp.addRemovedModule(*rit);
3330 void GuiDocument::modulesChanged()
3332 modulesToParams(bp_);
3334 if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()
3335 && (nonModuleChanged_ || shellescapeChanged_)) {
3336 int const ret = Alert::prompt(_("Unapplied changes"),
3337 _("Some changes in the dialog were not yet applied.\n"
3338 "If you do not apply now, they will be lost after this action."),
3339 1, 1, _("&Apply"), _("&Dismiss"));
3344 modulesChanged_ = true;
3345 bp_.makeDocumentClass();
3351 void GuiDocument::updateModuleInfo()
3353 selectionManager->update();
3355 //Module description
3356 bool const focus_on_selected = selectionManager->selectedFocused();
3357 QAbstractItemView * lv;
3358 bool category = false;
3359 if (focus_on_selected) {
3360 lv = modulesModule->selectedLV;
3363 lv = modulesModule->availableLV;
3364 if (lv->selectionModel()->selectedIndexes().isEmpty()) {
3365 modulesModule->infoML->document()->clear();
3368 QModelIndex const & idx = lv->selectionModel()->currentIndex();
3373 if (!focus_on_selected
3374 && modules_av_model_.itemFromIndex(idx)->hasChildren()) {
3375 // This is a category header
3376 modulesModule->infoML->document()->clear();
3380 string const modName = focus_on_selected ?
3381 modules_sel_model_.getIDString(idx.row())
3382 : fromqstr(modules_av_model_.data(idx, Qt::UserRole).toString());
3383 docstring desc = getModuleDescription(modName);
3385 LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
3386 if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
3389 desc += _("Module provided by document class.");
3393 docstring cat = getModuleCategory(modName);
3397 desc += bformat(_("<p><b>Category:</b> %1$s.</p>"),
3398 translateIfPossible(cat));
3402 vector<string> pkglist = getPackageList(modName);
3403 docstring pkgdesc = formatStrVec(pkglist, _("and"));
3404 if (!pkgdesc.empty()) {
3407 desc += bformat(_("<p><b>Package(s) required:</b> %1$s.</p>"), pkgdesc);
3410 pkglist = getRequiredList(modName);
3411 if (!pkglist.empty()) {
3412 vector<string> const reqdescs = idsToNames(pkglist);
3413 pkgdesc = formatStrVec(reqdescs, _("or"));
3416 desc += bformat(_("<p><b>Modules required:</b> %1$s.</p>"), pkgdesc);
3419 pkglist = getExcludedList(modName);
3420 if (!pkglist.empty()) {
3421 vector<string> const reqdescs = idsToNames(pkglist);
3422 pkgdesc = formatStrVec(reqdescs, _( "and"));
3425 desc += bformat(_("<p><b>Modules excluded:</b> %1$s.</p>"), pkgdesc);
3430 desc += bformat(_("<p><b>Filename:</b> <tt>%1$s.module</tt>.</p>"), from_utf8(modName));
3432 if (!isModuleAvailable(modName)) {
3435 desc += _("<p><font color=red><b>WARNING: Some required packages are unavailable!</b></font></p>");
3438 modulesModule->infoML->document()->setHtml(toqstr(desc));
3442 void GuiDocument::updateNumbering()
3444 DocumentClass const & tclass = documentClass();
3446 numberingModule->tocTW->setUpdatesEnabled(false);
3447 numberingModule->tocTW->clear();
3449 int const depth = numberingModule->depthSL->value();
3450 int const toc = numberingModule->tocSL->value();
3451 QString const no = qt_("No");
3452 QString const yes = qt_("Yes");
3453 QTreeWidgetItem * item = nullptr;
3455 DocumentClass::const_iterator lit = tclass.begin();
3456 DocumentClass::const_iterator len = tclass.end();
3457 for (; lit != len; ++lit) {
3458 int const toclevel = lit->toclevel;
3459 if (toclevel != Layout::NOT_IN_TOC && !lit->counter.empty()) {
3460 item = new QTreeWidgetItem(numberingModule->tocTW);
3461 item->setText(0, toqstr(translateIfPossible(lit->name())));
3462 item->setText(1, (toclevel <= depth) ? yes : no);
3463 item->setText(2, (toclevel <= toc) ? yes : no);
3467 numberingModule->tocTW->setUpdatesEnabled(true);
3468 numberingModule->tocTW->update();
3472 void GuiDocument::getTableStyles()
3474 // We look for lyx files in the subdirectory dir of
3476 // 2) build_lyxdir (if not empty)
3478 // in this order. Files with a given sub-hierarchy will
3479 // only be listed once.
3480 // We also consider i18n subdirectories and store them separately.
3483 // The three locations to look at.
3484 string const user = addPath(package().user_support().absFileName(), "tabletemplates");
3485 string const build = addPath(package().build_support().absFileName(), "tabletemplates");
3486 string const system = addPath(package().system_support().absFileName(), "tabletemplates");
3488 dirs << toqstr(user)
3492 for (int i = 0; i < dirs.size(); ++i) {
3493 QString const & dir = dirs.at(i);
3494 QDirIterator it(dir, QDir::Files, QDirIterator::Subdirectories);
3495 while (it.hasNext()) {
3496 QString fn = QFileInfo(it.next()).fileName();
3497 if (!fn.endsWith(".lyx") || fn.contains("_1x"))
3499 QString data = fn.left(fn.lastIndexOf(".lyx"));
3500 QString guiname = data;
3501 guiname = toqstr(translateIfPossible(qstring_to_ucs4(guiname.replace('_', ' '))));
3502 QString relpath = toqstr(makeRelPath(qstring_to_ucs4(fn),
3503 qstring_to_ucs4(dir)));
3504 if (textLayoutModule->tableStyleCO->findData(data) == -1)
3505 textLayoutModule->tableStyleCO->addItem(guiname, data);
3511 void GuiDocument::updateDefaultFormat()
3515 // make a copy in order to consider unapplied changes
3516 BufferParams param_copy = buffer().params();
3517 param_copy.useNonTeXFonts = fontModule->osFontsCB->isChecked();
3518 int const idx = latexModule->classCO->currentIndex();
3520 string const classname = fromqstr(latexModule->classCO->getData(idx));
3521 param_copy.setBaseClass(classname, buffer().layoutPos());
3522 param_copy.makeDocumentClass(true);
3524 outputModule->defaultFormatCO->blockSignals(true);
3525 outputModule->defaultFormatCO->clear();
3526 outputModule->defaultFormatCO->addItem(qt_("Default"),
3527 QVariant(QString("default")));
3528 FormatList const & formats =
3529 param_copy.exportableFormats(true);
3530 for (Format const * f : formats)
3531 outputModule->defaultFormatCO->addItem
3532 (toqstr(translateIfPossible(f->prettyname())),
3533 QVariant(toqstr(f->name())));
3534 outputModule->defaultFormatCO->blockSignals(false);
3538 bool GuiDocument::isChildIncluded(string const & child)
3540 if (includeonlys_.empty())
3542 return (std::find(includeonlys_.begin(),
3543 includeonlys_.end(), child) != includeonlys_.end());
3547 void GuiDocument::applyView()
3549 // auto-validate local layout
3550 if (!localLayout->isValid()) {
3551 localLayout->validate();
3552 if (!localLayout->isValid()) {
3553 setApplyStopped(true);
3554 docPS->setCurrentPanel(N_("Local Layout"));
3560 preambleModule->apply(bp_);
3561 localLayout->apply(bp_);
3564 bp_.suppress_date = latexModule->suppressDateCB->isChecked();
3565 bp_.use_refstyle = latexModule->refstyleCB->isChecked();
3568 string const engine =
3569 fromqstr(biblioModule->citeEngineCO->itemData(
3570 biblioModule->citeEngineCO->currentIndex()).toString());
3571 bp_.setCiteEngine(engine);
3573 CiteEngineType const style = CiteEngineType(biblioModule->citeStyleCO->itemData(
3574 biblioModule->citeStyleCO->currentIndex()).toInt());
3575 if (theCiteEnginesList[engine]->hasEngineType(style))
3576 bp_.setCiteEngineType(style);
3578 bp_.setCiteEngineType(ENGINE_TYPE_DEFAULT);
3580 bp_.splitbib(biblioModule->bibtopicCB->isChecked());
3582 bp_.multibib = fromqstr(biblioModule->bibunitsCO->itemData(
3583 biblioModule->bibunitsCO->currentIndex()).toString());
3585 bp_.setDefaultBiblioStyle(fromqstr(biblioModule->defaultBiblioCO->currentText()));
3587 bp_.biblatex_bibstyle = fromqstr(biblioModule->biblatexBbxCO->currentText());
3588 bp_.biblatex_citestyle = fromqstr(biblioModule->biblatexCbxCO->currentText());
3589 bp_.biblio_opts = fromqstr(biblioModule->citePackageOptionsLE->text());
3591 string const bibtex_command =
3592 fromqstr(biblioModule->bibtexCO->itemData(
3593 biblioModule->bibtexCO->currentIndex()).toString());
3594 string const bibtex_options =
3595 fromqstr(biblioModule->bibtexOptionsLE->text());
3596 if (bibtex_command == "default" || bibtex_options.empty())
3597 bp_.bibtex_command = bibtex_command;
3599 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
3601 if (biblioChanged_) {
3602 buffer().invalidateBibinfoCache();
3603 buffer().removeBiblioTempFiles();
3607 indicesModule->apply(bp_);
3609 // language & quotes
3610 switch (langModule->encodingCO->currentIndex()) {
3611 case EncodingSets::unicode: {
3612 if (!fontModule->osFontsCB->isChecked())
3613 bp_.inputenc = fromqstr(langModule->unicodeEncodingCO->itemData(
3614 langModule->unicodeEncodingCO->currentIndex()).toString());
3617 case EncodingSets::legacy: {
3618 bp_.inputenc = "auto-legacy";
3619 bp_.inputenc = fromqstr(langModule->autoEncodingCO->itemData(
3620 langModule->autoEncodingCO->currentIndex()).toString());
3623 case EncodingSets::custom: {
3624 bp_.inputenc = fromqstr(langModule->customEncodingCO->itemData(
3625 langModule->customEncodingCO->currentIndex()).toString());
3629 // this should never happen
3630 bp_.inputenc = "utf8";
3632 bp_.quotes_style = QuoteStyle(langModule->quoteStyleCO->itemData(
3633 langModule->quoteStyleCO->currentIndex()).toInt());
3634 bp_.dynamic_quotes = langModule->dynamicQuotesCB->isChecked();
3636 QString const langname = langModule->languageCO->itemData(
3637 langModule->languageCO->currentIndex()).toString();
3638 Language const * newlang = lyx::languages.getLanguage(fromqstr(langname));
3639 Cursor & cur = const_cast<BufferView *>(bufferview())->cursor();
3640 // If current cursor language was the document language, then update it too.
3641 if (cur.current_font.language() == bp_.language) {
3642 cur.current_font.setLanguage(newlang);
3643 cur.real_current_font.setLanguage(newlang);
3645 bp_.language = newlang;
3647 QString const pack = langModule->languagePackageCO->itemData(
3648 langModule->languagePackageCO->currentIndex()).toString();
3649 if (pack == "custom")
3651 fromqstr(langModule->languagePackageLE->text());
3653 bp_.lang_package = fromqstr(pack);
3656 bp_.backgroundcolor = set_backgroundcolor;
3657 bp_.isbackgroundcolor = is_backgroundcolor;
3658 bp_.fontcolor = set_fontcolor;
3659 bp_.isfontcolor = is_fontcolor;
3660 bp_.notefontcolor = set_notefontcolor;
3661 bp_.isnotefontcolor = is_notefontcolor;
3662 if (is_notefontcolor) {
3663 // Set information used in statusbar (#12130)
3664 lcolor.setColor("notefontcolor", lyx::X11hexname(set_notefontcolor));
3665 lcolor.setGUIName("notefontcolor", N_("greyedout inset text"));
3667 bp_.boxbgcolor = set_boxbgcolor;
3668 bp_.isboxbgcolor = is_boxbgcolor;
3671 if (bp_.documentClass().hasTocLevels()) {
3672 bp_.tocdepth = numberingModule->tocSL->value();
3673 bp_.secnumdepth = numberingModule->depthSL->value();
3675 bp_.use_lineno = numberingModule->linenoCB->isChecked();
3676 bp_.lineno_opts = fromqstr(numberingModule->linenoLE->text());
3679 bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
3680 bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
3681 bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
3682 bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
3685 bp_.graphics_driver =
3686 tex_graphics[latexModule->psdriverCO->currentIndex()];
3689 int idx = latexModule->classCO->currentIndex();
3691 string const classname = fromqstr(latexModule->classCO->getData(idx));
3692 bp_.setBaseClass(classname, buffer().layoutPos());
3696 modulesToParams(bp_);
3699 map<string, string> const & packages = BufferParams::auto_packages();
3700 for (map<string, string>::const_iterator it = packages.begin();
3701 it != packages.end(); ++it) {
3702 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
3705 int row = mathsModule->packagesTW->row(item);
3708 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1)->layout()->itemAt(0)->widget();
3709 if (rb->isChecked()) {
3710 bp_.use_package(it->first, BufferParams::package_auto);
3713 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2)->layout()->itemAt(0)->widget();
3714 if (rb->isChecked()) {
3715 bp_.use_package(it->first, BufferParams::package_on);
3718 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3)->layout()->itemAt(0)->widget();
3719 if (rb->isChecked())
3720 bp_.use_package(it->first, BufferParams::package_off);
3722 // if math is indented
3723 bp_.is_math_indent = mathsModule->MathIndentCB->isChecked();
3724 if (bp_.is_math_indent) {
3725 // if formulas are indented
3726 if (mathsModule->MathIndentCO->itemData(mathsModule->MathIndentCO->currentIndex()) == "custom") {
3727 Length mathindent(widgetsToLength(mathsModule->MathIndentLE,
3728 mathsModule->MathIndentLengthCO));
3729 bp_.setMathIndent(mathindent);
3732 bp_.setMathIndent(Length());
3734 switch (mathsModule->MathNumberingPosCO->currentIndex()) {
3736 bp_.math_numbering_side = BufferParams::LEFT;
3739 bp_.math_numbering_side = BufferParams::DEFAULT;
3742 bp_.math_numbering_side = BufferParams::RIGHT;
3745 // this should never happen
3746 bp_.math_numbering_side = BufferParams::DEFAULT;
3751 if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
3752 bp_.pagestyle = "default";
3754 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
3755 for (size_t i = 0; i != pagestyles.size(); ++i)
3756 if (pagestyles[i].second == style_gui)
3757 bp_.pagestyle = pagestyles[i].first;
3761 switch (textLayoutModule->lspacingCO->currentIndex()) {
3763 bp_.spacing().set(Spacing::Single);
3766 bp_.spacing().set(Spacing::Onehalf);
3769 bp_.spacing().set(Spacing::Double);
3772 string s = widgetToDoubleStr(textLayoutModule->lspacingLE);
3774 bp_.spacing().set(Spacing::Single);
3776 bp_.spacing().set(Spacing::Other, s);
3781 if (textLayoutModule->twoColumnCB->isChecked())
3786 bp_.justification = textLayoutModule->justCB->isChecked();
3788 if (textLayoutModule->indentRB->isChecked()) {
3789 // if paragraphs are separated by an indentation
3790 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
3791 if (textLayoutModule->indentCO->itemData(textLayoutModule->indentCO->currentIndex()) == "custom") {
3792 Length parindent(widgetsToLength(textLayoutModule->indentLE,
3793 textLayoutModule->indentLengthCO));
3794 bp_.setParIndent(parindent);
3797 bp_.setParIndent(Length());
3799 // if paragraphs are separated by a skip
3800 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
3801 VSpace::VSpaceKind spacekind =
3802 VSpace::VSpaceKind(textLayoutModule->skipCO->itemData(textLayoutModule->skipCO->currentIndex()).toInt());
3803 switch (spacekind) {
3804 case VSpace::SMALLSKIP:
3805 case VSpace::MEDSKIP:
3806 case VSpace::BIGSKIP:
3807 case VSpace::HALFLINE:
3808 case VSpace::FULLLINE:
3809 bp_.setDefSkip(VSpace(spacekind));
3811 case VSpace::LENGTH: {
3813 widgetsToLength(textLayoutModule->skipLE,
3814 textLayoutModule->skipLengthCO)
3820 // this should never happen
3821 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
3825 bp_.tablestyle = fromqstr(textLayoutModule->tableStyleCO->itemData(
3826 textLayoutModule->tableStyleCO->currentIndex()).toString());
3829 fromqstr(latexModule->optionsLE->text());
3831 bp_.use_default_options =
3832 latexModule->defaultOptionsCB->isChecked();
3834 if (latexModule->childDocGB->isChecked())
3836 fromqstr(latexModule->childDocLE->text());
3838 bp_.master = string();
3841 bp_.clearIncludedChildren();
3842 updateIncludeonlys();
3843 if (masterChildModule->includeonlyRB->isChecked()) {
3844 list<string>::const_iterator it = includeonlys_.begin();
3845 for (; it != includeonlys_.end() ; ++it) {
3846 bp_.addIncludedChildren(*it);
3849 if (masterChildModule->maintainCRNoneRB->isChecked())
3850 bp_.maintain_unincluded_children =
3851 BufferParams::CM_None;
3852 else if (masterChildModule->maintainCRMostlyRB->isChecked())
3853 bp_.maintain_unincluded_children =
3854 BufferParams::CM_Mostly;
3856 bp_.maintain_unincluded_children =
3857 BufferParams::CM_Strict;
3858 updateIncludeonlyDisplay();
3861 bp_.float_placement = floatModule->getPlacement();
3862 bp_.float_alignment = floatModule->getAlignment();
3865 // text should have passed validation
3866 idx = listingsModule->packageCO->currentIndex();
3867 bp_.use_minted = string(lst_packages[idx]) == "Minted";
3868 bp_.listings_params =
3869 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
3872 bp_.default_output_format = fromqstr(outputModule->defaultFormatCO->itemData(
3873 outputModule->defaultFormatCO->currentIndex()).toString());
3875 bool const nontexfonts = fontModule->osFontsCB->isChecked();
3876 bp_.useNonTeXFonts = nontexfonts;
3878 bp_.shell_escape = outputModule->shellescapeCB->isChecked();
3879 if (!bp_.shell_escape)
3880 theSession().shellescapeFiles().remove(buffer().absFileName());
3881 else if (!theSession().shellescapeFiles().find(buffer().absFileName()))
3882 theSession().shellescapeFiles().insert(buffer().absFileName());
3883 Buffer & buf = const_cast<Buffer &>(buffer());
3884 buf.params().shell_escape = bp_.shell_escape;
3886 bp_.output_sync = outputModule->outputsyncCB->isChecked();
3888 bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
3890 int mathfmt = outputModule->mathoutCB->currentIndex();
3893 BufferParams::MathOutput const mo =
3894 static_cast<BufferParams::MathOutput>(mathfmt);
3895 bp_.html_math_output = mo;
3896 bp_.html_be_strict = outputModule->strictCB->isChecked();
3897 bp_.html_css_as_file = outputModule->cssCB->isChecked();
3898 bp_.html_math_img_scale = outputModule->mathimgSB->value();
3899 bp_.display_pixel_ratio = theGuiApp()->pixelRatio();
3901 int tablefmt = outputModule->tableoutCB->currentIndex();
3904 auto const to = static_cast<BufferParams::TableOutput>(tablefmt);
3905 bp_.docbook_table_output = to;
3907 int mathmlprefix = outputModule->mathmlprefixCB->currentIndex();
3908 if (mathmlprefix == -1)
3910 auto const mp = static_cast<BufferParams::MathMLNameSpacePrefix>(mathmlprefix);
3911 bp_.docbook_mathml_prefix = mp;
3913 bp_.save_transient_properties =
3914 outputModule->saveTransientPropertiesCB->isChecked();
3915 bp_.postpone_fragile_content =
3916 outputModule->postponeFragileCB->isChecked();
3919 bp_.fonts_roman[nontexfonts] =
3920 fromqstr(fontModule->fontsRomanCO->
3921 getData(fontModule->fontsRomanCO->currentIndex()));
3922 bp_.fonts_roman[!nontexfonts] = fromqstr(fontModule->font_roman);
3923 bp_.font_roman_opts = fromqstr(fontModule->fontspecRomanLE->text());
3925 bp_.fonts_sans[nontexfonts] =
3926 fromqstr(fontModule->fontsSansCO->
3927 getData(fontModule->fontsSansCO->currentIndex()));
3928 bp_.fonts_sans[!nontexfonts] = fromqstr(fontModule->font_sans);
3929 bp_.font_sans_opts = fromqstr(fontModule->fontspecSansLE->text());
3931 bp_.fonts_typewriter[nontexfonts] =
3932 fromqstr(fontModule->fontsTypewriterCO->
3933 getData(fontModule->fontsTypewriterCO->currentIndex()));
3934 bp_.fonts_typewriter[!nontexfonts] = fromqstr(fontModule->font_typewriter);
3935 bp_.font_typewriter_opts = fromqstr(fontModule->fontspecTypewriterLE->text());
3937 bp_.fonts_math[nontexfonts] =
3938 fromqstr(fontModule->fontsMathCO->
3939 itemData(fontModule->fontsMathCO->currentIndex()).toString());
3940 bp_.fonts_math[!nontexfonts] = fromqstr(fontModule->font_math);
3942 QString const fontenc =
3943 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
3944 if (fontenc == "custom")
3945 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
3947 bp_.fontenc = fromqstr(fontenc);
3950 fromqstr(fontModule->cjkFontLE->text());
3952 bp_.use_microtype = fontModule->microtypeCB->isChecked();
3953 bp_.use_dash_ligatures = !fontModule->dashesCB->isChecked();
3955 bp_.fonts_sans_scale[nontexfonts] = fontModule->scaleSansSB->value();
3956 bp_.fonts_sans_scale[!nontexfonts] = fontModule->font_sf_scale;
3958 bp_.fonts_typewriter_scale[nontexfonts] = fontModule->scaleTypewriterSB->value();
3959 bp_.fonts_typewriter_scale[!nontexfonts] = fontModule->font_tt_scale;
3961 bp_.fonts_expert_sc = fontModule->fontScCB->isChecked();
3963 bp_.fonts_roman_osf = fontModule->fontOsfCB->isChecked();
3964 bp_.fonts_sans_osf = fontModule->fontSansOsfCB->isChecked();
3965 bp_.fonts_typewriter_osf = fontModule->fontTypewriterOsfCB->isChecked();
3967 bp_.fonts_default_family = GuiDocument::fontfamilies[
3968 fontModule->fontsDefaultCO->currentIndex()];
3970 if (fontModule->fontsizeCO->currentIndex() == 0)
3971 bp_.fontsize = "default";
3974 fromqstr(fontModule->fontsizeCO->currentText());
3977 bp_.papersize = PAPER_SIZE(
3978 pageLayoutModule->papersizeCO->currentIndex());
3980 bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
3981 pageLayoutModule->paperwidthUnitCO);
3983 bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
3984 pageLayoutModule->paperheightUnitCO);
3986 if (pageLayoutModule->facingPagesCB->isChecked())
3987 bp_.sides = TwoSides;
3989 bp_.sides = OneSide;
3991 if (pageLayoutModule->landscapeRB->isChecked())
3992 bp_.orientation = ORIENTATION_LANDSCAPE;
3994 bp_.orientation = ORIENTATION_PORTRAIT;
3997 bp_.use_geometry = !marginsModule->marginCB->isChecked();
3999 Ui::MarginsUi const * m = marginsModule;
4001 bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
4002 bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
4003 bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
4004 bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
4005 bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
4006 bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
4007 bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
4008 bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
4011 branchesModule->apply(bp_);
4014 PDFOptions & pdf = bp_.pdfoptions();
4015 pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
4016 pdf.title = fromqstr(pdfSupportModule->titleLE->text());
4017 pdf.author = fromqstr(pdfSupportModule->authorLE->text());
4018 pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
4019 pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
4021 pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
4022 pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
4023 pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
4024 pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
4026 pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
4027 pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
4028 pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
4029 pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
4031 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
4032 if (pdfSupportModule->fullscreenCB->isChecked())
4033 pdf.pagemode = pdf.pagemode_fullscreen;
4035 pdf.pagemode.clear();
4036 pdf.quoted_options = pdf.quoted_options_check(
4037 fromqstr(pdfSupportModule->optionsTE->toPlainText()));
4038 bp_.document_metadata = qstring_to_ucs4(pdfSupportModule->metadataTE->toPlainText()
4039 .trimmed().replace(QRegularExpression("\n+"), "\n"));
4042 bp_.track_changes = changesModule->trackChangesCB->isChecked();
4043 bp_.output_changes = changesModule->outputChangesCB->isChecked();
4044 bool const cb_switched_off = (bp_.change_bars
4045 && !changesModule->changeBarsCB->isChecked());
4046 bp_.change_bars = changesModule->changeBarsCB->isChecked();
4047 if (cb_switched_off)
4048 // if change bars have been switched off,
4049 // we need to ditch the aux file
4050 buffer().requireFreshStart(true);
4053 nonModuleChanged_ = false;
4054 shellescapeChanged_ = false;
4058 void GuiDocument::paramsToDialog()
4060 // set the default unit
4061 Length::UNIT const default_unit = Length::defaultUnit();
4064 preambleModule->update(bp_, id());
4065 localLayout->update(bp_, id());
4068 latexModule->suppressDateCB->setChecked(bp_.suppress_date);
4069 latexModule->refstyleCB->setChecked(bp_.use_refstyle);
4072 string const cite_engine = bp_.citeEngine();
4074 biblioModule->citeEngineCO->setCurrentIndex(
4075 biblioModule->citeEngineCO->findData(toqstr(cite_engine)));
4077 updateEngineType(documentClass().opt_enginetype(),
4078 bp_.citeEngineType());
4080 checkPossibleCiteEngines();
4082 biblioModule->citeStyleCO->setCurrentIndex(
4083 biblioModule->citeStyleCO->findData(bp_.citeEngineType()));
4085 biblioModule->bibtopicCB->setChecked(bp_.splitbib());
4087 biblioModule->bibunitsCO->clear();
4088 biblioModule->bibunitsCO->addItem(qt_("No"), QString());
4089 if (documentClass().hasLaTeXLayout("part"))
4090 biblioModule->bibunitsCO->addItem(qt_("per part"), toqstr("part"));
4091 if (documentClass().hasLaTeXLayout("chapter"))
4092 biblioModule->bibunitsCO->addItem(qt_("per chapter"), toqstr("chapter"));
4093 if (documentClass().hasLaTeXLayout("section"))
4094 biblioModule->bibunitsCO->addItem(qt_("per section"), toqstr("section"));
4095 if (documentClass().hasLaTeXLayout("subsection"))
4096 biblioModule->bibunitsCO->addItem(qt_("per subsection"), toqstr("subsection"));
4097 biblioModule->bibunitsCO->addItem(qt_("per child document"), toqstr("child"));
4099 int const mbpos = biblioModule->bibunitsCO->findData(toqstr(bp_.multibib));
4101 biblioModule->bibunitsCO->setCurrentIndex(mbpos);
4103 biblioModule->bibunitsCO->setCurrentIndex(0);
4105 updateEngineDependends();
4108 updateDefaultBiblio(bp_.biblatex_bibstyle, "bbx");
4109 updateDefaultBiblio(bp_.biblatex_citestyle, "cbx");
4111 updateDefaultBiblio(bp_.defaultBiblioStyle());
4113 biblioModule->citePackageOptionsLE->setText(toqstr(bp_.biblio_opts));
4117 split(bp_.bibtex_command, command, ' ');
4119 int bpos = biblioModule->bibtexCO->findData(toqstr(command));
4121 // We add and set the unknown compiler, indicating that it is unavailable
4122 // to assure document compilation and for security reasons, a fallback
4123 // will be used on document processing stage
4124 biblioModule->bibtexCO->addItem(toqstr(bformat(_("%1$s (not available)"),
4125 from_utf8(command))), toqstr(command));
4126 bpos = biblioModule->bibtexCO->findData(toqstr(command));
4128 biblioModule->bibtexCO->setCurrentIndex(bpos);
4129 biblioModule->bibtexOptionsLE->setText(toqstr(options).trimmed());
4130 biblioModule->bibtexOptionsLE->setEnabled(
4131 biblioModule->bibtexCO->currentIndex() != 0);
4133 biblioChanged_ = false;
4136 // We may be called when there is no Buffer, e.g., when
4137 // the last view has just been closed.
4138 bool const isReadOnly = isBufferAvailable() ? buffer().isReadonly() : false;
4139 indicesModule->update(bp_, isReadOnly);
4141 // language & quotes
4142 int const pos = langModule->languageCO->findData(toqstr(
4143 bp_.language->lang()));
4144 langModule->languageCO->setCurrentIndex(pos);
4146 updateQuoteStyles();
4148 langModule->quoteStyleCO->setCurrentIndex(
4149 langModule->quoteStyleCO->findData(static_cast<int>(bp_.quotes_style)));
4150 langModule->dynamicQuotesCB->setChecked(bp_.dynamic_quotes);
4152 // LaTeX input encoding: set after the fonts (see below)
4154 int p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
4156 langModule->languagePackageCO->setCurrentIndex(
4157 langModule->languagePackageCO->findData("custom"));
4158 langModule->languagePackageLE->setText(toqstr(bp_.lang_package));
4160 langModule->languagePackageCO->setCurrentIndex(p);
4161 langModule->languagePackageLE->clear();
4165 if (bp_.isfontcolor) {
4166 colorModule->mainTextCF->setStyleSheet(
4167 colorFrameStyleSheet(rgb2qcolor(bp_.fontcolor)));
4168 colorModule->mainTextCF->setVisible(true);
4170 colorModule->mainTextCF->setVisible(false);
4171 set_fontcolor = bp_.fontcolor;
4172 is_fontcolor = bp_.isfontcolor;
4174 colorModule->noteFontCF->setStyleSheet(
4175 colorFrameStyleSheet(rgb2qcolor(bp_.notefontcolor)));
4176 set_notefontcolor = bp_.notefontcolor;
4177 is_notefontcolor = bp_.isnotefontcolor;
4179 if (bp_.isbackgroundcolor) {
4180 colorModule->pageBackgroundCF->setStyleSheet(
4181 colorFrameStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
4182 colorModule->pageBackgroundCF->setVisible(true);
4184 colorModule->pageBackgroundCF->setVisible(false);
4185 set_backgroundcolor = bp_.backgroundcolor;
4186 is_backgroundcolor = bp_.isbackgroundcolor;
4188 colorModule->boxBackgroundCF->setStyleSheet(
4189 colorFrameStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
4190 set_boxbgcolor = bp_.boxbgcolor;
4191 is_boxbgcolor = bp_.isboxbgcolor;
4194 int const min_toclevel = documentClass().min_toclevel();
4195 int const max_toclevel = documentClass().max_toclevel();
4196 if (documentClass().hasTocLevels()) {
4197 numberingModule->setEnabled(true);
4198 numberingModule->depthSL->setMinimum(min_toclevel - 1);
4199 numberingModule->depthSL->setMaximum(max_toclevel);
4200 numberingModule->depthSL->setValue(bp_.secnumdepth);
4201 numberingModule->tocSL->setMaximum(min_toclevel - 1);
4202 numberingModule->tocSL->setMaximum(max_toclevel);
4203 numberingModule->tocSL->setValue(bp_.tocdepth);
4206 numberingModule->setEnabled(false);
4207 numberingModule->tocTW->clear();
4210 numberingModule->linenoCB->setChecked(bp_.use_lineno);
4211 numberingModule->linenoLE->setEnabled(bp_.use_lineno);
4212 numberingModule->linenoLA->setEnabled(bp_.use_lineno);
4213 numberingModule->linenoLE->setText(toqstr(bp_.lineno_opts));
4216 bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
4217 bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
4218 bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
4219 bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
4220 bulletsModule->init();
4223 int nitem = findToken(tex_graphics, bp_.graphics_driver);
4225 latexModule->psdriverCO->setCurrentIndex(nitem);
4229 mathsModule->MathIndentCB->setChecked(bp_.is_math_indent);
4230 if (bp_.is_math_indent) {
4231 Length const mathindent = bp_.getMathIndent();
4233 if (!mathindent.empty()) {
4234 lengthToWidgets(mathsModule->MathIndentLE,
4235 mathsModule->MathIndentLengthCO,
4236 mathindent, default_unit);
4239 mathsModule->MathIndentCO->setCurrentIndex(indent);
4240 enableMathIndent(indent);
4242 switch(bp_.math_numbering_side) {
4243 case BufferParams::LEFT:
4244 mathsModule->MathNumberingPosCO->setCurrentIndex(0);
4246 case BufferParams::DEFAULT:
4247 mathsModule->MathNumberingPosCO->setCurrentIndex(1);
4249 case BufferParams::RIGHT:
4250 mathsModule->MathNumberingPosCO->setCurrentIndex(2);
4253 map<string, string> const & packages = BufferParams::auto_packages();
4254 for (map<string, string>::const_iterator it = packages.begin();
4255 it != packages.end(); ++it) {
4256 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
4259 int row = mathsModule->packagesTW->row(item);
4260 switch (bp_.use_package(it->first)) {
4261 case BufferParams::package_off: {
4263 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3)->layout()->itemAt(0)->widget();
4264 rb->setChecked(true);
4267 case BufferParams::package_on: {
4269 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2)->layout()->itemAt(0)->widget();
4270 rb->setChecked(true);
4273 case BufferParams::package_auto: {
4275 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1)->layout()->itemAt(0)->widget();
4276 rb->setChecked(true);
4282 switch (bp_.spacing().getSpace()) {
4283 case Spacing::Other: nitem = 3; break;
4284 case Spacing::Double: nitem = 2; break;
4285 case Spacing::Onehalf: nitem = 1; break;
4286 case Spacing::Default: case Spacing::Single: nitem = 0; break;
4290 string const & layoutID = bp_.baseClassID();
4291 setLayoutComboByIDString(layoutID);
4293 updatePagestyle(documentClass().opt_pagestyle(),
4296 textLayoutModule->lspacingCO->setCurrentIndex(nitem);
4297 if (bp_.spacing().getSpace() == Spacing::Other) {
4298 doubleToWidget(textLayoutModule->lspacingLE,
4299 bp_.spacing().getValueAsString());
4302 int ts = textLayoutModule->tableStyleCO->findData(toqstr(bp_.tablestyle));
4304 textLayoutModule->tableStyleCO->setCurrentIndex(ts);
4306 if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
4307 textLayoutModule->indentRB->setChecked(true);
4308 string parindent = bp_.getParIndent().asString();
4309 QString indent = toqstr("default");
4310 if (!parindent.empty()) {
4311 lengthToWidgets(textLayoutModule->indentLE,
4312 textLayoutModule->indentLengthCO,
4313 parindent, default_unit);
4314 indent = toqstr("custom");
4316 textLayoutModule->indentCO->setCurrentIndex(textLayoutModule->indentCO->findData(indent));
4317 setIndent(textLayoutModule->indentCO->currentIndex());
4319 textLayoutModule->skipRB->setChecked(true);
4320 VSpace::VSpaceKind skip = bp_.getDefSkip().kind();
4321 textLayoutModule->skipCO->setCurrentIndex(textLayoutModule->skipCO->findData(skip));
4322 if (skip == VSpace::LENGTH) {
4323 string const length = bp_.getDefSkip().asLyXCommand();
4324 lengthToWidgets(textLayoutModule->skipLE,
4325 textLayoutModule->skipLengthCO,
4326 length, default_unit);
4328 setSkip(textLayoutModule->skipCO->currentIndex());
4331 textLayoutModule->twoColumnCB->setChecked(
4333 textLayoutModule->justCB->setChecked(bp_.justification);
4335 if (!bp_.options.empty()) {
4336 latexModule->optionsLE->setText(
4337 toqstr(bp_.options));
4339 latexModule->optionsLE->setText(QString());
4343 latexModule->defaultOptionsCB->setChecked(
4344 bp_.use_default_options);
4345 updateSelectedModules();
4346 selectionManager->updateProvidedModules(
4347 bp_.baseClass()->providedModules());
4348 selectionManager->updateExcludedModules(
4349 bp_.baseClass()->excludedModules());
4351 if (!documentClass().options().empty()) {
4352 latexModule->defaultOptionsLE->setText(
4353 toqstr(documentClass().options()));
4355 latexModule->defaultOptionsLE->setText(
4356 toqstr(_("[No options predefined]")));
4359 latexModule->defaultOptionsLE->setEnabled(
4360 bp_.use_default_options
4361 && !documentClass().options().empty());
4363 latexModule->defaultOptionsCB->setEnabled(
4364 !documentClass().options().empty());
4366 if (!bp_.master.empty()) {
4367 latexModule->childDocGB->setChecked(true);
4368 latexModule->childDocLE->setText(
4369 toqstr(bp_.master));
4371 latexModule->childDocLE->setText(QString());
4372 latexModule->childDocGB->setChecked(false);
4376 if (!bufferview() || !buffer().hasChildren()) {
4377 masterChildModule->childrenTW->clear();
4378 includeonlys_.clear();
4379 docPS->showPanel("Child Documents", false);
4380 if (docPS->isCurrentPanel("Child Documents"))
4381 docPS->setCurrentPanel("Document Class");
4383 docPS->showPanel("Child Documents", true);
4384 masterChildModule->setEnabled(true);
4385 includeonlys_ = bp_.getIncludedChildren();
4386 updateIncludeonlys();
4387 updateIncludeonlyDisplay();
4389 switch (bp_.maintain_unincluded_children) {
4390 case BufferParams::CM_None:
4391 masterChildModule->maintainCRNoneRB->setChecked(true);
4393 case BufferParams::CM_Mostly:
4394 masterChildModule->maintainCRMostlyRB->setChecked(true);
4396 case BufferParams::CM_Strict:
4398 masterChildModule->maintainCRStrictRB->setChecked(true);
4403 floatModule->setPlacement(bp_.float_placement);
4404 floatModule->setAlignment(bp_.float_alignment);
4407 // break listings_params to multiple lines
4409 InsetListingsParams(bp_.listings_params).separatedParams();
4410 listingsModule->listingsED->setPlainText(toqstr(lstparams));
4411 int nn = findToken(lst_packages, bp_.use_minted ? "Minted" : "Listings");
4413 listingsModule->packageCO->setCurrentIndex(nn);
4416 // some languages only work with Polyglossia (which requires non-TeX fonts)
4417 Language const * lang = lyx::languages.getLanguage(
4418 fromqstr(langModule->languageCO->itemData(
4419 langModule->languageCO->currentIndex()).toString()));
4420 bool const need_fontspec =
4421 lang->babel().empty() && !lang->polyglossia().empty()
4422 && lang->required() != "CJK" && lang->required() != "japanese";
4423 bool const os_fonts_available =
4424 bp_.baseClass()->outputType() == lyx::LATEX
4425 && LaTeXFeatures::isAvailable("fontspec");
4426 fontModule->osFontsCB->setEnabled(os_fonts_available && !need_fontspec);
4427 fontModule->osFontsCB->setChecked(
4428 (os_fonts_available && bp_.useNonTeXFonts) || need_fontspec);
4429 updateFontsize(documentClass().opt_fontsize(),
4432 QString font = toqstr(bp_.fontsRoman());
4433 bool foundfont = fontModule->fontsRomanCO->set(font, false);
4435 fontModule->fontsRomanCO->addItemSort(font, font + qt_(" (not installed)"),
4436 qt_("Uninstalled used fonts"),
4437 qt_("This font is not installed and won't be used in output"),
4438 false, false, false, true);
4439 fontModule->fontsRomanCO->set(font);
4441 fontModule->font_roman = toqstr(bp_.fonts_roman[!bp_.useNonTeXFonts]);
4443 font = toqstr(bp_.fontsSans());
4444 foundfont = fontModule->fontsSansCO->set(font, false);
4446 fontModule->fontsSansCO->addItemSort(font, font + qt_(" (not installed)"),
4447 qt_("Uninstalled used fonts"),
4448 qt_("This font is not installed and won't be used in output"),
4449 false, false, false, true);
4450 fontModule->fontsSansCO->set(font);
4452 fontModule->font_sans = toqstr(bp_.fonts_sans[!bp_.useNonTeXFonts]);
4454 font = toqstr(bp_.fontsTypewriter());
4455 foundfont = fontModule->fontsTypewriterCO->set(font, false);
4457 fontModule->fontsTypewriterCO->addItemSort(font, font + qt_(" (not installed)"),
4458 qt_("Uninstalled used fonts"),
4459 qt_("This font is not installed and won't be used in output"),
4460 false, false, false, true);
4461 fontModule->fontsTypewriterCO->set(font);
4463 fontModule->font_typewriter = toqstr(bp_.fonts_typewriter[!bp_.useNonTeXFonts]);
4465 font = toqstr(bp_.fontsMath());
4466 int mpos = fontModule->fontsMathCO->findData(font);
4468 mpos = fontModule->fontsMathCO->count();
4469 fontModule->fontsMathCO->addItem(font + qt_(" (not installed)"), font);
4471 fontModule->fontsMathCO->setCurrentIndex(mpos);
4472 fontModule->font_math = toqstr(bp_.fonts_math[!bp_.useNonTeXFonts]);
4474 if (bp_.useNonTeXFonts && os_fonts_available) {
4475 fontModule->fontencLA->setEnabled(false);
4476 fontModule->fontencCO->setEnabled(false);
4477 fontModule->fontencLE->setEnabled(false);
4479 fontModule->fontencLA->setEnabled(true);
4480 fontModule->fontencCO->setEnabled(true);
4481 fontModule->fontencLE->setEnabled(true);
4482 romanChanged(fontModule->fontsRomanCO->currentIndex());
4483 sansChanged(fontModule->fontsSansCO->currentIndex());
4484 ttChanged(fontModule->fontsTypewriterCO->currentIndex());
4487 if (!bp_.fonts_cjk.empty())
4488 fontModule->cjkFontLE->setText(
4489 toqstr(bp_.fonts_cjk));
4491 fontModule->cjkFontLE->setText(QString());
4493 fontModule->microtypeCB->setChecked(bp_.use_microtype);
4494 fontModule->dashesCB->setChecked(!bp_.use_dash_ligatures);
4496 fontModule->fontScCB->setChecked(bp_.fonts_expert_sc);
4497 fontModule->fontOsfCB->setChecked(bp_.fonts_roman_osf);
4498 fontModule->fontSansOsfCB->setChecked(bp_.fonts_sans_osf);
4499 fontModule->fontTypewriterOsfCB->setChecked(bp_.fonts_typewriter_osf);
4500 fontModule->scaleSansSB->setValue(bp_.fontsSansScale());
4501 fontModule->font_sf_scale = bp_.fonts_sans_scale[!bp_.useNonTeXFonts];
4502 fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale());
4503 fontModule->font_tt_scale = bp_.fonts_typewriter_scale[!bp_.useNonTeXFonts];
4504 if (!bp_.font_roman_opts.empty())
4505 fontModule->fontspecRomanLE->setText(
4506 toqstr(bp_.font_roman_opts));
4508 fontModule->fontspecRomanLE->setText(QString());
4509 if (!bp_.font_sans_opts.empty())
4510 fontModule->fontspecSansLE->setText(
4511 toqstr(bp_.font_sans_opts));
4513 fontModule->fontspecSansLE->setText(QString());
4514 if (!bp_.font_typewriter_opts.empty())
4515 fontModule->fontspecTypewriterLE->setText(
4516 toqstr(bp_.font_typewriter_opts));
4518 fontModule->fontspecTypewriterLE->setText(QString());
4520 nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
4522 fontModule->fontsDefaultCO->setCurrentIndex(nn);
4524 if (bp_.fontenc == "auto" || bp_.fontenc == "default") {
4525 fontModule->fontencCO->setCurrentIndex(
4526 fontModule->fontencCO->findData(toqstr(bp_.fontenc)));
4527 fontModule->fontencLE->setEnabled(false);
4529 fontModule->fontencCO->setCurrentIndex(
4530 fontModule->fontencCO->findData("custom"));
4531 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
4534 // LaTeX input encoding
4535 // Set after fonts because non-tex fonts override "\inputencoding".
4536 inputencodingToDialog();
4539 // This must be set _after_ fonts since updateDefaultFormat()
4540 // checks osFontsCB settings.
4541 // update combobox with formats
4542 updateDefaultFormat();
4543 int index = outputModule->defaultFormatCO->findData(toqstr(
4544 bp_.default_output_format));
4545 // set to default if format is not found
4548 outputModule->defaultFormatCO->setCurrentIndex(index);
4550 outputModule->shellescapeCB->setChecked(bp_.shell_escape);
4551 outputModule->outputsyncCB->setChecked(bp_.output_sync);
4552 outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
4553 outputModule->synccustomCB->setEnabled(bp_.output_sync);
4554 outputModule->synccustomLA->setEnabled(bp_.output_sync);
4556 outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
4557 outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
4558 outputModule->strictCB->setChecked(bp_.html_be_strict);
4559 outputModule->cssCB->setChecked(bp_.html_css_as_file);
4561 outputModule->tableoutCB->setCurrentIndex(bp_.docbook_table_output);
4562 outputModule->mathmlprefixCB->setCurrentIndex(bp_.docbook_mathml_prefix);
4564 outputModule->saveTransientPropertiesCB
4565 ->setChecked(bp_.save_transient_properties);
4566 outputModule->postponeFragileCB
4567 ->setChecked(bp_.postpone_fragile_content);
4570 bool const extern_geometry =
4571 documentClass().provides("geometry");
4572 int const psize = bp_.papersize;
4573 pageLayoutModule->papersizeCO->setCurrentIndex(psize);
4574 setCustomPapersize(!extern_geometry && psize == 1);
4575 pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
4577 bool const landscape =
4578 bp_.orientation == ORIENTATION_LANDSCAPE;
4579 pageLayoutModule->landscapeRB->setChecked(landscape);
4580 pageLayoutModule->portraitRB->setChecked(!landscape);
4581 pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
4582 pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
4584 pageLayoutModule->facingPagesCB->setChecked(
4585 bp_.sides == TwoSides);
4587 lengthToWidgets(pageLayoutModule->paperwidthLE,
4588 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, default_unit);
4589 lengthToWidgets(pageLayoutModule->paperheightLE,
4590 pageLayoutModule->paperheightUnitCO, bp_.paperheight, default_unit);
4593 Ui::MarginsUi * m = marginsModule;
4597 lengthToWidgets(m->topLE, m->topUnit,
4598 bp_.topmargin, default_unit);
4600 lengthToWidgets(m->bottomLE, m->bottomUnit,
4601 bp_.bottommargin, default_unit);
4603 lengthToWidgets(m->innerLE, m->innerUnit,
4604 bp_.leftmargin, default_unit);
4606 lengthToWidgets(m->outerLE, m->outerUnit,
4607 bp_.rightmargin, default_unit);
4609 lengthToWidgets(m->headheightLE, m->headheightUnit,
4610 bp_.headheight, default_unit);
4612 lengthToWidgets(m->headsepLE, m->headsepUnit,
4613 bp_.headsep, default_unit);
4615 lengthToWidgets(m->footskipLE, m->footskipUnit,
4616 bp_.footskip, default_unit);
4618 lengthToWidgets(m->columnsepLE, m->columnsepUnit,
4619 bp_.columnsep, default_unit);
4622 updateUnknownBranches();
4623 branchesModule->update(bp_);
4626 PDFOptions const & pdf = bp_.pdfoptions();
4627 pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
4628 if (bp_.documentClass().provides("hyperref"))
4629 pdfSupportModule->use_hyperrefGB->setTitle(qt_("C&ustomize Hyperref Options"));
4631 pdfSupportModule->use_hyperrefGB->setTitle(qt_("&Use Hyperref Support"));
4632 pdfSupportModule->titleLE->setText(toqstr(pdf.title));
4633 pdfSupportModule->authorLE->setText(toqstr(pdf.author));
4634 pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
4635 pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
4637 pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
4638 pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
4639 pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
4641 pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
4642 pdfSupportModule->bookmarksopenlevelSB->setEnabled(pdf.bookmarksopen);
4643 pdfSupportModule->bookmarksopenlevelLA->setEnabled(pdf.bookmarksopen);
4645 pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
4646 pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
4647 pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
4648 pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
4650 nn = findToken(backref_opts, pdf.backref);
4652 pdfSupportModule->backrefCO->setCurrentIndex(nn);
4654 pdfSupportModule->fullscreenCB->setChecked
4655 (pdf.pagemode == pdf.pagemode_fullscreen);
4657 pdfSupportModule->optionsTE->setPlainText(
4658 toqstr(pdf.quoted_options));
4660 pdfSupportModule->metadataTE->setPlainText(
4661 toqstr(rtrim(bp_.document_metadata, "\n")));
4664 changesModule->trackChangesCB->setChecked(bp_.track_changes);
4665 changesModule->outputChangesCB->setChecked(bp_.output_changes);
4666 changesModule->changeBarsCB->setChecked(bp_.change_bars);
4667 changesModule->changeBarsCB->setEnabled(bp_.output_changes);
4669 // Make sure that the bc is in the INITIAL state
4670 if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
4673 // clear changed branches cache
4674 changedBranches_.clear();
4676 // re-initiate module filter
4677 if (!filter_->text().isEmpty())
4678 moduleFilterPressed();
4681 nonModuleChanged_ = false;
4682 shellescapeChanged_ = false;
4686 void GuiDocument::saveDocDefault()
4688 // we have to apply the params first
4694 void GuiDocument::updateAvailableModules()
4696 modules_av_model_.clear();
4697 list<modInfoStruct> modInfoList = getModuleInfo();
4698 // Sort names according to the locale
4699 modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
4700 return 0 < b.name.localeAwareCompare(a.name);
4702 QIcon user_icon(guiApp ? guiApp->getScaledPixmap("images/", "lyxfiles-user")
4703 : getPixmap("images/", "lyxfiles-user", "svgz,png"));
4704 QIcon system_icon(guiApp ? guiApp->getScaledPixmap("images/", "lyxfiles-system")
4705 : getPixmap("images/", "lyxfiles-system", "svgz,png"));
4708 catfont.setBold(true);
4710 unavbrush.setColor(Qt::gray);
4711 for (modInfoStruct const & m : modInfoList) {
4712 QStandardItem * item = new QStandardItem();
4713 QStandardItem * catItem;
4714 QString const catname = m.category;
4715 QList<QStandardItem *> fcats = modules_av_model_.findItems(catname, Qt::MatchExactly);
4717 catItem = fcats.first();
4719 catItem = new QStandardItem();
4720 catItem->setText(catname);
4721 catItem->setFont(catfont);
4722 modules_av_model_.insertRow(i, catItem);
4725 item->setEditable(false);
4726 catItem->setEditable(false);
4727 item->setData(m.name, Qt::DisplayRole);
4729 item->setForeground(unavbrush);
4730 item->setData(toqstr(m.id), Qt::UserRole);
4731 item->setData(m.description, Qt::ToolTipRole);
4733 item->setIcon(user_icon);
4735 item->setIcon(system_icon);
4736 catItem->appendRow(item);
4738 modules_av_model_.sort(0);
4742 void GuiDocument::updateSelectedModules()
4744 modules_sel_model_.clear();
4745 list<modInfoStruct> const selModList = getSelectedModules();
4747 for (modInfoStruct const & m : selModList) {
4748 modules_sel_model_.insertRow(i, m.name, m.id, m.description);
4754 void GuiDocument::updateIncludeonlyDisplay()
4756 if (includeonlys_.empty()) {
4757 masterChildModule->includeallRB->setChecked(true);
4758 masterChildModule->childrenTW->setEnabled(false);
4759 masterChildModule->maintainGB->setEnabled(false);
4761 masterChildModule->includeonlyRB->setChecked(true);
4762 masterChildModule->childrenTW->setEnabled(true);
4763 masterChildModule->maintainGB->setEnabled(true);
4768 void GuiDocument::updateIncludeonlys(bool const cleanup)
4770 masterChildModule->childrenTW->clear();
4771 QString const no = qt_("No");
4772 QString const yes = qt_("Yes");
4774 ListOfBuffers children = buffer().getChildren();
4775 ListOfBuffers::const_iterator it = children.begin();
4776 ListOfBuffers::const_iterator end = children.end();
4777 bool has_unincluded = false;
4778 bool all_unincluded = true;
4779 for (; it != end; ++it) {
4780 QTreeWidgetItem * item = new QTreeWidgetItem(masterChildModule->childrenTW);
4783 to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
4784 from_utf8(buffer().filePath())));
4785 item->setText(0, toqstr(name));
4786 item->setText(1, isChildIncluded(name) ? yes : no);
4787 if (!isChildIncluded(name))
4788 has_unincluded = true;
4790 all_unincluded = false;
4792 // Both if all children are included and if none is included
4793 // is equal to "include all" (i.e., omit \includeonly).
4794 if (cleanup && (!has_unincluded || all_unincluded))
4795 includeonlys_.clear();
4799 bool GuiDocument::isBiblatex() const
4801 QString const engine =
4802 biblioModule->citeEngineCO->itemData(
4803 biblioModule->citeEngineCO->currentIndex()).toString();
4805 // this can happen if the cite engine is unknown, which can happen
4806 // if one is using a file that came from someone else, etc. in that
4807 // case, we crash if we proceed.
4808 if (engine.isEmpty())
4811 return theCiteEnginesList[fromqstr(engine)]->getCiteFramework() == "biblatex";
4815 void GuiDocument::updateDefaultBiblio(string const & style,
4816 string const & which)
4818 QString const bibstyle = toqstr(style);
4819 biblioModule->defaultBiblioCO->clear();
4824 if (which != "cbx") {
4825 // First the bbx styles
4826 biblioModule->biblatexBbxCO->clear();
4827 QStringList str = texFileList("bbxFiles.lst");
4828 // test whether we have a valid list, otherwise run rescan
4829 if (str.isEmpty()) {
4830 rescanTexStyles("bbx");
4831 str = texFileList("bbxFiles.lst");
4833 for (int i = 0; i != str.size(); ++i)
4834 str[i] = onlyFileName(str[i]);
4835 // sort on filename only (no path)
4838 for (int i = 0; i != str.count(); ++i) {
4839 QString item = changeExtension(str[i], "");
4840 if (item == bibstyle)
4842 biblioModule->biblatexBbxCO->addItem(item);
4845 if (item_nr == -1 && !bibstyle.isEmpty()) {
4846 biblioModule->biblatexBbxCO->addItem(bibstyle);
4847 item_nr = biblioModule->biblatexBbxCO->count() - 1;
4851 biblioModule->biblatexBbxCO->setCurrentIndex(item_nr);
4853 biblioModule->biblatexBbxCO->clearEditText();
4856 if (which != "bbx") {
4857 // now the cbx styles
4858 biblioModule->biblatexCbxCO->clear();
4859 QStringList str = texFileList("cbxFiles.lst");
4860 // test whether we have a valid list, otherwise run rescan
4861 if (str.isEmpty()) {
4862 rescanTexStyles("cbx");
4863 str = texFileList("cbxFiles.lst");
4865 for (int i = 0; i != str.size(); ++i)
4866 str[i] = onlyFileName(str[i]);
4867 // sort on filename only (no path)
4870 for (int i = 0; i != str.count(); ++i) {
4871 QString item = changeExtension(str[i], "");
4872 if (item == bibstyle)
4874 biblioModule->biblatexCbxCO->addItem(item);
4877 if (item_nr == -1 && !bibstyle.isEmpty()) {
4878 biblioModule->biblatexCbxCO->addItem(bibstyle);
4879 item_nr = biblioModule->biblatexCbxCO->count() - 1;
4883 biblioModule->biblatexCbxCO->setCurrentIndex(item_nr);
4885 biblioModule->biblatexCbxCO->clearEditText();
4888 biblioModule->biblatexBbxCO->clear();
4889 biblioModule->biblatexCbxCO->clear();
4890 QStringList str = texFileList("bstFiles.lst");
4891 // test whether we have a valid list, otherwise run rescan
4892 if (str.isEmpty()) {
4893 rescanTexStyles("bst");
4894 str = texFileList("bstFiles.lst");
4896 for (int i = 0; i != str.size(); ++i)
4897 str[i] = onlyFileName(str[i]);
4898 // sort on filename only (no path)
4901 for (int i = 0; i != str.count(); ++i) {
4902 QString item = changeExtension(str[i], "");
4903 if (item == bibstyle)
4905 biblioModule->defaultBiblioCO->addItem(item);
4908 if (item_nr == -1 && !bibstyle.isEmpty()) {
4909 biblioModule->defaultBiblioCO->addItem(bibstyle);
4910 item_nr = biblioModule->defaultBiblioCO->count() - 1;
4914 biblioModule->defaultBiblioCO->setCurrentIndex(item_nr);
4916 biblioModule->defaultBiblioCO->clearEditText();
4919 updateResetDefaultBiblio();
4923 void GuiDocument::updateResetDefaultBiblio()
4925 QString const engine =
4926 biblioModule->citeEngineCO->itemData(
4927 biblioModule->citeEngineCO->currentIndex()).toString();
4928 CiteEngineType const cet =
4929 CiteEngineType(biblioModule->citeStyleCO->itemData(
4930 biblioModule->citeStyleCO->currentIndex()).toInt());
4932 string const defbib = theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet);
4934 QString const bbx = biblioModule->biblatexBbxCO->currentText();
4935 QString const cbx = biblioModule->biblatexCbxCO->currentText();
4936 biblioModule->resetCbxPB->setEnabled(defbib != fromqstr(cbx));
4937 biblioModule->resetBbxPB->setEnabled(defbib != fromqstr(bbx));
4938 biblioModule->matchBbxPB->setEnabled(bbx != cbx && !cbx.isEmpty()
4939 && biblioModule->biblatexBbxCO->findText(cbx) != -1);
4941 biblioModule->resetDefaultBiblioPB->setEnabled(
4942 defbib != fromqstr(biblioModule->defaultBiblioCO->currentText()));
4946 void GuiDocument::matchBiblatexStyles()
4948 updateDefaultBiblio(fromqstr(biblioModule->biblatexCbxCO->currentText()), "bbx");
4953 void GuiDocument::updateContents()
4955 // Nothing to do here as the document settings is not cursor dependent.
4960 void GuiDocument::useClassDefaults()
4962 if (buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
4963 int const ret = Alert::prompt(_("Unapplied changes"),
4964 _("Some changes in the dialog were not yet applied.\n"
4965 "If you do not apply now, they will be lost after this action."),
4966 1, 1, _("&Apply"), _("&Dismiss"));
4971 int idx = latexModule->classCO->currentIndex();
4972 string const classname = fromqstr(latexModule->classCO->getData(idx));
4973 if (!bp_.setBaseClass(classname, buffer().layoutPos())) {
4974 Alert::error(_("Error"), _("Unable to set document class."));
4977 bp_.useClassDefaults();
4983 void GuiDocument::setLayoutComboByIDString(string const & idString)
4985 if (!latexModule->classCO->set(toqstr(idString)))
4986 Alert::warning(_("Can't set layout!"),
4987 bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
4991 bool GuiDocument::isValid()
4993 bool const listings_valid = validateListingsParameters().isEmpty();
4994 bool const local_layout_valid = !localLayout->editing();
4995 bool const preamble_valid = !preambleModule->editing();
4997 docPS->markPanelValid(N_("Listings[[inset]]"), listings_valid);
4998 docPS->markPanelValid(N_("Local Layout"), local_layout_valid && localLayout->isValid());
4999 docPS->markPanelValid(N_("LaTeX Preamble"), preamble_valid);
5001 return listings_valid && local_layout_valid && preamble_valid;
5005 char const * const GuiDocument::fontfamilies[5] = {
5006 "default", "rmdefault", "sfdefault", "ttdefault", ""
5010 char const * GuiDocument::fontfamilies_gui[5] = {
5011 N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
5015 bool GuiDocument::initialiseParams(string const &)
5017 BufferView const * view = bufferview();
5019 bp_ = BufferParams();
5023 prev_buffer_filename_ = view->buffer().absFileName();
5024 bp_ = view->buffer().params();
5026 updateAvailableModules();
5027 //FIXME It'd be nice to make sure here that the selected
5028 //modules are consistent: That required modules are actually
5029 //selected, and that we don't have conflicts. If so, we could
5030 //at least pop up a warning.
5036 void GuiDocument::clearParams()
5038 bp_ = BufferParams();
5042 BufferId GuiDocument::id() const
5044 BufferView const * const view = bufferview();
5045 return view? &view->buffer() : nullptr;
5049 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
5051 return moduleNames_;
5055 list<GuiDocument::modInfoStruct> const
5056 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
5058 list<modInfoStruct> mInfo;
5059 for (string const & name : mods) {
5061 LyXModule const * const mod = theModuleList[name];
5066 m.name = toqstr(name + " (") + qt_("Not Found") + toqstr(")");
5068 m.missingreqs = true;
5076 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
5078 return makeModuleInfo(params().getModules());
5082 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
5084 return makeModuleInfo(params().baseClass()->providedModules());
5088 DocumentClass const & GuiDocument::documentClass() const
5090 return bp_.documentClass();
5094 static void dispatch_bufferparams(Dialog const & dialog,
5095 BufferParams const & bp, FuncCode lfun, Buffer const * buf)
5098 ss << "\\begin_header\n";
5099 bp.writeFile(ss, buf);
5100 ss << "\\end_header\n";
5101 dialog.dispatch(FuncRequest(lfun, ss.str()));
5105 void GuiDocument::dispatchParams()
5107 // We need a non-const buffer object.
5108 Buffer & buf = const_cast<BufferView *>(bufferview())->buffer();
5109 // There may be several undo records; group them (bug #8998)
5110 // This handles undo groups automagically
5111 UndoGroupHelper ugh(&buf);
5113 // This must come first so that a language change is correctly noticed
5116 // We need to load the master before we formally update the params,
5117 // since otherwise we run updateBuffer, etc, before the child's master
5119 if (!params().master.empty()) {
5120 FileName const master_file = support::makeAbsPath(params().master,
5121 support::onlyPath(buffer().absFileName()));
5122 if (isLyXFileName(master_file.absFileName())) {
5123 Buffer * master = checkAndLoadLyXFile(master_file, true);
5125 if (master->isChild(const_cast<Buffer *>(&buffer())))
5126 const_cast<Buffer &>(buffer()).setParent(master);
5128 Alert::warning(_("Assigned master does not include this file"),
5129 bformat(_("You must include this file in the document\n"
5130 "'%1$s' in order to use the master document\n"
5131 "feature."), from_utf8(params().master)));
5133 Alert::warning(_("Could not load master"),
5134 bformat(_("The master document '%1$s'\n"
5135 "could not be loaded."),
5136 from_utf8(params().master)));
5140 // Apply the BufferParams. Note that this will set the base class
5141 // and then update the buffer's layout.
5142 dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY, &buffer());
5144 // Generate the colours requested by each new branch.
5145 BranchList & branchlist = params().branchlist();
5146 if (!branchlist.empty()) {
5147 BranchList::const_iterator it = branchlist.begin();
5148 BranchList::const_iterator const end = branchlist.end();
5149 for (; it != end; ++it) {
5150 docstring const & current_branch = it->branch();
5151 Branch const * branch = branchlist.find(current_branch);
5152 string const bcolor = branch->color();
5154 if (bcolor.size() == 7 && bcolor[0] == '#')
5155 rgbcol = lyx::rgbFromHexName(bcolor);
5157 guiApp->getRgbColor(lcolor.getFromLyXName(bcolor), rgbcol);
5158 string const x11hexname = X11hexname(rgbcol);
5159 // display the new color
5160 docstring const str = current_branch + ' ' + from_ascii(x11hexname);
5161 dispatch(FuncRequest(LFUN_SET_COLOR, str));
5164 // rename branches in the document
5165 executeBranchRenaming();
5166 // and clear changed branches cache
5167 changedBranches_.clear();
5169 // Generate the colours requested by indices.
5170 IndicesList & indiceslist = params().indiceslist();
5171 if (!indiceslist.empty()) {
5172 IndicesList::const_iterator it = indiceslist.begin();
5173 IndicesList::const_iterator const end = indiceslist.end();
5174 for (; it != end; ++it) {
5175 docstring const & current_index = it->shortcut();
5176 Index const * index = indiceslist.findShortcut(current_index);
5177 string const x11hexname = X11hexname(index->color());
5178 // display the new color
5179 docstring const str = current_index + ' ' + from_ascii(x11hexname);
5180 dispatch(FuncRequest(LFUN_SET_COLOR, str));
5184 // If we used an LFUN, we would not need these two lines:
5185 BufferView * bv = const_cast<BufferView *>(bufferview());
5186 bv->processUpdateFlags(Update::Force | Update::FitCursor);
5190 void GuiDocument::setLanguage() const
5192 Language const * const newL = bp_.language;
5193 if (buffer().params().language == newL)
5196 string const & lang_name = newL->lang();
5197 dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
5201 void GuiDocument::saveAsDefault() const
5203 dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT, &buffer());
5207 bool GuiDocument::providesOSF(QString const & font) const
5209 if (fontModule->osFontsCB->isChecked())
5210 // FIXME: we should check if the fonts really
5211 // have OSF support. But how?
5213 return theLaTeXFonts().getLaTeXFont(
5214 qstring_to_ucs4(font)).providesOSF(ot1(),
5220 bool GuiDocument::providesSC(QString const & font) const
5222 if (fontModule->osFontsCB->isChecked())
5224 return theLaTeXFonts().getLaTeXFont(
5225 qstring_to_ucs4(font)).providesSC(ot1(),
5231 bool GuiDocument::providesScale(QString const & font) const
5233 if (fontModule->osFontsCB->isChecked())
5235 return theLaTeXFonts().getLaTeXFont(
5236 qstring_to_ucs4(font)).providesScale(ot1(),
5242 bool GuiDocument::providesExtraOpts(QString const & font) const
5244 if (fontModule->osFontsCB->isChecked())
5246 return theLaTeXFonts().getLaTeXFont(
5247 qstring_to_ucs4(font)).providesMoreOptions(ot1(),
5253 bool GuiDocument::providesNoMath(QString const & font) const
5255 if (fontModule->osFontsCB->isChecked())
5257 return theLaTeXFonts().getLaTeXFont(
5258 qstring_to_ucs4(font)).providesNoMath(ot1(),
5263 bool GuiDocument::hasMonolithicExpertSet(QString const & font) const
5265 if (fontModule->osFontsCB->isChecked())
5267 return theLaTeXFonts().getLaTeXFont(
5268 qstring_to_ucs4(font)).hasMonolithicExpertSet(ot1(),
5275 GuiDocument::modInfoStruct GuiDocument::modInfo(LyXModule const & mod)
5277 // FIXME Unicode: docstrings would be better for these parameters but this
5278 // change requires a lot of others
5281 QString const guiname = toqstr(translateIfPossible(from_utf8(mod.getName())));
5282 m.missingreqs = !isModuleAvailable(mod.getID());
5283 if (m.missingreqs) {
5284 m.name = qt_("%1 (missing req.)").arg(guiname);
5287 m.category = mod.category().empty() ? qt_("Miscellaneous")
5288 : toqstr(translateIfPossible(from_utf8(mod.category())));
5289 QString desc = toqstr(translateIfPossible(from_utf8(mod.getDescription())));
5290 // Find the first sentence of the description
5291 QTextBoundaryFinder bf(QTextBoundaryFinder::Sentence, desc);
5292 int pos = bf.toNextBoundary();
5295 m.local = mod.isLocal();
5296 QString const mtype = m.local ? qt_("personal module") : qt_("distributed module");
5297 QString modulename = qt_("<b>Module name:</b> <i>%1</i> (%2)").arg(toqstr(m.id)).arg(mtype);
5298 // Tooltip is the desc followed by the module name and the type
5299 m.description = QString("%1%2")
5300 .arg(desc.isEmpty() ? QString() : QString("<p>%1</p>").arg(desc),
5303 m.description += QString("<p>%1</p>").arg(qt_("<b>Note:</b> Some requirements for this module are missing!"));
5308 void GuiDocument::loadModuleInfo()
5310 moduleNames_.clear();
5311 for (LyXModule const & mod : theModuleList)
5312 moduleNames_.push_back(modInfo(mod));
5316 void GuiDocument::updateUnknownBranches()
5320 list<docstring> used_branches;
5321 buffer().getUsedBranches(used_branches);
5322 list<docstring>::const_iterator it = used_branches.begin();
5323 QStringList unknown_branches;
5324 for (; it != used_branches.end() ; ++it) {
5325 if (!buffer().params().branchlist().find(*it))
5326 unknown_branches.append(toqstr(*it));
5328 branchesModule->setUnknownBranches(unknown_branches);
5332 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
5334 map<docstring, docstring>::iterator it = changedBranches_.begin();
5335 for (; it != changedBranches_.end() ; ++it) {
5336 if (it->second == oldname) {
5337 // branch has already been renamed
5338 it->second = newname;
5343 changedBranches_[oldname] = newname;
5347 void GuiDocument::executeBranchRenaming() const
5349 map<docstring, docstring>::const_iterator it = changedBranches_.begin();
5350 for (; it != changedBranches_.end() ; ++it) {
5351 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
5352 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
5357 void GuiDocument::allPackagesAuto()
5363 void GuiDocument::allPackagesAlways()
5369 void GuiDocument::allPackagesNot()
5375 void GuiDocument::allPackages(int col)
5377 for (int row = 0; row < mathsModule->packagesTW->rowCount(); ++row) {
5379 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, col)->layout()->itemAt(0)->widget();
5380 rb->setChecked(true);
5385 void GuiDocument::linenoToggled(bool on)
5387 numberingModule->linenoLE->setEnabled(on);
5388 numberingModule->linenoLA->setEnabled(on);
5392 void GuiDocument::outputChangesToggled(bool on)
5394 changesModule->changeBarsCB->setEnabled(on);
5398 void GuiDocument::setOutputSync(bool on)
5400 outputModule->synccustomCB->setEnabled(on);
5401 outputModule->synccustomLA->setEnabled(on);
5406 } // namespace frontend
5409 #include "moc_GuiDocument.cpp"