Work with sub paragragraphs

<< Click to Display Table of Contents >>

Navigation:  Appendix >

Work with sub paragragraphs

WPTools Version 9 stores the text in a paragraph tree. The paragraphs are connected using the property 'NextPar'. Some paragraph types require that contents paragraphs are stored on a deeper level, as children paragraphs. For example tables are created that way.

 

You can use this feature to separate the text into different sections. (Don't mix up with the text sections described here)

 

These sections can be useful if you need to use one editor to edit or display the text which is stored in different locations, for example different database fields or even database records. It is even thinkabele to use WPTools similar to a database grid!

 

We created demo which showshow this can be done. You find this demo in the directory SubParagraphs.

 

clip0117

 

The demo shows how to use the paint line event to show the gray header bands. It also contains the code which moves the text from and to the main editor or the fields.

 

This code is executed when '<<<<' is pressed:

 

procedure TWPSubParDemo.LoadDataClick(Sender: TObject);

var par: TParagraph;

 block: TWPRTFDataBlock;

 mem: TMemoryStream;

 s: string;

 charattr_for_ANSI: Cardinal;

begin

 mem := TMemoryStream.Create;

 AllText.LockScreen;

try

   AllText.Clear;

  // AFTER the clear we calculate our ANSI character property

   AllText.AttrHelper.Clear;

   AllText.AttrHelper.SetFontName('Courier New');

   AllText.AttrHelper.SetFontSize(1000);

   charattr_for_ANSI := AllText.AttrHelper.CharAttr;

  // and now create the text

   AllText.CheckHasBody;

   block := AllText.ActiveText;

   par := block.FirstPar;

   par.ASet(WPAT_ParProtected, 1);

   par.Name := 'FieldA';

   par.ParagraphType := wpIsXMLTopLevel;

   s := FieldA.Text;

  // SetAllText creates a sub paragraph when the first #13#10 is found!

  if s <> '' then par.SetAllText(#13 + #10 + s, charattr_for_ANSI); // The first ANSI Text

 

   par.NextPar := TParagraph.Create(block);

   par := par.NextPar;

   par.ParagraphType := wpIsXMLTopLevel;

   par.ASet(WPAT_ParProtected, 1);

   par.Name := 'FieldB';

   par.ASet(WPAT_CharFontSize, 900);

   FieldB.SaveToStream(mem, 'WPTOOLS');

   mem.Position := 0;

  par.LoadFromStream(mem, 'AUTO', '', [wploadpar_AsChildrenPar]); // The formatted Text

 

   par.NextPar := TParagraph.Create(block);

   par := par.NextPar;

   par.ParagraphType := wpIsXMLTopLevel;

   par.ASet(WPAT_ParProtected, 1);

   par.Name := 'FieldC';

   s := FieldC.Text;

  if s <> '' then par.SetAllText(#13 + #10 + s, charattr_for_ANSI); // The last ANSI Text

finally

   mem.Free;

   AllText.UnLockScreen(true);

end;

end;

 

This code is executed when '>>>>' is pressed:

 

procedure TWPSubParDemo.PostDataClick(Sender: TObject);

var par, cpar: TParagraph;

 mem: TMemoryStream;

begin

 par := AllText.FirstPar;

while par <> nil do

begin

  if par.ParagraphType = wpIsXMLTopLevel then

  begin

    if par.Name = 'FieldA' then

    begin

       FieldA.Text := par.GetAllText(false, false);

    end

    else if par.Name = 'FieldB' then

    begin

       FieldB.LockScreen;

      try

        // This code uses AppendParCopy() to copy the text --------------------

         FieldB.Clear;

         cpar := par.ChildPar;

        while cpar <> nil do

           FieldB.BodyText.AppendParCopy(cpar);

         FieldB.CheckHasBody;

 

        // The code uses a stream to copy the text ----------------------------

        // this will be useful if you need to save to a blob field!

        {mem := TMemoryStream.Create;

         try

           if par.SaveToStream(mem, true, 'WPTOOLS') then

           begin

             mem.Position := 0;

             FieldB.LoadFromStream(mem, 'WPTOOLS', true);

           end

           else FieldB.Clear;

         finally

           mem.Free;

         end;}

      finally

         FieldB.UnLockScreen(true);

      end;

    end

    else if par.Name = 'FieldC' then

    begin

       FieldC.Text := par.GetAllText(false, false);

    end;

  end;

   par := par.NextPar; // do NOT use "next" here

end;

end;