{-------------------------------------------------------------------------------
  Demo: printing documents using TRVReportHelper.
  This demo loads RVF file in rvh.RichView and prints it.
  rvh2 is used to print header: (- page no -).

  Advantages of this method:
  - possibility to make custom complex headers and footers, different for
    different pages;
  - possibility to implement nonstandard layouts, printing several documents
    in different areas on the same page,etc
  Disadvantages of this method:
  - no preview (at least, not with TRVPrintPreview)
  - you need to calculate all margins yourself

 ------------------------------------------------------------------------------

  For example, you can open RVF file created by ActionText (including readme.rvf).
  Do not try to load file from the editor demo (Demos\*\Editors\Editor 1) - it does
  not contain a collection of styles, so it can be opened only by
  applications having that collection of styles.

-------------------------------------------------------------------------------}

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Printers, Dialogs,
  RVScroll, RichView, PtblRV, RVReport, StdCtrls, RVStyle;

type
  TForm1 = class(TForm)
    Button1: TButton;
    rvh: TRVReportHelper;
    RVStyle1: TRVStyle;
    OpenDialog1: TOpenDialog;
    Button2: TButton;
    rvh2: TRVReportHelper;
    RVStyle2: TRVStyle;
    Button3: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  with rvh.RichView do begin
    RVFOptions := [rvfoSavePicturesBody,rvfoSaveControlsBody,rvfoSaveBinary,
      rvfoSaveBack,rvfoLoadBack,rvfoSaveTextStyles,rvfoSaveParaStyles,
      rvfoSaveLayout,rvfoLoadLayout];
    Options := Options + [rvoTagsArePChars];
    RVFParaStylesReadMode := rvf_sInsertMerge;
    RVFTextStylesReadMode := rvf_sInsertMerge;
    Style := RVStyle1;
  end;
  with rvh2.RichView do begin
    Style := RVStyle2;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then begin
    rvh.RichView.Clear;
    rvh.RichView.LoadRVF(OpenDialog1.FileName);
  end;
end;

// print one column
procedure TForm1.Button2Click(Sender: TObject);
var DocWidth, DocHeight, DocLeft, DocTop, HeaderTop, LineY,
    PageNo: Integer;
begin
  if rvh.RichView.ItemCount=0 then begin
    Application.MessageBox('Document is empty!', 'Empty', 0);
    exit;
  end;
  Printer.Title := 'ReportHelper Test';
  Printer.BeginDoc;
  try
    PageNo := 1;
    DocLeft := Printer.PageWidth div 20; // margins = 5%
    DocWidth := Printer.PageWidth - DocLeft*2;
    HeaderTop := Printer.PageHeight div 20; // margins = 5%
    rvh.Init(Printer.Canvas, DocWidth);
    while True do begin
      // creating & formatting header
      rvh2.RichView.Clear;
      rvh2.RichView.AddFmt('- %d -', [PageNo], 0, 1);
      rvh2.Init(Printer.Canvas, DocWidth);
      rvh2.FormatNextPage(Printer.PageHeight);
      DocTop := HeaderTop+rvh2.EndAt+HeaderTop div 2;
      // formatting next page of document
      DocHeight := Printer.PageHeight-DocTop-HeaderTop;
      if not rvh.FormatNextPage(DocHeight) then
        break;
      // starting new page
      if PageNo>1 then
        Printer.NewPage;
      // drawing line between header and document
      with Printer.Canvas do begin
        Pen.Style := psInsideFrame;
        Pen.Width := 10;
        Pen.Color := clBlack;
        LineY := HeaderTop+rvh2.EndAt+HeaderTop div 4;
        MoveTo(DocLeft*2, LineY);
        LineTo(Printer.PageWidth-DocLeft*2, LineY);
      end;
      // drawing header and document
      rvh2.DrawPageAt(DocLeft, HeaderTop, 1, Printer.Canvas, False, rvh2.EndAt);
      rvh.DrawPageAt(DocLeft, DocTop, PageNo, Printer.Canvas, False, DocHeight);
      inc(PageNo);
    end;
  finally
    Printer.EndDoc;
  end;
end;

// print two columns
procedure TForm1.Button3Click(Sender: TObject);
var ColWidth, DocHeight, DocTop, Col1Left, Col2Left,
    HeaderLeft, HeaderTop, HeaderWidth, LineY,
    PageNo: Integer;
begin
  if rvh.RichView.ItemCount=0 then begin
    Application.MessageBox('Document is empty!', 'Empty', 0);
    exit;
  end;
  Printer.Title := 'ReportHelper Test';
  Printer.BeginDoc;
  try
    PageNo := 1;
    HeaderLeft := Printer.PageWidth div 20; // margins = 5%
    HeaderWidth := Printer.PageWidth - HeaderLeft*2;
    HeaderTop := Printer.PageHeight div 20; // margins = 5%
    ColWidth := (HeaderWidth-HeaderLeft) div 2;
    Col1Left := HeaderLeft;
    Col2Left := Col1Left+ColWidth+HeaderLeft div 2;
    rvh.Init(Printer.Canvas, ColWidth);
    while True do begin
      // creating & formatting header
      rvh2.RichView.Clear;
      rvh2.RichView.AddFmt('- %d -', [PageNo], 0, 1);
      rvh2.Init(Printer.Canvas, HeaderWidth);
      rvh2.FormatNextPage(Printer.PageHeight);
      DocTop := HeaderTop+rvh2.EndAt+HeaderTop div 2;
      // formatting the first column of document
      DocHeight := Printer.PageHeight-DocTop-HeaderTop;
      if not rvh.FormatNextPage(DocHeight) then
        break;
      // starting new page
      if PageNo>1 then
        Printer.NewPage;
      // drawing line between header and document
      with Printer.Canvas do begin
        Pen.Style := psInsideFrame;
        Pen.Width := 10;
        Pen.Color := clBlack;
        LineY := HeaderTop+rvh2.EndAt+HeaderTop div 4;
        MoveTo(HeaderLeft*2, LineY);
        LineTo(Printer.PageWidth-HeaderLeft*2, LineY);
      end;
      // drawing header and document
      rvh2.DrawPageAt(HeaderLeft, HeaderTop, 1, Printer.Canvas, False, rvh2.EndAt);
      rvh.DrawPageAt(Col1Left, DocTop, PageNo*2-1, Printer.Canvas, False, DocHeight);
      if rvh.FormatNextPage(DocHeight) then
        rvh.DrawPageAt(Col2Left, DocTop, PageNo*2, Printer.Canvas, False, DocHeight);
      inc(PageNo);
    end;
  finally
    Printer.EndDoc;
  end;
end;

end.
