unit F_PE_Text;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls,
  U_PreviewEngine;

type
  TfrmPEText = class(TCustomPreviewEngineForm)
    rtePreview: TRichEdit;
  private
    { Private declarations }
  protected
    function GetRenderers: TRendererList; override;
  public
    { Public declarations }
    procedure Clear; override;
  end;

var
  frmPEText: TfrmPEText;

implementation
uses
  System.Win.Registry;

{$R *.dfm}

type
  { ------------------------------------------------------------------------------------------------ }
  TTextRenderer = class(TRenderer)
  private
    FFont: TFont;
  public
    constructor Create(const Parent: TCustomPreviewEngineForm; const Name: string = '');
    destructor  Destroy; override;
    function  CouldShowFile(const FileName: string): boolean; override;
    function  TryShowFile(const FileName: string): boolean; override;
    procedure PopulateInfo(const Lines: IInfoLineDisplayer); override;
  end {TTextRenderer};

  { ------------------------------------------------------------------------------------------------ }
  TRichTextRenderer = class(TRenderer)
  public
    function  CouldShowFile(const FileName: string): boolean; override;
    function  TryShowFile(const FileName: string): boolean; override;
    procedure PopulateInfo(const Lines: IInfoLineDisplayer); override;
  end {TRichTextRenderer};


{ ================================================================================================ }
{ TfrmPEText }

{ ------------------------------------------------------------------------------------------------ }
procedure TfrmPEText.Clear;
begin
  inherited;
  rtePreview.Clear;
end {TfrmPEText.Clear};

{ ------------------------------------------------------------------------------------------------ }
function TfrmPEText.GetRenderers: TRendererList;
begin
  Result := inherited GetRenderers;
  if Result.Count = 0 then begin
    Result.Add(TRichTextRenderer.Create(Self, 'Rich Text'));
    Result.Add(TTextRenderer.Create(Self, 'Plain Text'));
  end;
end {TfrmPEText.GetRenderers};



{ ================================================================================================ }
{ TTextRenderer }

{ ------------------------------------------------------------------------------------------------ }
constructor TTextRenderer.Create(const Parent: TCustomPreviewEngineForm; const Name: string);
begin
  inherited;
  FFont := TFont.Create;
  FFont.Assign(TfrmPEText(Parent).rtePreview.Font);
end {TTextRenderer.Create};

{ ------------------------------------------------------------------------------------------------ }
destructor TTextRenderer.Destroy;
begin
  FFont.Free;
  inherited;
end {TTextRenderer.Destroy};

{ ------------------------------------------------------------------------------------------------ }
function TTextRenderer.CouldShowFile(const FileName: string): boolean;
var
  Ext: string;
  Reg: TRegistry;
begin
  Ext := ExtractFileExt(FileName);
  Result := SameFileName(Ext, '.txt');
  if Result then
    Exit;
  Reg := TRegistry.Create(KEY_READ);
  try
    Reg.RootKey := HKEY_CLASSES_ROOT;
    Result := Reg.OpenKeyReadOnly(Ext) and SameText(Reg.ReadString('PerceivedType'), 'text');
  finally
    Reg.Free;
  end;
end {TTextRenderer.CouldShowFile};

{ ------------------------------------------------------------------------------------------------ }
function TTextRenderer.TryShowFile(const FileName: string): boolean;
begin
  with TfrmPEText(Form).rtePreview do begin
    Lines.BeginUpdate;
    try
      Clear;
      PlainText := True;
      Font.Assign(FFont);
      Lines.LoadFromFile(FileName);
    finally
      Lines.EndUpdate;
    end;
  end;
  Result := True;
end {TTextRenderer.TryShowFile};

{ ------------------------------------------------------------------------------------------------ }
procedure TTextRenderer.PopulateInfo(const Lines: IInfoLineDisplayer);
begin
  inherited;
  with TfrmPEText(Form).rtePreview.Lines do begin
    Lines.Add('Text', 'Lines', Count);
    Lines.Add('Text', 'Encoding', Encoding.EncodingName);
  end;
end {TTextRenderer.PopulateInfo};


{ ================================================================================================ }
{ TRichTextRenderer }

{ ------------------------------------------------------------------------------------------------ }
function TRichTextRenderer.CouldShowFile(const FileName: string): boolean;
begin
  Result := SameFileName(ExtractFileExt(FileName), '.rtf');
end {TRichTextRenderer.CouldShowFile};

{ ------------------------------------------------------------------------------------------------ }
function TRichTextRenderer.TryShowFile(const FileName: string): boolean;
begin
  with TfrmPEText(Form).rtePreview do begin
    Lines.BeginUpdate;
    try
      PlainText := False;
      Lines.LoadFromFile(FileName);
    finally
      Lines.EndUpdate;
    end;
  end;
  Result := True;
end {TRichTextRenderer.TryShowFile};

{ ------------------------------------------------------------------------------------------------ }
procedure TRichTextRenderer.PopulateInfo(const Lines: IInfoLineDisplayer);
begin
  inherited;
  with TfrmPEText(Form).rtePreview.Lines do begin
    Lines.Add('Text', 'Lines', Count);
    Lines.Add('Text', 'Encoding', Encoding.EncodingName);
  end;
end {TRichTextRenderer.PopulateInfo};




////////////////////////////////////////////////////////////////////////////////////////////////////
initialization
  TCustomPreviewEngineForm.RegisterForm(TfrmPEText);

end.
