mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-21 09:23:07 +02:00
600 lines
16 KiB
ObjectPascal
600 lines
16 KiB
ObjectPascal
{ $Id$ }
|
|
{
|
|
/***************************************************************************
|
|
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+}
|
|
|
|
{$Define DeleteMeWhenComboBoxFocusIsFixed}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, LCLType, Controls, StdCtrls, Forms, Buttons, ExtCtrls,
|
|
LResources, SynEdit, IDEProcs;
|
|
|
|
type
|
|
TFindDlgComponent = (fdcText, fdcReplace);
|
|
TOnFindDlgKey = procedure(Sender: TObject; var Key: Word; Shift:TShiftState;
|
|
FindDlgComponent: TFindDlgComponent) of Object;
|
|
|
|
TLazFindReplaceDialog = class(TForm)
|
|
private
|
|
FOnKey: TOnFindDlgKey;
|
|
fReplaceAllClickedLast: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);
|
|
published
|
|
TextToFindLabel:TLabel;
|
|
ReplaceWithLabel:TLabel;
|
|
{$IFDEF DeleteMeWhenComboBoxFocusIsFixed}
|
|
TextToFindComboBox:TEdit;
|
|
ReplaceTextComboBox:TEdit;
|
|
{$ELSE}
|
|
TextToFindComboBox:TComboBox;
|
|
ReplaceTextComboBox:TComboBox;
|
|
{$ENDIF}
|
|
OptionsGroupBox:TGroupBox;
|
|
CaseSensitiveCheckBox:TCheckBox;
|
|
WholeWordsOnlyCheckBox:TCheckBox;
|
|
RegularExpressionsCheckBox: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);
|
|
procedure FormResize(Sender: TObject);
|
|
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;
|
|
public
|
|
property ComponentText[c: TFindDlgComponent]: string
|
|
read GetComponentText write SetComponentText;
|
|
constructor Create(TheOwner:TComponent); override;
|
|
end;
|
|
|
|
var FindReplaceDlg:TLazFindReplaceDialog;
|
|
|
|
|
|
implementation
|
|
|
|
|
|
{ TLazFindReplaceDialog }
|
|
|
|
constructor TLazFindReplaceDialog.Create(TheOwner:TComponent);
|
|
begin
|
|
inherited Create(TheOwner);
|
|
if LazarusResources.Find(ClassName)=nil then begin
|
|
Caption:='';
|
|
Width:=400;
|
|
Height:=285;
|
|
Position:=poDesigned;
|
|
|
|
{$IFDEF DeleteMeWhenComboBoxFocusIsFixed}
|
|
TextToFindComboBox:=TEdit.Create(Self);
|
|
{$ELSE}
|
|
TextToFindComboBox:=TComboBox.Create(Self);
|
|
{$ENDIF}
|
|
with TextToFindComboBox do begin
|
|
Name:='TextToFindComboBox';
|
|
Parent:=Self;
|
|
Left:=90;
|
|
Top:=4;
|
|
Width:=220;
|
|
Height:=21;
|
|
Text:='';
|
|
OnKeyDown:=@TextToFindComboBoxKeyDown;
|
|
Visible:=true;
|
|
end;
|
|
|
|
TextToFindLabel:=TLabel.Create(Self);
|
|
with TextToFindLabel do begin
|
|
Name:='TextToFindLabel';
|
|
Parent:=Self;
|
|
Left:=8;
|
|
Top:=8;
|
|
Width:=80;
|
|
Height:=15;
|
|
Caption:='Text to Find';
|
|
Visible:=true;
|
|
end;
|
|
|
|
{$IFDEF DeleteMeWhenComboBoxFocusIsFixed}
|
|
ReplaceTextComboBox:=TEdit.Create(Self);
|
|
{$ELSE}
|
|
ReplaceTextComboBox:=TComboBox.Create(Self);
|
|
{$ENDIF}
|
|
with ReplaceTextComboBox do begin
|
|
Name:='ReplaceTextComboBox';
|
|
Parent:=Self;
|
|
Left:=90;
|
|
Top:=28;
|
|
Width:=220;
|
|
Height:=21;
|
|
Text:='';
|
|
OnKeyDown:=@TextToFindComboBoxKeyDown;
|
|
Visible:=true;
|
|
end;
|
|
|
|
ReplaceWithLabel:=TLabel.Create(Self);
|
|
with ReplaceWithLabel do begin
|
|
Name:='ReplaceWithLabel';
|
|
Parent:=Self;
|
|
Left:=8;
|
|
Top:=32;
|
|
Width:=80;
|
|
Height:=15;
|
|
Caption:='Replace With';
|
|
Visible:=true;
|
|
end;
|
|
|
|
OptionsGroupBox:=TGroupBox.Create(Self);
|
|
with OptionsGroupBox do begin
|
|
Name:='OptionsGroupBox';
|
|
Parent:=Self;
|
|
Left:=4;
|
|
Top:=58;
|
|
Width:=150;
|
|
Height:=105;
|
|
Caption:='Options';
|
|
Visible:=true;
|
|
end;
|
|
|
|
CaseSensitiveCheckBox:=TCheckBox.Create(Self);
|
|
with CaseSensitiveCheckBox do begin
|
|
Name:='CaseSensitiveCheckBox';
|
|
Parent:=OptionsGroupBox;
|
|
Left:=8;
|
|
Top:=6;
|
|
Width:=135;
|
|
Height:=17;
|
|
Caption:='Case Sensitive';
|
|
Visible:=true;
|
|
end;
|
|
|
|
WholeWordsOnlyCheckBox:=TCheckBox.Create(Self);
|
|
with WholeWordsOnlyCheckBox do begin
|
|
Name:='WholeWordsOnlyCheckBox';
|
|
Parent:=OptionsGroupBox;
|
|
Left:=8;
|
|
Top:=26;
|
|
Width:=135;
|
|
Height:=17;
|
|
Caption:='Whole Words Only';
|
|
Visible:=true;
|
|
end;
|
|
|
|
RegularExpressionsCheckBox:=TCheckBox.Create(Self);
|
|
with RegularExpressionsCheckBox do begin
|
|
Name:='RegularExpressionsCheckBox';
|
|
Parent:=OptionsGroupBox;
|
|
Left:=8;
|
|
Top:=46;
|
|
Width:=135;
|
|
Height:=17;
|
|
Caption:='Regular Expressions';
|
|
Visible:=true;
|
|
end;
|
|
|
|
PromptOnReplaceCheckBox:=TCheckBox.Create(Self);
|
|
with PromptOnReplaceCheckBox do begin
|
|
Name:='PromptOnReplaceCheckBox';
|
|
Parent:=OptionsGroupBox;
|
|
Left:=8;
|
|
Top:=66;
|
|
Width:=135;
|
|
Height:=17;
|
|
Caption:='Prompt On Replace';
|
|
Checked:=true;
|
|
Visible:=true;
|
|
end;
|
|
|
|
OriginRadioGroup:=TRadioGroup.Create(Self);
|
|
with OriginRadioGroup do begin
|
|
Name:='OriginRadioGroup';
|
|
Parent:=Self;
|
|
Left:=161;
|
|
Top:=58;
|
|
Width:=150;
|
|
Height:=105;
|
|
Caption:='Origin';
|
|
with Items do begin
|
|
BeginUpdate;
|
|
Clear;
|
|
Add('From Cursor');
|
|
Add('Entire Scope');
|
|
EndUpdate;
|
|
end;
|
|
ItemIndex:=0;
|
|
Visible:=true;
|
|
end;
|
|
|
|
ScopeRadioGroup:=TRadioGroup.Create(Self);
|
|
with ScopeRadioGroup do begin
|
|
Name:='ScopeRadioGroup';
|
|
Parent:=Self;
|
|
Left:=4;
|
|
Top:=168;
|
|
Width:=150;
|
|
Height:=65;
|
|
Caption:='Scope';
|
|
with Items do begin
|
|
BeginUpdate;
|
|
Clear;
|
|
Add('Global');
|
|
Add('Selected Text');
|
|
EndUpdate;
|
|
end;
|
|
ItemIndex:=0;
|
|
Visible:=true;
|
|
end;
|
|
|
|
DirectionRadioGroup:=TRadioGroup.Create(Self);
|
|
with DirectionRadioGroup do begin
|
|
Name:='DirectionRadioGroup';
|
|
Parent:=Self;
|
|
Left:=161;
|
|
Top:=168;
|
|
Width:=150;
|
|
Height:=65;
|
|
Caption:='Direction';
|
|
with Items do begin
|
|
BeginUpdate;
|
|
Clear;
|
|
Add('Up');
|
|
Add('Down');
|
|
EndUpdate;
|
|
end;
|
|
ItemIndex:=1;
|
|
Visible:=true;
|
|
end;
|
|
|
|
OkButton:=TButton.Create(Self);
|
|
with OkButton do begin
|
|
Name:='OkButton';
|
|
Parent:=Self;
|
|
Left:=33;
|
|
Top:=245;
|
|
Width:=75;
|
|
Height:=25;
|
|
Caption:='Ok';
|
|
OnClick:=@OkButtonClick;
|
|
Visible:=true;
|
|
end;
|
|
|
|
ReplaceAllButton:=TButton.Create(Self);
|
|
with ReplaceAllButton do begin
|
|
Name:='ReplaceAllButton';
|
|
Parent:=Self;
|
|
Left:=121;
|
|
Top:=245;
|
|
Width:=75;
|
|
Height:=25;
|
|
Caption:='Replace All';
|
|
OnClick:=@ReplaceAllButtonClick;
|
|
Visible:=true;
|
|
end;
|
|
|
|
CancelButton:=TButton.Create(Self);
|
|
with CancelButton do begin
|
|
Name:='CancelButton';
|
|
Parent:=Self;
|
|
Left:=209;
|
|
Top:=245;
|
|
Width:=75;
|
|
Height:=25;
|
|
Caption:='Cancel';
|
|
OnClick:=@CancelButtonClick;
|
|
Visible:=true;
|
|
end;
|
|
|
|
OnResize:=@FormResize;
|
|
end;
|
|
fReplaceAllClickedLast:=false;
|
|
FormResize(Self);
|
|
TextToFindComboBox.SetFocus;
|
|
end;
|
|
|
|
procedure TLazFindReplaceDialog.TextToFindComboBoxKeyDown(
|
|
Sender: TObject; var Key:Word; Shift:TShiftState);
|
|
var Component: TFindDlgComponent;
|
|
begin
|
|
if (Key=VK_RETURN) then
|
|
OkButtonClick(Sender)
|
|
else if (Key=VK_ESCAPE) then
|
|
CancelButtonClick(Sender)
|
|
else if Key=VK_TAB then begin
|
|
if (Sender=TextToFindComboBox) and (ReplaceTextComboBox.Enabled) then
|
|
ReplaceTextComboBox.SetFocus;
|
|
if Sender=ReplaceTextComboBox then
|
|
TextToFindComboBox.SetFocus;
|
|
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
|
|
fReplaceAllClickedLast:=false;
|
|
TextToFindComboBox.SetFocus;
|
|
ModalResult:=mrOk;
|
|
end;
|
|
|
|
procedure TLazFindReplaceDialog.ReplaceAllButtonClick(Sender:TObject);
|
|
begin
|
|
fReplaceAllClickedLast:=true;
|
|
TextToFindComboBox.SetFocus;
|
|
ModalResult:=mrAll;
|
|
end;
|
|
|
|
procedure TLazFindReplaceDialog.CancelButtonClick(Sender:TObject);
|
|
begin
|
|
TextToFindComboBox.SetFocus;
|
|
ModalResult:=mrCancel;
|
|
end;
|
|
|
|
procedure TLazFindReplaceDialog.FormResize(Sender: TObject);
|
|
var MaxX, TxtLabelWidth, OptionsWidth, ButtonWidth: integer;
|
|
begin
|
|
TxtLabelWidth:=100;
|
|
MaxX:=ClientWidth;
|
|
OptionsWidth:=(MaxX-3*4) div 2;
|
|
ButtonWidth:=90;
|
|
|
|
with TextToFindLabel do begin
|
|
Left:=8;
|
|
Top:=8;
|
|
Width:=TxtLabelWidth;
|
|
end;
|
|
|
|
with TextToFindComboBox do begin
|
|
Left:=TextToFindLabel.Left+TextToFindLabel.Width+2;
|
|
Top:=TextToFindLabel.Top-4;
|
|
Width:=MaxX-Left-4;
|
|
end;
|
|
|
|
with ReplaceWithLabel do begin
|
|
Left:=TextToFindLabel.Left;
|
|
Top:=TextToFindLabel.Top+TextToFindLabel.Height+8;
|
|
Width:=TextToFindLabel.Width;
|
|
end;
|
|
|
|
with ReplaceTextComboBox do begin
|
|
Left:=TextToFindComboBox.Left;
|
|
Top:=ReplaceWithLabel.Top-4;
|
|
Width:=MaxX-Left-4;
|
|
end;
|
|
|
|
with OptionsGroupBox do begin
|
|
Left:=4;
|
|
Top:=ReplaceWithLabel.Top+ReplaceWithLabel.Height+3;
|
|
Width:=OptionsWidth;
|
|
Height:=110;
|
|
end;
|
|
|
|
with CaseSensitiveCheckBox do begin
|
|
Left:=8;
|
|
Top:=3;
|
|
Width:=Parent.ClientWidth-Left;
|
|
end;
|
|
|
|
with WholeWordsOnlyCheckBox do begin
|
|
Left:=8;
|
|
Top:=CaseSensitiveCheckBox.Top+CaseSensitiveCheckBox.Height+5;
|
|
Width:=Parent.ClientWidth-Left;
|
|
end;
|
|
|
|
with RegularExpressionsCheckBox do begin
|
|
Left:=8;
|
|
Top:=WholeWordsOnlyCheckBox.Top+WholeWordsOnlyCheckBox.Height+5;
|
|
Width:=Parent.ClientWidth-Left;
|
|
end;
|
|
|
|
with PromptOnReplaceCheckBox do begin
|
|
Left:=8;
|
|
Top:=RegularExpressionsCheckBox.Top+RegularExpressionsCheckBox.Height+5;
|
|
Width:=Parent.ClientWidth-Left;
|
|
end;
|
|
|
|
with OriginRadioGroup do begin
|
|
Left:=OptionsGroupBox.Left+OptionsGroupBox.Width+4;
|
|
Top:=OptionsGroupBox.Top;
|
|
Width:=OptionsWidth;
|
|
Height:=OptionsGroupBox.Height;
|
|
end;
|
|
|
|
with ScopeRadioGroup do begin
|
|
Left:=OptionsGroupBox.Left;
|
|
Top:=OptionsGroupBox.Top+OptionsGroupBox.Height+5;
|
|
Width:=OptionsWidth;
|
|
Height:=65;
|
|
end;
|
|
|
|
with DirectionRadioGroup do begin
|
|
Left:=OriginRadioGroup.Left;
|
|
Top:=OriginRadioGroup.Top+OriginRadioGroup.Height+5;
|
|
Width:=OptionsWidth;
|
|
Height:=65;
|
|
end;
|
|
|
|
with OkButton do begin
|
|
Left:=MaxX-10-3*(ButtonWidth+7);
|
|
Top:=245;
|
|
Width:=75;
|
|
end;
|
|
|
|
with ReplaceAllButton do begin
|
|
Left:=MaxX-10-2*(ButtonWidth+7);
|
|
Top:=245;
|
|
Width:=75;
|
|
end;
|
|
|
|
with CancelButton do begin
|
|
Left:=MaxX-10-1*(ButtonWidth+7);
|
|
Top:=245;
|
|
Width:=75;
|
|
end;
|
|
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;
|
|
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:='Replace';
|
|
OkButton.Caption:='Replace';
|
|
end else begin
|
|
Caption:='Find';
|
|
OkButton.Caption:='Find';
|
|
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 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
|
|
{$IFDEF DeleteMeWhenComboBoxFocusIsFixed}
|
|
TextToFindComboBox.Text:=NewFindText;
|
|
{$ELSE}
|
|
SetComboBoxText(TextToFindComboBox,NewFindText);
|
|
{$ENDIF}
|
|
end;
|
|
|
|
function TLazFindReplaceDialog.GetReplaceText:AnsiString;
|
|
begin
|
|
Result:=ReplaceTextComboBox.Text;
|
|
end;
|
|
|
|
procedure TLazFindReplaceDialog.SetReplaceText(NewReplaceText:AnsiString);
|
|
begin
|
|
{$IFDEF DeleteMeWhenComboBoxFocusIsFixed}
|
|
ReplaceTextComboBox.Text:=NewReplaceText;
|
|
{$ELSE}
|
|
SetComboBoxText(ReplaceTextComboBox,NewReplaceText);
|
|
{$ENDIF}
|
|
end;
|
|
|
|
procedure TLazFindReplaceDialog.SetComboBoxText(AComboBox:TComboBox;
|
|
const AText:AnsiString);
|
|
var a:integer;
|
|
begin
|
|
a:=AComboBox.Items.IndexOf(AText);
|
|
if a>=0 then
|
|
AComboBox.ItemIndex:=a
|
|
else begin
|
|
AComboBox.Items.Add(AText);
|
|
AComboBox.ItemIndex:=AComboBox.Items.IndexOf(AText);
|
|
end;
|
|
end;
|
|
|
|
end.
|