Hi!
I've been working on the ignore-spell-check feature using character
attributes (actually inside Font), but I'm having trouble with this. I
think much of the trouble is that I don't understand the intricacies of
Fonts (realized fonts, inheritance/ignore, how fonts are copied, etc.).
But more fundamentally, it's probably wrong to be doing this inside
Font. I've been trying to do that mainly because Font already provides
the kind of infrastructure that I want for a character-based attribute
(font spans, and a mechanism for writing and reading this from the .lyx
file). But I'm running into trouble, because there's just so much code
all over the place that deals with fonts, and since I don't understand
it well enough, I don't know what is safe to change and what isn't.
I'm attaching what I've got so far. It's very far from complete: first
and foremost, there's not even any UI yet for setting the
ignore-spelling attribute, yet! (I'm not even sure what kind of UI we
would want...); nor does the painting work --- I think it has to do with
how Text::getFont() gets the font, but again, I need a better
understanding of Font for that... What *is* working, though, is that
I've hard-coded into Paragraph.cpp something which ignores spelling for
notes by setting ignore to true --- and this does seem to work (though
there's a bug I only now noticed --- I'm only checking the first
character in each word to determine whether or not it's to be ignored).
But anyhow, I'm not so sure anymore that my proposed approach is really
the way to go. Hijacking Font seems to be problematic, and if we do
decide its the way to go, I will need help. What I would really like is
some kind of mechanism which would allow me to associate attributes with
each position in the text, but I don't think such a mechanism exists
(besides Font) (For the record, I still think that a character-attribute
based solution is the correct way to go, in order to keep things simple.
But that doesn't seem to be too east to achieve at the moment).
In the bigger picture, we still haven't really decided on the
requirements. I hear what people are saying, that this kind of
information doesn't belong in the file itself, but I'm not sure I agree.
I think that part of the problem is that some of the features we've
discussed really are more "preference-based", whereas others are more
"specific-text/instance-based" --- and sometimes these two notions
conflict. So I don't really know how to continue...
So, the upshot is: here's my aborted-patch, but I don't think I will
continue with it unless someone thinks this is a direction worth
pursuing, and can provide some help; I don't know what the correct way
to deal with this issue is --- so far none of the solutions seems to
provide an answer to all the issues. So for now, I'm supporting Mael's
approach --- which solves some of the problems, and isn't too intrusive
--- provided that it'll be possible to shut off all the ignores (i.e.,
to have the same situation that we have today, where everything is
spell-checked).
Good night!
Dov
Index: src/Color.h
===================================================================
--- src/Color.h (revision 19595)
+++ src/Color.h (working copy)
@@ -104,6 +104,8 @@
depthbar,
/// Color for marking foreign language words
language,
+ /// Color for marking text whose spelling is to be ignored
+ ignore_spelling,
/// Text color for command insets
command,
Index: src/Font.cpp
===================================================================
--- src/Font.cpp (revision 19595)
+++ src/Font.cpp (working copy)
@@ -167,37 +167,41 @@
Font::Font()
- : bits(sane), lang(default_language), open_encoding_(false)
+ : bits(sane), lang(default_language), ignore_spelling(false),
+ open_encoding_(false)
{}
Font::Font(Font::FONT_INIT1)
- : bits(inherit), lang(default_language), open_encoding_(false)
+ : bits(inherit), lang(default_language), ignore_spelling(false),
+ open_encoding_(false)
{}
Font::Font(Font::FONT_INIT2)
- : bits(ignore), lang(ignore_language), open_encoding_(false)
+ : bits(ignore), lang(ignore_language), ignore_spelling(false),
+ open_encoding_(false)
{}
Font::Font(Font::FONT_INIT3)
- : bits(sane), lang(default_language), open_encoding_(false)
+ : bits(sane), lang(default_language), ignore_spelling(false),
+ open_encoding_(false)
{}
Font::Font(Font::FONT_INIT1, Language const * l)
- : bits(inherit), lang(l), open_encoding_(false)
+ : bits(inherit), lang(l), ignore_spelling(false), open_encoding_(false)
{}
Font::Font(Font::FONT_INIT2, Language const * l)
- : bits(ignore), lang(l), open_encoding_(false)
+ : bits(ignore), lang(l), ignore_spelling(false), open_encoding_(false)
{}
Font::Font(Font::FONT_INIT3, Language const * l)
- : bits(sane), lang(l), open_encoding_(false)
+ : bits(sane), lang(l), ignore_spelling(false), open_encoding_(false)
{}
@@ -274,6 +278,10 @@
lang = l;
}
+void Font::setIgnoreSpelling(bool i)
+{
+ ignore_spelling = i;
+}
void Font::setNumber(Font::FONT_MISC_STATE n)
{
@@ -524,8 +532,10 @@
os << bformat(_("Language: %1$s, "),
_(language()->display()));
if (number() != OFF)
- os << bformat(_(" Number %1$s"),
+ os << bformat(_(" Number %1$s, "),
_(GUIMiscNames[number()]));
+ if (ignoreSpelling() == true)
+ os << _(" Ignore Spelling, ");
return rtrim(os.str(), ", ");
}
@@ -735,6 +745,8 @@
else
os << "\\lang unknown\n";
}
+ if (orgfont.ignoreSpelling() != ignoreSpelling())
+ os << "\\spelling " << (ignoreSpelling() ? "off" : "on") <<
"\n";
}
@@ -992,7 +1004,8 @@
<< " underbar " << font.bits.underbar
<< " noun " << font.bits.noun
<< " number " << font.bits.number
- << " lang: " << (font.lang ? font.lang->lang() : 0);
+ << " lang: " << (font.lang ? font.lang->lang() : 0)
+ << (font.ignoreSpelling() ? " ignore spelling" : "");
}
Index: src/Text.cpp
===================================================================
--- src/Text.cpp (revision 19595)
+++ src/Text.cpp (working copy)
@@ -189,6 +189,16 @@
font.setLanguage(bp.language);
lex.printError("Unknown language `$$Token'");
}
+ } else if (token == "\\spelling") {
+ lex.next();
+ string const tok = lex.getString();
+ if (tok == "off")
+ font.setIgnoreSpelling(true);
+ else if (tok == "on")
+ font.setIgnoreSpelling(false);
+ else
+ // FIXME: assert? error? for now just assuming on...
+ font.setIgnoreSpelling(false);
} else if (token == "\\numeric") {
lex.next();
font.setNumber(font.setLyXMisc(lex.getString()));
Index: src/Font.h
===================================================================
--- src/Font.h (revision 19595)
+++ src/Font.h (working copy)
@@ -225,6 +225,8 @@
///
Language const * language() const { return lang; }
///
+ bool ignoreSpelling() const { return ignore_spelling; }
+ ///
bool isRightToLeft() const;
///
bool isVisibleRightToLeft() const;
@@ -242,6 +244,7 @@
void setNumber(Font::FONT_MISC_STATE n);
void setColor(Color_color c);
void setLanguage(Language const * l);
+ void setIgnoreSpelling(bool i);
/// Set family after LyX text format
Font & setLyXFamily(std::string const &);
@@ -345,6 +348,8 @@
FontBits bits;
///
Language const * lang;
+ ///
+ bool ignore_spelling;
/// Sane font
static FontBits sane;
/// All inherit font
Index: src/frontends/controllers/ControlSpellchecker.cpp
===================================================================
--- src/frontends/controllers/ControlSpellchecker.cpp (revision 19595)
+++ src/frontends/controllers/ControlSpellchecker.cpp (working copy)
@@ -159,14 +159,15 @@
if (isLetter(cur)) {
if (!inword) {
inword = true;
- ignoreword = false;
cur.resetAnchor();
word.clear();
- lang_code = cur.paragraph().getFontSettings(bp,
cur.pos()).language()->code();
+ Font font = cur.paragraph().getFontSettings(bp,
cur.pos());
+ lang_code = font.language()->code();
+ ignoreword = font.ignoreSpelling();
}
// Insets like optional hyphens and ligature
// break are part of a word.
- if (!cur.paragraph().isInset(cur.pos())) {
+ if (!cur.paragraph().isInset(cur.pos()) && !ignoreword)
{
Paragraph::value_type const c =
cur.paragraph().getChar(cur.pos());
word += c;
Index: src/Paragraph.cpp
===================================================================
--- src/Paragraph.cpp (revision 19595)
+++ src/Paragraph.cpp (working copy)
@@ -1294,8 +1294,11 @@
// be moving current_font into Cursor, and getting rid of all this...
// (see
http://thread.gmane.org/gmane.editors.lyx.devel/88869/focus=88944)
if (inset->asTextInset()) {
- inset->asTextInset()->text_.current_font = font;
- inset->asTextInset()->text_.real_current_font = font;
+ Font font_copy = font;
+ if (inset->lyxCode() == Inset::NOTE_CODE)
+ font_copy.setIgnoreSpelling(true);
+ inset->asTextInset()->text_.current_font = font_copy;
+ inset->asTextInset()->text_.real_current_font = font_copy;
}
}
Index: src/rowpainter.cpp
===================================================================
--- src/rowpainter.cpp (revision 19595)
+++ src/rowpainter.cpp (working copy)
@@ -80,6 +80,7 @@
private:
void paintForeignMark(double orig_x, Font const & font, int desc = 0);
+ void paintIgnoreSpelling(double orig_x, Font const & font, int desc =
0);
void paintHebrewComposeChar(pos_type & vpos, Font const & font);
void paintArabicComposeChar(pos_type & vpos, Font const & font);
void paintChars(pos_type & vpos, Font const & font,
@@ -408,6 +409,18 @@
}
+void RowPainter::paintIgnoreSpelling(double orig_x, Font const & font, int
desc)
+{
+ // FIXME:if (!lyxrc.mark_ignore_spelling)
+ // return;
+ if (font.ignoreSpelling() == false)
+ return;
+
+ int const y = yo_ + 2 + desc;
+ pain_.line(int(orig_x), y, int(x_), y, Color::ignore_spelling);
+}
+
+
void RowPainter::paintFromPos(pos_type & vpos)
{
pos_type const pos = bidi_.vis2log(vpos);
@@ -420,6 +433,8 @@
++vpos;
paintForeignMark(orig_x, orig_font,
par_.getInset(pos)->descent());
+ paintIgnoreSpelling(orig_x, orig_font,
+ par_.getInset(pos)->descent());
return;
}
@@ -444,6 +459,7 @@
}
paintForeignMark(orig_x, orig_font);
+ paintIgnoreSpelling(orig_x, orig_font);
}
@@ -859,6 +875,7 @@
x_ += separator_;
++vpos;
paintForeignMark(orig_x, orig_font);
+ paintIgnoreSpelling(orig_x, orig_font);
} else {
paintFromPos(vpos);
}
Index: src/Color.cpp
===================================================================
--- src/Color.cpp (revision 19595)
+++ src/Color.cpp (working copy)
@@ -178,6 +178,7 @@
{ shadedbg, N_("shaded box"), "shaded", "#ff0000", "shaded" },
{ depthbar, N_("depth bar"), "depthbar", "IndianRed", "depthbar" },
{ language, N_("language"), "language", "Blue", "language" },
+ { ignore_spelling, N_("ignore spelling"), "ignore_spelling", "Green",
"ignore_spelling" },
{ command, N_("command inset"), "command", "black", "command" },
{ commandbg, N_("command inset background"), "commandbg", "azure",
"commandbg" },
{ commandframe, N_("command inset frame"), "commandframe", "black",
"commandframe" },