[Example] Saving additional information in RTF files

Demos, code samples. Only questions related to the existing topics are allowed here.
Post Reply
Sergey Tkachenko
Site Admin
Posts: 13398
Joined: Sat Aug 27, 2005 10:28 am
Contact:

[Example] Saving additional information in RTF files

Post by Sergey Tkachenko » Tue Sep 06, 2005 5:47 pm

Use OnSaveRTFExtra event:

Saving margins

Code: Select all

procedure TForm3.RichViewEdit1SaveRTFExtra(Sender: TCustomRichView;
  Area: TRVRTFSaveArea; Obj: TObject; Index1, Index2: Integer;
  InStyleSheet: Boolean; var RTFCode: TRVAnsiString);

  function MMToTwips(mm: Integer): Integer;
  begin
    Result := Round(mm*1440*5/127);
  end;

begin
  // uncomment "AnsiStrings." if you use Delphi 2009+
  if Area=rv_rtfs_Doc then
    RTFCode := {AnsiStrings.}Format('\margl%d\margt%d\margr%d\margb%d',
      [MMToTwips(RVPrint1.LeftMarginMM),
       MMToTwips(RVPrint1.TopMarginMM),
       MMToTwips(RVPrint1.RightMarginMM),
       MMToTwips(RVPrint1.BottomMarginMM)]);
end;
Note: since TRichView v10, you can save and load margins specified in DocParameters.

Saving plain text header and footer

Code: Select all

procedure TForm3.RichViewEdit1SaveRTFExtra(Sender: TCustomRichView;
  Area: TRVRTFSaveArea; Obj: TObject; Index1, Index2: Integer;
  InStyleSheet: Boolean; var RTFCode: TRVAnsiString);
begin
  if Area=rv_rtfs_Doc then
    RTFCode :=
     '{\header\pard\plain\posxc THIS IS HEADER WITH PAGENUMBER: {\field{\*\fldinst PAGE}{\fldrslt 1}}\par}'+
     '{\footer\pard\plain\posxr THIS IS FOOTER\par}';
end;
In this example:
\posxc - keyword for aligning header/footer to center
\posxr - keyword for aligning header/footer to right
{\field{\*\fldinst PAGE}{\fldrslt 1}} - code for inserting page number
Note: since TRichView v11, you can save and load header and footer in other richviews, see rvrtfSaveHeaderFooter in RTFOptions
Last edited by Sergey Tkachenko on Sun Feb 13, 2011 9:47 am, edited 3 times in total.

Sergey Tkachenko
Site Admin
Posts: 13398
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko » Sat Nov 25, 2006 4:52 pm

How to save several documents in on RTF file so that page numbers restarted on each subdocument.

Assuming that subdocuments are stored in RVF files.

The main procedure:

Code: Select all

procedure CreateRTFWithSections(const RVFFiles: array of String;
  const RTFFile: String; rv: TCustomRichView);
var i: Integer;
    Stream: TFileStream;
begin
  rv.Clear;
  with rv.Style do begin
    TextStyles.Clear;
    TextStyles.Add;
    with TextStyles.Add do
      Options := [rvteoRTFCode];
    ParaStyles.Clear;
    ParaStyles.Add;
    ListStyles.Clear;
  end;
  for i := Low(RVFFiles) to High(RVFFiles) do
    try
      Stream := TFileStream.Create(RVFFiles[i], fmOpenRead);
      try
        rv.InsertRVFFromStream(Stream, rv.ItemCount);
        if i<>High(RVFFiles) then
          rv.AddNL('\sect\pgnrestart', 1, 0);
      finally
        Stream.Free;
      end;
    except
      rv.AddNL('Error loading file', 0, 0);
    end;
  rv.SaveRTF(RTFFile, False);
end;
OnSaveRTFExtra event

Code: Select all

procedure TForm1.RichView1SaveRTFExtra(Sender: TCustomRichView;
  Area: TRVRTFSaveArea; Obj: TObject; Index1, Index2: Integer;
  InStyleSheet: Boolean; var RTFCode: TRVAnsiString);
begin
  case Area of
    rv_rtfs_Doc:
      RTFCode :=
       '{\header\pard\plain\posxc - {\field{\*\fldinst PAGE}{\fldrslt 1}} -\par}';
     rv_rtfs_TextStyle:
       if Index1=1 then
         RTFCode := '\v'; // making TextStyles[1] hidden, otherwise empty line
           // appears at the top of sections
  end;
end;
Example:

Code: Select all

  CreateRTFWithSections(['doc1.rvf', 'doc2.rvf', 'doc3.rvf'], 'Result.rtf', RichView1);
  RichView1.Format; // if you want to display
end;
Last edited by Sergey Tkachenko on Thu Dec 11, 2008 4:18 pm, edited 1 time in total.

Sergey Tkachenko
Site Admin
Posts: 13398
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko » Thu Dec 13, 2007 10:44 am

Similar example, how to save RTF with several sections, each section has its own orientation: http://www.trichview.com/support/files/ ... tation.zip

This example has a small problem: empty line at the beginning of each section. To minimize this problem, this line has a very small size.

Sergey Tkachenko
Site Admin
Posts: 13398
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko » Thu Jan 28, 2010 11:22 am

The same as above, but without empty line at the beginning:
http://www.trichview.com/support/files/ ... ation2.zip

The reason why this empty line occurs is the following.
To prevent its appearing, RTF code must contain '\sect' (section break) instead of '\par' (paragraph break). The previous code wrote '\sect' in addition to '\par', because there is no documented way for not-saving '\par', if the item starts a new paragraph. And the document representing a new section must start a new paragraph, otherwise paragraph attributes of the first line will be lost.

How it is solved:
1) RTF code (text having style TextStyles[1], with rvteoRTFCode in Option) is written to the end of the section, not from the new line.

2) When writing this text in RTF, OnSaveItemToFile occurs. In this event, we include rvstRTFSkipPar in RVData.State. This flag forces TRichView to skip saving the next paragraph break ('\par'). This flag is used internally for saving some special items, but here it helps to solve the problem with the empty line.

Post Reply