lazarus/ide/findreplacedialog.pp
mattias aa746f870e now using SynRegExpr for Find-Replace in IDE
git-svn-id: trunk@3775 -
2003-01-01 17:45:43 +00:00

532 lines
15 KiB
ObjectPascal

{
/***************************************************************************
findreplacedialog.pp
--------------------
***************************************************************************/
Author: Mattias Gaertner
*****************************************************************************
* *
* See the file COPYING.modifiedLGPL, included in this distribution, *
* for details about the copyright. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* *
*****************************************************************************
Abstract:
Find and replace dialog form.
Usage:
Add to program
"Application.CreateForm(TLazFindReplaceDialog, FindReplaceDlg);"
Set the FindReplaceDlg.Options poperty
then do MResult:=FindReplaceDlg.ShowModal
ShowModal can have three possible results:
- mrOk for Find/Replace.
- mrAll for ReplaceAll
- mrCancel for Cancel
ToDo:
}
unit FindReplaceDialog;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, LCLType, Controls, StdCtrls, Forms, Buttons, ExtCtrls,
LResources, Dialogs, SynEditTypes, SynRegExpr, SynEdit, IDEProcs,
LazarusIdeStrConsts;
type
TFindDlgComponent = (fdcText, fdcReplace);
TOnFindDlgKey = procedure(Sender: TObject; var Key: Word; Shift:TShiftState;
FindDlgComponent: TFindDlgComponent) of Object;
TLazFindReplaceDialog = class(TForm)
TextToFindLabel:TLabel;
ReplaceWithLabel:TLabel;
TextToFindComboBox:TComboBox;
ReplaceTextComboBox:TComboBox;
OptionsGroupBox:TGroupBox;
CaseSensitiveCheckBox:TCheckBox;
WholeWordsOnlyCheckBox:TCheckBox;
RegularExpressionsCheckBox:TCheckBox;
MultiLineCheckBox:TCheckBox;
PromptOnReplaceCheckBox:TCheckBox;
DirectionRadioGroup:TRadioGroup;
ScopeRadioGroup:TRadioGroup;
OriginRadioGroup:TRadioGroup;
OkButton:TButton;
ReplaceAllButton:TButton;
CancelButton:TButton;
procedure TextToFindComboboxKeyDown(Sender: TObject; var Key:Word;
Shift:TShiftState);
procedure OkButtonClick(Sender:TObject);
procedure ReplaceAllButtonClick(Sender:TObject);
procedure CancelButtonClick(Sender:TObject);
private
FOnKey: TOnFindDlgKey;
fReplaceAllClickedLast:boolean;
RegExpr: TRegExpr;
function CheckInput: boolean;
function GetComponentText(c: TFindDlgComponent): string;
procedure SetComponentText(c: TFindDlgComponent; const AValue: string);
procedure SetOnKey(const AValue: TOnFindDlgKey);
procedure SetOptions(NewOptions:TSynSearchOptions);
function GetOptions:TSynSearchOptions;
function GetFindText:AnsiString;
procedure SetFindText(NewFindText:AnsiString);
function GetReplaceText:AnsiString;
procedure SetReplaceText(NewReplaceText:AnsiString);
procedure SetComboBoxText(AComboBox:TComboBox;const AText:AnsiString);
public
constructor Create(TheOwner:TComponent); override;
destructor Destroy; override;
public
property Options:TSynSearchOptions read GetOptions write SetOptions;
property FindText:AnsiString read GetFindText write SetFindText;
property ReplaceText:AnsiString read GetReplaceText write SetReplaceText;
property OnKey: TOnFindDlgKey read FOnKey write SetOnKey;
property ComponentText[c: TFindDlgComponent]: string
read GetComponentText write SetComponentText;
end;
var FindReplaceDlg:TLazFindReplaceDialog;
implementation
{ TLazFindReplaceDialog }
constructor TLazFindReplaceDialog.Create(TheOwner:TComponent);
begin
inherited Create(TheOwner);
if LazarusResources.Find(ClassName)=nil then begin
Name:='LazFindReplaceDialog';
Caption:='';
Width:=400;
Height:=300;
BorderStyle:= bsDialog;
Position:=poDesigned;
TextToFindComboBox:=TComboBox.Create(Self);
with TextToFindComboBox do begin
Name:='TextToFindComboBox';
Parent:=Self;
Left:=90;
Top:=4;
Width:= 306;
Anchors:= [akLeft, akTop, akRight];
Text:='';
OnKeyDown:=@TextToFindComboBoxKeyDown;
Visible:=true;
end;
TextToFindLabel:=TLabel.Create(Self);
with TextToFindLabel do begin
Name:='TextToFindLabel';
Parent:=Self;
Left:=8;
Top:=8;
Width:= 100;
Caption:=dlgTextToFing;
Visible:=true;
FocusControl:= TextToFindComboBox;
end;
ReplaceTextComboBox:=TComboBox.Create(Self);
with ReplaceTextComboBox do begin
Name:='ReplaceTextComboBox';
Parent:=Self;
Left:=90;
Top:=28;
Width:= 306;
Anchors:= [akLeft, akTop, akRight];
Text:='';
OnKeyDown:=@TextToFindComboBoxKeyDown;
Visible:=true;
end;
ReplaceWithLabel:=TLabel.Create(Self);
with ReplaceWithLabel do begin
Name:='ReplaceWithLabel';
Parent:=Self;
Left:=8;
Top:=32;
Width:= 100;
Caption:=dlgReplaceWith;
Visible:=true;
FocusControl:= ReplaceTextComboBox;
end;
OptionsGroupBox:=TGroupBox.Create(Self);
with OptionsGroupBox do begin
Name:='OptionsGroupBox';
Parent:=Self;
Left:=4;
Top:=58;
Width:=194;
Height:=150;
Caption:=dlgFROpts ;
Visible:=true;
end;
CaseSensitiveCheckBox:=TCheckBox.Create(Self);
with CaseSensitiveCheckBox do begin
Name:='CaseSensitiveCheckBox';
Parent:=OptionsGroupBox;
AutoSize := True;
Left:=8;
Top:=6;
Width:=155;
Caption:=dlgCaseSensitive ;
Visible:=true;
end;
WholeWordsOnlyCheckBox:=TCheckBox.Create(Self);
with WholeWordsOnlyCheckBox do begin
Name:='WholeWordsOnlyCheckBox';
Parent:=OptionsGroupBox;
AutoSize := False;
Left:=8;
Top:=31;
Width:=155;
Caption:=dlgWholeWordsOnly;
Visible:=true;
end;
RegularExpressionsCheckBox:=TCheckBox.Create(Self);
with RegularExpressionsCheckBox do begin
Name:='RegularExpressionsCheckBox';
Parent:=OptionsGroupBox;
AutoSize := False;
Left:=8;
Top:=56;
Width:=155;
Caption:=dlgRegularExpressions;
Visible:=true;
end;
MultiLineCheckBox:=TCheckBox.Create(Self);
with MultiLineCheckBox do begin
Name:='MultiLineCheckBox';
Parent:=OptionsGroupBox;
AutoSize := False;
Left:=8;
Top:=81;
Width:=155;
Caption:=dlgMultiLine;
Visible:=true;
Enabled:=false;
end;
PromptOnReplaceCheckBox:=TCheckBox.Create(Self);
with PromptOnReplaceCheckBox do begin
Name:='PromptOnReplaceCheckBox';
Parent:=OptionsGroupBox;
AutoSize := False;
Left:=8;
Top:=106;
Width:=135;
Caption:=dlgPromptOnReplace ;
Checked:=true;
Visible:=true;
end;
OriginRadioGroup:=TRadioGroup.Create(Self);
with OriginRadioGroup do begin
Name:='OriginRadioGroup';
Parent:= Self;
Left:= 202;
Top:= 58;
Width:= 194;
Height:=65;
Caption:=dlgSROrigin;
with Items do begin
BeginUpdate;
Clear;
Add(dlgFromCursor);
Add(dlgEntireScope);
EndUpdate;
end;
ItemIndex:=0;
Visible:=true;
end;
ScopeRadioGroup:=TRadioGroup.Create(Self);
with ScopeRadioGroup do begin
Name:='ScopeRadioGroup';
Parent:=Self;
Left:=202;
Top:=128;
Width:=194;
Height:=65;
Caption:=dlgScope;
with Items do begin
BeginUpdate;
Clear;
Add(dlgGlobal);
Add(dlgSelectedText);
EndUpdate;
end;
ItemIndex:=0;
Visible:=true;
end;
DirectionRadioGroup:=TRadioGroup.Create(Self);
with DirectionRadioGroup do begin
Name:='DirectionRadioGroup';
Parent:=Self;
Left:=202;
Top:=198;
Width:=194;
Height:=65;
Caption:=dlgDirection;
with Items do begin
BeginUpdate;
Clear;
Add(dlgUpWord);
Add(dlgDownWord );
EndUpdate;
end;
ItemIndex:=1;
Visible:=true;
end;
OkButton:=TButton.Create(Self);
with OkButton do begin
Name:='OkButton';
Parent:= Self;
Left:= 130;
Top:= 268;
Caption:='Ok';
OnClick:=@OkButtonClick;
Visible:=true;
end;
ReplaceAllButton:=TButton.Create(Self);
with ReplaceAllButton do begin
Name:='ReplaceAllButton';
Parent:= Self;
Left:= 210;
Top:= 268;
Width:=99;
Caption:=dlgReplaceAll;
OnClick:=@ReplaceAllButtonClick;
Visible:=true;
end;
CancelButton:=TButton.Create(Self);
with CancelButton do begin
Name:='CancelButton';
Parent:= Self;
Left:= 320;
Top:= 268;
Caption:=dlgCancel;
OnClick:=@CancelButtonClick;
Visible:=true;
end;
end;
fReplaceAllClickedLast:=false;
TextToFindComboBox.SetFocus;
end;
destructor TLazFindReplaceDialog.Destroy;
begin
RegExpr.Free;
inherited Destroy;
end;
procedure TLazFindReplaceDialog.TextToFindComboBoxKeyDown(
Sender: TObject; var Key:Word; Shift:TShiftState);
var Component: TFindDlgComponent;
begin
//writeln('TLazFindReplaceDialog.TextToFindComboBoxKeyDown Key=',Key,' RETURN=',VK_RETURN,' TAB=',VK_TAB,' DOWN=',VK_DOWN,' UP=',VK_UP);
if (Key=VK_RETURN) then begin
OkButtonClick(Sender);
Key:=VK_UNKNOWN;
end else if (Key=VK_ESCAPE) then begin
CancelButtonClick(Sender);
Key:=VK_UNKNOWN;
end else if Key=VK_TAB then begin
if (Sender=TextToFindComboBox) and (ReplaceTextComboBox.Enabled) then
ReplaceTextComboBox.SetFocus;
if Sender=ReplaceTextComboBox then
TextToFindComboBox.SetFocus;
Key:=VK_UNKNOWN;
end else if Assigned(OnKey) then begin
if Sender=TextToFindComboBox then
Component:=fdcText
else
Component:=fdcReplace;
OnKey(Sender, Key, Shift, Component);
end;
end;
procedure TLazFindReplaceDialog.OkButtonClick(Sender:TObject);
begin
if not CheckInput then exit;
fReplaceAllClickedLast:=false;
TextToFindComboBox.SetFocus;
ModalResult:=mrOk;
end;
procedure TLazFindReplaceDialog.ReplaceAllButtonClick(Sender:TObject);
begin
if not CheckInput then exit;
fReplaceAllClickedLast:=true;
TextToFindComboBox.SetFocus;
ModalResult:=mrAll;
end;
procedure TLazFindReplaceDialog.CancelButtonClick(Sender:TObject);
begin
TextToFindComboBox.SetFocus;
ModalResult:=mrCancel;
end;
function TLazFindReplaceDialog.CheckInput: boolean;
begin
Result:=false;
if RegularExpressionsCheckBox.Checked then begin
if RegExpr=nil then RegExpr:=TRegExpr.Create;
try
RegExpr.Expression:=FindText;
RegExpr.Exec('test');
except
on E: ERegExpr do begin
MessageDlg('Error in regular expression',
E.Message,mtError,[mbCancel],0);
exit;
end;
end;
if ReplaceTextComboBox.Enabled then begin
try
RegExpr.Substitute(ReplaceText);
except
on E: ERegExpr do begin
MessageDlg('Error in regular expression',
E.Message,mtError,[mbCancel],0);
exit;
end;
end;
end;
end;
Result:=true;
end;
function TLazFindReplaceDialog.GetComponentText(c: TFindDlgComponent): string;
begin
case c of
fdcText: Result:=FindText;
else
Result:=Replacetext;
end;
end;
procedure TLazFindReplaceDialog.SetComponentText(c: TFindDlgComponent;
const AValue: string);
begin
case c of
fdcText: FindText:=AValue;
else
Replacetext:=AValue;
end;
end;
procedure TLazFindReplaceDialog.SetOnKey(const AValue: TOnFindDlgKey);
begin
FOnKey:=AValue;
end;
procedure TLazFindReplaceDialog.SetOptions(NewOptions:TSynSearchOptions);
begin
CaseSensitiveCheckBox.Checked:=ssoMatchCase in NewOptions;
WholeWordsOnlyCheckBox.Checked:=ssoWholeWord in NewOptions;
RegularExpressionsCheckBox.Checked:=ssoRegExpr in NewOptions;
MultiLineCheckBox.Checked:=ssoRegExprMultiLine in NewOptions;
PromptOnReplaceCheckBox.Checked:=ssoPrompt in NewOptions;
if ssoEntireScope in NewOptions
then OriginRadioGroup.ItemIndex:=1
else OriginRadioGroup.ItemIndex:=0;
if ssoSelectedOnly in NewOptions
then ScopeRadioGroup.ItemIndex:=1
else ScopeRadioGroup.ItemIndex:=0;
if ssoBackwards in NewOptions
then DirectionRadioGroup.ItemIndex:=0
else DirectionRadioGroup.ItemIndex:=1;
ReplaceAllButton.Enabled:=ssoReplace in NewOptions;
ReplaceTextComboBox.Enabled:=ReplaceAllButton.Enabled;
ReplaceWithLabel.Enabled:=ReplaceAllButton.Enabled;
PromptOnReplaceCheckBox.Enabled:=ReplaceAllButton.Enabled;
if ssoReplace in NewOptions then begin
Caption:=lisMenuReplace;
OkButton.Caption:=lisMenuReplace;
end else begin
Caption:=lisMenuFind ;
OkButton.Caption:=lisMenuFind ;
end;
end;
function TLazFindReplaceDialog.GetOptions:TSynSearchOptions;
begin
Result:=[];
if CaseSensitiveCheckBox.Checked then Include(Result,ssoMatchCase);
if WholeWordsOnlyCheckBox.Checked then Include(Result,ssoWholeWord);
if RegularExpressionsCheckBox.Checked then Include(Result,ssoRegExpr);
if MultiLineCheckBox.Checked then Include(Result,ssoRegExprMultiLine);
if PromptOnReplaceCheckBox.Checked then Include(Result,ssoPrompt);
if OriginRadioGroup.ItemIndex=1 then Include(Result,ssoEntireScope);
if ScopeRadioGroup.ItemIndex=1 then include(Result,ssoSelectedOnly);
if DirectionRadioGroup.ItemIndex=0 then include(Result,ssoBackwards);
if ReplaceAllButton.Enabled then include(Result,ssoReplace);
if fReplaceAllClickedLast then include(Result,ssoReplaceAll);
end;
function TLazFindReplaceDialog.GetFindText:AnsiString;
begin
Result:=TextToFindComboBox.Text;
end;
procedure TLazFindReplaceDialog.SetFindText(NewFindText:AnsiString);
begin
// SetComboBoxText(TextToFindComboBox,NewFindText);
TextToFindComboBox.Text:= NewFindText;
TextToFindComboBox.SelectAll;
end;
function TLazFindReplaceDialog.GetReplaceText:AnsiString;
begin
Result:=ReplaceTextComboBox.Text;
end;
procedure TLazFindReplaceDialog.SetReplaceText(NewReplaceText:AnsiString);
begin
SetComboBoxText(ReplaceTextComboBox,NewReplaceText);
end;
procedure TLazFindReplaceDialog.SetComboBoxText(AComboBox:TComboBox;
const AText:AnsiString);
var a:integer;
begin
a:=AComboBox.Items.IndexOf(AText);
//writeln('TLazFindReplaceDialog.SetComboBoxText ',AText,' ',a);
if a>=0 then
AComboBox.ItemIndex:=a
else begin
AComboBox.Items.Add(AText);
AComboBox.ItemIndex:=AComboBox.Items.IndexOf(AText);
end;
end;
end.