search & replace, add all opened files as possible scope, close #284

This commit is contained in:
Basile Burg 2018-04-16 12:10:17 +02:00
parent 113a53ab54
commit 6db3591788
2 changed files with 95 additions and 65 deletions

View File

@ -63,14 +63,14 @@ inherited CESearchWidget: TCESearchWidget
AutoSize = True AutoSize = True
BorderSpacing.Around = 4 BorderSpacing.Around = 4
Caption = 'Options' Caption = 'Options'
ClientHeight = 68 ClientHeight = 69
ClientWidth = 410 ClientWidth = 412
TabOrder = 4 TabOrder = 4
object FlowPanel1: TFlowPanel object FlowPanel1: TFlowPanel
Left = 0 Left = 0
Height = 68 Height = 69
Top = 0 Top = 0
Width = 410 Width = 412
Align = alClient Align = alClient
AutoSize = True AutoSize = True
BevelOuter = bvNone BevelOuter = bvNone
@ -129,40 +129,38 @@ inherited CESearchWidget: TCESearchWidget
TabOrder = 1 TabOrder = 1
end end
object chkCaseSens: TCheckBox object chkCaseSens: TCheckBox
Left = 100 Left = 0
Height = 22 Height = 22
Top = 0 Top = 46
Width = 117 Width = 117
Anchors = [] Anchors = []
Caption = 'case sensitive' Caption = 'case sensitive'
TabOrder = 2 TabOrder = 2
end end
object chkFromCur: TCheckBox object chkFromCur: TCheckBox
Left = 100 Left = 117
Height = 22 Height = 22
Top = 23 Top = 0
Width = 99 Width = 99
Anchors = [] Anchors = []
Caption = 'from cursor' Caption = 'from cursor'
Checked = True Checked = True
OnChange = chkFromCurChange
State = cbChecked State = cbChecked
TabOrder = 3 TabOrder = 3
end end
object chkBack: TCheckBox object chkBack: TCheckBox
Left = 217 Left = 117
Height = 22 Height = 22
Top = 0 Top = 23
Width = 87 Width = 87
Anchors = [] Anchors = []
Caption = 'backward' Caption = 'backward'
OnChange = chkBackChange
TabOrder = 4 TabOrder = 4
end end
object chkWWord: TCheckBox object chkWWord: TCheckBox
Left = 217 Left = 117
Height = 22 Height = 22
Top = 23 Top = 46
Width = 99 Width = 99
Anchors = [] Anchors = []
Caption = 'whole word' Caption = 'whole word'

View File

