Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!uwvax!uwmacc!dubois From: dubois@uwmacc.UUCP (Bill Winkle) Newsgroups: net.micro.mac Subject: Re: TextEdit Bugs Message-ID: <261@uwmacc.UUCP> Date: Mon, 15-Sep-86 17:05:53 EDT Article-I.D.: uwmacc.261 Posted: Mon Sep 15 17:05:53 1986 Date-Received: Tue, 16-Sep-86 20:46:04 EDT Distribution: net Organization: Brain-Dead Software Lines: 108 This is a reply to an article on info-mac > Date: Sun, 14 Sep 86 02:36 N > From: > Subject: RE:TextEdit Bugs > I also have a third bug to add to the list. It isn't a serious bug, but it's > something you have to be aware of when you're programming with TextEdit. > Several text editors, including MockWrite and MiniEdit from Macintosh Revealed, > always make sure the edit window is completely filled with text, if possible. > This means that they scroll their text down whenever empty space appears at > the bottom after a cut or paste. Part of checking how far to scroll down is > looking at the value of nLines which tells you how many lines the TextEdit > record has. > However, if the caret is all the way at the end of the text record on an empty > line, TextEdit doesn't consider this a line and therefore nLines is one too > little. This means that our text editor (MockWrite) will not scroll down far > enough and the caret will be on a nonexisting and invisible line! As soon as > you type a character, TextEdit creates the new line, the text editor will see > scrolling is necessary and your caret comes back into view. But once you type > a backspace, the line is destroyed and the caret vanishes again. I don't think this is a bug in TextEdit, it's a bug in the programs that use TextEdit. I know that I consider Chernicoff's code wrong, from looking at it (I haven't actually used it). In any case, here's a function I use to determine the number of display lines a text record takes. It may not be intuitive, but it's correct. Programs that fiddle with text should make sure to do similar tests. /* Determine number of display lines needed for text record. If empty, need one line. If there's a carriage return at the end, then need another line to allow placement of caret at beginning of last line plus one. */ DisplayCount (te) TEHandle te; { int nLines, teLength; nLines = (**te).nLines; teLength = (**te).teLength; if (teLength == 0 || (*((**te).hText))[teLength-1] == '\r') ++nLines; return (nLines); } You run into a similar problem determining which line the caret is actually in. Again, it's not a bug in TextEdit, you just have to be careful. Again, I think (but cannot verify without testing) that Chernicoff's code is wrong. Here's what I use. (This is a dumb algorithm; it really should do binary search). /* Return the line number that the caret (or the beginning of the currently selected text) is in. Value returned is in the range 0..(**te).nLines. If = (**te).nLines, the caret is past the last line. The only special case to watch out for is at the very end of the text. If the last character is not a carriage return, then the caret is on the (nLines-1)th line, not the (nLines)th line. */ GetCaretPos (te) TEHandle te; { int i; int nLines; int teLength; int selStart; int lineStart; selStart = (**te).selStart; nLines = (**te).nLines; teLength = (**te).teLength; if (selStart == teLength) { if (teLength != 0 && (*(**te).hText))[teLength-1] != '\r') return (nLines - 1); return (nLines); } for (i = 0; /* empty */; ++i) { if ((lineStart = (**te).lineStarts[i]) >= selStart) break; /* succeeds eventually */ } if (lineStart != selStart) --i; return (i); } I hope this saves someone some trouble. -- Paul DuBois UUCP: {allegra,ihnp4,seismo}!uwvax!uwmacc!dubois | ARPA: dubois@easter --+-- | "If it works, I didn't write it." |