Tabela de conteúdos

Descrição

Classe que pode ser utilizada para pré-determinar formatações para um componente TRichEdit, como por exemplo para fazer um editor de comandos SQL.

Implementação

unit uFormatRichEdit;
 
interface
 
uses
  Vcl.ComCtrls, Vcl.Graphics, System.Classes;
 
type
  TRichEditFormatado = class
  private
    FEstilo       : TFontStyles;
    FCor          : Integer;
    FUltText      : WideString;
  protected
    FCompRichEdit   : TRichEdit;
    FCorOriginal    : Integer;
    FEstiloOriginal : TFontStyles;
    procedure limparFormatacao();
    procedure formatar();virtual;
  public
    constructor create (richEditDeControle : TRichEdit);
    destructor free;
    property estilo : TFontStyles read FEstilo write FEstilo;
    property cor : Integer read FCor write FCor;
  end;
 
Type
  TRichEditFormatadoLista = Array of TRichEditFormatado;
 
 
type
  TRichEditFormatadoPalavrasReservadas = class(TRichEditFormatado)
  protected
    Fpalavras: TStringList;
    procedure setPalavras(const Value: TStringList);
    procedure formatar(); override;
  public
    constructor create(richEditDeControle : TRichEdit);
    destructor free();
    property palavras : TStringList read Fpalavras write setPalavras;
    procedure adicionarPalavra(const palavra : string);
    procedure removerPalavra(const palavra : string);
  end;
 
type
  TRichEditFormatadoTermos = class(TRichEditFormatado)
  protected
    FtermoInicial: string;
    FtermoFinal: string;
    procedure SettermoInicial(const Value: string);
    procedure SettermoFinal(const Value: string);
    procedure formatar(); override;
  public
    constructor create(richEditDeControle : TRichEdit);
    property termoInicial : string read FtermoInicial write SettermoInicial;
    property termoFinal : string read FtermoFinal write SettermoFinal;
  end;
 
type
  TTipoFormatacaoRichEdit = (tfPalavraReservada, tfTermos);
 
type
  TRichEditListaFormatacoes = class(TRichEditFormatado)
  private
    FlistaFormatacao: TRichEditFormatadoLista;
    procedure SetlistaFormatacao(const Value: TRichEditFormatadoLista);
    procedure formatarRichEdit(sender : TObject);
  public
    constructor create(richEditDeControle : TRichEdit);
    destructor free();
    procedure adicionarRichEditFormatado(const richEditFormatado : TRichEditFormatado); overload;
    function adicionarRichEditFormatado(const tipo : TTipoFormatacaoRichEdit):TRichEditFormatado; overload;
    property listaFormatacao: TRichEditFormatadoLista read FlistaFormatacao write SetlistaFormatacao;
  end;
 
 
implementation
 
uses
  Winapi.Messages, Vcl.Controls, System.SysUtils;
 
{ TFormatRichEdit }
 
constructor TRichEditFormatado.create(richEditDeControle: TRichEdit);
begin
  FCompRichEdit   := richEditDeControle;
  FCorOriginal    := FCompRichEdit.Font.Color;
  FEstiloOriginal := FCompRichEdit.Font.Style;
end;
 
procedure TRichEditFormatado.formatar;
begin
 
end;
 
destructor TRichEditFormatado.free;
begin
  FCompRichEdit := nil;
end;
 
procedure TRichEditFormatado.limparFormatacao;
begin
  with FCompRichEdit do
  begin
    SelStart := 0;
    SelLength := Length(FCompRichEdit.Lines.Text);
    SelAttributes.Style := [];
    SelAttributes.Color := clBlack;
  end;
end;
 
{ TRichEditFormatadaPalavrasReservadas }
 
procedure TRichEditFormatadoPalavrasReservadas.adicionarPalavra(
  const palavra: string);
begin
  if Fpalavras.IndexOf(trim(palavra)) < 0 then
    Fpalavras.Add(trim(palavra));
end;
 
constructor TRichEditFormatadoPalavrasReservadas.create(
  richEditDeControle: TRichEdit);
begin
  inherited Create(richEditDeControle);
  Fpalavras := TStringList.Create;
end;
 
procedure TRichEditFormatadoPalavrasReservadas.formatar();
var
  I      : byte;
  aux    : integer;
begin
  for I := 0 to palavras.Count - 1 do
  begin
    aux := 0;
    while True do
    begin
      aux := FCompRichEdit.FindText(palavras[i],aux,Length(FCompRichEdit.Lines.Text),[stWholeWord]);
      if aux > -1 then
      begin
        with FCompRichEdit do
        begin
          SelStart := aux;
          SelLength := Length(palavras[i]);
          SelAttributes.Style := estilo;
          SelAttributes.Color := cor;
        end;
        aux := aux + (Length(palavras[i]));
      end
      else
        break;
    end;
  end;
end;
 
destructor TRichEditFormatadoPalavrasReservadas.free;
begin
  Fpalavras.Free;
  inherited free;
end;
 
procedure TRichEditFormatadoPalavrasReservadas.removerPalavra(
  const palavra: string);
var
  aux : integer;
begin
  aux := Fpalavras.IndexOf(Trim(palavra));
  if aux >= 0 then
    Fpalavras.Delete(aux);
end;
 
procedure TRichEditFormatadoPalavrasReservadas.SetPalavras(
  const Value: TStringList);
begin
  Fpalavras.Clear;
  Fpalavras := Value;
