WPCubed Product Support

How to read the text in a line

I use the following code to read three lines of text:

var
  par : TParagraph;

  procedure ReadThreeLines;
  var
    s                  : string;
    pos                : integer;
    LocalLine         : integer;
    LocalOriginalLine : integer;
  begin 
    LocalLine         := WPRichText_Work.TextCursor.active_line;
    LocalOriginalLine := LocalLine;

    par := WPRichText_Work.ActiveParagraph;
    if ( par <> nil ) then
       s := par.GetLineText(LocalLine)
    else
       s := '';
    LocalLineaConReferencia := s;

    LocalLine := LocalOriginalLine;
    if ( par <> nil ) and
       ( par.PrevLine(LocalLine) ) then
       s := par.GetLineText(LocalLine)
    else
       s := '';
    LocalLineaAnterior := s;

    LocalLine := LocalOriginalLine;
    if ( par <> nil ) and
       ( par.NextLine(LocalLine) ) then
       s := par.GetLineText(LocalLine)
    else
       s := '';
    LocalLineaSiguiente := s;
  end; 

  threeLines := LocalLineaAnterior + 
                      LocalLineaConReferencia + 
                      LocalLineaSiguiente;

This code works perfectly if I run the program, read some text, point with the mouse to any text and press an appropiate button.

But when I run the program and want to automatize a process using CPMoveNext, threeLines appears always empty ('').

What is the problem?

With WPTools4 I use the following code to get the text in a line:

var
  par                     : PTParagraph;
  lin                     : PTLine;
  pa                      : PTAttr;
  pc                      : PChar;

      lin := WPRichText.Memo.active_line;
      pa  := lin^.pa;
      pos := 0;
      s   := '';
      for pos := 0 to lin^.plen - 1 do begin
        if not ( afsHidden in pa^.Style ) then
           s := s + WPGetChar(lin, pos)^;
        inc(pa);
      end; // for ...

What is the equivalent code using WPTools6?

Thank you in advance for your help.

Kind regards,

Carlos Borrero

#1 ♥ 0
6.9k Views 2 users read 4 min
support

Hi,

WPTools 4 does not use line records like WPTools 4 did. The paragraphs are kept intact, which usually make things a lot easier when accessing the text.

The TParagraph object has some line methods, they report the start and the length of the characters in one text line. Useing this values You can use GetSubText to extract the relevant characters.

Do not use CPMoveDown - they are for user interaction and use some extra code to solve the undefined state, when the cursor is at the end of one line - since this can be also the start of the next line.

Julian

#2 ♥ 0

The following code doesn't work either:

par := WPRichText_Work.ActiveParagraph;
    if ( par <> nil ) then begin
       LocalLinea         := WPRichText_Work.TextCursor.active_line;
       LocalLineaOriginal := LocalLinea;

       // Construye LineaConReferencia
       LocalLineOffset         := par.LineOffset(LocalLinea);
       LocalLineLength         := par.LineLength(LocalLinea);
       s                       := par.GetSubText(LocalLineOffset, LocalLineLength);
       LocalLineaConReferencia := s;

       // Construye LineaAnterior
       LocalLinea := LocalLineaOriginal;
       if ( par.PrevLine(LocalLinea) ) then begin
          LocalLineOffset      := par.LineOffset(LocalLinea);
          LocalLineLength      := par.LineLength(LocalLinea);
          s                    := par.GetSubText(LocalLineOffset, LocalLineLength);
       end // if ...
       else
          s := '';
       LocalLineaAnterior := s;

       // Construye LineaSiguiente
       LocalLinea := LocalLineaOriginal;
       if ( par.NextLine(LocalLinea) ) then begin
          LocalLineOffset      := par.LineOffset(LocalLinea);
          LocalLineLength      := par.LineLength(LocalLinea);
          s                    := par.GetSubText(LocalLineOffset, LocalLineLength);
       end // if ...
       else
          s := '';
       LocalLineaSiguiente := s;
    end; // if ...

The problems seems to be on the following line:
LocalLinea := WPRichText_Work.TextCursor.active_line;

I suppose WPRichText_Work.TextCursor.active_line reads the line number, within a paragraph.

But seems it doesn't.

Any ideas on how to know the line number within a paragraph that corresponds to CPPosition?

LineOffset and LineLength need to have this parameter.

Kind regards,

Carlos Borrero

#3 ♥ 0
support

Hi,

I tried this:

i := WPRichText1.ActivePosInPar;
i := WPRichText1.ActiveParagraph.LineOfPos(i, false);

which is basically the same as TextCursor.activeline.

I aslo tried this

i := WPRichText1.TextCursor.active_line;
s := WPRichText1.ActiveParagraph.GetLineText(i);
ShowMessage(IntToStr(i)+'='+s);

which works like GetSubText.

Julian

#4 ♥ 0
support

When You start Your code, is the text already reformatted? If not, no lines are
available.

The example I wrote can also be coded in such a sub procedure

function GetThreeLines(par : TParagraph; pos_in_par : Integer) : string;   var s, e : Integer;   begin       s := par.LineOfPos(pos_in_par);       if s<par.LineCount-1 then e := s+1 else e := s;       if s>0 then dec(s);        s := par.LineOffset(s);       e := par.LineOffset(e)+par.LineLength(e);       Result := par.GetSubText( s, e-s );   end;

which is used like this:

GetThreeLines( WPRichText1.ActiveParagraph, WPRichText1.ActivePosInPar )

Please use pos_in_par wherever You can and not line indexes (used to ber
pointers)

But is it possible that You do not need to read the lines of the paragraph but
the lines of a page? I mean, that you need the last line of the previous
paragraph in case your refence is on the first line of a paragraph. In this case
the sub procedure will NOT work. But you entry post did not suggest this.

I You need that:

s := WPRichText1.CPLine;   if WPRichText1.CPMoveUpLine then   begin     s := WPRichText1.CPLine + s;     WPRichText1.CPMoveDownLine;   end;   if WPRichText1.CPMoveDownLine then   begin     s := s + WPRichText1.CPLine;     WPRichText1.CPMoveUpLine;   end;

BTW:

function TWPCustomRtfEdit.GetCPLine: string;
var nr, i, l: Integer;
begin
  if FMemo.Cursor.active_paragraph <> nil then
  begin
    nr := FMemo.Cursor.active_line;
    i := FMemo.Cursor.active_paragraph.LineOffset(nr);
    l := FMemo.Cursor.active_paragraph.LineLength(nr);
    Result := FMemo.Cursor.active_paragraph.GetSubText(i, l)
  end else Result := '';
end;

CPMoveNext would not change anything, but the text must be formatted.

Julian

#5 ♥ 0
This category is archived. No new posts are possible.