search & replace, added btn to select the scope of "find all"

This commit is contained in:
Basile Burg 2016-01-26 10:36:12 +01:00
parent a8681e3f37
commit 3fdbf6b4be
4 changed files with 215 additions and 90 deletions

BIN
icons/file/document_all.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 B

View File

@ -1067,6 +1067,20 @@ LazarusResources.Add('document_plus','PNG',[
+#159'8Ej'#12#255'/'#187#148#251#229#151#0#3#0'7'#190#22'@6n'#188'T'#0#0#0#0
+'IEND'#174'B`'#130
]);
LazarusResources.Add('document_all','PNG',[
#137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#16#0#0#0#16#8#4#0#0#0#181#250'7'
+#234#0#0#0#4'gAMA'#0#0#175#200'7'#5#138#233#0#0#0#25'tEXtSoftware'#0'Adobe I'
+'mageReadyq'#201'e<'#0#0#0#207'IDAT('#207'u'#145'M'#10#194'0'#16'FG='#135'R'
+#207'P'#218#30#195'3'#184#243':E'#23#30#193'#'#184'q'#163#208#222#192'C("'
+#180#218#159#180#240'9'#153#180'i'#10#149#15#134#132'y'#188'0'#25#162#21#5#20
+#218'x4'#7#185'!'#10'T'#221'B'#167'A'#137'}LkZ'#140#129#176#229#198#29#23#156
+#145#226#138#221#137'6'#174'G'#128#10'7(L{'#4'P'#12#252#243#8#208' '#193#216
+#163'o'#135'X#'#29#144'b'#240#228'x'#227#193#167#2'G'#141#12'@'#239')'#144
+#225#217'yxp'#23'0'#181#194#151#145#151'X,'#144'X'#192' '#133'<4i0H'#205#200
+#167#3'<.'#17'm{'#143#137'b'#164'4'#0'O:'#227'a"'#215#160#207'JF'#22'@'#254
+#203'zt'#179#143#3#12#30'7uN'#254'x'#181#158#179'x'#29#159#150'?,?X'#234#201
+'.Yw'#0#0#0#0'IEND'#174'B`'#130
]);
LazarusResources.Add('folder','PNG',[
#137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#16#0#0#0#16#8#6#0#0#0#31#243#255'a'
+#0#0#0#25'tEXtSoftware'#0'Adobe ImageReadyq'#201'e<'#0#0#2#26'IDATx'#218#164

View File

@ -1,26 +1,26 @@
inherited CESearchWidget: TCESearchWidget
Left = 742
Height = 282
Height = 287
Top = 278
Width = 394
Width = 393
Caption = 'Search & replace'
ClientHeight = 282
ClientWidth = 394
ClientHeight = 287
ClientWidth = 393
inherited Back: TPanel
Height = 282
Width = 394
ClientHeight = 282
ClientWidth = 394
Height = 287
Width = 393
ClientHeight = 287
ClientWidth = 393
inherited Content: TPanel
Height = 282
Width = 394
ClientHeight = 282
ClientWidth = 394
Height = 287
Width = 393
ClientHeight = 287
ClientWidth = 393
object cbToFind: TComboBox[0]
Left = 4
Height = 23
Top = 4
Width = 386
Width = 385
Align = alTop
AutoSize = False
BorderSpacing.Around = 4
@ -32,8 +32,8 @@ inherited CESearchWidget: TCESearchWidget
object btnFind: TBitBtn[1]
Left = 4
Height = 24
Top = 170
Width = 386
Top = 167
Width = 385
Align = alBottom
BorderSpacing.Around = 4
Caption = 'btnFind'
@ -78,8 +78,8 @@ inherited CESearchWidget: TCESearchWidget
object btnReplace: TBitBtn[2]
Left = 4
Height = 24
Top = 226
Width = 386
Top = 195
Width = 385
Align = alBottom
BorderSpacing.Around = 4
Caption = 'btnReplace'
@ -123,14 +123,14 @@ inherited CESearchWidget: TCESearchWidget
end
object grpOpts: TGroupBox[3]
Left = 4
Height = 108
Height = 105
Top = 58
Width = 386
Width = 385
Align = alClient
BorderSpacing.Around = 4
Caption = 'Options'
ClientHeight = 78
ClientWidth = 382
ClientHeight = 75
ClientWidth = 381
TabOrder = 4
object chkWWord: TCheckBox
Left = 8
@ -190,8 +190,8 @@ inherited CESearchWidget: TCESearchWidget
object btnReplaceAll: TBitBtn[4]
Left = 4
Height = 24
Top = 254
Width = 386
Top = 259
Width = 385
Align = alBottom
BorderSpacing.Around = 4
Caption = 'btnReplaceAll'
@ -237,18 +237,18 @@ inherited CESearchWidget: TCESearchWidget
Left = 4
Height = 23
Top = 31
Width = 386
Width = 385
Align = alTop
BorderSpacing.Around = 4
BevelOuter = bvNone
ClientHeight = 23
ClientWidth = 386
ClientWidth = 385
TabOrder = 5
object cbReplaceWth: TComboBox
Left = 108
Height = 23
Top = 0
Width = 278
Width = 277
Align = alClient
Anchors = [akTop, akLeft, akBottom]
ItemHeight = 0
@ -267,51 +267,72 @@ inherited CESearchWidget: TCESearchWidget
TabOrder = 0
end
end
object btnFindAll: TBitBtn[6]
Left = 4
Height = 24
Top = 198
Width = 386
object Panel2: TPanel[6]
Left = 0
Height = 32
Top = 223
Width = 393
Align = alBottom
BorderSpacing.Around = 4
Caption = 'btnFindAll'
Glyph.Data = {
36040000424D3604000000000000360000002800000010000000100000000100
2000000000000004000064000000640000000000000000000000FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF003E39
34FF393430FF332F2BFF2C2925FF272421FF201D1BFF1716141A110F0EDB0B0A
09FF070706FF040403FF000000FF000000FFFFFFFF00FFFFFF00FFFFFF004641
3BFF857A70FFC3B8AEFF7C7268FF7F756BFF36322DFF1E1C190F282522D49589
7DFFBAAEA2FF7C7268FF7F756BFF010101FFFFFFFF00FFFFFF00FFFFFF004D47
41FF83786FFFCCC3BAFF786F65FF7B7167FF2F2B28F9272421011D1B18EE9589
7DFFC2B8ADFF786F65FF7C7268FF060505FFFFFFFF00FFFFFF00FFFFFF00534C
46FC83786FFFCCC3BAFF797066FF71685FFF37332ED5FFFFFF00252220D5857A
70FFC2B8ADFF786F65FF7B7167FF0A0908FCFFFFFF00FFFFFF00FFFFFF005A52
4CC39F9286FFCCC3BAFFC0B4AAFFA6988BFF3E3934A8FFFFFF002C2925A89084
79FFC2B8ADFFC0B4AAFFA89B8EFF110F0EC3FFFFFF00FFFFFF00797066055C55
4EF9423D38FF58514AFF3D3833FF332F2BFF23201DE5171614301E1C19B51A18
16FF252220FF191715FF0F0E0DFF010101EE00000002FFFFFF009F9286059D91
85FFB1A396FF7F756BFF7C7268FF776D64FF6C635BFF2E2A26FF564F48FF8076
6CFF7C7268FF776D64FF70675EFF000000FE00000005FFFFFF00AB9D9004AFA1
94E1BAAEA2FF82776DFF82776DFFAA917BFFBAA794FFB7A48EFAB09781FF9F8D
7DFF836D5BFF716357FF95897DFF040403E000000003FFFFFF00B9ACA008877D
72489B8E82FF9D9185FF867B71FF564F48FF504A44FF80766CFF6E665DFF826C
58FFA6917DFF948474FF564F48FF0C0B0B7A07070601FFFFFF00FFFFFF00FFFF
FF00746B62FFA4978AFF95897DFF9F9286FF3E3934FFFFFFFF004C4640FF7E74
6AFF857A70FF3E3934FF453F3AA72522200C15131102FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF008E8378E2C3B8AEFF655D55FFFFFFFF007C7268FFA89B
8EFF9C8F83E4FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF009C8F83E2BCB0A4FF9D9185FFFFFFFF00AEA093FF9D91
85FF655D55DAFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
}
BevelOuter = bvNone
ClientHeight = 32
ClientWidth = 393
TabOrder = 6
object btnFindAll: TBitBtn
Left = 4
Height = 24
Top = 4
Width = 352
Align = alClient
BorderSpacing.Around = 4
Caption = 'btnFindAll'
Glyph.Data = {
36040000424D3604000000000000360000002800000010000000100000000100
2000000000000004000064000000640000000000000000000000FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF003E39
34FF393430FF332F2BFF2C2925FF272421FF201D1BFF1716141A110F0EDB0B0A
09FF070706FF040403FF000000FF000000FFFFFFFF00FFFFFF00FFFFFF004641
3BFF857A70FFC3B8AEFF7C7268FF7F756BFF36322DFF1E1C190F282522D49589
7DFFBAAEA2FF7C7268FF7F756BFF010101FFFFFFFF00FFFFFF00FFFFFF004D47
41FF83786FFFCCC3BAFF786F65FF7B7167FF2F2B28F9272421011D1B18EE9589
7DFFC2B8ADFF786F65FF7C7268FF060505FFFFFFFF00FFFFFF00FFFFFF00534C
46FC83786FFFCCC3BAFF797066FF71685FFF37332ED5FFFFFF00252220D5857A
70FFC2B8ADFF786F65FF7B7167FF0A0908FCFFFFFF00FFFFFF00FFFFFF005A52
4CC39F9286FFCCC3BAFFC0B4AAFFA6988BFF3E3934A8FFFFFF002C2925A89084
79FFC2B8ADFFC0B4AAFFA89B8EFF110F0EC3FFFFFF00FFFFFF00797066055C55
4EF9423D38FF58514AFF3D3833FF332F2BFF23201DE5171614301E1C19B51A18
16FF252220FF191715FF0F0E0DFF010101EE00000002FFFFFF009F9286059D91
85FFB1A396FF7F756BFF7C7268FF776D64FF6C635BFF2E2A26FF564F48FF8076
6CFF7C7268FF776D64FF70675EFF000000FE00000005FFFFFF00AB9D9004AFA1
94E1BAAEA2FF82776DFF82776DFFAA917BFFBAA794FFB7A48EFAB09781FF9F8D
7DFF836D5BFF716357FF95897DFF040403E000000003FFFFFF00B9ACA008877D
72489B8E82FF9D9185FF867B71FF564F48FF504A44FF80766CFF6E665DFF826C
58FFA6917DFF948474FF564F48FF0C0B0B7A07070601FFFFFF00FFFFFF00FFFF
FF00746B62FFA4978AFF95897DFF9F9286FF3E3934FFFFFFFF004C4640FF7E74
6AFF857A70FF3E3934FF453F3AA72522200C15131102FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF008E8378E2C3B8AEFF655D55FFFFFFFF007C7268FFA89B
8EFF9C8F83E4FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF009C8F83E2BCB0A4FF9D9185FFFFFFFF00AEA093FF9D91
85FF655D55DAFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
}
TabOrder = 0
end
object btnAllScope: TBitBtn
Left = 360
Height = 24
Top = 4
Width = 29
Align = alRight
BorderSpacing.Around = 4
OnClick = btnAllScopeClick
TabOrder = 1
end
end
end
end

View File

@ -8,7 +8,7 @@ uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
Menus, StdCtrls, actnList, Buttons, SynEdit, SynEditSearch, SynEditTypes,
ce_common, ce_mru, ce_widget, ce_synmemo, ce_interfaces, ce_observer,
ce_writableComponent, ce_dialogs, strutils;
ce_writableComponent, ce_dialogs, ce_sharedres;
type
@ -43,7 +43,8 @@ type
end;
{ TCESearchWidget }
TCESearchWidget = class(TCEWidget, ICEMultiDocObserver)
TCESearchWidget = class(TCEWidget, ICEMultiDocObserver, ICEProjectObserver)
btnAllScope: TBitBtn;
btnFind: TBitBtn;
btnFindAll: TBitBtn;
btnReplace: TBitBtn;
@ -60,6 +61,8 @@ type
grpOpts: TGroupBox;
imgList: TImageList;
Panel1: TPanel;
Panel2: TPanel;
procedure btnAllScopeClick(Sender: TObject);
procedure cbReplaceWthChange(Sender: TObject);
procedure cbToFindChange(Sender: TObject);
procedure chkEnableRepChange(Sender: TObject);
@ -75,21 +78,31 @@ type
fCancelAll: boolean;
fHasSearched: boolean;
fHasRestarted: boolean;
fProj: ICECommonProject;
fAllInProj: boolean;
function getOptions: TSynSearchOptions;
procedure actReplaceAllExecute(sender: TObject);
procedure replaceEvent(Sender: TObject; const ASearch, AReplace:
string; Line, Column: integer; var ReplaceAction: TSynReplaceAction);
protected
procedure updateImperative; override;
public
constructor Create(aOwner: TComponent); override;
destructor Destroy; override;
//
procedure projNew(aProject: ICECommonProject);
procedure projChanged(aProject: ICECommonProject);
procedure projClosing(aProject: ICECommonProject);
procedure projFocused(aProject: ICECommonProject);
procedure projCompiling(aProject: ICECommonProject);
//
procedure docNew(aDoc: TCESynMemo);
procedure docClosing(aDoc: TCESynMemo);
procedure docFocused(aDoc: TCESynMemo);
procedure docChanged(aDoc: TCESynMemo);
//
procedure findAll(const filename: string; lines: TStrings);
protected
procedure updateImperative; override;
public
constructor Create(aOwner: TComponent); override;
destructor Destroy; override;
//
procedure actFindNextExecute(sender: TObject);
procedure actReplaceNextExecute(sender: TObject);
procedure actFindAllExecute(sender: TObject);
@ -215,6 +228,7 @@ begin
btnReplace.Action := fActReplaceNext;
btnReplaceAll.Action := fActReplaceAll;
btnFindAll.Action := fActFindAll;
AssignPng(btnAllScope, 'document');
updateImperative;
//
EntitiesConnector.addObserver(self);
@ -256,7 +270,7 @@ begin
end;
procedure TCESearchWidget.replaceEvent(Sender: TObject; const ASearch, AReplace:
string; Line, Column: integer; var ReplaceAction: TSynReplaceAction);
string; Line, Column: integer; var ReplaceAction: TSynReplaceAction);
begin
case dlgReplaceAll of
mrYes: ReplaceAction := raReplace;
@ -271,6 +285,37 @@ begin
end;
procedure TCESearchWidget.actFindAllExecute(sender: TObject);
var
i: integer;
syn: TSynEdit;
fnm: string;
begin
if fDoc.isNil and not fAllInProj then
exit;
if (fProj = nil) and fAllInProj then
exit;
//
fSearchMru.Insert(0,fToFind);
cbToFind.Items.Assign(fSearchMru);
//
if fAllInProj then
begin
syn := TSynEdit.Create(nil);
try
for i := 0 to fProj.sourcesCount-1 do
begin
fnm := fProj.sourceAbsolute(i);
syn.Lines.LoadFromFile(fnm);
findAll(fnm, syn.Lines);
end;
finally
syn.Free;
end;
end
else findAll(fDoc.fileName, fDoc.Lines);
end;
procedure TCESearchWidget.findAll(const filename: string; lines: TStrings);
var
search: TSynEditSearch;
options: TSynSearchOptions;
@ -282,11 +327,6 @@ var
i: integer;
res: array of TPoint = nil;
begin
if fDoc.isNil then exit;
//
fSearchMru.Insert(0,fToFind);
cbToFind.Items.Assign(fSearchMru);
//
search := TSynEditSearch.Create;
try
options := getOptions;
@ -294,10 +334,12 @@ begin
search.Whole := ssoWholeWord in options;
search.RegularExpressions:= ssoRegExpr in options;
search.Pattern:=fToFind;
search.IdentChars:=fDoc.IdentChars;
// search.IdentChars:= [];
start := Point(1,1);
stop := Point(high(integer), fDoc.Lines.Count);
while search.FindNextOne(fDoc.Lines, start, stop, startf, stopf) do
stop := Point(high(integer), lines.Count);
while search.FindNextOne(lines, start, stop, startf, stopf) do
begin
setLength(res, length(res) + 1);
res[high(res)].X := startf.X;
@ -307,10 +349,10 @@ begin
msgs := getMessageDisplay;
msg := format('%d result(s) for the pattern <%s>', [length(res), fToFind]);
msgs.message(msg, nil, amcMisc, amkInf);
fmt := fDoc.fileName + '(%d,%d): "%s"';
fmt := fileName + '(%d,%d): "%s"';
for i := 0 to high(res) do
begin
msg := format(fmt, [res[i].Y, res[i].X, Trim(fDoc.Lines.Strings[res[i].Y-1])]);
msg := format(fmt, [res[i].Y, res[i].X, Trim(lines.Strings[res[i].Y-1])]);
msgs.message(msg, nil, amcMisc, amkInf);
end;
finally
@ -413,6 +455,35 @@ begin
end;
{$ENDREGION}
{$REGION ICEProjectObserver ----------------------------------------------------}
procedure TCESearchWidget.projNew(aProject: ICECommonProject);
begin
fProj := aProject;
updateImperative;
end;
procedure TCESearchWidget.projChanged(aProject: ICECommonProject);
begin
end;
procedure TCESearchWidget.projClosing(aProject: ICECommonProject);
begin
if fProj = aProject then
fProj := nil;
updateImperative;
end;
procedure TCESearchWidget.projFocused(aProject: ICECommonProject);
begin
fProj := aProject;
updateImperative;
end;
procedure TCESearchWidget.projCompiling(aProject: ICECommonProject);
begin
end;
{$ENDREGION}
{$REGION ICEMultiDocObserver ---------------------------------------------------}
procedure TCESearchWidget.docNew(aDoc: TCESynMemo);
begin
@ -461,14 +532,33 @@ begin
updateImperative;
end;
procedure TCESearchWidget.updateImperative;
procedure TCESearchWidget.btnAllScopeClick(Sender: TObject);
begin
fAllInProj := not fAllInProj;
if fAllInProj then
begin
AssignPng(btnAllScope, 'document_all');
btnAllScope.Hint := 'all project sources';
end
else
begin
AssignPng(btnAllScope, 'document');
btnAllScope.Hint := 'selected source';
end;
updateImperative;
end;
procedure TCESearchWidget.updateImperative;
var
canAll: boolean;
begin
canAll := (fDoc.isNotNil and not fAllInProj) or (fAllInProj and (fProj <> nil));
btnFind.Enabled := fDoc.isNotNil and fToFind.isNotEmpty;
btnFindAll.Enabled := fDoc.isNotNil and fToFind.isNotEmpty;
btnFindAll.Enabled := canAll;
btnReplace.Enabled := fDoc.isNotNil and chkEnableRep.Checked and fToFind.isNotEmpty;
btnReplaceAll.Enabled := btnReplace.Enabled;
cbReplaceWth.Enabled := fDoc.isNotNil and chkEnableRep.Checked;
cbToFind.Enabled := fDoc.isNotNil;
cbToFind.Enabled := canAll;
end;
{$ENDREGION}