Footnotes

Top  Previous  Next

Footnotes are implemented similar to text boxes. Like text boxes the contents are stored in the RTFDataCollection. But footnotes do not use a TWPObject class to be painted, they use just one  TWPTextObj instance with ObjType = wpobjFootnote.

 

Text text of the footnote uses the style mentioned in the StyleName properety of the TWPTextObj as basis style.

 

NEW: Footnotes can now be several pages long!

 

footnote_page_span

 

Use the flag wpfKeepFootnotesOnPage in property FormatOptionsEx2 to make the formatting routine try not to not split up footnotes as long as possible by creating a new page before the footnote.

 

So a footnote can be created with the following code. This code also check if a paragraph style names 'Footnotes' exists and, if not, creates one.

 

The code also create a default text with an text object named 'TEXTNR'. This text object will display the number of the footnote.

 

At the end the complete text of the footnote is selected, except for the number.

 

procedure TWPTextBoxDemo.InsertFootnoteClick(Sender: TObject);

var foottext : TWPRTFDataBlock;

   footobj : TWPTextObj;

begin

  // Create default foonote style:

  if WPRichText1.ParStyles.GetID('Footnotes')=0 then

  begin

    with WPRichText1.ParStyles.AddStyle('Footnotes') do

    begin

        ASetFontName('Times New Roman');

        ASet(WPAT_CharFontSize, 600);

    end;

  end;

 

  inc(FootNoteNr);

  WPRichText1.CurrAttr.AddStyle([afsSuper]);

  footobj := WPRichText1.TextObjects.InsertNewObject(wpobjFootnote,false, false);

  WPRichText1.CurrAttr.DeleteStyle([afsSuper]);

  footobj.Name := 'FOOT_' + IntToStr(FootNoteNr);

  footobj.StyleName := 'Footnotes';

  foottext := WPRichText1.HeaderFooter.Get(wpIsFootnote, wpraOnAllPages, footobj.Name);

  foottext.RtfText.AsString

       := '<html><textobj name="TEXTNR"/>) ' + Edit1.Text + '</html>';

  WPRichText1.CursorOnText := foottext;

  WPRichText1.CPPosition := 3;

  WPRichText1.SetSelPosLen(3, MaxInt);

  WPRichText1.ShowCursor;

  WPRichText1.SetFocus;

end;

 

Since this is bit much code to simple create a footnote we have implemented the function

InputFootnote(PlaceCursor: Boolean; CreateNumber: Boolean = TRUE; InitText: string = #32);

which does basically the same as the above code.

 

 

 

Please use the method

 

  InputFootnote(PlaceCursor: Boolean; CreateNumber: Boolean = TRUE; InitText: string = #32);

 

to create a footnote. Like textboxes, headers and footers the footnotes are also "text layers".

 

The text layers are all stored as collection items in the collection HeaderFooters.

 

 

Do you need to create footnotes by drag&drop? This is also possible´.

 

Please implement the drag&drop events as follows.

 

procedure TForm1.WPRichText1DragDrop(Sender, Source: TObject; X, Y: Integer);

var par : TParagraph;

   posinpar : Integer;

begin

 if Source=DragMeBtn then

 begin

    // this code can be used to create text without additional attributes

    (*

    if WPRichText1.GetLineFromXY(X,Y,par,posinpar) then

    begin

       WPRichText1.TextCursor.MoveTo(par, posinpar);

      WPRichText1.InputFootnote('This is the text in the footnote',

          [wpCreateNumberInFootnote, wpNumberInFootnoteIsSuperScript]);

       WPRichText1.ReformatAll(false, true);

    end;

    *)

 

    // Create formatted text, such as "bold" text:

    if WPRichText1.GetLineFromXY(X,Y,par,posinpar) then

    begin

       WPRichText1.TextCursor.MoveTo(par, posinpar);

       WPRichText1.InputFootnote('',[wpPlaceCursorInFootnote]);

       WPRichText1.InputString('Footnote with ');

       WPRichText1.CurrAttr.Style := [afsBold];

       WPRichText1.InputString('bold ');

       WPRichText1.CurrAttr.Style := [];

       WPRichText1.InputString(' text.');

       WPRichText1.TextCursor.MoveTo(par, posinpar+1);

       WPRichText1.ReformatAll(false, true);

    end;

 end;

 

end;

 

procedure TForm1.WPRichText1DragOver(Sender, Source: TObject; X, Y: Integer;

 State: TDragState; var Accept: Boolean);

var par : TParagraph;

   posinpar : Integer;

begin

  // Accept footnote, but not inside of another footnote

  Accept := (Source = DragMeBtn);

  if Accept and

        WPRichText1.CheckHasBody and

        ( not   WPRichText1.GetLineFromXY(X,Y,par,posinpar) or

        (par.RTFData.Kind<>wpIsBody) ) then Accept := false;

end;