Mael Hilléreau wrote:
Le 14 août 07 à 16:22, Helge Hafting a écrit :
Mael Hilléreau wrote:
Le 14 août 07 à 14:01, Helge Hafting a écrit :
What happens if you add a new note?
For that, you will indeed need a document setting saying
"don't spellcheck notes".
Ah! I think we're dealing with some kind of type-level here...
Nothing wrong with that - but the document structure
and screen redrawing should be kept as simple as possible.
A type-level approach would be as much simple (at least): just use what
is already implemented: insets and layouts. The Inset::allowSpellcheck()
method is already there, and what I propose is just to use it. If you
have one note inset now, you'll have one note inset next; the only
difference is that it won't be spellchecked because its
allowSpellcheck() function will return false.
But (a) it wouldn't be as flexible (what if I want granularity smaller
than inset --- a word here, a word there?); (b) what if you and I don't
agree about what types should or should not be ignored; (c) what if what
I want ignored is not type-based at all --- I want to ignore this note,
and that table, and a third standard paragraph, but not all instances of
any of these types?
So inset-type would be a nice higher level, because it will allow me to
easily do what I usually want; but we still need to account for
exceptions, which inset-type can't do. (Don't say "we can have a special
'ignore spelling' inset": I think it will be hard to correctly implement
the latex output method for such an inset. What should happen in terms
of latex output in this case is absolutely nothing: it should be as if
the inset weren't there; but I think that it would be hard to achieve
this "nothing" in the current architecture, because there are too many
things which *do* happen when a new inset is started --- just look at
the relevant code...)
Regarding character-styles, I have two half-objections to using this:
(a) I'm not really sure that character styles are where the concept of
ignoring the spell-checker belongs. I see character styles as a tool for
semantic markup, whereas ignore spelling is not, IMO --- although agree
this may be debatable --- semantic, but technical. And mixing concepts
is a bad idea, even if today I can't point to a specific reason why. (b)
I'm not familiar enough with character styles, so you'll have to help me
here: is it possible to define a character style which leaves everything
exactly as it is, and only changes a single attribute (in our case: the
spelling)? If so, then OK (that's why this is only a half-objection ;)
); if not, though, then we'd need to theoretically double the number of
character styles: for every existing style, we would now have one with
spelling and one without...
Screen redrawing doesn't need anything more, frame and background are
already visible enough. You'd like a green underline? Then what happens
for already blue underlined text, can we stack those lines? If no,
further coding will be necessary.
This is really a non-issue, Mael. Attached is a patch which will deal
with this part of the problem. (The patch assumes a Font attribute and
method called ignore_spelling(), along the lines of what I suggested
last night at http://permalink.gmane.org/gmane.editors.lyx.devel/91874.
To tell the truth, I think I would prefer to have another new function,
something like 'paintSpecialMarkings' which would call both
paintForeignMark and paintIgnoreSpelling --- but this is just a
proof-of-concept patch. And no, don't expect it to compile! ;) ).
Then this is applied at note creation time too.
What about my old document that I created without this option? Should
I "remake" all notes?
It is usually ok that new features only are available after
you get the new LyX. :-)
Ok... but it's better if you can make new features available into new
documents. In fact, this could be possible with a per-character approach
by clicking on a document setting (find all notes into the doc and mark
them as not spellchecked)...
Almost any way we deal with this will entail a format change, and
together with that will be a lyx2lyx function (or XSLT?) to convert to
the new format. At that point, *if* we decide (and this is a big if, I'm
not at all suer I think this is correct) that every note should be
marked as ignore-spelling, then we could do that at the time of the
conversion.
Settings applied at inset creation time keeps
the spellchecker logic (and screen display logic) relatively simple.
Ok, but it makes creation less simple...
Indeed. It is all about "where to put the complexity/slowness".
Screen drawing should be kept fast and simple - it is slow enough
as it is already. At least on some machines. Actually,
put an ERT in a table cell and it is usually slow enough anywhere.
We could just use insets and layouts in a way similar to the way they're
used normally. The special inset wouldn't require much more processing,
even though its display could differ a bit from normal insets (e.g.
lines not broken).
The main window contents gets painted often - not the
place where you want any extra complexity.
I don't understand.
It's a question of adding complexity once (when the inset is created)
versus added complexity at screen painting, which happens every time the
cursor moves, i.e., all the time...
But the truth is, I'm much more worried about the next point than about
the efficiency.
If something extra happens at note creation time, then the delay
will be small because only that one note inset gets a treatment.
If this have to happen at spellcheck time, then we get all these delays
at the same time. Perhaps this don't matter much for efficiency,
but there is code maintainability too.
But what you propose is to replace one type-level information
(nospellcheck), by two processes (one at creation time, the other at
click on a document setting), the spellchecker test being required in
all cases (however, doing this test on a type base would require less
computations than on a word, or character base). In addition, until now
we just considered notes. What about comments, branches and layouts ?
Degree of abstraction is just too low to deal with all these things, and
maintainability is clearly worse!! I'd prefer to maintain 1 information,
than n processes!
The point is, though, that the ignore spell check will have a very
clear, simple interface: a character attribute. When we later decide
that actually this or that situation should or should not be ignore
spelling, we don't have to touch the core again (the core, in this case,
being the spell-checker itself; the lyx buffer; the file format; the
painting; etc.) --- we just have small methods here and there which are
in a one-to-one relation with the new situation. That's much more
maintainable than adding longer and longer lists of situations to what I
called "the core".
Mael.
Dov
Index: lyx-devel/src/rowpainter.cpp
===================================================================
--- lyx-devel.orig/src/rowpainter.cpp 2007-08-14 20:22:15.000000000 +0300
+++ lyx-devel/src/rowpainter.cpp 2007-08-14 20:26:07.000000000 +0300
@@ -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)
+{
+ if (!lyxrc.mark_ignore_spelling)
+ return;
+ if (font.ignore_spelling() == 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);
}