dubois@uwmacc.UUCP (Paul DuBois) (09/08/86)
I am going to conjecture that there is a certain bug in TextEdit, and a depending-on-your-taste-it's-a bug as well. Both of these relate to the use of word wrap in a TE record (that is, when (**hTE).crOnly = 0). Certain bug: type a few lines into a text window, putting returns at the end of each line, say ________________________________________ |abc |def |ghi | You can either put a cr at the end of the last line or not. Now click the mouse below the text and swipe up till the mouse is just after the f or the c - that is, so that all lines below the mouse are inverted, plus everything *after* the text on the line on which the mouse is. Hit backspace (or Cut or Clear). All the selected text disappears, and you have a blinking caret after the (now-)last line, which is as it should be. But the rest of that same line (where there is no text) remains inverted. I find this highly reproducible, both in my own programs, and in other applications using word wrap in text records (e.g., the STR editing window in ResEdit). No big deal, right. Wrong. I've noticed that this results in later screwups in the window of caret activating/deactivating - sometimes two carets appear, or the caret doesn't go away when the window is deactivated. Depending-on-taste bug: It seems to me that the purpose of word wrap is to keep things from disappearing off the right end of the view rectangle (assuming a properly set up destination rectangle), and indeed, when you are typing text words get shoved down to the next line if they'd go off the right end. But try this: type some stuff almost to the right edge. Then type spaces. You caret disappears. It doesn't wrap. Clicking in the text puts the caret at the right spot, clicking below the text makes it "go away" - it's really at the end of the line with all the spaces at the end of it. **That is, it's NOT in the view rectangle.** Can anyone confirm this, or (preferably) tell me that I'm doing something wrong, and what to do instead? -- Paul DuBois UUCP: {allegra,ihnp4,seismo}!uwvax!uwmacc!dubois | ARPA: dubois@easter --+-- | Begin at my sanctuary... | Ezekiel 9:6
dubois@uwmacc.UUCP (Bill Winkle) (09/16/86)
This is a reply to an article on info-mac > Date: Sun, 14 Sep 86 02:36 N > From: <INFOEARN%HLERUL5.BITNET@WISCVM.WISC.EDU> > 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." |
dlc@lanl.ARPA (Dale Carstensen) (09/18/86)
> > From: <INFOEARN%HLERUL5.BITNET@WISCVM.WISC.EDU> > From: dubois@uwmacc.UUCP (Bill Winkle @ Brain-Dead Software) The above two discussed keeping the TextEdit caret in the visible window when the caret is on the last line of the TE text. A simpler way to locate the caret exists. A TERec field named selRect is a Rect which contains the caret when no selection is active (selStart is the same as selEnd). So all that needs to be done to make sure the caret is in the visible window, is to make sure that Rect is in the visible window. A lot of consideration of font size parameters is also not necessary. Unfortunately, IM doesn't say much about selRect. There are some strange special values that appear in it. So, to figure out how to write your program, you need to do a lot of peering at selRect with MacsBug or something that displays it independently. I think I did a fair job in the Aztec C version of SKEL that I submitted to info-mac, available in the Sumex archives. Anything that keeps track of rectangle coordinates for scrolling in windows can be confusing, so expect to have to think really hard about how to write your scrolling routines, and expect a few surprises from the trap handlers. Dale Carstensen dlc@lanl.arpa {cmcl2|ihnp4}!lanl!dlc.uucp