{==============================================================================}
{
  This demo shows how to implement listbox-like selection using hypertext.
  Property settings:
  - rvoTagsArePChars is included in srv.RichViewEdit.Options
  - rvoAllowSelection is excluded from srv.RichViewEdit.Options
  - srv.RichViewEdit.TabNavigation = rvtnNone
  - srv.RichViewEdit.Style = RVStyle1
  - 3 text styles are created in RVStyle.TextStyles
    TextStyles[0] - normal text
    TextStyles[1] - hypertext
    TextStyles[2] - hypertext with background

  NOTE: This demo is a bit overcomplicated.
    If you do not use tables (TRVTableItemInfo), you do not need to
    work with RVData variables (because documents without tables
    have only one RVData - srv.RichViewEdit.RVData)
  NOTE2: phonebook can be saved (srv.RichViewEdit.SaveRVFFromFile)
    and loaded (srv.RichViewEdit.LoadRVFFromFile). In order to load bullets (images with phones),
    process OnRVFImageListNeeded.
}
{==============================================================================}
unit Unit1;

interface

{$I RV_Defs.inc}

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  {$IFDEF RICHVIEWDEF4}
  ImgList,
  {$ENDIF}
  Dialogs, StdCtrls, RVScroll, RichView, RVStyle, CRVFData, SclRView;

type
  TForm1 = class(TForm)
    ImageList1: TImageList;
    RVStyle1: TRVStyle;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Edit1: TEdit;
    srv: TSRichViewEdit;
    procedure FormCreate(Sender: TObject);
    procedure rvJump(Sender: TObject; id: Integer);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
    FSelectedRVData: TCustomRVFormattedData;
    FSelectedItemNo: Integer;
    function MakeTag(s: String): Integer;
    function GetTagStr(tag: Integer): String;
    procedure Select(RVData: TCustomRVFormattedData; ItemNo: Integer);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}

{ TForm1 }

const
  TEXTSTYLE_NOTMALTEXT = 0;
  TEXTSTYLE_JUMP = 1;
  TEXTSTYLE_SELECTED = 2;

function TForm1.MakeTag(s: String): Integer;
begin
  Result := Integer(StrNew(PChar(s)));
end;

function TForm1.GetTagStr(tag: Integer): String;
var i: Integer;
begin
  // reverse function
  Result := PChar(tag);
  for i := 1 to Length(Result) do
    if Result[i]=#1 then
      Result[i] := ' ';
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  srv.SetMargin(85, 50, 20, 52);

  srv.RichViewEdit.AddNL('Telephone directory:',0,0);
  srv.RichViewEdit.AddBulletEx('',0, ImageList1, 0);
  srv.RichViewEdit.AddTag('Kim Lumber',TEXTSTYLE_JUMP, MakeTag('123-4567'));
  srv.RichViewEdit.AddBulletEx('',0, ImageList1, 0);
  srv.RichViewEdit.AddTag('Phil Forest',TEXTSTYLE_JUMP, MakeTag('234-5678'));
  srv.RichViewEdit.AddBulletEx('',0, ImageList1, 0);
  srv.RichViewEdit.AddTag('Woody Young',TEXTSTYLE_JUMP, MakeTag('345-6789'));
  srv.RichViewEdit.Format;
end;

procedure TForm1.Select(RVData: TCustomRVFormattedData; ItemNo: Integer);
begin
  if (FSelectedRVData<>nil) and (FSelectedRVData=RVData) and
     (FSelectedItemNo=ItemNo) then begin
    Button2.Click;
    exit;
  end;
  if FSelectedRVData<>nil then
    FSelectedRVData.GetItem(FSelectedItemNo).StyleNo := TEXTSTYLE_JUMP;
  if RVData<>nil then begin
    Edit1.Text := GetTagStr(RVData.GetItemTag(ItemNo));
    RVData.GetItem(ItemNo).StyleNo := TEXTSTYLE_SELECTED;
  end;
  FSelectedRVData := RVData;
  FSelectedItemNo := ItemNo;
  srv.RichViewEdit.Refresh;
  {
   In this demo, two text styles (TEXTSTYLE_SELECTED and TEXTSTYLE_JUMP)
   have difference only in colors.
   But if they had different font name/size/style, or different jump flag,
   Refresh would be not enough - change this line to srv.RichViewEdit.Format;
  }
end;
{------------------------------------------------------------------------------}
procedure TForm1.rvJump(Sender: TObject; id: Integer);
var RVData: TCustomRVFormattedData;
    ItemNo: Integer;
begin
  srv.RichViewEdit.GetJumpPointLocation(id, RVData, ItemNo);
  Select(RVData, ItemNo);
end;
{------------------------------------------------------------------------------}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2.Edit1.Text := '';
  Form2.Edit2.Text := '';
  if Form2.ShowModal=mrOk then begin
    srv.RichViewEdit.AddBulletEx('',0, ImageList1, 0);
    srv.RichViewEdit.AddTag(Form2.Edit1.Text ,TEXTSTYLE_JUMP, MakeTag(Form2.Edit2.Text));
    srv.RichViewEdit.FormatTail;
    Select(srv.RichViewEdit.RVData, srv.RichViewEdit.ItemCount-1);
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  if FSelectedRVData=nil then begin
    Beep;
    exit;
  end;
  Form2.Edit1.Text := FSelectedRVData.GetItemText(FSelectedItemNo);
  Form2.Edit2.Text := GetTagStr(FSelectedRVData.GetItemTag(FSelectedItemNo));
  if Form2.ShowModal=mrOk then begin
    FSelectedRVData.SetItemText(FSelectedItemNo, Form2.Edit1.Text);
    FSelectedRVData.SetItemTag(FSelectedItemNo, MakeTag(Form2.Edit2.Text));
    srv.RichViewEdit.Format;
    Edit1.Text := Form2.Edit2.Text;
  end;
end;


procedure TForm1.Button3Click(Sender: TObject);
var RVData: TCustomRVFormattedData;
    ItemNo: Integer;
begin
  if FSelectedRVData=nil then begin
    Beep;
    exit;
  end;
  RVData := FSelectedRVData;
  ItemNo := FSelectedItemNo;
  Select(nil, -1);
  RVData.DeleteItems(ItemNo-1, 2); // deleting two items: image and text
  srv.RichViewEdit.Format;
  Edit1.Text := '';
end;

end.