end;
 
{ TRichEditListaFormatacoes }
 
procedure TRichEditListaFormatacoes.adicionarRichEditFormatado(
  const richEditFormatado: TRichEditFormatado);
begin
  SetLength(FlistaFormatacao,length(FlistaFormatacao) + 1);
  FlistaFormatacao[High(FlistaFormatacao)] := richEditFormatado;
end;
 
function TRichEditListaFormatacoes.adicionarRichEditFormatado(const tipo : TTipoFormatacaoRichEdit): TRichEditFormatado;
begin
  case tipo of
    tfPalavraReservada: adicionarRichEditFormatado(TRichEditFormatadoPalavrasReservadas.create(FCompRichEdit));
    tfTermos: adicionarRichEditFormatado(TRichEditFormatadoTermos.create(FCompRichEdit));
  end;
 
  Result := FlistaFormatacao[High(FlistaFormatacao)];
end;
 
constructor TRichEditListaFormatacoes.create;
begin
  inherited create(richEditDeControle);
  SetLength(FlistaFormatacao,0);
  richEditDeControle.OnChange := formatarRichEdit;
end;
 
procedure TRichEditListaFormatacoes.formatarRichEdit(sender: TObject);
var
  I      : Integer;
  posAtu : integer;
begin
  if FUltText <> FCompRichEdit.Lines.Text then
  begin
    FCompRichEdit.Lines.BeginUpdate;
    posAtu := FCompRichEdit.SelStart;
 
    limparFormatacao();
    for I := Low(FlistaFormatacao) to High(FlistaFormatacao) do
      FlistaFormatacao[i].formatar();
 
    FCompRichEdit.SelStart := posAtu;
    FCompRichEdit.SelAttributes.Style := FEstiloOriginal;
    FCompRichEdit.SelAttributes.Color := FCorOriginal;
 
    FUltText := FCompRichEdit.Lines.Text;
    FCompRichEdit.Lines.EndUpdate;
  end;
end;
 
destructor TRichEditListaFormatacoes.free;
var
  I: Integer;
begin
  for I := Low(FlistaFormatacao) to High(FlistaFormatacao) do
    FlistaFormatacao[i].free;
  SetLength(FlistaFormatacao,0);
  limparFormatacao();
  FCompRichEdit.OnChange := nil;
end;
 
procedure TRichEditListaFormatacoes.SetlistaFormatacao(
  const Value: TRichEditFormatadoLista);
begin
  FlistaFormatacao := Value;
end;
 
{ TRichEditFormatadoTermos }
 
constructor TRichEditFormatadoTermos.create(richEditDeControle: TRichEdit);
begin
  inherited Create(richEditDeControle);
end;
 
procedure TRichEditFormatadoTermos.formatar;
var
  posTermo1  : integer;
  posTermo2 : integer;
begin
  posTermo1 := 0;
  while (true) do
  begin
    posTermo1 := FCompRichEdit.FindText(FtermoInicial,posTermo1,Length(FCompRichEdit.Lines.Text),[]);
    if posTermo1 > -1 then
    begin
      FCompRichEdit.SelStart := posTermo1;
      posTermo2 := FCompRichEdit.FindText(FtermoFinal,posTermo1,Length(FCompRichEdit.Lines.Text) - posTermo1,[]);
      if posTermo2 > -1 then
      begin
        with FCompRichEdit do
        begin
          SelLength := posTermo2 - (posTermo1- Length(termoFinal));
          SelAttributes.Color := FCor;
          SelAttributes.Style := FEstilo;
        end;
        Inc(posTermo1);
      end
      else
        break;
    end
    else
      break;
  end;
end;
 
procedure TRichEditFormatadoTermos.SettermoFinal(const Value: string);
begin
  FtermoFinal := Value;
end;
 
procedure TRichEditFormatadoTermos.SettermoInicial(const Value: string);
begin
  FtermoInicial := Value;
end;
 
end.

Exemplo de uso

procedure TForm1.configurarRichEdit(RichEdit: TRichEdit);
var
  idx : integer;
begin
  richEditFormatado := TRichEditListaFormatacoes.create(RichEdit);
 
  //PALAVRAS RESERVADAS
  richEditFormatado.adicionarRichEditFormatado(tfPalavraReservada);
  idx := high(richEditFormatado.listaFormatacao);
  with TRichEditFormatadoPalavrasReservadas(richEditFormatado.listaFormatacao[idx]) do
  begin
    estilo := [fsBold];
    cor    := clBlack;
    adicionarPalavra('select');
    adicionarPalavra('from');
    adicionarPalavra('where');
    removerPalavra('casinha branca');
  end;
 
  richEditFormatado.adicionarRichEditFormatado(tfPalavraReservada);
  idx := high(richEditFormatado.listaFormatacao);
  with TRichEditFormatadoPalavrasReservadas(richEditFormatado.listaFormatacao[idx]) do
  begin
    estilo := [fsBold];
    cor    := clBlue;
    adicionarPalavra('tbl_cliente');
  end;
 
  //TERMOS
  richEditFormatado.adicionarRichEditFormatado(tfTermos);
  idx := high(richEditFormatado.listaFormatacao);
  with TRichEditFormatadoTermos(richEditFormatado.listaFormatacao[idx]) do
  begin
    estilo := [fsBold];
    cor    := clGreen;
    termoInicial := '--';
    termoFinal   := #13;
  end;
end;