Re: Intro and BCF Texts question

Hans Klaver (hansklav@xs4all.nl)
Tue, 20 Jan 1998 23:13:06 +0100

Manfred Wuttke wrote:

> When I open a text document and write something with the keyboard at the
> caret position, process this input and write a result by a procedure to
> the text, the view is changed at the end of the commands so that the
> input is cleared at the original position and appended at the end of the
> text:
>
> >> input
> << result
>
> changes to
>
> >>
> << resultinput
>
> Is this behaviour intended by the framework?
> What can I do? Views.Update(..) at the fitting place doesn't work,
> writing the input in a buffer and inserting it again doesn't work either.
>
> I'm working with Blackbox 1.3 beta for the Macintosh.

The trick is to use caret positioning properly before writing to your text.
Use TextControllers.Controller.CaretPos() to get the current position of the
caret, and TextModels.Reader.SetPos(pos) and
TextFormatters.Formatter.SetPos(pos) to
set the reader and formatter to the right spot.

Here is some example:

MODULE TextMath;

IMPORT TextModels, TextControllers, TextMappers;

CONST line = 0DX;

PROCEDURE ProcessLine*;
(*
PRE: The caret is located at the end of a line
POST: The text on the line is read, processed and written on the next line
preceded by "<< "
*)
VAR
i, j, n: INTEGER;
ch: CHAR;
oldPos: INTEGER;
buf, str: ARRAY 128 OF CHAR;
text: TextModels.Model;
c: TextControllers.Controller;
r: TextModels.Reader;
f: TextMappers.Formatter;
BEGIN
c := TextControllers.Focus(); (* get the controler of the focus text *)
IF c.HasSelection() THEN RETURN END; (* otherwise Trap when setting the
reader *)
text := c.text; (* get the text of the focus window *)
r := text.NewReader(NIL); (* connect a reader to the text *)
oldPos := c.CaretPos(); (* remember position of the caret *)
IF oldPos = 0 THEN RETURN END; (* caret is at beginning of text *)
r.SetPos(oldPos); (* set the reader on the caret position in the text *)
(* Now read backward a stretch of text into a buffer, e.g. until the start
of the line *)
n := 0; r.ReadPrevChar(ch);
WHILE ch # line DO
buf[n] := ch;
INC(n); r.ReadPrevChar(ch)
END;
(* Do something with the characters in the (inverse!) buffer *)
j := 0;
FOR i := n - 1 TO 0 BY -1 DO str[j] := buf[i]; INC(j) END; str[j] := 0X;
(* Write the string to the text at the proper position *)
f.ConnectTo(text); (* open formatter on text *)
f.SetPos(oldPos); (* set caret to old position *)
f.WriteLn;
f.WriteString("<< " + str);
END ProcessLine;

END TextMath.

TextMath.ProcessLine

Try it out!

Hans Klaver