This revives a ten year old idea (and patch) by Dov.
You can now mark in the character dialog text and exclude it from spell
checking.
Fixes: #1042
File format change
Remaining issue: The instant spell checking marks are not immediately
removed, but only after some editing.
-----------------------
+2018-05-06 Jürgen Spitzmüller <spitz@lyx.org>
+ * format incremented to 551: add font info param \nospellcheck that prevents
+ text from being spellchecked.
+
2018-04-22 Jürgen Spitzmüller <spitz@lyx.org>
* format incremented to 550: rename \fontencoding global to \fontencoding auto.
Semantic change: this is now automatically set depending on the document fonts.
document.header[i] = document.header[i].replace("auto", "global")
+def revert_nospellcheck(document):
+ " Remove nospellcheck font info param "
+
+ i = 0
+ while True:
+ i = find_token(document.body, '\\nospellcheck', i)
+ if i == -1:
+ return
+ del document.body[i]
+
+
##
# Conversion hub
#
[547, []],
[548, []],
[549, []],
- [550, [convert_fontenc]]
+ [550, [convert_fontenc]],
+ [551, []]
]
revert = [
+ [549, [revert_nospellcheck]],
[549, [revert_fontenc]],
[548, []],# dummy format change
[547, [revert_lscape]],
os << "\\emph " << LyXMiscNames[bits_.emph()] << "\n";
if (orgfont.fontInfo().number() != bits_.number())
os << "\\numeric " << LyXMiscNames[bits_.number()] << "\n";
+ if (orgfont.fontInfo().nospellcheck() != bits_.nospellcheck())
+ os << "\\nospellcheck " << LyXMiscNames[bits_.nospellcheck()] << "\n";
if (orgfont.fontInfo().underbar() != bits_.underbar()) {
// This is only for backwards compatibility
switch (bits_.underbar()) {
<< "uwave " << bits_.uwave() << '\n'
<< "noun " << bits_.noun() << '\n'
<< "number " << bits_.number() << '\n'
+ << "nospellcheck " << bits_.nospellcheck() << '\n'
<< "color " << bits_.color() << '\n'
<< "language " << lang << '\n'
<< "toggleall " << convert<string>(toggle);
} else if (token == "emph" || token == "underbar"
|| token == "noun" || token == "number"
|| token == "uuline" || token == "uwave"
- || token == "strikeout" || token == "xout") {
+ || token == "strikeout" || token == "xout"
+ || token == "nospellcheck") {
int const next = lex.getInteger();
FontState const misc = FontState(next);
bits_.setNoun(misc);
else if (token == "number")
bits_.setNumber(misc);
+ else if (token == "nospellcheck")
+ bits_.setNoSpellcheck(misc);
} else if (token == "color") {
int const next = lex.getInteger();
<< " uuline " << f.uuline()
<< " uwave " << f.uwave()
<< " noun " << f.noun()
- << " number " << f.number();
+ << " number " << f.number()
+ << " nospellcheck " << f.nospellcheck();
}
FONT_OFF,
FONT_OFF,
FONT_OFF,
+ FONT_OFF,
FONT_OFF);
FontInfo const inherit_font(
FONT_INHERIT,
FONT_INHERIT,
FONT_INHERIT,
- FONT_OFF);
+ FONT_OFF,
+ FONT_INHERIT);
FontInfo const ignore_font(
IGNORE_FAMILY,
FONT_IGNORE,
FONT_IGNORE,
FONT_IGNORE,
+ FONT_IGNORE,
FONT_IGNORE);
color_ = Color_inherit;
if (background_ == tmplt.background_)
background_ = Color_inherit;
+ if (nospellcheck_ == tmplt.nospellcheck_)
+ noun_ = FONT_INHERIT;
}
if (background_ == Color_inherit)
background_ = tmplt.background_;
+ if (nospellcheck_ == FONT_INHERIT)
+ nospellcheck_ = tmplt.nospellcheck_;
+
return *this;
}
setUwave(setMisc(newfont.uwave_, uwave_));
setNoun(setMisc(newfont.noun_, noun_));
setNumber(setMisc(newfont.number_, number_));
+ setNoSpellcheck(setMisc(newfont.nospellcheck_, nospellcheck_));
if (newfont.color_ == color_ && toggleall)
setColor(Color_inherit); // toggle 'back'
&& uuline_ != FONT_INHERIT && uwave_ != FONT_INHERIT
&& strikeout_ != FONT_INHERIT && xout_ != FONT_INHERIT
&& noun_ != FONT_INHERIT && color_ != Color_inherit
- && background_ != Color_inherit);
+ && background_ != Color_inherit && nospellcheck_ != FONT_INHERIT);
}
f.setUwave(FONT_ON);
} else if (ttok == "noun") {
f.setNoun(FONT_ON);
+ } else if (ttok == "nospellcheck") {
+ f.setNoSpellcheck(FONT_ON);
+ } else if (ttok == "no_nospellcheck") {
+ f.setNoSpellcheck(FONT_OFF);
} else {
lex.printError("Illegal misc type");
}
oss << indent << "\tMisc Noun\n";
else if (f.noun() == FONT_OFF)
oss << indent << "\tMisc No_Noun\n";
+ if (f.nospellcheck() == FONT_ON)
+ oss << indent << "\tMisc NoSpellcheck\n";
+ else if (f.nospellcheck() == FONT_OFF)
+ oss << indent << "\tMisc No_NoSpellcheck\n";
if (f.color() != Color_inherit && f.color() != Color_none)
oss << indent << "\tColor " << lcolor.getLyXName(f.color())
<< '\n';
FontState uuline,
FontState uwave,
FontState noun,
- FontState number)
+ FontState number,
+ FontState nospellcheck)
: family_(family), series_(series), shape_(shape), size_(size),
style_(LM_ST_TEXT), color_(color), background_(background), emph_(emph),
underbar_(underbar), strikeout_(strikeout), xout_(xout), uuline_(uuline),
- uwave_(uwave), noun_(noun), number_(number)
+ uwave_(uwave), noun_(noun), number_(number), nospellcheck_(nospellcheck)
{}
/// Decreases font size by one
void setColor(ColorCode c) { color_ = c; }
ColorCode background() const { return background_; }
void setBackground(ColorCode b) { background_ = b; }
+ FontState nospellcheck() const { return nospellcheck_; }
+ void setNoSpellcheck(FontState n) { nospellcheck_ = n; }
//@}
///
FontState noun_;
///
FontState number_;
+ ///
+ FontState nospellcheck_;
};
&& lhs.uuline_ == rhs.uuline_
&& lhs.uwave_ == rhs.uwave_
&& lhs.noun_ == rhs.noun_
- && lhs.number_ == rhs.number_;
+ && lhs.number_ == rhs.number_
+ && lhs.nospellcheck_ == rhs.nospellcheck_;
}
docstring word = asString(from, to, AS_STR_INSETS | AS_STR_SKIPDELETE);
Language * lang = d->getSpellLanguage(from);
+ if (getFontSettings(d->inset_owner_->buffer().params(), from).fontInfo().nospellcheck() == FONT_ON)
+ return result;
+
wl = WordLangTuple(word, lang);
if (word.empty())
}
+void RowPainter::paintLanguageMarkings(Row::Element const & e) const
+{
+ paintForeignMark(e);
+ paintNoSpellingMark(e);
+}
+
+
void RowPainter::paintForeignMark(Row::Element const & e) const
{
Language const * lang = e.font.language();
}
+void RowPainter::paintNoSpellingMark(Row::Element const & e) const
+{
+ //if (!lyxrc.mark_no_spelling)
+ // return;
+ if (e.font.language() == latex_language)
+ return;
+ if (!e.font.fontInfo().nospellcheck())
+ return;
+
+ int const desc = e.inset ? e.dim.descent() : 0;
+ int const y = yo_ + pi_.base.solidLineOffset()
+ + desc + pi_.base.solidLineThickness() / 2;
+ pi_.pain.line(int(x_), y, int(x_ + e.full_width()), y, Color_language,
+ Painter::line_onoffdash, pi_.base.solidLineThickness());
+}
+
+
void RowPainter::paintMisspelledMark(Row::Element const & e) const
{
// if changed the misspelled marker gets placed slightly lower than normal
Row::Element const & e = *cit;
if (e.type == Row::INSET) {
paintInset(e);
- // The line that indicates word in a different language
- paintForeignMark(e);
+ // The markings of foreign languages
+ // and of text ignored for spellchecking
+ paintLanguageMarkings(e);
// change tracking (not for insets that handle it themselves)
if (!e.inset->canPaintChange(*pi_.base.bv))
paintChange(e);
pi_.pain.textDecoration(e.font.fontInfo(), int(x_), yo_, int(e.full_width()));
}
- // The line that indicates word in a different language
- paintForeignMark(e);
+ // The markings of foreign languages
+ // and of text ignored for spellchecking
+ paintLanguageMarkings(e);
// change tracking (not for insets that handle it themselves)
if (e.type != Row::INSET || ! e.inset->canPaintChange(*pi_.base.bv))
void paintSelection() const;
private:
+ void paintLanguageMarkings(Row::Element const & e) const;
void paintForeignMark(Row::Element const & e) const;
+ void paintNoSpellingMark(Row::Element const & e) const;
void paintStringAndSel(Row::Element const & e) const;
void paintMisspelledMark(Row::Element const & e) const;
void paintChange(Row::Element const & e) const;
} else if (token == "\\numeric") {
lex.next();
font.fontInfo().setNumber(setLyXMisc(lex.getString()));
+ } else if (token == "\\nospellcheck") {
+ lex.next();
+ font.fontInfo().setNoSpellcheck(setLyXMisc(lex.getString()));
} else if (token == "\\emph") {
lex.next();
font.fontInfo().setEmph(setLyXMisc(lex.getString()));
newfi.setNoun(oldfi.noun() == FONT_OFF ? FONT_ON : FONT_OFF);
if (newfi.number() == FONT_TOGGLE)
newfi.setNumber(oldfi.number() == FONT_OFF ? FONT_ON : FONT_OFF);
+ if (newfi.nospellcheck() == FONT_TOGGLE)
+ newfi.setNoSpellcheck(oldfi.nospellcheck() == FONT_OFF ? FONT_ON : FONT_OFF);
}
setFont(cur.bv(), cur.selectionBegin().top(),
bc().addReadOnly(strikeCO);
bc().addReadOnly(nounCB);
bc().addReadOnly(emphCB);
+ bc().addReadOnly(nospellcheckCB);
bc().addReadOnly(langCO);
bc().addReadOnly(colorCO);
bc().addReadOnly(autoapplyCB);
}
+void GuiCharacter::on_nospellcheckCB_clicked()
+{
+ // skip intermediate state at user click
+ if (!nospellcheck_) {
+ nospellcheckCB->setCheckState(Qt::Checked);
+ nospellcheck_ = true;
+ }
+ change_adaptor();
+}
+
+
+
void GuiCharacter::change_adaptor()
{
changed();
font.fontInfo().setEmph(FONT_IGNORE);
if (fi.noun() != tmp.fontInfo().noun())
font.fontInfo().setNoun(FONT_IGNORE);
+ if (fi.nospellcheck() != tmp.fontInfo().nospellcheck())
+ font.fontInfo().setNoSpellcheck(FONT_IGNORE);
if (fi.color() != tmp.fontInfo().color())
font.fontInfo().setColor(Color_ignore);
if (fi.underbar() != tmp.fontInfo().underbar()
colorCO->setCurrentIndex(colorCO->findData(toqstr(lcolor.getLyXName(fi.color()))));
emphCB->setCheckState(getMarkupState(fi.emph()));
nounCB->setCheckState(getMarkupState(fi.noun()));
+ nospellcheckCB->setCheckState(getMarkupState(fi.nospellcheck()));
emph_ = emphCB->checkState() == Qt::Checked;
noun_ = nounCB->checkState() == Qt::Checked;
+ nospellcheck_ = nospellcheckCB->checkState() == Qt::Checked;
// reset_language is a null pointer.
QString const lang = (font.language() == reset_language)
fi.setSize(size[sizeCO->currentIndex()].second);
fi.setEmph(setMarkupState(emphCB->checkState()));
fi.setNoun(setMarkupState(nounCB->checkState()));
+ fi.setNoSpellcheck(setMarkupState(nospellcheckCB->checkState()));
setBar(fi, bar[ulineCO->currentIndex()].second);
setStrike(fi, strike[strikeCO->currentIndex()].second);
fi.setColor(lcolor.getFromLyXName(fromqstr(colorCO->itemData(colorCO->currentIndex()).toString())));
void change_adaptor();
void on_emphCB_clicked();
void on_nounCB_clicked();
+ void on_nospellcheckCB_clicked();
private:
/// \name Dialog inherited methods
bool emph_;
///
bool noun_;
+ ///
+ bool nospellcheck_;
};
} // namespace frontend
<x>0</x>
<y>0</y>
<width>523</width>
- <height>365</height>
+ <height>412</height>
</rect>
</property>
<property name="windowTitle">
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
- <layout class="QGridLayout" name="gridLayout_6">
- <item row="0" column="0">
+ <layout class="QGridLayout" name="gridLayout_7">
+ <item row="2" column="0" colspan="2">
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="autoapplyCB">
+ <property name="toolTip">
+ <string>Apply each change automatically</string>
+ </property>
+ <property name="text">
+ <string>Apply changes &immediately</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="okPB">
+ <property name="text">
+ <string>&OK</string>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="applyPB">
+ <property name="text">
+ <string>&Apply</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="closePB">
+ <property name="text">
+ <string>Close</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ <property name="default">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox">
</layout>
</item>
<item row="1" column="0">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QGroupBox" name="groupBox_4">
- <property name="title">
- <string>&Language</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_7">
- <item row="0" column="0">
+ <widget class="QGroupBox" name="groupBox_4">
+ <property name="title">
+ <string>Language Settings</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_6">
+ <item row="0" column="0">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="LanguageLA">
+ <property name="text">
+ <string>&Language:</string>
+ </property>
+ <property name="buddy">
+ <cstring>langCO</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QComboBox" name="langCO">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
</widget>
</item>
</layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_3">
- <property name="title">
- <string>Semantic Markup</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_5">
- <item row="0" column="0">
- <widget class="QCheckBox" name="emphCB">
- <property name="toolTip">
- <string>Semantic emphasizing (italic by default, but can be adapted)</string>
- </property>
- <property name="text">
- <string>&Emphasized</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QCheckBox" name="nounCB">
- <property name="toolTip">
- <string>Semantic markup of nouns (small caps by default, but can be adapted)</string>
- </property>
- <property name="text">
- <string>&Noun</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </item>
- <item row="2" column="0">
- <spacer>
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Expanding</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
+ </item>
+ <item row="1" column="0">
+ <widget class="QCheckBox" name="nospellcheckCB">
+ <property name="toolTip">
+ <string>If this is selected, the marked text will not be spellchecked</string>
+ </property>
+ <property name="text">
+ <string>E&xclude from Spellchecking</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
</item>
- <item row="3" column="0">
- <layout class="QHBoxLayout">
- <property name="spacing">
- <number>6</number>
+ <item row="1" column="1">
+ <widget class="QGroupBox" name="groupBox_3">
+ <property name="title">
+ <string>Semantic Markup</string>
</property>
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QCheckBox" name="autoapplyCB">
- <property name="toolTip">
- <string>Apply each change automatically</string>
- </property>
- <property name="text">
- <string>Apply changes &immediately</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Expanding</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="okPB">
- <property name="text">
- <string>&OK</string>
- </property>
- <property name="default">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="applyPB">
- <property name="text">
- <string>&Apply</string>
- </property>
- <property name="autoDefault">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="closePB">
- <property name="text">
- <string>Close</string>
- </property>
- <property name="autoDefault">
- <bool>false</bool>
- </property>
- <property name="default">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- </layout>
+ <layout class="QGridLayout" name="gridLayout_5">
+ <item row="0" column="0">
+ <widget class="QCheckBox" name="emphCB">
+ <property name="toolTip">
+ <string>Semantic emphasizing (italic by default, but can be adapted)</string>
+ </property>
+ <property name="text">
+ <string>&Emphasized</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QCheckBox" name="nounCB">
+ <property name="toolTip">
+ <string>Semantic markup of nouns (small caps by default, but can be adapted)</string>
+ </property>
+ <property name="text">
+ <string>&Noun</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
</item>
</layout>
</widget>
// Do not remove the comment below, so we get merge conflict in
// independent branches. Instead add your own.
-#define LYX_FORMAT_LYX 550 // spitz: \fontenc auto
-#define LYX_FORMAT_TEX2LYX 550
+#define LYX_FORMAT_LYX 551 // spitz: \nospellcheck font param
+#define LYX_FORMAT_TEX2LYX 551
#if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX
#ifndef _MSC_VER