====== 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;