@ -46,6 +46,8 @@ type
procedure assignTo(target: TPersistent); override; procedure assignTo(target: TPersistent); override;
end; end;
TSearchScope = (scDoc, scProj, scOpened);
TCESearchWidget = class(TCEWidget, ICEDocumentObserver, ICEProjectObserver) TCESearchWidget = class(TCEWidget, ICEDocumentObserver, ICEProjectObserver)
btnAllScope: TBitBtn; btnAllScope: TBitBtn;
btnFind: TBitBtn; btnFind: TBitBtn;
@ -69,9 +71,7 @@ type
procedure btnAllScopeClick(Sender: TObject); procedure btnAllScopeClick(Sender: TObject);
procedure cbReplaceWthChange(Sender: TObject); procedure cbReplaceWthChange(Sender: TObject);
procedure cbToFindChange(Sender: TObject); procedure cbToFindChange(Sender: TObject);
procedure chkBackChange(Sender: TObject);
procedure chkEnableRepChange(Sender: TObject); procedure chkEnableRepChange(Sender: TObject);
procedure chkFromCurChange(Sender: TObject);
private private
fDoc: TCESynMemo; fDoc: TCESynMemo;
fToFind: string; fToFind: string;
@ -85,7 +85,7 @@ type
fHasSearched: boolean; fHasSearched: boolean;
fHasRestarted: boolean; fHasRestarted: boolean;
fProj: ICECommonProject; fProj: ICECommonProject;
fAllInProj: boolean; fFindScope: TSearchScope;
function getOptions: TSynSearchOptions; function getOptions: TSynSearchOptions;
procedure actReplaceAllExecute(sender: TObject); procedure actReplaceAllExecute(sender: TObject);
procedure replaceEvent(Sender: TObject; const ASearch, AReplace: procedure replaceEvent(Sender: TObject; const ASearch, AReplace:
@ -121,6 +121,7 @@ implementation
const const
OptsFname = 'search.txt'; OptsFname = 'search.txt';
FindScopeStr: array[TSearchScope] of string = ('Document', 'Project', 'Opened docs');
{$REGION TCESearchOptions ------------------------------------------------------} {$REGION TCESearchOptions ------------------------------------------------------}
constructor TCESearchOptions.create(aOwner: TComponent); constructor TCESearchOptions.create(aOwner: TComponent);
@ -272,6 +273,7 @@ begin
AssignPng(btnReplaceAll, 'TEXT_REPLACE32'); AssignPng(btnReplaceAll, 'TEXT_REPLACE32');
end; end;
end; end;
btnAllScope.Caption:= FindScopeStr[fFindScope];
updateImperative; updateImperative;
EntitiesConnector.addObserver(self); EntitiesConnector.addObserver(self);
@ -334,36 +336,63 @@ var
f: string; f: string;
s: integer = 0; s: integer = 0;
m: ICEMessagesDisplay; m: ICEMessagesDisplay;
h: ICEMultiDocHandler;
begin begin
if fDoc.isNil and not fAllInProj then if (fDoc.isNil and (fFindScope <> scProj)) or
exit; ((fProj = nil) and (fFindScope = scProj)) then
if (fProj = nil) and fAllInProj then exit;
exit;
fSearchMru.Insert(0,fToFind); fSearchMru.Insert(0,fToFind);
cbToFind.Items.Assign(fSearchMru); cbToFind.Items.Assign(fSearchMru);
if fAllInProj then case fFindScope of
begin scDoc:
c := TSynEditStringList.Create; begin
try findAll(fDoc.fileName, fDoc.Lines, true);
for i := 0 to fProj.sourcesCount-1 do
begin
f := fProj.sourceAbsolute(i);
c.LoadFromFile(f);
s += findAll(f, c, false);
end;
if s = 0 then
begin
m := getMessageDisplay;
m.message(format('0 result for the pattern <%s>', [fToFind]),
nil, amcMisc, amkInf);
end;
finally
c.Free;
end; end;
end
else findAll(fDoc.fileName, fDoc.Lines, true); scProj:
begin
c := TSynEditStringList.Create;
try
for i := 0 to fProj.sourcesCount-1 do
begin
f := fProj.sourceAbsolute(i);
c.LoadFromFile(f);
s += findAll(f, c, false);
end;
if s = 0 then
begin
m := getMessageDisplay;
m.message(format('0 result for the pattern <%s>', [fToFind]),
nil, amcMisc, amkInf);
end;
finally
c.Free;
end;
end;
scOpened:
begin
c := TSynEditStringList.Create;
h := getMultiDocHandler;
try
for i := 0 to h.documentCount-1 do
begin
f := h.getDocument(i).fileName;
s += findAll(f, h.getDocument(i).Lines, false);
end;
if s = 0 then
begin
m := getMessageDisplay;
m.message(format('0 result for the pattern <%s>', [fToFind]),
nil, amcMisc, amkInf);
end;
finally
c.Free;
end;
end;
end;
end; end;
function TCESearchWidget.findAll(const filename: string; lines: TStrings; function TCESearchWidget.findAll(const filename: string; lines: TStrings;
@ -417,11 +446,12 @@ end;
procedure TCESearchWidget.actFindNextExecute(sender: TObject); procedure TCESearchWidget.actFindNextExecute(sender: TObject);
begin begin
if fDoc.isNil then exit; if fDoc.isNil then
// exit;
fSearchMru.Insert(0, fToFind); fSearchMru.Insert(0, fToFind);
cbToFind.Items.Assign(fSearchMru); cbToFind.Items.Assign(fSearchMru);
//
if not chkFromCur.Checked then if not chkFromCur.Checked then
begin begin
if chkBack.Checked then if chkBack.Checked then
@ -453,13 +483,14 @@ end;
procedure TCESearchWidget.actReplaceNextExecute(sender: TObject); procedure TCESearchWidget.actReplaceNextExecute(sender: TObject);
begin begin
if fDoc.isNil then exit; if fDoc.isNil then
// exit;
fSearchMru.Insert(0, fToFind); fSearchMru.Insert(0, fToFind);
fReplaceMru.Insert(0, fReplaceWth); fReplaceMru.Insert(0, fReplaceWth);
cbToFind.Items.Assign(fSearchMru); cbToFind.Items.Assign(fSearchMru);
cbReplaceWth.Items.Assign(fReplaceMru); cbReplaceWth.Items.Assign(fReplaceMru);
//
if chkPrompt.Checked then if chkPrompt.Checked then
fDoc.OnReplaceText := @replaceEvent; fDoc.OnReplaceText := @replaceEvent;
if not chkFromCur.Checked then if not chkFromCur.Checked then
@ -486,11 +517,13 @@ procedure TCESearchWidget.actReplaceAllExecute(sender: TObject);
var var
opts: TSynSearchOptions; opts: TSynSearchOptions;
begin begin
if fDoc.isNil then exit; if fDoc.isNil then
exit;
cbReplaceWth.Items.Assign(fReplaceMru); cbReplaceWth.Items.Assign(fReplaceMru);
opts := getOptions + [ssoReplace]; opts := getOptions + [ssoReplace];
opts -= [ssoBackwards]; opts -= [ssoBackwards];
//
fSearchMru.Insert(0, fToFind); fSearchMru.Insert(0, fToFind);
fReplaceMru.Insert(0, fReplaceWth); fReplaceMru.Insert(0, fReplaceWth);
if chkPrompt.Checked then fDoc.OnReplaceText := @replaceEvent; if chkPrompt.Checked then fDoc.OnReplaceText := @replaceEvent;
@ -577,22 +610,12 @@ begin
updateImperative; updateImperative;
end; end;
procedure TCESearchWidget.chkBackChange(Sender: TObject);
begin
end;
procedure TCESearchWidget.chkEnableRepChange(Sender: TObject); procedure TCESearchWidget.chkEnableRepChange(Sender: TObject);
begin begin
if Updating then exit; if Updating then exit;
updateImperative; updateImperative;
end; end;
procedure TCESearchWidget.chkFromCurChange(Sender: TObject);
begin
end;
procedure TCESearchWidget.cbReplaceWthChange(Sender: TObject); procedure TCESearchWidget.cbReplaceWthChange(Sender: TObject);
begin begin
if Updating then exit; if Updating then exit;
@ -603,15 +626,23 @@ end;
procedure TCESearchWidget.btnAllScopeClick(Sender: TObject); procedure TCESearchWidget.btnAllScopeClick(Sender: TObject);
begin begin
fAllInProj := not fAllInProj; case fFindScope of
if fAllInProj then scDoc: fFindScope := scProj;
scProj: fFindScope := scOpened;
scOpened: fFindScope := scDoc;
end;
btnAllScope.Caption:= FindScopeStr[fFindScope];
if fFindScope <> scDoc then
begin begin
case GetIconScaledSize of case GetIconScaledSize of
iss16: AssignPng(btnAllScope, 'DOCUMENT_ALL'); iss16: AssignPng(btnAllScope, 'DOCUMENT_ALL');
iss24: AssignPng(btnAllScope, 'DOCUMENT_ALL24'); iss24: AssignPng(btnAllScope, 'DOCUMENT_ALL24');
iss32: AssignPng(btnAllScope, 'DOCUMENT_ALL32'); iss32: AssignPng(btnAllScope, 'DOCUMENT_ALL32');
end; end;
btnAllScope.Hint := 'all project sources'; if fFindScope = scProj then
btnAllScope.Hint := 'find in all the project sources'
else
btnAllScope.Hint := 'find in all the documents currently opened';
end end
else else
begin begin
@ -620,7 +651,7 @@ begin
iss24: AssignPng(btnAllScope, 'DOCUMENT24'); iss24: AssignPng(btnAllScope, 'DOCUMENT24');
iss32: AssignPng(btnAllScope, 'DOCUMENT32'); iss32: AssignPng(btnAllScope, 'DOCUMENT32');
end; end;
btnAllScope.Hint := 'selected source'; btnAllScope.Hint := 'find in the selected source';
end; end;
updateImperative; updateImperative;
end; end;
@ -630,14 +661,15 @@ var
canAll: boolean; canAll: boolean;
hasTxt: boolean; hasTxt: boolean;
begin begin
canAll := ((fDoc.isNotNil and not fAllInProj) or (fAllInProj and (fProj <> nil))); canAll := ((fDoc.isNotNil and (fFindScope <> scProj)) or
((fFindScope = scProj) and (fProj <> nil)));
hasTxt := fToFind.isNotEmpty and not fToFind.isBlank; hasTxt := fToFind.isNotEmpty and not fToFind.isBlank;
btnFind.Enabled := fDoc.isNotNil and hasTxt; btnFind.Enabled := fDoc.isNotNil and hasTxt;
btnFindAll.Enabled := canAll and hasTxt; btnFindAll.Enabled := canAll and hasTxt;
btnReplace.Enabled := fDoc.isNotNil and chkEnableRep.Checked and fToFind.isNotEmpty; btnReplace.Enabled := fDoc.isNotNil and chkEnableRep.Checked and fToFind.isNotEmpty;
btnReplaceAll.Enabled := btnReplace.Enabled; btnReplaceAll.Enabled := btnReplace.Enabled;
cbReplaceWth.Enabled := fDoc.isNotNil and chkEnableRep.Checked; cbReplaceWth.Enabled := fDoc.isNotNil and chkEnableRep.Checked;
cbToFind.Enabled := canAll or fDoc.isNotNil; cbToFind.Enabled := canAll;
end; end;
{$ENDREGION} {$ENDREGION}